From 351fbd0d064cd478a846ee3c02b684ef8a65a98e Mon Sep 17 00:00:00 2001 From: Rob Hogan Date: Wed, 28 Jan 2026 04:04:47 -0800 Subject: [PATCH] react-native-babel-preset: Add transform snapshot tests Summary: Add snapshot tests to validate Babel transform output under `react-native/babel-preset` under different configurations (default, hermes-stable, hermes-canary) and options (dev/prod, ESM output, babel-runtime). This enables catching unintended transform changes during preset updates. The tests use a "kitchen-sink" input fixture covering private fields, async generators, Flow enums, JSX, hooks, and other syntax patterns, with separate output files per configuration for easy diffing. Changelog: [Internal] Differential Revision: D91677590 --- .../__fixtures__/kitchen-sink-input.js | 261 +++++++++++++ .../__fixtures__/output/default-dev.js | 311 +++++++++++++++ .../__fixtures__/output/default-prod.js | 310 +++++++++++++++ .../__fixtures__/output/hermes-canary-dev.js | 284 ++++++++++++++ .../__fixtures__/output/hermes-canary-prod.js | 278 ++++++++++++++ .../__fixtures__/output/hermes-stable-dev.js | 284 ++++++++++++++ ...-stable-prod-no-import-export-transform.js | 252 +++++++++++++ .../__fixtures__/output/hermes-stable-prod.js | 278 ++++++++++++++ .../__fixtures__/output/no-babel-runtime.js | 323 ++++++++++++++++ .../output/no-import-export-transform.js | 288 ++++++++++++++ .../output/with-babel-runtime-version.js | 306 +++++++++++++++ .../src/__tests__/transform-snapshot-test.js | 354 ++++++++++++++++++ 12 files changed, 3529 insertions(+) create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/kitchen-sink-input.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/default-dev.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/default-prod.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-canary-dev.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-canary-prod.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-dev.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-prod-no-import-export-transform.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-prod.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/no-babel-runtime.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/no-import-export-transform.js create mode 100644 packages/react-native-babel-preset/src/__tests__/__fixtures__/output/with-babel-runtime-version.js create mode 100644 packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/kitchen-sink-input.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/kitchen-sink-input.js new file mode 100644 index 00000000000000..761f2a2eabb605 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/kitchen-sink-input.js @@ -0,0 +1,261 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import type {Node} from 'react'; + +import * as React from 'react'; +import {useEffect, useState} from 'react'; + +// Flow enum +enum Status { + Active, + Inactive, + Pending, +} + +// Private class fields and methods +class Counter { + #count: number = 0; + static #instances: number = 0; + + constructor() { + Counter.#instances++; + } + + #increment(): void { + this.#count++; + } + + // $FlowExpectedError[unsafe-getters-setters] - Testing getter syntax + get value(): number { + return this.#count; + } + + increment(): void { + this.#increment(); + } + + // $FlowExpectedError[unsafe-getters-setters] - Testing static getter syntax + static get instanceCount(): number { + return Counter.#instances; + } +} + +// Async generator function +async function* asyncNumberGenerator( + max: number, +): AsyncGenerator { + for (let i = 0; i < max; i++) { + await new Promise(resolve => setTimeout(resolve, 100)); + yield i; + } +} + +// Async/await patterns +async function fetchData(url: string): Promise<{data: mixed}> { + const response = await fetch(url); + const data = await response.json(); + return {data}; +} + +// Optional chaining and nullish coalescing +function getNestedValue(obj: ?{a?: {b?: {c?: number}}}): number { + return obj?.a?.b?.c ?? 42; +} + +// Class with various features +class Animal { + name: string; + #age: number; + + constructor(name: string, age: number) { + this.name = name; + this.#age = age; + } + + speak(): string { + return `${this.name} makes a sound`; + } + + // $FlowExpectedError[unsafe-getters-setters] - Testing getter syntax + get age(): number { + return this.#age; + } +} + +class Dog extends Animal { + breed: string; + + constructor(name: string, age: number, breed: string) { + super(name, age); + this.breed = breed; + } + + speak(): string { + return `${this.name} barks!`; + } + + async fetchTreats(): Promise> { + await new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + } +} + +// Destructuring patterns +function processUser({ + name, + age = 18, + ...rest +}: { + name: string, + age?: number, + city?: string, + ... +}): string { + const {city = 'Unknown'} = rest; + return `${name} (${age}) from ${city}`; +} + +// Spread operators +function mergeConfigs( + base: T, + ...overrides: ReadonlyArray> +): T { + // $FlowExpectedError[incompatible-return] - Testing spread syntax + // $FlowExpectedError[incompatible-type] - Testing spread syntax + return {...base, ...overrides.reduce((acc, o) => ({...acc, ...o}), {})}; +} + +// for...of with destructuring +function sumPairs(pairs: Array<[number, number]>): number { + let total = 0; + for (const [a, b] of pairs) { + total += a + b; + } + return total; +} + +// Named capturing groups in regex +function parseDate( + dateString: string, +): ?{year: string, month: string, day: string} { + const regex = /(?\d{4})-(?\d{2})-(?\d{2})/; + const match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day, + }; + } + return null; +} + +// Try-catch with optional binding +function safeJsonParse(input: string): mixed { + try { + return JSON.parse(input); + } catch { + return null; + } +} + +// Unicode regex +function matchEmoji(text: string): ?string { + const match = text.match(/\p{Emoji}/u); + return match?.[0]; +} + +// Class expression +const MyClass = class { + value: number; + constructor(value: number) { + this.value = value; + } +}; + +// Dynamic import (syntax only) +async function loadModule(): Promise { + // $FlowExpectedError[cannot-resolve-module] - Testing dynamic import syntax + const module = await import('./some-module'); + return module.default; +} + +// React component using createClass pattern (legacy) +// $FlowExpectedError[prop-missing] - Testing legacy React.createClass +// $FlowExpectedError[signature-verification-failure] - Testing legacy React.createClass +const LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return {count: 0}; + }, + render() { + // $FlowExpectedError[object-this-reference] - Testing legacy this reference + return
{this.state.count}
; + }, +}); + +// Modern React functional component with hooks +function ModernComponent({initialCount = 0}: {initialCount?: number}): Node { + const [count, setCount] = useState(initialCount); + const [status, setStatus] = useState(Status.Active); + + useEffect(() => { + const timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + + async function handleAsyncClick(): Promise { + const data = await fetchData('/api/data'); + console.log(data); + } + + const handleClick = async () => { + await handleAsyncClick(); + setStatus(Status.Pending); + }; + + return ( +
+ {count} + {String(status)} + + +
+ ); +} + +// Export default from syntax +// $FlowExpectedError[cannot-resolve-module] - Testing export default from syntax +export {fetchData as default} from './data-utils'; + +// Named exports +export { + Counter, + Animal, + Dog, + asyncNumberGenerator, + getNestedValue, + processUser, + mergeConfigs, + sumPairs, + parseDate, + safeJsonParse, + matchEmoji, + MyClass, + loadModule, + ModernComponent, + LegacyComponent, +}; + +// Type exports +export type {Node}; diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/default-dev.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/default-dev.js new file mode 100644 index 00000000000000..9952762cf74f53 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/default-dev.js @@ -0,0 +1,311 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - Default transform profile in development mode + * - Options: {"dev":true} + */ + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LegacyComponent = exports.Dog = exports.Counter = exports.Animal = void 0; +exports.ModernComponent = ModernComponent; +exports.MyClass = void 0; +exports.asyncNumberGenerator = asyncNumberGenerator; +Object.defineProperty(exports, "default", { + enumerable: true, + get: function () { + return _dataUtils.fetchData; + } +}); +exports.getNestedValue = getNestedValue; +exports.loadModule = loadModule; +exports.matchEmoji = matchEmoji; +exports.mergeConfigs = mergeConfigs; +exports.parseDate = parseDate; +exports.processUser = processUser; +exports.safeJsonParse = safeJsonParse; +exports.sumPairs = sumPairs; +var _setPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/setPrototypeOf")); +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); +var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); +var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); +var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); +var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); +var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); +var _classPrivateFieldLooseBase2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseBase")); +var _classPrivateFieldLooseKey2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseKey")); +var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator")); +var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator")); +var _react = _interopRequireWildcard(require("react")); +var React = _react; +var _jsxRuntime = require("react/jsx-runtime"); +var _dataUtils = require("./data-utils"); +var _jsxFileName = "/data/sandcastle/boxes/fbsource/xplat/js/react-native-github/packages/react-native-babel-preset/src/__tests__/__fixtures__/kitchen-sink-input.js"; +function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), (0, _setPrototypeOf2.default)(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return (0, _inherits2.default)(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); } +function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); } +var _count = (0, _classPrivateFieldLooseKey2.default)("count"); +var _instances = (0, _classPrivateFieldLooseKey2.default)("instances"); +var _increment = (0, _classPrivateFieldLooseKey2.default)("increment"); +var Counter = exports.Counter = function () { + function Counter() { + (0, _classCallCheck2.default)(this, Counter); + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]++; + } + return (0, _createClass2.default)(Counter, [{ + key: "value", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]; + } + }, { + key: "increment", + value: function increment() { + (0, _classPrivateFieldLooseBase2.default)(this, _increment)[_increment](); + } + }], [{ + key: "instanceCount", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]; + } + }]); +}(); +function _increment2() { + (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = (0, _wrapAsyncGenerator2.default)(function* (max) { + for (var i = 0; i < max; i++) { + yield (0, _awaitAsyncGenerator2.default)(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = (0, _asyncToGenerator2.default)(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + return obj?.a?.b?.c ?? 42; +} +var _age = (0, _classPrivateFieldLooseKey2.default)("age"); +var Animal = exports.Animal = function () { + function Animal(name, age) { + (0, _classCallCheck2.default)(this, Animal); + Object.defineProperty(this, _age, { + writable: true, + value: void 0 + }); + this.name = name; + (0, _classPrivateFieldLooseBase2.default)(this, _age)[_age] = age; + } + return (0, _createClass2.default)(Animal, [{ + key: "speak", + value: function speak() { + return `${this.name} makes a sound`; + } + }, { + key: "age", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(this, _age)[_age]; + } + }]); +}(); +var Dog = exports.Dog = function (_Animal2) { + function Dog(name, age, breed) { + var _this; + (0, _classCallCheck2.default)(this, Dog); + _this = _callSuper(this, Dog, [name, age]); + _this.breed = breed; + return _this; + } + (0, _inherits2.default)(Dog, _Animal2); + return (0, _createClass2.default)(Dog, [{ + key: "speak", + value: function speak() { + return `${this.name} barks!`; + } + }, { + key: "fetchTreats", + value: function () { + var _fetchTreats = (0, _asyncToGenerator2.default)(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + }); + function fetchTreats() { + return _fetchTreats.apply(this, arguments); + } + return fetchTreats; + }() + }]); +}(Animal); +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _ref of pairs) { + var _ref2 = (0, _slicedToArray2.default)(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match?.[0]; +} +var MyClass = exports.MyClass = (0, _createClass2.default)(function MyClass(value) { + (0, _classCallCheck2.default)(this, MyClass); + this.value = value; +}); +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = (0, _asyncToGenerator2.default)(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = exports.LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return (0, _jsxRuntime.jsx)("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = (0, _react.useState)(initialCount), + _useState2 = (0, _slicedToArray2.default)(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = (0, _react.useState)(Status.Active), + _useState4 = (0, _slicedToArray2.default)(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + (0, _react.useEffect)(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = (0, _asyncToGenerator2.default)(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = (0, _asyncToGenerator2.default)(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return (0, _jsxRuntime.jsxs)("div", { + children: [(0, _jsxRuntime.jsx)("span", { + "data-testid": "count", + children: count + }), (0, _jsxRuntime.jsx)("span", { + "data-testid": "status", + children: String(status) + }), (0, _jsxRuntime.jsx)("button", { + onClick: handleClick, + children: "Increment" + }), (0, _jsxRuntime.jsx)(LegacyComponent, {})] + }); +} \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/default-prod.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/default-prod.js new file mode 100644 index 00000000000000..190d8969be82c1 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/default-prod.js @@ -0,0 +1,310 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - Default transform profile in production mode + * - Options: {"dev":false} + */ + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LegacyComponent = exports.Dog = exports.Counter = exports.Animal = void 0; +exports.ModernComponent = ModernComponent; +exports.MyClass = void 0; +exports.asyncNumberGenerator = asyncNumberGenerator; +Object.defineProperty(exports, "default", { + enumerable: true, + get: function () { + return _dataUtils.fetchData; + } +}); +exports.getNestedValue = getNestedValue; +exports.loadModule = loadModule; +exports.matchEmoji = matchEmoji; +exports.mergeConfigs = mergeConfigs; +exports.parseDate = parseDate; +exports.processUser = processUser; +exports.safeJsonParse = safeJsonParse; +exports.sumPairs = sumPairs; +var _setPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/setPrototypeOf")); +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); +var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); +var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); +var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); +var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); +var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); +var _classPrivateFieldLooseBase2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseBase")); +var _classPrivateFieldLooseKey2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseKey")); +var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator")); +var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator")); +var _react = _interopRequireWildcard(require("react")); +var React = _react; +var _jsxRuntime = require("react/jsx-runtime"); +var _dataUtils = require("./data-utils"); +function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), (0, _setPrototypeOf2.default)(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return (0, _inherits2.default)(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); } +function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); } +var _count = (0, _classPrivateFieldLooseKey2.default)("count"); +var _instances = (0, _classPrivateFieldLooseKey2.default)("instances"); +var _increment = (0, _classPrivateFieldLooseKey2.default)("increment"); +var Counter = exports.Counter = function () { + function Counter() { + (0, _classCallCheck2.default)(this, Counter); + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]++; + } + return (0, _createClass2.default)(Counter, [{ + key: "value", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]; + } + }, { + key: "increment", + value: function increment() { + (0, _classPrivateFieldLooseBase2.default)(this, _increment)[_increment](); + } + }], [{ + key: "instanceCount", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]; + } + }]); +}(); +function _increment2() { + (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = (0, _wrapAsyncGenerator2.default)(function* (max) { + for (var i = 0; i < max; i++) { + yield (0, _awaitAsyncGenerator2.default)(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = (0, _asyncToGenerator2.default)(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + return obj?.a?.b?.c ?? 42; +} +var _age = (0, _classPrivateFieldLooseKey2.default)("age"); +var Animal = exports.Animal = function () { + function Animal(name, age) { + (0, _classCallCheck2.default)(this, Animal); + Object.defineProperty(this, _age, { + writable: true, + value: void 0 + }); + this.name = name; + (0, _classPrivateFieldLooseBase2.default)(this, _age)[_age] = age; + } + return (0, _createClass2.default)(Animal, [{ + key: "speak", + value: function speak() { + return `${this.name} makes a sound`; + } + }, { + key: "age", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(this, _age)[_age]; + } + }]); +}(); +var Dog = exports.Dog = function (_Animal2) { + function Dog(name, age, breed) { + var _this; + (0, _classCallCheck2.default)(this, Dog); + _this = _callSuper(this, Dog, [name, age]); + _this.breed = breed; + return _this; + } + (0, _inherits2.default)(Dog, _Animal2); + return (0, _createClass2.default)(Dog, [{ + key: "speak", + value: function speak() { + return `${this.name} barks!`; + } + }, { + key: "fetchTreats", + value: function () { + var _fetchTreats = (0, _asyncToGenerator2.default)(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + }); + function fetchTreats() { + return _fetchTreats.apply(this, arguments); + } + return fetchTreats; + }() + }]); +}(Animal); +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _ref of pairs) { + var _ref2 = (0, _slicedToArray2.default)(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match?.[0]; +} +var MyClass = exports.MyClass = (0, _createClass2.default)(function MyClass(value) { + (0, _classCallCheck2.default)(this, MyClass); + this.value = value; +}); +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = (0, _asyncToGenerator2.default)(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = exports.LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return (0, _jsxRuntime.jsx)("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = (0, _react.useState)(initialCount), + _useState2 = (0, _slicedToArray2.default)(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = (0, _react.useState)(Status.Active), + _useState4 = (0, _slicedToArray2.default)(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + (0, _react.useEffect)(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = (0, _asyncToGenerator2.default)(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = (0, _asyncToGenerator2.default)(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return (0, _jsxRuntime.jsxs)("div", { + children: [(0, _jsxRuntime.jsx)("span", { + "data-testid": "count", + children: count + }), (0, _jsxRuntime.jsx)("span", { + "data-testid": "status", + children: String(status) + }), (0, _jsxRuntime.jsx)("button", { + onClick: handleClick, + children: "Increment" + }), (0, _jsxRuntime.jsx)(LegacyComponent, {})] + }); +} \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-canary-dev.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-canary-dev.js new file mode 100644 index 00000000000000..7770419f9f5f00 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-canary-dev.js @@ -0,0 +1,284 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - Hermes canary transform profile in development mode + * - Options: {"dev":true,"unstable_transformProfile":"hermes-canary"} + */ + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LegacyComponent = exports.Dog = exports.Counter = exports.Animal = void 0; +exports.ModernComponent = ModernComponent; +exports.MyClass = void 0; +exports.asyncNumberGenerator = asyncNumberGenerator; +Object.defineProperty(exports, "default", { + enumerable: true, + get: function () { + return _dataUtils.fetchData; + } +}); +exports.getNestedValue = getNestedValue; +exports.loadModule = loadModule; +exports.matchEmoji = matchEmoji; +exports.mergeConfigs = mergeConfigs; +exports.parseDate = parseDate; +exports.processUser = processUser; +exports.safeJsonParse = safeJsonParse; +exports.sumPairs = sumPairs; +var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); +var _setPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/setPrototypeOf")); +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); +var _classPrivateFieldLooseBase2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseBase")); +var _classPrivateFieldLooseKey2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseKey")); +var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator")); +var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator")); +var _react = _interopRequireWildcard(require("react")); +var React = _react; +var _jsxRuntime = require("react/jsx-runtime"); +var _dataUtils = require("./data-utils"); +var _jsxFileName = "/data/sandcastle/boxes/fbsource/xplat/js/react-native-github/packages/react-native-babel-preset/src/__tests__/__fixtures__/kitchen-sink-input.js"; +function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), (0, _setPrototypeOf2.default)(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return (0, _inherits2.default)(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +function _createForOfIteratorHelperLoose(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (t) return (t = t.call(r)).next.bind(t); if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var o = 0; return function () { return o >= r.length ? { done: !0 } : { done: !1, value: r[o++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } +function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } +var _count = (0, _classPrivateFieldLooseKey2.default)("count"); +var _instances = (0, _classPrivateFieldLooseKey2.default)("instances"); +var _increment = (0, _classPrivateFieldLooseKey2.default)("increment"); +class Counter { + constructor() { + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]++; + } + get value() { + return (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]; + } + increment() { + (0, _classPrivateFieldLooseBase2.default)(this, _increment)[_increment](); + } + static get instanceCount() { + return (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]; + } +} +exports.Counter = Counter; +function _increment2() { + (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = (0, _wrapAsyncGenerator2.default)(function* (max) { + for (var i = 0; i < max; i++) { + yield (0, _awaitAsyncGenerator2.default)(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = (0, _asyncToGenerator2.default)(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + var _obj$a$b$c, _obj$a; + return (_obj$a$b$c = obj == null || (_obj$a = obj.a) == null || (_obj$a = _obj$a.b) == null ? void 0 : _obj$a.c) != null ? _obj$a$b$c : 42; +} +class Animal { + #age; + constructor(name, age) { + this.name = name; + this.#age = age; + } + speak() { + return `${this.name} makes a sound`; + } + get age() { + return this.#age; + } +} +exports.Animal = Animal; +class Dog extends Animal { + constructor(name, age, breed) { + super(name, age); + this.breed = breed; + } + speak() { + return `${this.name} barks!`; + } + fetchTreats() { + return (0, _asyncToGenerator2.default)(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + })(); + } +} +exports.Dog = Dog; +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _iterator = _createForOfIteratorHelperLoose(pairs), _step; !(_step = _iterator()).done;) { + var _ref = _step.value; + var _ref2 = (0, _slicedToArray2.default)(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match != null && match.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch (_unused) { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match == null ? void 0 : match[0]; +} +var MyClass = class { + constructor(value) { + this.value = value; + } +}; +exports.MyClass = MyClass; +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = (0, _asyncToGenerator2.default)(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = exports.LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return (0, _jsxRuntime.jsx)("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = (0, _react.useState)(initialCount), + _useState2 = (0, _slicedToArray2.default)(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = (0, _react.useState)(Status.Active), + _useState4 = (0, _slicedToArray2.default)(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + (0, _react.useEffect)(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = (0, _asyncToGenerator2.default)(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = (0, _asyncToGenerator2.default)(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return (0, _jsxRuntime.jsxs)("div", { + children: [(0, _jsxRuntime.jsx)("span", { + "data-testid": "count", + children: count + }), (0, _jsxRuntime.jsx)("span", { + "data-testid": "status", + children: String(status) + }), (0, _jsxRuntime.jsx)("button", { + onClick: handleClick, + children: "Increment" + }), (0, _jsxRuntime.jsx)(LegacyComponent, {})] + }); +} \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-canary-prod.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-canary-prod.js new file mode 100644 index 00000000000000..510b81b7af5255 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-canary-prod.js @@ -0,0 +1,278 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - Hermes canary transform profile in production mode + * - Options: {"dev":false,"unstable_transformProfile":"hermes-canary"} + */ + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LegacyComponent = exports.Dog = exports.Counter = exports.Animal = void 0; +exports.ModernComponent = ModernComponent; +exports.MyClass = void 0; +exports.asyncNumberGenerator = asyncNumberGenerator; +Object.defineProperty(exports, "default", { + enumerable: true, + get: function () { + return _dataUtils.fetchData; + } +}); +exports.getNestedValue = getNestedValue; +exports.loadModule = loadModule; +exports.matchEmoji = matchEmoji; +exports.mergeConfigs = mergeConfigs; +exports.parseDate = parseDate; +exports.processUser = processUser; +exports.safeJsonParse = safeJsonParse; +exports.sumPairs = sumPairs; +var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); +var _setPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/setPrototypeOf")); +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); +var _classPrivateFieldLooseBase2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseBase")); +var _classPrivateFieldLooseKey2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseKey")); +var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator")); +var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator")); +var _react = _interopRequireWildcard(require("react")); +var React = _react; +var _jsxRuntime = require("react/jsx-runtime"); +var _dataUtils = require("./data-utils"); +function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), (0, _setPrototypeOf2.default)(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return (0, _inherits2.default)(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +var _count = (0, _classPrivateFieldLooseKey2.default)("count"); +var _instances = (0, _classPrivateFieldLooseKey2.default)("instances"); +var _increment = (0, _classPrivateFieldLooseKey2.default)("increment"); +class Counter { + constructor() { + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]++; + } + get value() { + return (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]; + } + increment() { + (0, _classPrivateFieldLooseBase2.default)(this, _increment)[_increment](); + } + static get instanceCount() { + return (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]; + } +} +exports.Counter = Counter; +function _increment2() { + (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = (0, _wrapAsyncGenerator2.default)(function* (max) { + for (var i = 0; i < max; i++) { + yield (0, _awaitAsyncGenerator2.default)(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = (0, _asyncToGenerator2.default)(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + return obj?.a?.b?.c ?? 42; +} +class Animal { + #age; + constructor(name, age) { + this.name = name; + this.#age = age; + } + speak() { + return `${this.name} makes a sound`; + } + get age() { + return this.#age; + } +} +exports.Animal = Animal; +class Dog extends Animal { + constructor(name, age, breed) { + super(name, age); + this.breed = breed; + } + speak() { + return `${this.name} barks!`; + } + fetchTreats() { + return (0, _asyncToGenerator2.default)(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + })(); + } +} +exports.Dog = Dog; +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _ref of pairs) { + var _ref2 = (0, _slicedToArray2.default)(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match?.[0]; +} +var MyClass = class { + constructor(value) { + this.value = value; + } +}; +exports.MyClass = MyClass; +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = (0, _asyncToGenerator2.default)(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = exports.LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return (0, _jsxRuntime.jsx)("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = (0, _react.useState)(initialCount), + _useState2 = (0, _slicedToArray2.default)(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = (0, _react.useState)(Status.Active), + _useState4 = (0, _slicedToArray2.default)(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + (0, _react.useEffect)(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = (0, _asyncToGenerator2.default)(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = (0, _asyncToGenerator2.default)(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return (0, _jsxRuntime.jsxs)("div", { + children: [(0, _jsxRuntime.jsx)("span", { + "data-testid": "count", + children: count + }), (0, _jsxRuntime.jsx)("span", { + "data-testid": "status", + children: String(status) + }), (0, _jsxRuntime.jsx)("button", { + onClick: handleClick, + children: "Increment" + }), (0, _jsxRuntime.jsx)(LegacyComponent, {})] + }); +} \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-dev.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-dev.js new file mode 100644 index 00000000000000..17fde6ae28efb8 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-dev.js @@ -0,0 +1,284 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - Hermes stable transform profile in development mode + * - Options: {"dev":true,"unstable_transformProfile":"hermes-stable"} + */ + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LegacyComponent = exports.Dog = exports.Counter = exports.Animal = void 0; +exports.ModernComponent = ModernComponent; +exports.MyClass = void 0; +exports.asyncNumberGenerator = asyncNumberGenerator; +Object.defineProperty(exports, "default", { + enumerable: true, + get: function () { + return _dataUtils.fetchData; + } +}); +exports.getNestedValue = getNestedValue; +exports.loadModule = loadModule; +exports.matchEmoji = matchEmoji; +exports.mergeConfigs = mergeConfigs; +exports.parseDate = parseDate; +exports.processUser = processUser; +exports.safeJsonParse = safeJsonParse; +exports.sumPairs = sumPairs; +var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); +var _setPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/setPrototypeOf")); +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); +var _classPrivateFieldLooseBase2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseBase")); +var _classPrivateFieldLooseKey2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseKey")); +var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator")); +var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator")); +var _react = _interopRequireWildcard(require("react")); +var React = _react; +var _jsxRuntime = require("react/jsx-runtime"); +var _dataUtils = require("./data-utils"); +var _jsxFileName = "/data/sandcastle/boxes/fbsource/xplat/js/react-native-github/packages/react-native-babel-preset/src/__tests__/__fixtures__/kitchen-sink-input.js"; +function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), (0, _setPrototypeOf2.default)(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return (0, _inherits2.default)(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +function _createForOfIteratorHelperLoose(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (t) return (t = t.call(r)).next.bind(t); if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var o = 0; return function () { return o >= r.length ? { done: !0 } : { done: !1, value: r[o++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } +function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } +var _count = (0, _classPrivateFieldLooseKey2.default)("count"); +var _instances = (0, _classPrivateFieldLooseKey2.default)("instances"); +var _increment = (0, _classPrivateFieldLooseKey2.default)("increment"); +class Counter { + constructor() { + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]++; + } + get value() { + return (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]; + } + increment() { + (0, _classPrivateFieldLooseBase2.default)(this, _increment)[_increment](); + } + static get instanceCount() { + return (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]; + } +} +exports.Counter = Counter; +function _increment2() { + (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = (0, _wrapAsyncGenerator2.default)(function* (max) { + for (var i = 0; i < max; i++) { + yield (0, _awaitAsyncGenerator2.default)(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = (0, _asyncToGenerator2.default)(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + var _obj$a$b$c, _obj$a; + return (_obj$a$b$c = obj == null || (_obj$a = obj.a) == null || (_obj$a = _obj$a.b) == null ? void 0 : _obj$a.c) != null ? _obj$a$b$c : 42; +} +class Animal { + #age; + constructor(name, age) { + this.name = name; + this.#age = age; + } + speak() { + return `${this.name} makes a sound`; + } + get age() { + return this.#age; + } +} +exports.Animal = Animal; +class Dog extends Animal { + constructor(name, age, breed) { + super(name, age); + this.breed = breed; + } + speak() { + return `${this.name} barks!`; + } + fetchTreats() { + return (0, _asyncToGenerator2.default)(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + })(); + } +} +exports.Dog = Dog; +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _iterator = _createForOfIteratorHelperLoose(pairs), _step; !(_step = _iterator()).done;) { + var _ref = _step.value; + var _ref2 = (0, _slicedToArray2.default)(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match != null && match.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch (_unused) { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match == null ? void 0 : match[0]; +} +var MyClass = class { + constructor(value) { + this.value = value; + } +}; +exports.MyClass = MyClass; +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = (0, _asyncToGenerator2.default)(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = exports.LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return (0, _jsxRuntime.jsx)("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = (0, _react.useState)(initialCount), + _useState2 = (0, _slicedToArray2.default)(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = (0, _react.useState)(Status.Active), + _useState4 = (0, _slicedToArray2.default)(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + (0, _react.useEffect)(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = (0, _asyncToGenerator2.default)(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = (0, _asyncToGenerator2.default)(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return (0, _jsxRuntime.jsxs)("div", { + children: [(0, _jsxRuntime.jsx)("span", { + "data-testid": "count", + children: count + }), (0, _jsxRuntime.jsx)("span", { + "data-testid": "status", + children: String(status) + }), (0, _jsxRuntime.jsx)("button", { + onClick: handleClick, + children: "Increment" + }), (0, _jsxRuntime.jsx)(LegacyComponent, {})] + }); +} \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-prod-no-import-export-transform.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-prod-no-import-export-transform.js new file mode 100644 index 00000000000000..1ac6b64b825f51 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-prod-no-import-export-transform.js @@ -0,0 +1,252 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - Hermes stable transform profile in production mode with import/export transform disabled + * - Options: {"dev":false,"unstable_transformProfile":"hermes-stable","disableImportExportTransform":true} + */ + +import _inherits from "@babel/runtime/helpers/inherits"; +import _setPrototypeOf from "@babel/runtime/helpers/setPrototypeOf"; +import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; +import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; +import _classPrivateFieldLooseBase from "@babel/runtime/helpers/classPrivateFieldLooseBase"; +import _classPrivateFieldLooseKey from "@babel/runtime/helpers/classPrivateFieldLooseKey"; +import _awaitAsyncGenerator from "@babel/runtime/helpers/awaitAsyncGenerator"; +import _wrapAsyncGenerator from "@babel/runtime/helpers/wrapAsyncGenerator"; +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), _setPrototypeOf(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +import * as React from 'react'; +import { useEffect, useState } from 'react'; +import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; +var _count = _classPrivateFieldLooseKey("count"); +var _instances = _classPrivateFieldLooseKey("instances"); +var _increment = _classPrivateFieldLooseKey("increment"); +class Counter { + constructor() { + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + _classPrivateFieldLooseBase(Counter, _instances)[_instances]++; + } + get value() { + return _classPrivateFieldLooseBase(this, _count)[_count]; + } + increment() { + _classPrivateFieldLooseBase(this, _increment)[_increment](); + } + static get instanceCount() { + return _classPrivateFieldLooseBase(Counter, _instances)[_instances]; + } +} +function _increment2() { + _classPrivateFieldLooseBase(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = _wrapAsyncGenerator(function* (max) { + for (var i = 0; i < max; i++) { + yield _awaitAsyncGenerator(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = _asyncToGenerator(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + return obj?.a?.b?.c ?? 42; +} +class Animal { + #age; + constructor(name, age) { + this.name = name; + this.#age = age; + } + speak() { + return `${this.name} makes a sound`; + } + get age() { + return this.#age; + } +} +class Dog extends Animal { + constructor(name, age, breed) { + super(name, age); + this.breed = breed; + } + speak() { + return `${this.name} barks!`; + } + fetchTreats() { + return _asyncToGenerator(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + })(); + } +} +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _ref of pairs) { + var _ref2 = _slicedToArray(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match?.[0]; +} +var MyClass = class { + constructor(value) { + this.value = value; + } +}; +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = _asyncToGenerator(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return _jsx("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = useState(initialCount), + _useState2 = _slicedToArray(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = useState(Status.Active), + _useState4 = _slicedToArray(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + useEffect(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = _asyncToGenerator(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = _asyncToGenerator(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return _jsxs("div", { + children: [_jsx("span", { + "data-testid": "count", + children: count + }), _jsx("span", { + "data-testid": "status", + children: String(status) + }), _jsx("button", { + onClick: handleClick, + children: "Increment" + }), _jsx(LegacyComponent, {})] + }); +} +export { fetchData as default } from './data-utils'; +export { Counter, Animal, Dog, asyncNumberGenerator, getNestedValue, processUser, mergeConfigs, sumPairs, parseDate, safeJsonParse, matchEmoji, MyClass, loadModule, ModernComponent, LegacyComponent }; \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-prod.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-prod.js new file mode 100644 index 00000000000000..383e6ed5c83a2d --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/hermes-stable-prod.js @@ -0,0 +1,278 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - Hermes stable transform profile in production mode + * - Options: {"dev":false,"unstable_transformProfile":"hermes-stable"} + */ + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LegacyComponent = exports.Dog = exports.Counter = exports.Animal = void 0; +exports.ModernComponent = ModernComponent; +exports.MyClass = void 0; +exports.asyncNumberGenerator = asyncNumberGenerator; +Object.defineProperty(exports, "default", { + enumerable: true, + get: function () { + return _dataUtils.fetchData; + } +}); +exports.getNestedValue = getNestedValue; +exports.loadModule = loadModule; +exports.matchEmoji = matchEmoji; +exports.mergeConfigs = mergeConfigs; +exports.parseDate = parseDate; +exports.processUser = processUser; +exports.safeJsonParse = safeJsonParse; +exports.sumPairs = sumPairs; +var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); +var _setPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/setPrototypeOf")); +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); +var _classPrivateFieldLooseBase2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseBase")); +var _classPrivateFieldLooseKey2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseKey")); +var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator")); +var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator")); +var _react = _interopRequireWildcard(require("react")); +var React = _react; +var _jsxRuntime = require("react/jsx-runtime"); +var _dataUtils = require("./data-utils"); +function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), (0, _setPrototypeOf2.default)(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return (0, _inherits2.default)(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +var _count = (0, _classPrivateFieldLooseKey2.default)("count"); +var _instances = (0, _classPrivateFieldLooseKey2.default)("instances"); +var _increment = (0, _classPrivateFieldLooseKey2.default)("increment"); +class Counter { + constructor() { + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]++; + } + get value() { + return (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]; + } + increment() { + (0, _classPrivateFieldLooseBase2.default)(this, _increment)[_increment](); + } + static get instanceCount() { + return (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]; + } +} +exports.Counter = Counter; +function _increment2() { + (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = (0, _wrapAsyncGenerator2.default)(function* (max) { + for (var i = 0; i < max; i++) { + yield (0, _awaitAsyncGenerator2.default)(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = (0, _asyncToGenerator2.default)(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + return obj?.a?.b?.c ?? 42; +} +class Animal { + #age; + constructor(name, age) { + this.name = name; + this.#age = age; + } + speak() { + return `${this.name} makes a sound`; + } + get age() { + return this.#age; + } +} +exports.Animal = Animal; +class Dog extends Animal { + constructor(name, age, breed) { + super(name, age); + this.breed = breed; + } + speak() { + return `${this.name} barks!`; + } + fetchTreats() { + return (0, _asyncToGenerator2.default)(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + })(); + } +} +exports.Dog = Dog; +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _ref of pairs) { + var _ref2 = (0, _slicedToArray2.default)(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match?.[0]; +} +var MyClass = class { + constructor(value) { + this.value = value; + } +}; +exports.MyClass = MyClass; +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = (0, _asyncToGenerator2.default)(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = exports.LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return (0, _jsxRuntime.jsx)("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = (0, _react.useState)(initialCount), + _useState2 = (0, _slicedToArray2.default)(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = (0, _react.useState)(Status.Active), + _useState4 = (0, _slicedToArray2.default)(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + (0, _react.useEffect)(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = (0, _asyncToGenerator2.default)(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = (0, _asyncToGenerator2.default)(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return (0, _jsxRuntime.jsxs)("div", { + children: [(0, _jsxRuntime.jsx)("span", { + "data-testid": "count", + children: count + }), (0, _jsxRuntime.jsx)("span", { + "data-testid": "status", + children: String(status) + }), (0, _jsxRuntime.jsx)("button", { + onClick: handleClick, + children: "Increment" + }), (0, _jsxRuntime.jsx)(LegacyComponent, {})] + }); +} \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/no-babel-runtime.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/no-babel-runtime.js new file mode 100644 index 00000000000000..48133ecf77dab1 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/no-babel-runtime.js @@ -0,0 +1,323 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - Without babel runtime helpers + * - Options: {"dev":false,"enableBabelRuntime":false} + */ + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LegacyComponent = exports.Dog = exports.Counter = exports.Animal = void 0; +exports.ModernComponent = ModernComponent; +exports.MyClass = void 0; +exports.asyncNumberGenerator = asyncNumberGenerator; +Object.defineProperty(exports, "default", { + enumerable: true, + get: function () { + return _dataUtils.fetchData; + } +}); +exports.getNestedValue = getNestedValue; +exports.loadModule = loadModule; +exports.matchEmoji = matchEmoji; +exports.mergeConfigs = mergeConfigs; +exports.parseDate = parseDate; +exports.processUser = processUser; +exports.safeJsonParse = safeJsonParse; +exports.sumPairs = sumPairs; +var _react = _interopRequireWildcard(require("react")); +var React = _react; +var _jsxRuntime = require("react/jsx-runtime"); +var _dataUtils = require("./data-utils"); +function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), _setPrototypeOf(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } +function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } +function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } +function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } +function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } +function _possibleConstructorReturn(t, e) { if (e && ("object" == typeof e || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } +function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } +function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); } +function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } +function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); } +function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } +function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } +function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } +function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } +function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } +function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } +function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } +function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } +function _classPrivateFieldLooseBase(e, t) { if (!{}.hasOwnProperty.call(e, t)) throw new TypeError("attempted to use private field on non-instance"); return e; } +var id = 0; +function _classPrivateFieldLooseKey(e) { return "__private_" + id++ + "_" + e; } +function _awaitAsyncGenerator(e) { return new _OverloadYield(e, 0); } +function _wrapAsyncGenerator(e) { return function () { return new AsyncGenerator(e.apply(this, arguments)); }; } +function AsyncGenerator(e) { var r, t; function resume(r, t) { try { var n = e[r](t), o = n.value, u = o instanceof _OverloadYield; Promise.resolve(u ? o.v : o).then(function (t) { if (u) { var i = "return" === r ? "return" : "next"; if (!o.k || t.done) return resume(i, t); t = e[i](t).value; } settle(n.done ? "return" : "normal", t); }, function (e) { resume("throw", e); }); } catch (e) { settle("throw", e); } } function settle(e, n) { switch (e) { case "return": r.resolve({ value: n, done: !0 }); break; case "throw": r.reject(n); break; default: r.resolve({ value: n, done: !1 }); } (r = r.next) ? resume(r.key, r.arg) : t = null; } this._invoke = function (e, n) { return new Promise(function (o, u) { var i = { key: e, arg: n, resolve: o, reject: u, next: null }; t ? t = t.next = i : (r = t = i, resume(e, n)); }); }, "function" != typeof e.return && (this.return = void 0); } +AsyncGenerator.prototype["function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"] = function () { return this; }, AsyncGenerator.prototype.next = function (e) { return this._invoke("next", e); }, AsyncGenerator.prototype.throw = function (e) { return this._invoke("throw", e); }, AsyncGenerator.prototype.return = function (e) { return this._invoke("return", e); }; +function _OverloadYield(e, d) { this.v = e, this.k = d; } +var _count = _classPrivateFieldLooseKey("count"); +var _instances = _classPrivateFieldLooseKey("instances"); +var _increment = _classPrivateFieldLooseKey("increment"); +var Counter = exports.Counter = function () { + function Counter() { + _classCallCheck(this, Counter); + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + _classPrivateFieldLooseBase(Counter, _instances)[_instances]++; + } + return _createClass(Counter, [{ + key: "value", + get: function () { + return _classPrivateFieldLooseBase(this, _count)[_count]; + } + }, { + key: "increment", + value: function increment() { + _classPrivateFieldLooseBase(this, _increment)[_increment](); + } + }], [{ + key: "instanceCount", + get: function () { + return _classPrivateFieldLooseBase(Counter, _instances)[_instances]; + } + }]); +}(); +function _increment2() { + _classPrivateFieldLooseBase(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = _wrapAsyncGenerator(function* (max) { + for (var i = 0; i < max; i++) { + yield _awaitAsyncGenerator(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = _asyncToGenerator(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + return obj?.a?.b?.c ?? 42; +} +var _age = _classPrivateFieldLooseKey("age"); +var Animal = exports.Animal = function () { + function Animal(name, age) { + _classCallCheck(this, Animal); + Object.defineProperty(this, _age, { + writable: true, + value: void 0 + }); + this.name = name; + _classPrivateFieldLooseBase(this, _age)[_age] = age; + } + return _createClass(Animal, [{ + key: "speak", + value: function speak() { + return `${this.name} makes a sound`; + } + }, { + key: "age", + get: function () { + return _classPrivateFieldLooseBase(this, _age)[_age]; + } + }]); +}(); +var Dog = exports.Dog = function (_Animal2) { + function Dog(name, age, breed) { + var _this; + _classCallCheck(this, Dog); + _this = _callSuper(this, Dog, [name, age]); + _this.breed = breed; + return _this; + } + _inherits(Dog, _Animal2); + return _createClass(Dog, [{ + key: "speak", + value: function speak() { + return `${this.name} barks!`; + } + }, { + key: "fetchTreats", + value: function () { + var _fetchTreats = _asyncToGenerator(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + }); + function fetchTreats() { + return _fetchTreats.apply(this, arguments); + } + return fetchTreats; + }() + }]); +}(Animal); +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _ref of pairs) { + var _ref2 = _slicedToArray(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match?.[0]; +} +var MyClass = exports.MyClass = _createClass(function MyClass(value) { + _classCallCheck(this, MyClass); + this.value = value; +}); +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = _asyncToGenerator(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = exports.LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return (0, _jsxRuntime.jsx)("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = (0, _react.useState)(initialCount), + _useState2 = _slicedToArray(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = (0, _react.useState)(Status.Active), + _useState4 = _slicedToArray(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + (0, _react.useEffect)(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = _asyncToGenerator(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = _asyncToGenerator(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return (0, _jsxRuntime.jsxs)("div", { + children: [(0, _jsxRuntime.jsx)("span", { + "data-testid": "count", + children: count + }), (0, _jsxRuntime.jsx)("span", { + "data-testid": "status", + children: String(status) + }), (0, _jsxRuntime.jsx)("button", { + onClick: handleClick, + children: "Increment" + }), (0, _jsxRuntime.jsx)(LegacyComponent, {})] + }); +} \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/no-import-export-transform.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/no-import-export-transform.js new file mode 100644 index 00000000000000..f50ff8f413cf0b --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/no-import-export-transform.js @@ -0,0 +1,288 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - With import/export transform disabled + * - Options: {"dev":false,"disableImportExportTransform":true} + */ + +import _setPrototypeOf from "@babel/runtime/helpers/setPrototypeOf"; +import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; +import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; +import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; +import _inherits from "@babel/runtime/helpers/inherits"; +import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; +import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; +import _createClass from "@babel/runtime/helpers/createClass"; +import _classPrivateFieldLooseBase from "@babel/runtime/helpers/classPrivateFieldLooseBase"; +import _classPrivateFieldLooseKey from "@babel/runtime/helpers/classPrivateFieldLooseKey"; +import _awaitAsyncGenerator from "@babel/runtime/helpers/awaitAsyncGenerator"; +import _wrapAsyncGenerator from "@babel/runtime/helpers/wrapAsyncGenerator"; +function _wrapRegExp() { _wrapRegExp = function (e, r) { return new BabelRegExp(e, void 0, r); }; var e = RegExp.prototype, r = new WeakMap(); function BabelRegExp(e, t, p) { var o = RegExp(e, t); return r.set(o, p || r.get(e)), _setPrototypeOf(o, BabelRegExp.prototype); } function buildGroups(e, t) { var p = r.get(t); return Object.keys(p).reduce(function (r, t) { var o = p[t]; if ("number" == typeof o) r[t] = e[o];else { for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++; r[t] = e[o[i]]; } return r; }, Object.create(null)); } return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) { var t = e.exec.call(this, r); if (t) { t.groups = buildGroups(t, this); var p = t.indices; p && (p.groups = buildGroups(p, this)); } return t; }, BabelRegExp.prototype[Symbol.replace] = function (t, p) { if ("string" == typeof p) { var o = r.get(this); return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) { if ("" === t) return e; var p = o[r]; return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : ""; })); } if ("function" == typeof p) { var i = this; return e[Symbol.replace].call(this, t, function () { var e = arguments; return "object" != typeof e[e.length - 1] && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e); }); } return e[Symbol.replace].call(this, t, p); }, _wrapRegExp.apply(this, arguments); } +function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } +function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); } +import * as React from 'react'; +import { useEffect, useState } from 'react'; +import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; +var _count = _classPrivateFieldLooseKey("count"); +var _instances = _classPrivateFieldLooseKey("instances"); +var _increment = _classPrivateFieldLooseKey("increment"); +var Counter = function () { + function Counter() { + _classCallCheck(this, Counter); + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + _classPrivateFieldLooseBase(Counter, _instances)[_instances]++; + } + return _createClass(Counter, [{ + key: "value", + get: function () { + return _classPrivateFieldLooseBase(this, _count)[_count]; + } + }, { + key: "increment", + value: function increment() { + _classPrivateFieldLooseBase(this, _increment)[_increment](); + } + }], [{ + key: "instanceCount", + get: function () { + return _classPrivateFieldLooseBase(Counter, _instances)[_instances]; + } + }]); +}(); +function _increment2() { + _classPrivateFieldLooseBase(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = _wrapAsyncGenerator(function* (max) { + for (var i = 0; i < max; i++) { + yield _awaitAsyncGenerator(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = _asyncToGenerator(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + return obj?.a?.b?.c ?? 42; +} +var _age = _classPrivateFieldLooseKey("age"); +var Animal = function () { + function Animal(name, age) { + _classCallCheck(this, Animal); + Object.defineProperty(this, _age, { + writable: true, + value: void 0 + }); + this.name = name; + _classPrivateFieldLooseBase(this, _age)[_age] = age; + } + return _createClass(Animal, [{ + key: "speak", + value: function speak() { + return `${this.name} makes a sound`; + } + }, { + key: "age", + get: function () { + return _classPrivateFieldLooseBase(this, _age)[_age]; + } + }]); +}(); +var Dog = function (_Animal2) { + function Dog(name, age, breed) { + var _this; + _classCallCheck(this, Dog); + _this = _callSuper(this, Dog, [name, age]); + _this.breed = breed; + return _this; + } + _inherits(Dog, _Animal2); + return _createClass(Dog, [{ + key: "speak", + value: function speak() { + return `${this.name} barks!`; + } + }, { + key: "fetchTreats", + value: function () { + var _fetchTreats = _asyncToGenerator(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + }); + function fetchTreats() { + return _fetchTreats.apply(this, arguments); + } + return fetchTreats; + }() + }]); +}(Animal); +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _ref of pairs) { + var _ref2 = _slicedToArray(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = _wrapRegExp(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match?.[0]; +} +var MyClass = _createClass(function MyClass(value) { + _classCallCheck(this, MyClass); + this.value = value; +}); +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = _asyncToGenerator(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return _jsx("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = useState(initialCount), + _useState2 = _slicedToArray(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = useState(Status.Active), + _useState4 = _slicedToArray(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + useEffect(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = _asyncToGenerator(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = _asyncToGenerator(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return _jsxs("div", { + children: [_jsx("span", { + "data-testid": "count", + children: count + }), _jsx("span", { + "data-testid": "status", + children: String(status) + }), _jsx("button", { + onClick: handleClick, + children: "Increment" + }), _jsx(LegacyComponent, {})] + }); +} +export { fetchData as default } from './data-utils'; +export { Counter, Animal, Dog, asyncNumberGenerator, getNestedValue, processUser, mergeConfigs, sumPairs, parseDate, safeJsonParse, matchEmoji, MyClass, loadModule, ModernComponent, LegacyComponent }; \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/with-babel-runtime-version.js b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/with-babel-runtime-version.js new file mode 100644 index 00000000000000..0c4f6584654055 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/__fixtures__/output/with-babel-runtime-version.js @@ -0,0 +1,306 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - With specific babel runtime version + * - Options: {"dev":false,"enableBabelRuntime":"7.25.0"} + */ + +var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LegacyComponent = exports.Dog = exports.Counter = exports.Animal = void 0; +exports.ModernComponent = ModernComponent; +exports.MyClass = void 0; +exports.asyncNumberGenerator = asyncNumberGenerator; +Object.defineProperty(exports, "default", { + enumerable: true, + get: function () { + return _dataUtils.fetchData; + } +}); +exports.getNestedValue = getNestedValue; +exports.loadModule = loadModule; +exports.matchEmoji = matchEmoji; +exports.mergeConfigs = mergeConfigs; +exports.parseDate = parseDate; +exports.processUser = processUser; +exports.safeJsonParse = safeJsonParse; +exports.sumPairs = sumPairs; +var _wrapRegExp2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapRegExp")); +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); +var _callSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/callSuper")); +var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); +var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); +var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); +var _classPrivateFieldLooseBase2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseBase")); +var _classPrivateFieldLooseKey2 = _interopRequireDefault(require("@babel/runtime/helpers/classPrivateFieldLooseKey")); +var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator")); +var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator")); +var _react = _interopRequireWildcard(require("react")); +var React = _react; +var _jsxRuntime = require("react/jsx-runtime"); +var _dataUtils = require("./data-utils"); +var _count = (0, _classPrivateFieldLooseKey2.default)("count"); +var _instances = (0, _classPrivateFieldLooseKey2.default)("instances"); +var _increment = (0, _classPrivateFieldLooseKey2.default)("increment"); +var Counter = exports.Counter = function () { + function Counter() { + (0, _classCallCheck2.default)(this, Counter); + Object.defineProperty(this, _increment, { + value: _increment2 + }); + Object.defineProperty(this, _count, { + writable: true, + value: 0 + }); + (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]++; + } + return (0, _createClass2.default)(Counter, [{ + key: "value", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]; + } + }, { + key: "increment", + value: function increment() { + (0, _classPrivateFieldLooseBase2.default)(this, _increment)[_increment](); + } + }], [{ + key: "instanceCount", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(Counter, _instances)[_instances]; + } + }]); +}(); +function _increment2() { + (0, _classPrivateFieldLooseBase2.default)(this, _count)[_count]++; +} +Object.defineProperty(Counter, _instances, { + writable: true, + value: 0 +}); +function asyncNumberGenerator(_x) { + return _asyncNumberGenerator.apply(this, arguments); +} +function _asyncNumberGenerator() { + _asyncNumberGenerator = (0, _wrapAsyncGenerator2.default)(function* (max) { + for (var i = 0; i < max; i++) { + yield (0, _awaitAsyncGenerator2.default)(new Promise(resolve => setTimeout(resolve, 100))); + yield i; + } + }); + return _asyncNumberGenerator.apply(this, arguments); +} +function fetchData(_x2) { + return _fetchData.apply(this, arguments); +} +function _fetchData() { + _fetchData = (0, _asyncToGenerator2.default)(function* (url) { + var response = yield fetch(url); + var data = yield response.json(); + return { + data + }; + }); + return _fetchData.apply(this, arguments); +} +function getNestedValue(obj) { + return obj?.a?.b?.c ?? 42; +} +var _age = (0, _classPrivateFieldLooseKey2.default)("age"); +var Animal = exports.Animal = function () { + function Animal(name, age) { + (0, _classCallCheck2.default)(this, Animal); + Object.defineProperty(this, _age, { + writable: true, + value: void 0 + }); + this.name = name; + (0, _classPrivateFieldLooseBase2.default)(this, _age)[_age] = age; + } + return (0, _createClass2.default)(Animal, [{ + key: "speak", + value: function speak() { + return `${this.name} makes a sound`; + } + }, { + key: "age", + get: function () { + return (0, _classPrivateFieldLooseBase2.default)(this, _age)[_age]; + } + }]); +}(); +var Dog = exports.Dog = function (_Animal2) { + function Dog(name, age, breed) { + var _this; + (0, _classCallCheck2.default)(this, Dog); + _this = (0, _callSuper2.default)(this, Dog, [name, age]); + _this.breed = breed; + return _this; + } + (0, _inherits2.default)(Dog, _Animal2); + return (0, _createClass2.default)(Dog, [{ + key: "speak", + value: function speak() { + return `${this.name} barks!`; + } + }, { + key: "fetchTreats", + value: function () { + var _fetchTreats = (0, _asyncToGenerator2.default)(function* () { + yield new Promise(resolve => setTimeout(resolve, 100)); + return ['bone', 'biscuit', 'toy']; + }); + function fetchTreats() { + return _fetchTreats.apply(this, arguments); + } + return fetchTreats; + }() + }]); +}(Animal); +function processUser({ + name, + age = 18, + ...rest +}) { + var _rest$city = rest.city, + city = _rest$city === void 0 ? 'Unknown' : _rest$city; + return `${name} (${age}) from ${city}`; +} +function mergeConfigs(base, ...overrides) { + return { + ...base, + ...overrides.reduce((acc, o) => ({ + ...acc, + ...o + }), {}) + }; +} +function sumPairs(pairs) { + var total = 0; + for (var _ref of pairs) { + var _ref2 = (0, _slicedToArray2.default)(_ref, 2); + var a = _ref2[0]; + var b = _ref2[1]; + total += a + b; + } + return total; +} +function parseDate(dateString) { + var regex = (0, _wrapRegExp2.default)(/(\d{4})-(\d{2})-(\d{2})/, { + year: 1, + month: 2, + day: 3 + }); + var match = dateString.match(regex); + if (match?.groups) { + return { + year: match.groups.year, + month: match.groups.month, + day: match.groups.day + }; + } + return null; +} +function safeJsonParse(input) { + try { + return JSON.parse(input); + } catch { + return null; + } +} +function matchEmoji(text) { + var match = text.match(/(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDC-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9\uDEF0-\uDEF8])/); + return match?.[0]; +} +var MyClass = exports.MyClass = (0, _createClass2.default)(function MyClass(value) { + (0, _classCallCheck2.default)(this, MyClass); + this.value = value; +}); +function loadModule() { + return _loadModule.apply(this, arguments); +} +function _loadModule() { + _loadModule = (0, _asyncToGenerator2.default)(function* () { + var module = yield import('./some-module'); + return module.default; + }); + return _loadModule.apply(this, arguments); +} +var LegacyComponent = exports.LegacyComponent = React.createClass({ + displayName: 'LegacyComponent', + getInitialState() { + return { + count: 0 + }; + }, + render() { + return (0, _jsxRuntime.jsx)("div", { + children: this.state.count + }); + } +}); +function ModernComponent({ + initialCount = 0 +}) { + var _useState = (0, _react.useState)(initialCount), + _useState2 = (0, _slicedToArray2.default)(_useState, 2), + count = _useState2[0], + setCount = _useState2[1]; + var _useState3 = (0, _react.useState)(Status.Active), + _useState4 = (0, _slicedToArray2.default)(_useState3, 2), + status = _useState4[0], + setStatus = _useState4[1]; + (0, _react.useEffect)(() => { + var timer = setInterval(() => { + setCount(c => c + 1); + }, 1000); + return () => clearInterval(timer); + }, []); + function handleAsyncClick() { + return _handleAsyncClick.apply(this, arguments); + } + function _handleAsyncClick() { + _handleAsyncClick = (0, _asyncToGenerator2.default)(function* () { + var data = yield fetchData('/api/data'); + console.log(data); + }); + return _handleAsyncClick.apply(this, arguments); + } + var handleClick = function () { + var _ref3 = (0, _asyncToGenerator2.default)(function* () { + yield handleAsyncClick(); + setStatus(Status.Pending); + }); + return function handleClick() { + return _ref3.apply(this, arguments); + }; + }(); + return (0, _jsxRuntime.jsxs)("div", { + children: [(0, _jsxRuntime.jsx)("span", { + "data-testid": "count", + children: count + }), (0, _jsxRuntime.jsx)("span", { + "data-testid": "status", + children: String(status) + }), (0, _jsxRuntime.jsx)("button", { + onClick: handleClick, + children: "Increment" + }), (0, _jsxRuntime.jsx)(LegacyComponent, {})] + }); +} \ No newline at end of file diff --git a/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js b/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js new file mode 100644 index 00000000000000..f8cdd837207092 --- /dev/null +++ b/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js @@ -0,0 +1,354 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +// $FlowExpectedError[untyped-import] - Preset is untyped +const preset = require('../index'); +const babel = require('@babel/core'); +const fs = require('fs'); +const path = require('path'); + +const FIXTURES_DIR = path.join(__dirname, '__fixtures__'); +const OUTPUT_DIR = path.join(FIXTURES_DIR, 'output'); +const INPUT_FILE = path.join(FIXTURES_DIR, 'kitchen-sink-input.js'); + +const inputCode = fs.readFileSync(INPUT_FILE, 'utf-8'); + +const testConfigs = [ + { + name: 'default-dev', + options: { + dev: true, + }, + description: 'Default transform profile in development mode', + }, + { + name: 'default-prod', + options: { + dev: false, + }, + description: 'Default transform profile in production mode', + }, + { + name: 'hermes-stable-dev', + options: { + dev: true, + unstable_transformProfile: 'hermes-stable', + }, + description: 'Hermes stable transform profile in development mode', + }, + { + name: 'hermes-stable-prod', + options: { + dev: false, + unstable_transformProfile: 'hermes-stable', + }, + description: 'Hermes stable transform profile in production mode', + }, + { + name: 'hermes-canary-dev', + options: { + dev: true, + unstable_transformProfile: 'hermes-canary', + }, + description: 'Hermes canary transform profile in development mode', + }, + { + name: 'hermes-canary-prod', + options: { + dev: false, + unstable_transformProfile: 'hermes-canary', + }, + description: 'Hermes canary transform profile in production mode', + }, + { + name: 'no-import-export-transform', + options: { + dev: false, + disableImportExportTransform: true, + }, + description: 'With import/export transform disabled', + }, + { + name: 'hermes-stable-prod-no-import-export-transform', + options: { + dev: false, + unstable_transformProfile: 'hermes-stable', + disableImportExportTransform: true, + }, + description: + 'Hermes stable transform profile in production mode with import/export transform disabled', + }, + { + name: 'with-babel-runtime-version', + options: { + dev: false, + enableBabelRuntime: '7.25.0', + }, + description: 'With specific babel runtime version', + }, + { + name: 'no-babel-runtime', + options: { + dev: false, + enableBabelRuntime: false, + }, + description: 'Without babel runtime helpers', + }, +]; + +function transformCode( + code: string, + options: {[string]: mixed}, +): string | null { + const result = babel.transformSync(code, { + babelrc: false, + configFile: false, + filename: INPUT_FILE, + presets: [[preset, options]], + sourceMaps: false, + compact: false, + }); + return result?.code ?? null; +} + +function getSnapshotPath(configName: string): string { + return path.join(OUTPUT_DIR, `${configName}.js`); +} + +function ensureDirectoryExists(dir: string): void { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, {recursive: true}); + } +} + +function makeHeader(description: string, options: {[string]: mixed}): string { + return `/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated + * @noformat + * @noflow + * @nolint + * + * This is a snapshot of the transform output for testing purposes. + * To update, run: js1 test transform-snapshot-test.js -u + * + * Transform configuration: + * - ${description} + * - Options: ${JSON.stringify(options)} + */ + +`; +} + +function validateCodeIsParseable( + code: string, + sourceType: 'module' | 'script' = 'script', +): boolean { + try { + babel.parseSync(code, { + babelrc: false, + configFile: false, + filename: 'test.js', + parserOpts: { + sourceType, + }, + }); + return true; + } catch { + return false; + } +} + +describe('react-native-babel-preset transform snapshots', () => { + beforeAll(() => { + ensureDirectoryExists(OUTPUT_DIR); + }); + + describe.each(testConfigs)( + '$name ($description)', + ({name, options, description}) => { + const snapshotPath = getSnapshotPath(name); + + it('transforms the kitchen-sink input correctly', () => { + const transformedCode = transformCode(inputCode, options); + const header = makeHeader(description, options); + const fullContent = header + (transformedCode ?? ''); + + // Check if we're in update mode - this allows our snapshots to be + // updated when Jest is run with -u in the usual way. Unfortunately + // it's a private API. + const isUpdateMode = + // $FlowFixMe[prop-missing] - private API + expect.getState().snapshotState._updateSnapshot === 'all'; + + if (isUpdateMode) { + fs.writeFileSync(snapshotPath, fullContent); + } + + // Compare against file + expect(fs.existsSync(snapshotPath)).toBe(true); + const expectedContent = fs.readFileSync(snapshotPath, 'utf-8'); + expect(fullContent).toBe(expectedContent); + }); + + it('produces parseable JavaScript output', () => { + const transformedCode = transformCode(inputCode, options); + const sourceType = + options.disableImportExportTransform === true ? 'module' : 'script'; + expect(validateCodeIsParseable(transformedCode ?? '', sourceType)).toBe( + true, + ); + }); + }, + ); + + describe('specific feature transformations', () => { + it('handles private class fields', () => { + const code = ` + class Counter { + #count = 0; + increment() { this.#count++; } + get value() { return this.#count; } + } + `; + const result = transformCode(code, {dev: false}); + expect(result).not.toContain('#count'); + }); + + it('handles async generators', () => { + const code = ` + async function* gen() { + yield 1; + await Promise.resolve(); + yield 2; + } + `; + const result = transformCode(code, {dev: false}); + expect(result).toContain('_wrapAsyncGenerator'); + }); + + it('handles optional chaining', () => { + const code = `const x = obj?.a?.b?.c;`; + const result = transformCode(code, { + dev: true, + unstable_transformProfile: 'hermes-stable', + }); + expect(result).not.toContain('?.'); + }); + + it('handles nullish coalescing', () => { + const code = `const x = a ?? b;`; + const result = transformCode(code, { + dev: true, + unstable_transformProfile: 'hermes-stable', + }); + expect(result).not.toContain('??'); + }); + + it('handles flow enums', () => { + const code = ` + // @flow + enum Status { Active, Inactive } + const s: Status = Status.Active; + `; + const result = transformCode(code, {dev: false}); + expect(result).toContain('Status'); + }); + + it('preserves classes with hermes-stable profile in prod', () => { + const code = ` + class Animal { + constructor(name) { + this.name = name; + } + speak() { + return this.name; + } + } + `; + const result = transformCode(code, { + dev: false, + unstable_transformProfile: 'hermes-stable', + }); + expect(result).toContain('class Animal'); + }); + + it('transforms classes with default profile', () => { + const code = ` + class Animal { + constructor(name) { + this.name = name; + } + speak() { + return this.name; + } + } + `; + const result = transformCode(code, {dev: false}); + expect(result).not.toContain('class Animal'); + }); + + it('handles named capturing groups in regex', () => { + const code = `const match = str.match(/(?\\d{4})-(?\\d{2})/);`; + const result = transformCode(code, {dev: false}); + expect(result).toContain('_wrapRegExp'); + }); + + it('handles destructuring with defaults', () => { + const code = `const {a, b = 10, ...rest} = obj;`; + const result = transformCode(code, {dev: false}); + expect(result).toContain('_objectWithoutProperties'); + }); + + it('handles JSX transformation', () => { + const code = `const el =
Hello
;`; + const result = transformCode(code, {dev: false}); + expect(result).toContain('jsx'); + }); + + it('strips flow types', () => { + const code = ` + // @flow + type User = {name: string, age: number}; + function greet(user: User): string { + return user.name; + } + `; + const result = transformCode(code, {dev: false}); + expect(result).not.toContain(': User'); + expect(result).not.toContain(': string'); + }); + + it('transforms export default from syntax', () => { + const code = `export {default} from './module';`; + const result = transformCode(code, {dev: false}); + expect(result).toContain('require'); + }); + + it('preserves import/export with disableImportExportTransform', () => { + const code = ` + import {foo} from './module'; + export const bar = foo; + `; + const result = transformCode(code, { + dev: false, + disableImportExportTransform: true, + }); + expect(result).toContain('import'); + expect(result).toContain('export'); + }); + }); +});