chore: build

This commit is contained in:
2026-05-01 22:28:13 +02:00
parent ece977f268
commit 99ce3e4bb3
532 changed files with 5244 additions and 13124 deletions
+2 -2
View File
@@ -32,7 +32,7 @@ buildscript {
def reactNativeVersion = project.extensions.getByType(ExpoModuleExtension).reactNativeVersion
group = 'host.exp.exponent'
version = '54.0.33'
version = '54.0.34'
expoModule {
// We can't prebuild the module because it depends on the generated files.
@@ -43,7 +43,7 @@ android {
namespace "expo.core"
defaultConfig {
versionCode 1
versionName "54.0.33"
versionName "54.0.34"
consumerProguardFiles("proguard-rules.pro")
}
testOptions {
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"installGlobal.d.ts","sourceRoot":"","sources":["../../src/winter/installGlobal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyDH;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAI,CA6BrF"}
{"version":3,"file":"installGlobal.d.ts","sourceRoot":"","sources":["../../src/winter/installGlobal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyDH;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAI,CAkCrF"}
+18 -18
View File
@@ -1,5 +1,5 @@
{
"@expo/fingerprint": "~0.15.4",
"@expo/fingerprint": "~0.15.5",
"@expo/metro-runtime": "~6.1.2",
"@expo/vector-icons": "^15.0.3",
"@expo/ui": "~0.2.0-beta.9",
@@ -19,9 +19,9 @@
"expo-app-loader-provider": "~8.0.0",
"expo-apple-authentication": "~8.0.8",
"expo-application": "~7.0.8",
"expo-asset": "~12.0.12",
"expo-asset": "~12.0.13",
"expo-audio": "~1.1.1",
"expo-auth-session": "~7.0.10",
"expo-auth-session": "~7.0.11",
"expo-av": "~16.0.8",
"expo-background-fetch": "~14.0.9",
"expo-background-task": "~1.0.10",
@@ -36,47 +36,47 @@
"expo-clipboard": "~8.0.8",
"expo-constants": "~18.0.13",
"expo-contacts": "~15.0.11",
"expo-crypto": "~15.0.8",
"expo-dev-client": "~6.0.20",
"expo-crypto": "~15.0.9",
"expo-dev-client": "~6.0.21",
"expo-device": "~8.0.10",
"expo-document-picker": "~14.0.8",
"expo-file-system": "~19.0.21",
"expo-file-system": "~19.0.22",
"expo-font": "~14.0.11",
"expo-gl": "~16.0.10",
"expo-glass-effect": "~0.1.8",
"expo-glass-effect": "~0.1.10",
"expo-google-app-auth": "~8.3.0",
"expo-haptics": "~15.0.8",
"expo-image": "~3.0.11",
"expo-image-loader": "~6.0.0",
"expo-image-manipulator": "~14.0.8",
"expo-image-picker": "~17.0.10",
"expo-image-picker": "~17.0.11",
"expo-intent-launcher": "~13.0.8",
"expo-insights": "~0.10.8",
"expo-keep-awake": "~15.0.8",
"expo-linear-gradient": "~15.0.8",
"expo-linking": "~8.0.11",
"expo-linking": "~8.0.12",
"expo-local-authentication": "~17.0.8",
"expo-localization": "~17.0.8",
"expo-location": "~19.0.8",
"expo-mail-composer": "~15.0.8",
"expo-manifests": "~1.0.10",
"expo-manifests": "~1.0.11",
"expo-maps": "~0.12.10",
"expo-mcp": "~0.2.1",
"expo-media-library": "~18.2.1",
"expo-mesh-gradient": "~0.4.8",
"expo-module-template": "~11.0.18",
"expo-modules-core": "~3.0.29",
"expo-module-template": "~11.0.19",
"expo-modules-core": "~3.0.30",
"expo-navigation-bar": "~5.0.10",
"expo-network": "~8.0.8",
"expo-notifications": "~0.32.16",
"expo-notifications": "~0.32.17",
"expo-print": "~15.0.8",
"expo-live-photo": "~1.0.8",
"expo-router": "~6.0.23",
"expo-screen-capture": "~8.0.9",
"expo-screen-orientation": "~9.0.8",
"expo-screen-orientation": "~9.0.9",
"expo-secure-store": "~15.0.8",
"expo-sensors": "~15.0.8",
"expo-server": "~1.0.5",
"expo-server": "~1.0.6",
"expo-sharing": "~14.0.8",
"expo-sms": "~14.0.8",
"expo-speech": "~14.0.8",
@@ -88,10 +88,10 @@
"expo-system-ui": "~6.0.9",
"expo-task-manager": "~14.0.9",
"expo-tracking-transparency": "~6.0.8",
"expo-updates": "~29.0.16",
"expo-updates": "~29.0.17",
"expo-video-thumbnails": "~10.0.8",
"expo-video": "~3.0.15",
"expo-web-browser": "~15.0.10",
"expo-video": "~3.0.16",
"expo-web-browser": "~15.0.11",
"jest-expo": "~54.0.17",
"lottie-react-native": "~7.3.1",
"react": "19.1.0",
+1 -1
View File
@@ -123,7 +123,7 @@ const args = (0, _arg().default)({
});
if (args['--version']) {
// Version is added in the build script.
console.log("54.0.23");
console.log("54.0.24");
process.exit(0);
}
if (args['--non-interactive']) {
@@ -26,16 +26,16 @@ function _fs() {
};
return data;
}
function _minimatch() {
const data = require("minimatch");
_minimatch = function() {
function _path() {
const data = /*#__PURE__*/ _interop_require_default(require("path"));
_path = function() {
return data;
};
return data;
}
function _path() {
const data = /*#__PURE__*/ _interop_require_default(require("path"));
_path = function() {
function _picomatch() {
const data = /*#__PURE__*/ _interop_require_default(require("picomatch"));
_picomatch = function() {
return data;
};
return data;
@@ -132,8 +132,9 @@ function assetPatternsToBeBundled(exp) {
// needed because android doesn't support assets that start with numbers.
const fullPatterns = assetPatternsToBeBundled.map((p)=>_path().default.join(projectRoot, p));
logPatterns(fullPatterns);
const matches = (0, _picomatch().default)(fullPatterns);
const allBundledAssets = assets.map((asset)=>{
const shouldBundle = shouldBundleAsset(asset, fullPatterns);
const shouldBundle = shouldBundleAsset(asset, matches);
if (shouldBundle) {
var _asset_files;
debug(`${shouldBundle ? 'Include' : 'Exclude'} asset ${(_asset_files = asset.files) == null ? void 0 : _asset_files[0]}`);
@@ -158,10 +159,10 @@ function logPatterns(patterns) {
_log.log('\nProcessing asset bundle patterns:');
patterns.forEach((p)=>_log.log('- ' + p));
}
function shouldBundleAsset(asset, patterns) {
function shouldBundleAsset(asset, matcher) {
var _asset_files;
const file = (_asset_files = asset.files) == null ? void 0 : _asset_files[0];
return !!('__packager_asset' in asset && asset.__packager_asset && file && patterns.some((pattern)=>(0, _minimatch().minimatch)(file, pattern)));
return !!('__packager_asset' in asset && asset.__packager_asset && file && matcher(file));
}
async function exportAssetsAsync(projectRoot, { exp, outputDir, bundles: { web, ...bundles }, baseUrl, files = new Map(), hostedNative }) {
var _assets_;
File diff suppressed because one or more lines are too long
@@ -20,13 +20,15 @@ const _errors = require("../../utils/errors");
async function getMainActivityAsync(projectRoot) {
const filePath = await _configplugins().AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);
const androidManifest = await _configplugins().AndroidConfig.Manifest.readAndroidManifestAsync(filePath);
// Assert MainActivity defined.
const activity = await _configplugins().AndroidConfig.Manifest.getRunnableActivity(androidManifest);
if (!activity) {
const runnableActivity = _configplugins().AndroidConfig.Manifest.getRunnableActivity(androidManifest);
if (runnableActivity) {
return runnableActivity.$['android:name'];
}
const mainActivity = _configplugins().AndroidConfig.Manifest.getMainActivity(androidManifest);
if (!mainActivity) {
throw new _errors.CommandError('ANDROID_MALFORMED', `${filePath} is missing a runnable activity element.`);
}
// Often this is ".MainActivity"
return activity.$['android:name'];
return mainActivity.$['android:name'];
}
async function resolveLaunchPropsAsync(projectRoot, options) {
const mainActivity = await getMainActivityAsync(projectRoot);
@@ -1 +1 @@
{"version":3,"sources":["../../../../src/run/android/resolveLaunchProps.ts"],"sourcesContent":["import { AndroidConfig } from '@expo/config-plugins';\n\nimport { AndroidAppIdResolver } from '../../start/platforms/android/AndroidAppIdResolver';\nimport { CommandError } from '../../utils/errors';\n\nexport interface LaunchProps {\n /**\n * The \"common\" Android package name, configured through the app manifest.\n * @see https://source.android.com/docs/core/architecture/hidl/code-style#package-names\n */\n packageName: string;\n /**\n * Optional customized application ID, used in product flavors.\n * @see https://developer.android.com/build/build-variants#change-app-id\n */\n customAppId?: string;\n /**\n * The main activity to launch, by default this is `.MainActivity`.\n * @see https://github.com/expo/expo/blob/c0aec226a43c0f186258a063a6145c3e52246f8a/templates/expo-template-bare-minimum/android/app/src/main/AndroidManifest.xml#L22\n */\n mainActivity: string;\n /**\n * The full launch activity reference used in the app intent to launch the app with `adb am start -n <launchActivity>`.\n * Usually, this is structured as `<package-name>/.<activity-name>`.\n * For product flavors, this is structured as `<custom-app-id>/<package-name>.<activity-name>`.\n * @see https://developer.android.com/studio/command-line/adb#IntentSpec\n */\n launchActivity: string;\n}\n\nasync function getMainActivityAsync(projectRoot: string): Promise<string> {\n const filePath = await AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);\n const androidManifest = await AndroidConfig.Manifest.readAndroidManifestAsync(filePath);\n\n // Assert MainActivity defined.\n const activity = await AndroidConfig.Manifest.getRunnableActivity(androidManifest);\n if (!activity) {\n throw new CommandError(\n 'ANDROID_MALFORMED',\n `${filePath} is missing a runnable activity element.`\n );\n }\n // Often this is \".MainActivity\"\n return activity.$['android:name'];\n}\n\nexport async function resolveLaunchPropsAsync(\n projectRoot: string,\n options: { appId?: string }\n): Promise<LaunchProps> {\n const mainActivity = await getMainActivityAsync(projectRoot);\n const packageName = await new AndroidAppIdResolver(projectRoot).getAppIdFromNativeAsync();\n const customAppId = options.appId;\n\n const launchActivity =\n customAppId && customAppId !== packageName\n ? `${customAppId}/${packageName}${mainActivity}`\n : `${packageName}/${mainActivity}`;\n\n return {\n mainActivity,\n launchActivity,\n packageName,\n customAppId,\n };\n}\n"],"names":["resolveLaunchPropsAsync","getMainActivityAsync","projectRoot","filePath","AndroidConfig","Paths","getAndroidManifestAsync","androidManifest","Manifest","readAndroidManifestAsync","activity","getRunnableActivity","CommandError","$","options","mainActivity","packageName","AndroidAppIdResolver","getAppIdFromNativeAsync","customAppId","appId","launchActivity"],"mappings":";;;;+BA8CsBA;;;eAAAA;;;;yBA9CQ;;;;;;sCAEO;wBACR;AA2B7B,eAAeC,qBAAqBC,WAAmB;IACrD,MAAMC,WAAW,MAAMC,8BAAa,CAACC,KAAK,CAACC,uBAAuB,CAACJ;IACnE,MAAMK,kBAAkB,MAAMH,8BAAa,CAACI,QAAQ,CAACC,wBAAwB,CAACN;IAE9E,+BAA+B;IAC/B,MAAMO,WAAW,MAAMN,8BAAa,CAACI,QAAQ,CAACG,mBAAmB,CAACJ;IAClE,IAAI,CAACG,UAAU;QACb,MAAM,IAAIE,oBAAY,CACpB,qBACA,GAAGT,SAAS,wCAAwC,CAAC;IAEzD;IACA,gCAAgC;IAChC,OAAOO,SAASG,CAAC,CAAC,eAAe;AACnC;AAEO,eAAeb,wBACpBE,WAAmB,EACnBY,OAA2B;IAE3B,MAAMC,eAAe,MAAMd,qBAAqBC;IAChD,MAAMc,cAAc,MAAM,IAAIC,0CAAoB,CAACf,aAAagB,uBAAuB;IACvF,MAAMC,cAAcL,QAAQM,KAAK;IAEjC,MAAMC,iBACJF,eAAeA,gBAAgBH,cAC3B,GAAGG,YAAY,CAAC,EAAEH,cAAcD,cAAc,GAC9C,GAAGC,YAAY,CAAC,EAAED,cAAc;IAEtC,OAAO;QACLA;QACAM;QACAL;QACAG;IACF;AACF"}
{"version":3,"sources":["../../../../src/run/android/resolveLaunchProps.ts"],"sourcesContent":["import { AndroidConfig } from '@expo/config-plugins';\n\nimport { AndroidAppIdResolver } from '../../start/platforms/android/AndroidAppIdResolver';\nimport { CommandError } from '../../utils/errors';\n\nexport interface LaunchProps {\n /**\n * The \"common\" Android package name, configured through the app manifest.\n * @see https://source.android.com/docs/core/architecture/hidl/code-style#package-names\n */\n packageName: string;\n /**\n * Optional customized application ID, used in product flavors.\n * @see https://developer.android.com/build/build-variants#change-app-id\n */\n customAppId?: string;\n /**\n * The main activity to launch, by default this is `.MainActivity`.\n * @see https://github.com/expo/expo/blob/c0aec226a43c0f186258a063a6145c3e52246f8a/templates/expo-template-bare-minimum/android/app/src/main/AndroidManifest.xml#L22\n */\n mainActivity: string;\n /**\n * The full launch activity reference used in the app intent to launch the app with `adb am start -n <launchActivity>`.\n * Usually, this is structured as `<package-name>/.<activity-name>`.\n * For product flavors, this is structured as `<custom-app-id>/<package-name>.<activity-name>`.\n * @see https://developer.android.com/studio/command-line/adb#IntentSpec\n */\n launchActivity: string;\n}\n\nasync function getMainActivityAsync(projectRoot: string): Promise<string> {\n const filePath = await AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);\n const androidManifest = await AndroidConfig.Manifest.readAndroidManifestAsync(filePath);\n const runnableActivity = AndroidConfig.Manifest.getRunnableActivity(androidManifest);\n if (runnableActivity) {\n return runnableActivity.$['android:name'];\n }\n const mainActivity = AndroidConfig.Manifest.getMainActivity(androidManifest);\n if (!mainActivity) {\n throw new CommandError(\n 'ANDROID_MALFORMED',\n `${filePath} is missing a runnable activity element.`\n );\n }\n return mainActivity.$['android:name'];\n}\n\nexport async function resolveLaunchPropsAsync(\n projectRoot: string,\n options: { appId?: string }\n): Promise<LaunchProps> {\n const mainActivity = await getMainActivityAsync(projectRoot);\n const packageName = await new AndroidAppIdResolver(projectRoot).getAppIdFromNativeAsync();\n const customAppId = options.appId;\n\n const launchActivity =\n customAppId && customAppId !== packageName\n ? `${customAppId}/${packageName}${mainActivity}`\n : `${packageName}/${mainActivity}`;\n\n return {\n mainActivity,\n launchActivity,\n packageName,\n customAppId,\n };\n}\n"],"names":["resolveLaunchPropsAsync","getMainActivityAsync","projectRoot","filePath","AndroidConfig","Paths","getAndroidManifestAsync","androidManifest","Manifest","readAndroidManifestAsync","runnableActivity","getRunnableActivity","$","mainActivity","getMainActivity","CommandError","options","packageName","AndroidAppIdResolver","getAppIdFromNativeAsync","customAppId","appId","launchActivity"],"mappings":";;;;+BA+CsBA;;;eAAAA;;;;yBA/CQ;;;;;;sCAEO;wBACR;AA2B7B,eAAeC,qBAAqBC,WAAmB;IACrD,MAAMC,WAAW,MAAMC,8BAAa,CAACC,KAAK,CAACC,uBAAuB,CAACJ;IACnE,MAAMK,kBAAkB,MAAMH,8BAAa,CAACI,QAAQ,CAACC,wBAAwB,CAACN;IAC9E,MAAMO,mBAAmBN,8BAAa,CAACI,QAAQ,CAACG,mBAAmB,CAACJ;IACpE,IAAIG,kBAAkB;QACpB,OAAOA,iBAAiBE,CAAC,CAAC,eAAe;IAC3C;IACA,MAAMC,eAAeT,8BAAa,CAACI,QAAQ,CAACM,eAAe,CAACP;IAC5D,IAAI,CAACM,cAAc;QACjB,MAAM,IAAIE,oBAAY,CACpB,qBACA,GAAGZ,SAAS,wCAAwC,CAAC;IAEzD;IACA,OAAOU,aAAaD,CAAC,CAAC,eAAe;AACvC;AAEO,eAAeZ,wBACpBE,WAAmB,EACnBc,OAA2B;IAE3B,MAAMH,eAAe,MAAMZ,qBAAqBC;IAChD,MAAMe,cAAc,MAAM,IAAIC,0CAAoB,CAAChB,aAAaiB,uBAAuB;IACvF,MAAMC,cAAcJ,QAAQK,KAAK;IAEjC,MAAMC,iBACJF,eAAeA,gBAAgBH,cAC3B,GAAGG,YAAY,CAAC,EAAEH,cAAcJ,cAAc,GAC9C,GAAGI,YAAY,CAAC,EAAEJ,cAAc;IAEtC,OAAO;QACLA;QACAS;QACAL;QACAG;IACF;AACF"}
File diff suppressed because one or more lines are too long
@@ -115,7 +115,7 @@ async function launchAppAsync(binaryPath, manager, props, appId) {
await manager.getDefaultDevServer().openCustomRuntimeAsync('simulator', {
applicationId: appId
}, {
device
device: device.device
});
}
async function getLaunchInfoForBinaryAsync(binaryPath) {
File diff suppressed because one or more lines are too long
@@ -22,6 +22,13 @@ function _spawnasync() {
};
return data;
}
function _path() {
const data = /*#__PURE__*/ _interop_require_default(require("path"));
_path = function() {
return data;
};
return data;
}
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../../log"));
const _Prerequisite = require("../Prerequisite");
function _interop_require_default(obj) {
@@ -71,14 +78,44 @@ function _interop_require_wildcard(obj, nodeInterop) {
return newObj;
}
const debug = require('debug')('expo:doctor:apple:simulatorApp');
async function getSimulatorAppIdAsync() {
/**
* Get the bundle ID of the Simulator.app via AppleScript / LaunchServices.
* May return null if the Simulator.app is not registered in LaunchServices
* (e.g. when Xcode lives on an external or renamed volume).
*/ async function getSimulatorAppIdViaAppleScriptAsync() {
try {
return (await (0, _osascript().execAsync)('id of app "Simulator"')).trim();
} catch {
// This error may occur in CI where the users intends to install just the simulators but no Xcode.
// This error may occur in CI where the user intends to install just the simulators but no
// Xcode, or when Simulator.app is not registered in LaunchServices (e.g. Xcode on an
// external or renamed volume).
}
return null;
}
/**
* Fallback: locate Simulator.app via the active Xcode developer directory and read its
* CFBundleIdentifier directly from the app bundle's Info.plist.
* This works even when LaunchServices hasn't indexed Simulator.app.
*/ async function getSimulatorAppIdFromBundleAsync() {
try {
const { stdout: developerDir } = await (0, _spawnasync().default)('xcode-select', [
'--print-path'
]);
const simulatorInfoPlist = _path().default.join(developerDir.trim(), 'Applications', 'Simulator.app', 'Contents', 'Info.plist');
const { stdout: bundleId } = await (0, _spawnasync().default)('defaults', [
'read',
simulatorInfoPlist,
'CFBundleIdentifier'
]);
return bundleId.trim() || null;
} catch {
// Simulator.app not found at the expected path or xcode-select is unavailable.
}
return null;
}
async function getSimulatorAppIdAsync() {
return await getSimulatorAppIdViaAppleScriptAsync() ?? await getSimulatorAppIdFromBundleAsync();
}
class SimulatorAppPrerequisite extends _Prerequisite.Prerequisite {
static #_ = this.instance = new SimulatorAppPrerequisite();
async assertImplementation() {
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
{"version":3,"sources":["../../../../../src/start/platforms/ios/ApplePlatformManager.ts"],"sourcesContent":["import { AppleAppIdResolver } from './AppleAppIdResolver';\nimport { AppleDeviceManager } from './AppleDeviceManager';\nimport { Device } from './simctl';\nimport { AppIdResolver } from '../AppIdResolver';\nimport { BaseOpenInCustomProps, PlatformManager } from '../PlatformManager';\n\n/** Manages launching apps on Apple simulators. */\nexport class ApplePlatformManager extends PlatformManager<Device> {\n constructor(\n protected projectRoot: string,\n protected port: number,\n options: {\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL. */\n getExpoGoUrl: () => string;\n /** Get redirect URL for native disambiguation. */\n getRedirectUrl: () => string | null;\n /** Dev Client */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n }\n ) {\n super(projectRoot, {\n platform: 'ios',\n ...options,\n resolveDeviceAsync: AppleDeviceManager.resolveAsync,\n });\n }\n\n async openAsync(\n options:\n | { runtime: 'expo' | 'web' }\n | { runtime: 'custom'; props?: Partial<BaseOpenInCustomProps> },\n resolveSettings?: Partial<{ shouldPrompt?: boolean; device?: Device }>\n ): Promise<{ url: string }> {\n await AppleDeviceManager.assertSystemRequirementsAsync();\n return super.openAsync(options, resolveSettings);\n }\n\n _getAppIdResolver(): AppIdResolver {\n return new AppleAppIdResolver(this.projectRoot);\n }\n\n _resolveAlternativeLaunchUrl(\n applicationId: string,\n props?: Partial<BaseOpenInCustomProps>\n ): string {\n return applicationId;\n }\n}\n"],"names":["ApplePlatformManager","PlatformManager","constructor","projectRoot","port","options","platform","resolveDeviceAsync","AppleDeviceManager","resolveAsync","openAsync","resolveSettings","assertSystemRequirementsAsync","_getAppIdResolver","AppleAppIdResolver","_resolveAlternativeLaunchUrl","applicationId","props"],"mappings":";;;;+BAOaA;;;eAAAA;;;oCAPsB;oCACA;iCAGoB;AAGhD,MAAMA,6BAA6BC,gCAAe;IACvDC,YACE,AAAUC,WAAmB,EAC7B,AAAUC,IAAY,EACtBC,OASC,CACD;QACA,KAAK,CAACF,aAAa;YACjBG,UAAU;YACV,GAAGD,OAAO;YACVE,oBAAoBC,sCAAkB,CAACC,YAAY;QACrD,SAjBUN,cAAAA,kBACAC,OAAAA;IAiBZ;IAEA,MAAMM,UACJL,OAEiE,EACjEM,eAAsE,EAC5C;QAC1B,MAAMH,sCAAkB,CAACI,6BAA6B;QACtD,OAAO,KAAK,CAACF,UAAUL,SAASM;IAClC;IAEAE,oBAAmC;QACjC,OAAO,IAAIC,sCAAkB,CAAC,IAAI,CAACX,WAAW;IAChD;IAEAY,6BACEC,aAAqB,EACrBC,KAAsC,EAC9B;QACR,OAAOD;IACT;AACF"}
{"version":3,"sources":["../../../../../src/start/platforms/ios/ApplePlatformManager.ts"],"sourcesContent":["import { AppleAppIdResolver } from './AppleAppIdResolver';\nimport { AppleDeviceManager } from './AppleDeviceManager';\nimport { Device } from './simctl';\nimport { AppIdResolver } from '../AppIdResolver';\nimport { BaseOpenInCustomProps, BaseResolveDeviceProps, PlatformManager } from '../PlatformManager';\n\n/** Manages launching apps on Apple simulators. */\nexport class ApplePlatformManager extends PlatformManager<Device> {\n constructor(\n protected projectRoot: string,\n protected port: number,\n options: {\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL. */\n getExpoGoUrl: () => string;\n /** Get redirect URL for native disambiguation. */\n getRedirectUrl: () => string | null;\n /** Dev Client */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n }\n ) {\n super(projectRoot, {\n platform: 'ios',\n ...options,\n resolveDeviceAsync: AppleDeviceManager.resolveAsync,\n });\n }\n\n async openAsync(\n options:\n | { runtime: 'expo' | 'web' }\n | { runtime: 'custom'; props?: Partial<BaseOpenInCustomProps> },\n resolveSettings?: BaseResolveDeviceProps<Device>\n ): Promise<{ url: string }> {\n await AppleDeviceManager.assertSystemRequirementsAsync();\n return super.openAsync(options, resolveSettings);\n }\n\n _getAppIdResolver(): AppIdResolver {\n return new AppleAppIdResolver(this.projectRoot);\n }\n\n _resolveAlternativeLaunchUrl(\n applicationId: string,\n props?: Partial<BaseOpenInCustomProps>\n ): string {\n return applicationId;\n }\n}\n"],"names":["ApplePlatformManager","PlatformManager","constructor","projectRoot","port","options","platform","resolveDeviceAsync","AppleDeviceManager","resolveAsync","openAsync","resolveSettings","assertSystemRequirementsAsync","_getAppIdResolver","AppleAppIdResolver","_resolveAlternativeLaunchUrl","applicationId","props"],"mappings":";;;;+BAOaA;;;eAAAA;;;oCAPsB;oCACA;iCAG4C;AAGxE,MAAMA,6BAA6BC,gCAAe;IACvDC,YACE,AAAUC,WAAmB,EAC7B,AAAUC,IAAY,EACtBC,OASC,CACD;QACA,KAAK,CAACF,aAAa;YACjBG,UAAU;YACV,GAAGD,OAAO;YACVE,oBAAoBC,sCAAkB,CAACC,YAAY;QACrD,SAjBUN,cAAAA,kBACAC,OAAAA;IAiBZ;IAEA,MAAMM,UACJL,OAEiE,EACjEM,eAAgD,EACtB;QAC1B,MAAMH,sCAAkB,CAACI,6BAA6B;QACtD,OAAO,KAAK,CAACF,UAAUL,SAASM;IAClC;IAEAE,oBAAmC;QACjC,OAAO,IAAIC,sCAAkB,CAAC,IAAI,CAACX,WAAW;IAChD;IAEAY,6BACEC,aAAqB,EACrBC,KAAsC,EAC9B;QACR,OAAOD;IACT;AACF"}
@@ -360,23 +360,37 @@ class BundlerDevServer {
}
return this.getUrlCreator().constructLoadingUrl({}, platform === 'emulator' ? 'android' : platform === 'simulator' ? 'ios' : null) ?? null;
}
async getPlatformManagerAsync(platform) {
async getPlatformManagerAsync(ofPlatform) {
const platform = ofPlatform;
if (!this.platformManagers[platform]) {
var _this_getInstance;
const Manager = PLATFORM_MANAGERS[platform]();
const port = (_this_getInstance = this.getInstance()) == null ? void 0 : _this_getInstance.location.port;
if (!port || !this.urlCreator) {
throw new _errors.CommandError('DEV_SERVER', 'Cannot interact with native platforms until dev server has started');
}
debug(`Creating platform manager (platform: ${platform}, port: ${port})`);
this.platformManagers[platform] = new Manager(this.projectRoot, port, {
const managerParams = {
getCustomRuntimeUrl: this.urlCreator.constructDevClientUrl.bind(this.urlCreator),
getExpoGoUrl: this.getExpoGoUrl.bind(this),
getRedirectUrl: this.getRedirectUrl.bind(this, platform),
getDevServerUrl: this.getDevServerUrl.bind(this, {
hostType: 'localhost'
})
});
};
switch(platform){
case 'simulator':
{
const Manager = PLATFORM_MANAGERS[platform]();
this.platformManagers[platform] = new Manager(this.projectRoot, port, managerParams);
break;
}
case 'emulator':
{
const Manager = PLATFORM_MANAGERS[platform]();
this.platformManagers[platform] = new Manager(this.projectRoot, port, managerParams);
break;
}
}
}
return this.platformManagers[platform];
}
File diff suppressed because one or more lines are too long
@@ -8,6 +8,13 @@ Object.defineProperty(exports, "createMetroMiddleware", {
return createMetroMiddleware;
}
});
function _paths() {
const data = require("@expo/config/paths");
_paths = function() {
return data;
};
return data;
}
function _connect() {
const data = /*#__PURE__*/ _interop_require_default(require("connect"));
_connect = function() {
@@ -15,6 +22,20 @@ function _connect() {
};
return data;
}
function _nodefs() {
const data = /*#__PURE__*/ _interop_require_default(require("node:fs"));
_nodefs = function() {
return data;
};
return data;
}
function _nodepath() {
const data = /*#__PURE__*/ _interop_require_default(require("node:path"));
_nodepath = function() {
return data;
};
return data;
}
const _compression = require("./compression");
const _createEventSocket = require("./createEventSocket");
const _createMessageSocket = require("./createMessageSocket");
@@ -31,7 +52,7 @@ function createMetroMiddleware(metroConfig) {
});
const events = (0, _createEventSocket.createEventsSocket)(messages);
const middleware = (0, _connect().default)().use(noCacheMiddleware).use(_compression.compression)// Support opening stack frames from clients directly in the editor
.use('/open-stack-frame', rawBodyMiddleware).use('/open-stack-frame', metroOpenStackFrameMiddleware)// Support the symbolication endpoint of Metro
.use('/open-stack-frame', rawBodyMiddleware).use('/open-stack-frame', createMetroOpenStackFrameMiddleware(metroConfig))// Support the symbolication endpoint of Metro
// See: https://github.com/facebook/metro/blob/a792d85ffde3c21c3fbf64ac9404ab0afe5ff957/packages/metro/src/Server.js#L1266
.use('/symbolicate', rawBodyMiddleware)// Support status check to detect if the packager needs to be started from the native side
.use('/status', createMetroStatusMiddleware(metroConfig));
@@ -45,7 +66,7 @@ function createMetroMiddleware(metroConfig) {
}
};
}
const noCacheMiddleware = (req, res, next)=>{
const noCacheMiddleware = (_req, res, next)=>{
res.setHeader('Surrogate-Control', 'no-store');
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
res.setHeader('Pragma', 'no-cache');
@@ -59,22 +80,64 @@ const rawBodyMiddleware = (req, _res, next)=>{
reqWithBody.on('data', (chunk)=>reqWithBody.rawBody += chunk);
reqWithBody.on('end', next);
};
const metroOpenStackFrameMiddleware = (req, res, next)=>{
// Only accept POST requests
if (req.method !== 'POST') return next();
// Only handle requests with a raw body
if (!('rawBody' in req) || !req.rawBody) {
res.statusCode = 406;
return res.end('Open stack frame requires the JSON stack frame as request body');
}
const frame = JSON.parse(req.rawBody);
(0, _editor.openInEditorAsync)(frame.file, frame.lineNumber).finally(()=>res.end('OK'));
};
function createMetroStatusMiddleware(metroConfig) {
return (_req, res)=>{
res.setHeader('X-React-Native-Project-Root', encodeURI(metroConfig.projectRoot));
res.end('packager-status:running');
};
}
function createMetroOpenStackFrameMiddleware(metroConfig) {
return async (req, res, next)=>{
if (req.method !== 'POST') {
return next();
}
if (!('rawBody' in req) || !req.rawBody) {
res.statusCode = 406;
return res.end('Open stack frame requires the JSON stack frame as request body');
}
let frame;
try {
const json = JSON.parse(req.rawBody);
if (typeof json === 'object' && json != null && typeof json.file === 'string') {
frame = {
file: json.file,
lineNumber: typeof json.lineNumber === 'number' && Number.isSafeInteger(json.lineNumber) ? json.lineNumber : undefined
};
}
} catch {}
if (!frame) {
res.statusCode = 400;
return res.end('Open stack frame requires the JSON stack frame as request body');
}
const root = (0, _paths().getMetroServerRoot)(metroConfig.projectRoot);
const file = await ensureFileInRootDirectory(root, frame.file);
if (!file) {
res.statusCode = 400;
return res.end('Open stack frame requires target file to be in server root');
}
try {
await (0, _editor.openInEditorAsync)(file, frame.lineNumber);
return res.end('OK');
} catch {
res.statusCode = 5006;
return res.end('Open stack frame failed to open local editor');
}
};
}
const ensureFileInRootDirectory = async (root, file)=>{
try {
file = _nodepath().default.resolve(root, file);
file = await _nodefs().default.promises.realpath(file);
// Cannot be accessed using Metro's server API, we need to move the file
// into the project root and try again.
if (!_nodepath().default.relative(root, file).startsWith('..' + _nodepath().default.sep)) {
return file;
} else {
return null;
}
} catch {
return null;
}
};
//# sourceMappingURL=createMetroMiddleware.js.map
File diff suppressed because one or more lines are too long
@@ -33,7 +33,7 @@ class FetchClient {
this.headers = {
accept: 'application/json',
'content-type': 'application/json',
'user-agent': `expo-cli/${"54.0.23"}`,
'user-agent': `expo-cli/${"54.0.24"}`,
authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
};
}
@@ -83,7 +83,7 @@ function createContext() {
cpu: summarizeCpuInfo(),
app: {
name: 'expo/cli',
version: "54.0.23"
version: "54.0.24"
},
ci: _ciinfo().isCI ? {
name: _ciinfo().name,
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@expo/cli",
"version": "54.0.23",
"version": "54.0.24",
"description": "The Expo CLI",
"main": "build/bin/cli",
"bin": {
@@ -50,7 +50,7 @@
"@expo/image-utils": "^0.8.8",
"@expo/json-file": "^10.0.8",
"@expo/metro": "~54.2.0",
"@expo/metro-config": "~54.0.14",
"@expo/metro-config": "~54.0.15",
"@expo/osascript": "^2.3.8",
"@expo/package-manager": "^1.9.10",
"@expo/plist": "^0.4.8",
@@ -73,16 +73,16 @@
"connect": "^3.7.0",
"debug": "^4.3.4",
"env-editor": "^0.4.1",
"expo-server": "^1.0.5",
"expo-server": "^1.0.6",
"freeport-async": "^2.0.0",
"getenv": "^2.0.0",
"glob": "^13.0.0",
"lan-network": "^0.1.6",
"lan-network": "^0.2.1",
"minimatch": "^9.0.0",
"node-forge": "^1.3.3",
"npm-package-arg": "^11.0.0",
"ora": "^3.4.0",
"picomatch": "^3.0.1",
"picomatch": "^4.0.3",
"pretty-bytes": "^5.6.0",
"pretty-format": "^29.7.0",
"progress": "^2.0.3",
@@ -144,7 +144,7 @@
"@types/klaw-sync": "^6.0.0",
"@types/node": "^22.14.0",
"@types/npm-package-arg": "^6.1.0",
"@types/picomatch": "^2.3.3",
"@types/picomatch": "^4.0.2",
"@types/progress": "^2.0.5",
"@types/prompts": "^2.0.6",
"@types/resolve": "^1.20.2",
@@ -169,5 +169,5 @@
"tree-kill": "^1.2.2",
"tsd": "^0.28.1"
},
"gitHead": "cfd65241fb73317b63e6736e7890a784a69940fc"
"gitHead": "dd4e87727c4ef32ac5d8a7b5a42fd80da254140f"
}
+64 -43
View File
@@ -107,7 +107,7 @@ console.log(isMatch('a/b.js')); //=> false
## API
### [picomatch](lib/picomatch.js#L32)
### [picomatch](lib/picomatch.js#L31)
Creates a matcher function from one or more glob patterns. The returned function takes a string to match as its first argument, and returns true if the string is a match. The returned matcher function also takes a boolean as the second argument that, when true, returns an object with additional information.
@@ -119,8 +119,6 @@ Creates a matcher function from one or more glob patterns. The returned function
**Example**
By default, `picomatch` uses [`os.platform()`](https://nodejs.org/api/os.html#osplatform) to detect the operating system.
```js
const picomatch = require('picomatch');
// picomatch(glob[, options]);
@@ -147,7 +145,7 @@ console.log(isMatch('a\\b')); //=> true
console.log(isMatch('a/b')); //=> true
```
### [.test](lib/picomatch.js#L117)
### [.test](lib/picomatch.js#L116)
Test `input` with the given `regex`. This is used by the main `picomatch()` function to test the input string.
@@ -167,7 +165,7 @@ console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
// { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
```
### [.matchBase](lib/picomatch.js#L161)
### [.matchBase](lib/picomatch.js#L160)
Match the basename of a filepath.
@@ -185,7 +183,7 @@ const picomatch = require('picomatch');
console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
```
### [.isMatch](lib/picomatch.js#L183)
### [.isMatch](lib/picomatch.js#L182)
Returns true if **any** of the given glob `patterns` match the specified `string`.
@@ -206,7 +204,7 @@ console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
```
### [.parse](lib/picomatch.js#L199)
### [.parse](lib/picomatch.js#L198)
Parse a glob pattern to create the source string for a regular expression.
@@ -223,7 +221,7 @@ const picomatch = require('picomatch');
const result = picomatch.parse(pattern[, options]);
```
### [.scan](lib/picomatch.js#L231)
### [.scan](lib/picomatch.js#L230)
Scan a glob pattern to separate the pattern into segments.
@@ -254,7 +252,7 @@ console.log(result);
negated: true }
```
### [.compileRe](lib/picomatch.js#L245)
### [.compileRe](lib/picomatch.js#L244)
Compile a regular expression from the `state` object returned by the
[parse()](#parse) method.
@@ -267,7 +265,18 @@ Compile a regular expression from the `state` object returned by the
* `returnState` **{Boolean}**: Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
* `returns` **{RegExp}**
### [.makeRe](lib/picomatch.js#L286)
**Example**
```js
const picomatch = require('picomatch');
const state = picomatch.parse('*.js');
// picomatch.compileRe(state[, options]);
console.log(picomatch.compileRe(state));
//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
```
### [.makeRe](lib/picomatch.js#L285)
Create a regular expression from a parsed glob pattern.
@@ -283,14 +292,14 @@ Create a regular expression from a parsed glob pattern.
```js
const picomatch = require('picomatch');
const state = picomatch.parse('*.js');
// picomatch.compileRe(state[, options]);
// picomatch.makeRe(state[, options]);
console.log(picomatch.compileRe(state));
const result = picomatch.makeRe('*.js');
console.log(result);
//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
```
### [.toRegex](lib/picomatch.js#L321)
### [.toRegex](lib/picomatch.js#L320)
Create a regular expression from the given regex source string.
@@ -325,11 +334,9 @@ The following options may be used with the main `picomatch()` function or any of
| `bash` | `boolean` | `false` | Follow bash matching rules more strictly - disallows backslashes as escape characters, and treats single stars as globstars (`**`). |
| `capture` | `boolean` | `undefined` | Return regex matches in supporting methods. |
| `contains` | `boolean` | `undefined` | Allows glob to match any part of the given string(s). |
| `cwd` | `string` | `process.cwd()` | Current working directory. Used by `picomatch.split()` |
| `debug` | `boolean` | `undefined` | Debug regular expressions when an error is thrown. |
| `dot` | `boolean` | `false` | Enable dotfile matching. By default, dotfiles are ignored unless a `.` is explicitly defined in the pattern, or `options.dot` is true |
| `expandRange` | `function` | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. |
| `failglob` | `boolean` | `false` | Throws an error if no matches are found. Based on the bash option of the same name. |
| `fastpaths` | `boolean` | `true` | To speed up processing, full parsing is skipped for a handful common glob patterns. Disable this behavior by setting this option to `false`. |
| `flags` | `string` | `undefined` | Regex flags to use in the generated regex. If defined, the `nocase` option will be overridden. |
| [format](#optionsformat) | `function` | `undefined` | Custom function for formatting the returned string. This is useful for removing leading slashes, converting Windows paths to Posix paths, etc. |
@@ -337,30 +344,25 @@ The following options may be used with the main `picomatch()` function or any of
| `keepQuotes` | `boolean` | `false` | Retain quotes in the generated regex, since quotes may also be used as an alternative to backslashes. |
| `literalBrackets` | `boolean` | `undefined` | When `true`, brackets in the glob pattern will be escaped so that only literal brackets will be matched. |
| `matchBase` | `boolean` | `false` | Alias for `basename` |
| `maxLength` | `boolean` | `65536` | Limit the max length of the input string. An error is thrown if the input string is longer than this value. |
| `maxLength` | `number` | `65536` | Limit the max length of the input string. An error is thrown if the input string is longer than this value. |
| `maxExtglobRecursion` | `number\|boolean` | `0` | Limit nested quantified extglobs and other risky repeated extglob forms. When the limit is exceeded, the extglob is treated as a literal string instead of being compiled to regex. Set to `false` to disable this safeguard. |
| `nobrace` | `boolean` | `false` | Disable brace matching, so that `{a,b}` and `{1..3}` would be treated as literal characters. |
| `nobracket` | `boolean` | `undefined` | Disable matching with regex brackets. |
| `nocase` | `boolean` | `false` | Make matching case-insensitive. Equivalent to the regex `i` flag. Note that this option is overridden by the `flags` option. |
| `nodupes` | `boolean` | `true` | Deprecated, use `nounique` instead. This option will be removed in a future major release. By default duplicates are removed. Disable uniquification by setting this option to false. |
| `noext` | `boolean` | `false` | Alias for `noextglob` |
| `noextglob` | `boolean` | `false` | Disable support for matching with extglobs (like `+(a\|b)`) |
| `noglobstar` | `boolean` | `false` | Disable support for matching nested directories with globstars (`**`) |
| `nonegate` | `boolean` | `false` | Disable support for negating with leading `!` |
| `noquantifiers` | `boolean` | `false` | Disable support for regex quantifiers (like `a{1,2}`) and treat them as brace patterns to be expanded. |
| [onIgnore](#optionsonIgnore) | `function` | `undefined` | Function to be called on ignored items. |
| [onMatch](#optionsonMatch) | `function` | `undefined` | Function to be called on matched items. |
| [onResult](#optionsonResult) | `function` | `undefined` | Function to be called on all items, regardless of whether or not they are matched or ignored. |
| `posix` | `boolean` | `false` | Support POSIX character classes ("posix brackets"). |
| `posixSlashes` | `boolean` | `undefined` | Convert all slashes in file paths to forward slashes. This does not convert slashes in the glob pattern itself |
| `prepend` | `boolean` | `undefined` | String to prepend to the generated regex used for matching. |
| `regex` | `boolean` | `false` | Use regular expression rules for `+` (instead of matching literal `+`), and for stars that follow closing parentheses or brackets (as in `)*` and `]*`). |
| `strictBrackets` | `boolean` | `undefined` | Throw an error if brackets, braces, or parens are imbalanced. |
| `strictSlashes` | `boolean` | `undefined` | When true, picomatch won't match trailing slashes with single stars. |
| `unescape` | `boolean` | `undefined` | Remove backslashes preceding escaped characters in the glob pattern. By default, backslashes are retained. |
| `unixify` | `boolean` | `undefined` | Alias for `posixSlashes`, for backwards compatibility. |
| `windows` | `boolean` | `false` | Also accept backslashes as the path separator. |
picomatch has automatic detection for regex positive and negative lookbehinds. If the pattern contains a negative lookbehind, you must be using Node.js >= 8.10 or else picomatch will throw an error.
| `windows` | `boolean` | `false` | Also accept backslashes as the path separator. |
### Scan Options
@@ -553,6 +555,13 @@ console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false
// supports nested extglobs
console.log(pm.isMatch('foo.bar', '!(!(foo)).!(!(bar))')); // true
// risky quantified extglobs are treated literally by default
console.log(pm.makeRe('+(a|aa)'));
//=> /^(?:\+\(a\|aa\))$/
// increase the limit to allow a small amount of nested quantified extglobs
console.log(pm.isMatch('aaa', '+(+(a))', { maxExtglobRecursion: 1 })); // true
```
#### POSIX brackets
@@ -589,7 +598,7 @@ See the [Bash Reference Manual](https://www.gnu.org/software/bash/manual/html_no
### Braces
Picomatch does not do brace expansion. For [brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) and advanced matching with braces, use [micromatch](https://github.com/micromatch/micromatch) instead. Picomatch has very basic support for braces.
Picomatch only does [brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) of comma-delimited lists (e.g. `a/{b,c}/d`). For advanced matching with braces, use [micromatch](https://github.com/micromatch/micromatch), which supports advanced syntax such as ranges (e.g. `{01..03}`) and increments (e.g. `{2..10..2}`).
### Matching special characters as literals
@@ -634,29 +643,41 @@ The following table shows which features are supported by [minimatch](https://gi
Performance comparison of picomatch and minimatch.
```
# .makeRe star
picomatch x 1,993,050 ops/sec ±0.51% (91 runs sampled)
minimatch x 627,206 ops/sec ±1.96% (87 runs sampled))
# .makeRe star (*)
picomatch x 3,251,247 ops/sec ±0.25% (95 runs sampled)
minimatch x 497,224 ops/sec ±0.11% (100 runs sampled)
# .makeRe star; dot=true
picomatch x 1,436,640 ops/sec ±0.62% (91 runs sampled)
minimatch x 525,876 ops/sec ±0.60% (88 runs sampled)
# .makeRe star; dot=true (*)
picomatch x 2,624,035 ops/sec ±0.16% (98 runs sampled)
minimatch x 446,244 ops/sec ±0.63% (99 runs sampled)
# .makeRe globstar
picomatch x 1,592,742 ops/sec ±0.42% (90 runs sampled)
minimatch x 962,043 ops/sec ±1.76% (91 runs sampled)d)
# .makeRe globstar (**)
picomatch x 2,524,465 ops/sec ±0.13% (99 runs sampled)
minimatch x 1,396,257 ops/sec ±0.58% (96 runs sampled)
# .makeRe globstars
picomatch x 1,615,199 ops/sec ±0.35% (94 runs sampled)
minimatch x 477,179 ops/sec ±1.33% (91 runs sampled)
# .makeRe globstars (**/**/**)
picomatch x 2,545,674 ops/sec ±0.10% (99 runs sampled)
minimatch x 1,196,835 ops/sec ±0.63% (98 runs sampled)
# .makeRe with leading star
picomatch x 1,220,856 ops/sec ±0.40% (92 runs sampled)
minimatch x 453,564 ops/sec ±1.43% (94 runs sampled)
# .makeRe with leading star (*.txt)
picomatch x 2,537,708 ops/sec ±0.11% (100 runs sampled)
minimatch x 345,284 ops/sec ±0.64% (96 runs sampled)
# .makeRe - basic braces
picomatch x 392,067 ops/sec ±0.70% (90 runs sampled)
minimatch x 99,532 ops/sec ±2.03% (87 runs sampled))
# .makeRe - basic braces ({a,b,c}*.txt)
picomatch x 505,430 ops/sec ±1.04% (94 runs sampled)
minimatch x 107,991 ops/sec ±0.54% (99 runs sampled)
# .makeRe - short ranges ({a..z}*.txt)
picomatch x 371,179 ops/sec ±2.91% (77 runs sampled)
minimatch x 14,104 ops/sec ±0.61% (99 runs sampled)
# .makeRe - medium ranges ({1..100000}*.txt)
picomatch x 384,958 ops/sec ±1.70% (82 runs sampled)
minimatch x 2.55 ops/sec ±3.22% (11 runs sampled)
# .makeRe - long ranges ({1..10000000}*.txt)
picomatch x 382,552 ops/sec ±1.52% (71 runs sampled)
minimatch x 0.83 ops/sec ±5.67% (7 runs sampled))
```
<br>
+4 -14
View File
@@ -1,27 +1,17 @@
'use strict';
const os = require('os');
const pico = require('./lib/picomatch');
const isWindows = os.platform() === 'win32';
const utils = require('./lib/utils');
function picomatch(glob, options, returnState = false) {
// default to os.platform()
if (options && (options.windows === null || options.windows === undefined)) {
// don't mutate the original options object
options = { ...options, windows: isWindows };
options = { ...options, windows: utils.isWindows() };
}
return pico(glob, options, returnState);
}
Object.assign(picomatch, pico);
module.exports = picomatch;
// public api
module.exports.test = pico.test;
module.exports.matchBase = pico.matchBase;
module.exports.isMatch = pico.isMatch;
module.exports.parse = pico.parse;
module.exports.scan = pico.scan;
module.exports.compileRe = pico.compileRe;
module.exports.toRegex = pico.toRegex;
// for tests
module.exports.makeRe = pico.makeRe;
@@ -3,6 +3,8 @@
const WIN_SLASH = '\\\\/';
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
const DEFAULT_MAX_EXTGLOB_RECURSION = 0;
/**
* Posix glob regex
*/
@@ -69,6 +71,7 @@ const WINDOWS_CHARS = {
*/
const POSIX_REGEX_SOURCE = {
__proto__: null,
alnum: 'a-zA-Z0-9',
alpha: 'a-zA-Z',
ascii: '\\x00-\\x7F',
@@ -86,6 +89,7 @@ const POSIX_REGEX_SOURCE = {
};
module.exports = {
DEFAULT_MAX_EXTGLOB_RECURSION,
MAX_LENGTH: 1024 * 64,
POSIX_REGEX_SOURCE,
@@ -99,6 +103,7 @@ module.exports = {
// Replace globs with equivalent patterns to reduce parsing time.
REPLACEMENTS: {
__proto__: null,
'***': '*',
'**/**': '**',
'**/**/**': '**'
+302 -5
View File
@@ -45,6 +45,277 @@ const syntaxError = (type, char) => {
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
};
const splitTopLevel = input => {
const parts = [];
let bracket = 0;
let paren = 0;
let quote = 0;
let value = '';
let escaped = false;
for (const ch of input) {
if (escaped === true) {
value += ch;
escaped = false;
continue;
}
if (ch === '\\') {
value += ch;
escaped = true;
continue;
}
if (ch === '"') {
quote = quote === 1 ? 0 : 1;
value += ch;
continue;
}
if (quote === 0) {
if (ch === '[') {
bracket++;
} else if (ch === ']' && bracket > 0) {
bracket--;
} else if (bracket === 0) {
if (ch === '(') {
paren++;
} else if (ch === ')' && paren > 0) {
paren--;
} else if (ch === '|' && paren === 0) {
parts.push(value);
value = '';
continue;
}
}
}
value += ch;
}
parts.push(value);
return parts;
};
const isPlainBranch = branch => {
let escaped = false;
for (const ch of branch) {
if (escaped === true) {
escaped = false;
continue;
}
if (ch === '\\') {
escaped = true;
continue;
}
if (/[?*+@!()[\]{}]/.test(ch)) {
return false;
}
}
return true;
};
const normalizeSimpleBranch = branch => {
let value = branch.trim();
let changed = true;
while (changed === true) {
changed = false;
if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
value = value.slice(2, -1);
changed = true;
}
}
if (!isPlainBranch(value)) {
return;
}
return value.replace(/\\(.)/g, '$1');
};
const hasRepeatedCharPrefixOverlap = branches => {
const values = branches.map(normalizeSimpleBranch).filter(Boolean);
for (let i = 0; i < values.length; i++) {
for (let j = i + 1; j < values.length; j++) {
const a = values[i];
const b = values[j];
const char = a[0];
if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) {
continue;
}
if (a === b || a.startsWith(b) || b.startsWith(a)) {
return true;
}
}
}
return false;
};
const parseRepeatedExtglob = (pattern, requireEnd = true) => {
if ((pattern[0] !== '+' && pattern[0] !== '*') || pattern[1] !== '(') {
return;
}
let bracket = 0;
let paren = 0;
let quote = 0;
let escaped = false;
for (let i = 1; i < pattern.length; i++) {
const ch = pattern[i];
if (escaped === true) {
escaped = false;
continue;
}
if (ch === '\\') {
escaped = true;
continue;
}
if (ch === '"') {
quote = quote === 1 ? 0 : 1;
continue;
}
if (quote === 1) {
continue;
}
if (ch === '[') {
bracket++;
continue;
}
if (ch === ']' && bracket > 0) {
bracket--;
continue;
}
if (bracket > 0) {
continue;
}
if (ch === '(') {
paren++;
continue;
}
if (ch === ')') {
paren--;
if (paren === 0) {
if (requireEnd === true && i !== pattern.length - 1) {
return;
}
return {
type: pattern[0],
body: pattern.slice(2, i),
end: i
};
}
}
}
};
const getStarExtglobSequenceOutput = pattern => {
let index = 0;
const chars = [];
while (index < pattern.length) {
const match = parseRepeatedExtglob(pattern.slice(index), false);
if (!match || match.type !== '*') {
return;
}
const branches = splitTopLevel(match.body).map(branch => branch.trim());
if (branches.length !== 1) {
return;
}
const branch = normalizeSimpleBranch(branches[0]);
if (!branch || branch.length !== 1) {
return;
}
chars.push(branch);
index += match.end + 1;
}
if (chars.length < 1) {
return;
}
const source = chars.length === 1
? utils.escapeRegex(chars[0])
: `[${chars.map(ch => utils.escapeRegex(ch)).join('')}]`;
return `${source}*`;
};
const repeatedExtglobRecursion = pattern => {
let depth = 0;
let value = pattern.trim();
let match = parseRepeatedExtglob(value);
while (match) {
depth++;
value = match.body.trim();
match = parseRepeatedExtglob(value);
}
return depth;
};
const analyzeRepeatedExtglob = (body, options) => {
if (options.maxExtglobRecursion === false) {
return { risky: false };
}
const max =
typeof options.maxExtglobRecursion === 'number'
? options.maxExtglobRecursion
: constants.DEFAULT_MAX_EXTGLOB_RECURSION;
const branches = splitTopLevel(body).map(branch => branch.trim());
if (branches.length > 1) {
if (
branches.some(branch => branch === '') ||
branches.some(branch => /^[*?]+$/.test(branch)) ||
hasRepeatedCharPrefixOverlap(branches)
) {
return { risky: true };
}
}
for (const branch of branches) {
const safeOutput = getStarExtglobSequenceOutput(branch);
if (safeOutput) {
return { risky: true, safeOutput };
}
if (repeatedExtglobRecursion(branch) > max) {
return { risky: true };
}
}
return { risky: false };
};
/**
* Parse the given input string.
* @param {String} input
@@ -209,8 +480,8 @@ const parse = (input, options) => {
if (tok.value || tok.output) append(tok);
if (prev && prev.type === 'text' && tok.type === 'text') {
prev.output = (prev.output || prev.value) + tok.value;
prev.value += tok.value;
prev.output = (prev.output || '') + tok.value;
return;
}
@@ -225,6 +496,8 @@ const parse = (input, options) => {
token.prev = prev;
token.parens = state.parens;
token.output = state.output;
token.startIndex = state.index;
token.tokensIndex = tokens.length;
const output = (opts.capture ? '(' : '') + token.open;
increment('parens');
@@ -234,6 +507,34 @@ const parse = (input, options) => {
};
const extglobClose = token => {
const literal = input.slice(token.startIndex, state.index + 1);
const body = input.slice(token.startIndex + 2, state.index);
const analysis = analyzeRepeatedExtglob(body, opts);
if ((token.type === 'plus' || token.type === 'star') && analysis.risky) {
const safeOutput = analysis.safeOutput
? (token.output ? '' : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput)
: undefined;
const open = tokens[token.tokensIndex];
open.type = 'text';
open.value = literal;
open.output = safeOutput || utils.escapeRegex(literal);
for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
tokens[i].value = '';
tokens[i].output = '';
delete tokens[i].suffix;
}
state.output = token.output + open.output;
state.backtrack = true;
push({ type: 'paren', extglob: true, value, output: '' });
decrement('parens');
return;
}
let output = token.close + (opts.capture ? ')' : '');
let rest;
@@ -698,10 +999,6 @@ const parse = (input, options) => {
const next = peek();
let output = value;
if (next === '<' && !utils.supportsLookbehinds()) {
throw new Error('Node.js v10 or higher is required for regex lookbehinds');
}
if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
output = `\\${value}`;
}
+11 -3
View File
@@ -233,6 +233,14 @@ picomatch.scan = (input, options) => scan(input, options);
* Compile a regular expression from the `state` object returned by the
* [parse()](#parse) method.
*
* ```js
* const picomatch = require('picomatch');
* const state = picomatch.parse('*.js');
* // picomatch.compileRe(state[, options]);
*
* console.log(picomatch.compileRe(state));
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
* ```
* @param {Object} `state`
* @param {Object} `options`
* @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
@@ -268,10 +276,10 @@ picomatch.compileRe = (state, options, returnOutput = false, returnState = false
*
* ```js
* const picomatch = require('picomatch');
* const state = picomatch.parse('*.js');
* // picomatch.compileRe(state[, options]);
* // picomatch.makeRe(state[, options]);
*
* console.log(picomatch.compileRe(state));
* const result = picomatch.makeRe('*.js');
* console.log(result);
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
* ```
* @param {String} `state` The object returned from the `.parse` method.
+14 -10
View File
@@ -1,3 +1,4 @@
/*global navigator*/
'use strict';
const {
@@ -13,22 +14,25 @@ exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
exports.isWindows = () => {
if (typeof navigator !== 'undefined' && navigator.platform) {
const platform = navigator.platform.toLowerCase();
return platform === 'win32' || platform === 'windows';
}
if (typeof process !== 'undefined' && process.platform) {
return process.platform === 'win32';
}
return false;
};
exports.removeBackslashes = str => {
return str.replace(REGEX_REMOVE_BACKSLASH, match => {
return match === '\\' ? '' : match;
});
};
exports.supportsLookbehinds = () => {
if (typeof process !== 'undefined') {
const segs = process.version.slice(1).split('.').map(Number);
if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
return true;
}
}
return false;
};
exports.escapeLast = (input, char, lastIdx) => {
const idx = input.lastIndexOf(char, lastIdx);
if (idx === -1) return input;
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "picomatch",
"description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.",
"version": "3.0.1",
"version": "4.0.4",
"homepage": "https://github.com/micromatch/picomatch",
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
"funding": "https://github.com/sponsors/jonschlinkert",
@@ -15,9 +15,10 @@
"posix.js",
"lib"
],
"sideEffects": false,
"main": "index.js",
"engines": {
"node": ">=10"
"node": ">=12"
},
"scripts": {
"lint": "eslint --cache --cache-location node_modules/.cache/.eslintcache --report-unused-disable-directives --ignore-path .gitignore .",
@@ -27,12 +28,11 @@
"test:cover": "nyc npm run mocha"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint": "^8.57.0",
"fill-range": "^7.0.1",
"gulp-format-md": "^2.0.0",
"mocha": "^6.2.2",
"nyc": "^15.0.0",
"time-require": "github:jonschlinkert/time-require"
"mocha": "^10.4.0",
"nyc": "^15.1.0"
},
"keywords": [
"glob",
+15 -6
View File
@@ -1,13 +1,22 @@
'use strict';
const createWebSocketStream = require('./lib/stream');
const extension = require('./lib/extension');
const PerMessageDeflate = require('./lib/permessage-deflate');
const Receiver = require('./lib/receiver');
const Sender = require('./lib/sender');
const subprotocol = require('./lib/subprotocol');
const WebSocket = require('./lib/websocket');
const WebSocketServer = require('./lib/websocket-server');
WebSocket.createWebSocketStream = require('./lib/stream');
WebSocket.Server = require('./lib/websocket-server');
WebSocket.Receiver = require('./lib/receiver');
WebSocket.Sender = require('./lib/sender');
WebSocket.createWebSocketStream = createWebSocketStream;
WebSocket.extension = extension;
WebSocket.PerMessageDeflate = PerMessageDeflate;
WebSocket.Receiver = Receiver;
WebSocket.Sender = Sender;
WebSocket.Server = WebSocketServer;
WebSocket.subprotocol = subprotocol;
WebSocket.WebSocket = WebSocket;
WebSocket.WebSocketServer = WebSocket.Server;
WebSocket.WebSocketServer = WebSocketServer;
module.exports = WebSocket;
@@ -37,6 +37,9 @@ class PerMessageDeflate {
* acknowledge disabling of client context takeover
* @param {Number} [options.concurrencyLimit=10] The number of concurrent
* calls to zlib
* @param {Boolean} [options.isServer=false] Create the instance in either
* server or client mode
* @param {Number} [options.maxPayload=0] The maximum allowed message length
* @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
* use of a custom server window size
* @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
@@ -47,16 +50,13 @@ class PerMessageDeflate {
* deflate
* @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
* inflate
* @param {Boolean} [isServer=false] Create the instance in either server or
* client mode
* @param {Number} [maxPayload=0] The maximum allowed message length
*/
constructor(options, isServer, maxPayload) {
this._maxPayload = maxPayload | 0;
constructor(options) {
this._options = options || {};
this._threshold =
this._options.threshold !== undefined ? this._options.threshold : 1024;
this._isServer = !!isServer;
this._maxPayload = this._options.maxPayload | 0;
this._isServer = !!this._options.isServer;
this._deflate = null;
this._inflate = null;
+5 -5
View File
@@ -293,11 +293,11 @@ class WebSocketServer extends EventEmitter {
this.options.perMessageDeflate &&
secWebSocketExtensions !== undefined
) {
const perMessageDeflate = new PerMessageDeflate(
this.options.perMessageDeflate,
true,
this.options.maxPayload
);
const perMessageDeflate = new PerMessageDeflate({
...this.options.perMessageDeflate,
isServer: true,
maxPayload: this.options.maxPayload
});
try {
const offers = extension.parse(secWebSocketExtensions);
+6 -6
View File
@@ -693,7 +693,7 @@ function initAsClient(websocket, address, protocols, options) {
} else {
try {
parsedUrl = new URL(address);
} catch (e) {
} catch {
throw new SyntaxError(`Invalid URL: ${address}`);
}
}
@@ -755,11 +755,11 @@ function initAsClient(websocket, address, protocols, options) {
opts.timeout = opts.handshakeTimeout;
if (opts.perMessageDeflate) {
perMessageDeflate = new PerMessageDeflate(
opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},
false,
opts.maxPayload
);
perMessageDeflate = new PerMessageDeflate({
...opts.perMessageDeflate,
isServer: false,
maxPayload: opts.maxPayload
});
opts.headers['Sec-WebSocket-Extensions'] = format({
[PerMessageDeflate.extensionName]: perMessageDeflate.offer()
});
+4 -3
View File
@@ -1,6 +1,6 @@
{
"name": "ws",
"version": "8.19.0",
"version": "8.20.0",
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",
"keywords": [
"HyBi",
@@ -55,12 +55,13 @@
}
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"benchmark": "^2.1.4",
"bufferutil": "^4.0.1",
"eslint": "^9.0.0",
"eslint": "^10.0.1",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-prettier": "^5.0.0",
"globals": "^16.0.0",
"globals": "^17.0.0",
"mocha": "^8.4.0",
"nyc": "^15.0.0",
"prettier": "^3.0.0",
+14 -1
View File
@@ -1,8 +1,21 @@
import createWebSocketStream from './lib/stream.js';
import extension from './lib/extension.js';
import PerMessageDeflate from './lib/permessage-deflate.js';
import Receiver from './lib/receiver.js';
import Sender from './lib/sender.js';
import subprotocol from './lib/subprotocol.js';
import WebSocket from './lib/websocket.js';
import WebSocketServer from './lib/websocket-server.js';
export { createWebSocketStream, Receiver, Sender, WebSocket, WebSocketServer };
export {
createWebSocketStream,
extension,
PerMessageDeflate,
Receiver,
Sender,
subprotocol,
WebSocket,
WebSocketServer
};
export default WebSocket;
+9 -9
View File
@@ -1,6 +1,6 @@
{
"name": "expo",
"version": "54.0.33",
"version": "54.0.34",
"description": "The Expo SDK",
"main": "src/Expo.ts",
"module": "src/Expo.ts",
@@ -75,23 +75,23 @@
"homepage": "https://github.com/expo/expo/tree/main/packages/expo",
"dependencies": {
"@babel/runtime": "^7.20.0",
"@expo/cli": "54.0.23",
"@expo/cli": "54.0.24",
"@expo/config": "~12.0.13",
"@expo/config-plugins": "~54.0.4",
"@expo/devtools": "0.1.8",
"@expo/fingerprint": "0.15.4",
"@expo/fingerprint": "0.15.5",
"@expo/metro": "~54.2.0",
"@expo/metro-config": "54.0.14",
"@expo/metro-config": "54.0.15",
"@expo/vector-icons": "^15.0.3",
"@ungap/structured-clone": "^1.3.0",
"babel-preset-expo": "~54.0.10",
"expo-asset": "~12.0.12",
"expo-asset": "~12.0.13",
"expo-constants": "~18.0.13",
"expo-file-system": "~19.0.21",
"expo-file-system": "~19.0.22",
"expo-font": "~14.0.11",
"expo-keep-awake": "~15.0.8",
"expo-modules-autolinking": "3.0.24",
"expo-modules-core": "3.0.29",
"expo-modules-autolinking": "3.0.25",
"expo-modules-core": "3.0.30",
"pretty-format": "^29.7.0",
"react-refresh": "^0.14.2",
"whatwg-url-without-unicode": "8.0.0-3"
@@ -124,5 +124,5 @@
"optional": true
}
},
"gitHead": "cfd65241fb73317b63e6736e7890a784a69940fc"
"gitHead": "dd4e87727c4ef32ac5d8a7b5a42fd80da254140f"
}
+8 -3
View File
@@ -81,9 +81,14 @@ export function installGlobal<T extends object>(name: string, getValue: () => T)
// @ts-ignore: globalThis is not defined in all environments
const object = typeof global !== 'undefined' ? global : globalThis;
const descriptor = Object.getOwnPropertyDescriptor(object, name);
if (__DEV__ && descriptor) {
const backupName = `original${name[0].toUpperCase()}${name.slice(1)}`;
Object.defineProperty(object, backupName, descriptor);
// NOTE(@kitten): We have to exclude descriptors with getters here
// When two calls of a "lazy getter" conflict, accessing the original will override the global again
// (e.g. `globalThis.originalURL` in react-native will set URL back to its own value)
if (__DEV__ && descriptor && !descriptor.get) {
const backupName = `original${name[0] ?? ''.toUpperCase()}${name.slice(1)}`;
// NOTE(@kitten): We don't want the global to be enumerably different in development
Object.defineProperty(object, backupName, { ...descriptor, enumerable: false });
}
const { enumerable, writable, configurable = false } = descriptor || {};
BIN
View File
Binary file not shown.