chore: add mobile app

This commit is contained in:
2026-02-07 22:33:02 +01:00
parent db34640acc
commit e89384ad4e
29327 changed files with 3886944 additions and 12 deletions
@@ -0,0 +1,17 @@
/**
* 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.
*
* @format
* @noflow
*/
'use strict';
module.exports = function () {
return {
plugins: [require('react-refresh/babel')],
};
};
@@ -0,0 +1,93 @@
/**
* 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.
*
* @format
* @noflow
*/
// This is the set of modules that React Native publicly exports and that we
// want to require lazily. Keep this list in sync with
// react-native/index.js (though having extra entries here is fairly harmless).
'use strict';
module.exports = new Set([
'AccessibilityInfo',
'ActivityIndicator',
'Button',
'DatePickerIOS',
'DrawerLayoutAndroid',
'FlatList',
'Image',
'ImageBackground',
'InputAccessoryView',
'KeyboardAvoidingView',
'Modal',
'Pressable',
'ProgressBarAndroid',
'ProgressViewIOS',
'SafeAreaView',
'ScrollView',
'SectionList',
'Slider',
'Switch',
'RefreshControl',
'StatusBar',
'Text',
'TextInput',
'Touchable',
'TouchableHighlight',
'TouchableNativeFeedback',
'TouchableOpacity',
'TouchableWithoutFeedback',
'View',
'VirtualizedList',
'VirtualizedSectionList',
// APIs
'ActionSheetIOS',
'Alert',
'Animated',
'Appearance',
'AppRegistry',
'AppState',
'AsyncStorage',
'BackHandler',
'Clipboard',
'DeviceInfo',
'Dimensions',
'Easing',
'ReactNative',
'I18nManager',
'InteractionManager',
'Keyboard',
'LayoutAnimation',
'Linking',
'LogBox',
'NativeEventEmitter',
'PanResponder',
'PermissionsAndroid',
'PixelRatio',
'PushNotificationIOS',
'Settings',
'Share',
'StyleSheet',
'Systrace',
'ToastAndroid',
'TVEventHandler',
'UIManager',
'ReactNative',
'UTFSequence',
'Vibration',
// Plugins
'RCTDeviceEventEmitter',
'RCTNativeAppEventEmitter',
'NativeModules',
'Platform',
'processColor',
'requireNativeComponent',
]);
@@ -0,0 +1,292 @@
/**
* 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.
*
* @format
* @noflow
*/
'use strict';
const passthroughSyntaxPlugins = require('../passthrough-syntax-plugins');
const lazyImports = require('./lazy-imports');
const EXCLUDED_FIRST_PARTY_PATHS = [
/[/\\]node_modules[/\\]/,
/[/\\]packages[/\\]react-native[/\\]/,
/[/\\]packages[/\\]virtualized-lists[/\\]/,
/[/\\]private[/\\]react-native-fantom[/\\]/,
];
function isTypeScriptSource(fileName) {
return !!fileName && fileName.endsWith('.ts');
}
function isTSXSource(fileName) {
return !!fileName && fileName.endsWith('.tsx');
}
function isFirstParty(fileName) {
return (
!!fileName &&
!EXCLUDED_FIRST_PARTY_PATHS.some(regex => regex.test(fileName))
);
}
// use `this.foo = bar` instead of `this.defineProperty('foo', ...)`
const loose = true;
// For Static Hermes testing (experimental), the hermes-canary transformProfile
// is used to enable regenerator (and some related lowering passes) because SH
// requires more Babel lowering than Hermes temporarily.
const getPreset = (src, options) => {
const transformProfile =
(options && options.unstable_transformProfile) || 'default';
const isHermesStable = transformProfile === 'hermes-stable';
const isHermesCanary = transformProfile === 'hermes-canary';
const isHermes = isHermesStable || isHermesCanary;
const isNull = src == null;
const hasClass = isNull || src.indexOf('class') !== -1;
const extraPlugins = [];
const firstPartyPlugins = [];
if (!options.useTransformReactJSXExperimental) {
extraPlugins.push([
require('@babel/plugin-transform-react-jsx'),
{runtime: 'automatic'},
]);
}
if (
!options.disableStaticViewConfigsCodegen &&
(src === null || /\bcodegenNativeComponent</.test(src))
) {
extraPlugins.push([require('@react-native/babel-plugin-codegen')]);
}
if (!options || !options.disableImportExportTransform) {
extraPlugins.push(
[require('@babel/plugin-proposal-export-default-from')],
[
require('@babel/plugin-transform-modules-commonjs'),
{
strict: false,
strictMode: false, // prevent "use strict" injections
lazy:
options && options.lazyImportExportTransform != null
? options.lazyImportExportTransform
: importSpecifier => lazyImports.has(importSpecifier),
allowTopLevelThis: true, // dont rewrite global `this` -> `undefined`
},
],
);
}
if (hasClass) {
extraPlugins.push([require('@babel/plugin-transform-classes')]);
}
if (!isHermes && (isNull || src.includes('=>'))) {
extraPlugins.push([require('@babel/plugin-transform-arrow-functions')]);
}
if (!isHermes) {
extraPlugins.push([require('@babel/plugin-transform-computed-properties')]);
extraPlugins.push([require('@babel/plugin-transform-parameters')]);
extraPlugins.push([
require('@babel/plugin-transform-shorthand-properties'),
]);
extraPlugins.push([
require('@babel/plugin-transform-optional-catch-binding'),
]);
extraPlugins.push([require('@babel/plugin-transform-function-name')]);
extraPlugins.push([require('@babel/plugin-transform-literals')]);
extraPlugins.push([require('@babel/plugin-transform-numeric-separator')]);
extraPlugins.push([require('@babel/plugin-transform-sticky-regex')]);
} else {
extraPlugins.push([
require('@babel/plugin-transform-named-capturing-groups-regex'),
]);
// Needed for regenerator for hermes-canary
if (isHermesCanary) {
extraPlugins.push([
require('@babel/plugin-transform-optional-catch-binding'),
]);
}
}
extraPlugins.push([
require('@babel/plugin-transform-destructuring'),
{useBuiltIns: true},
]);
if (!isHermes && (isNull || hasClass || src.indexOf('...') !== -1)) {
extraPlugins.push(
[require('@babel/plugin-transform-spread')],
[
require('@babel/plugin-transform-object-rest-spread'),
// Assume no dependence on getters or evaluation order. See https://github.com/babel/babel/pull/11520
{loose: true, useBuiltIns: true},
],
);
}
if (isNull || src.indexOf('async') !== -1) {
extraPlugins.push([
require('@babel/plugin-transform-async-generator-functions'),
]);
extraPlugins.push([require('@babel/plugin-transform-async-to-generator')]);
}
if (
isNull ||
src.indexOf('React.createClass') !== -1 ||
src.indexOf('createReactClass') !== -1
) {
extraPlugins.push([require('@babel/plugin-transform-react-display-name')]);
}
// Check !isHermesStable because this is needed for regenerator for
// hermes-canary
if (!isHermesStable && (isNull || src.indexOf('?.') !== -1)) {
extraPlugins.push([
require('@babel/plugin-transform-optional-chaining'),
{loose: true},
]);
}
// Check !isHermesStable because this is needed for regenerator for
// hermes-canary
if (!isHermesStable && (isNull || src.indexOf('??') !== -1)) {
extraPlugins.push([
require('@babel/plugin-transform-nullish-coalescing-operator'),
{loose: true},
]);
}
if (
!isHermes &&
(isNull ||
src.indexOf('??=') !== -1 ||
src.indexOf('||=') !== -1 ||
src.indexOf('&&=') !== -1)
) {
extraPlugins.push([
require('@babel/plugin-transform-logical-assignment-operators'),
{loose: true},
]);
}
if (options && options.dev && !options.disableDeepImportWarnings) {
firstPartyPlugins.push([require('../plugin-warn-on-deep-imports.js')]);
}
if (options && options.dev && !options.useTransformReactJSXExperimental) {
extraPlugins.push([require('@babel/plugin-transform-react-jsx-source')]);
extraPlugins.push([require('@babel/plugin-transform-react-jsx-self')]);
}
if (isHermesCanary) {
const hasForOf =
isNull || (src.indexOf('for') !== -1 && src.indexOf('of') !== -1);
if (hasForOf) {
// Needed for regenerator
extraPlugins.push([
require('@babel/plugin-transform-for-of'),
{loose: true},
]);
}
}
if (!options || options.enableBabelRuntime !== false) {
// Allows configuring a specific runtime version to optimize output
const isVersion = typeof options?.enableBabelRuntime === 'string';
extraPlugins.push([
require('@babel/plugin-transform-runtime'),
{
helpers: true,
regenerator: !isHermesStable,
...(isVersion && {version: options.enableBabelRuntime}),
},
]);
} else if (isHermesCanary) {
extraPlugins.push([require('@babel/plugin-transform-regenerator')]);
}
return {
comments: false,
compact: options.compact !== false,
overrides: [
// the flow strip types plugin must go BEFORE class properties!
// there'll be a test case that fails if you don't.
{
plugins: [require('@babel/plugin-transform-flow-strip-types')],
},
{
plugins: [
[
require('babel-plugin-syntax-hermes-parser'),
{
parseLangTypes: 'flow',
reactRuntimeTarget: '19',
...options.hermesParserOptions,
},
],
[require('babel-plugin-transform-flow-enums')],
[require('@babel/plugin-transform-block-scoping')],
[require('@babel/plugin-transform-class-properties'), {loose}],
[require('@babel/plugin-transform-private-methods'), {loose}],
[
require('@babel/plugin-transform-private-property-in-object'),
{loose},
],
[require('@babel/plugin-syntax-dynamic-import')],
[require('@babel/plugin-syntax-export-default-from')],
...passthroughSyntaxPlugins,
[require('@babel/plugin-transform-unicode-regex')],
],
},
{
test: isTypeScriptSource,
plugins: [
[
require('@babel/plugin-transform-typescript'),
{
isTSX: false,
allowNamespaces: true,
},
],
],
},
{
test: isTSXSource,
plugins: [
[
require('@babel/plugin-transform-typescript'),
{
isTSX: true,
allowNamespaces: true,
},
],
],
},
{
test: isFirstParty,
plugins: firstPartyPlugins,
},
{
plugins: extraPlugins,
},
],
};
};
module.exports = options => {
if (options.withDevTools == null) {
const env = process.env.BABEL_ENV || process.env.NODE_ENV;
if (!env || env === 'development') {
return getPreset(null, {...options, dev: true});
}
}
return getPreset(null, options);
};
module.exports.getPreset = getPreset;
+20
View File
@@ -0,0 +1,20 @@
/**
* 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.
*
* @format
* @noflow
*/
'use strict';
const main = require('./configs/main');
module.exports = function (babel, options) {
return main(options);
};
module.exports.getPreset = main.getPreset;
module.exports.passthroughSyntaxPlugins = require('./passthrough-syntax-plugins');
@@ -0,0 +1,23 @@
/**
* 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.
*
* @format
* @noflow
*/
'use strict';
// This list of syntax plugins is used for two purposes:
// 1. Enabling experimental syntax features in the INPUT to the Metro Babel
// transformer, regardless of whether we actually transform them.
// 2. Enabling these same features in parser passes that consume the OUTPUT of
// the Metro Babel transformer.
const passthroughSyntaxPlugins = [
[require('@babel/plugin-syntax-nullish-coalescing-operator')],
[require('@babel/plugin-syntax-optional-chaining')],
];
module.exports = passthroughSyntaxPlugins;
@@ -0,0 +1,135 @@
/**
* 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.
*
* @format
* @noflow
*/
'use strict';
function getWarningMessage(importPath, loc, source) {
const message = `Deep imports from the 'react-native' package are deprecated ('${importPath}').`;
if (source !== undefined) {
return `${message} Source: ${source} ${loc ? `${loc.start.line}:${loc.start.column}` : ''}`;
}
return message;
}
function createWarning(t, importPath, loc, source) {
const warningMessage = getWarningMessage(importPath, loc, source);
const warning = t.expressionStatement(
t.callExpression(
t.memberExpression(t.identifier('console'), t.identifier('warn')),
[t.stringLiteral(warningMessage)],
),
);
return warning;
}
function isDeepReactNativeImport(source) {
const parts = source.split('/');
return parts.length > 1 && parts[0] === 'react-native';
}
function isInitializeCoreImport(source) {
return source === 'react-native/Libraries/Core/InitializeCore';
}
function withLocation(node, loc) {
if (!node.loc) {
return {...node, loc};
}
return node;
}
module.exports = ({types: t}) => ({
name: 'warn-on-deep-imports',
visitor: {
ImportDeclaration(path, state) {
const source = path.node.source.value;
if (isDeepReactNativeImport(source) && !isInitializeCoreImport(source)) {
const loc = path.node.loc;
state.import.push({source, loc});
}
},
CallExpression(path, state) {
const callee = path.get('callee');
const args = path.get('arguments');
if (
callee.isIdentifier({name: 'require'}) &&
args.length === 1 &&
args[0].isStringLiteral()
) {
const source =
args[0].node.type === 'StringLiteral' ? args[0].node.value : '';
if (
isDeepReactNativeImport(source) &&
!isInitializeCoreImport(source)
) {
const loc = path.node.loc;
state.require.push({source, loc});
}
}
},
ExportNamedDeclaration(path, state) {
const source = path.node.source;
if (
source &&
isDeepReactNativeImport(source.value) &&
!isInitializeCoreImport(source)
) {
const loc = path.node.loc;
state.export.push({source: source.value, loc});
}
},
Program: {
enter(path, state) {
state.require = [];
state.import = [];
state.export = [];
},
exit(path, state) {
const {body} = path.node;
const requireWarnings = state.require.map(value =>
withLocation(
createWarning(t, value.source, value.loc, state.filename),
value.loc,
),
);
const importWarnings = state.import.map(value =>
withLocation(
createWarning(t, value.source, value.loc, state.filename),
value.loc,
),
);
const exportWarnings = state.export.map(value =>
withLocation(
createWarning(t, value.source, value.loc, state.filename),
value.loc,
),
);
const warnings = [
...requireWarnings,
...importWarnings,
...exportWarnings,
];
body.push(...warnings);
},
},
},
});