@expo/cli 0.24.2 → 0.24.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin/cli +1 -1
- package/build/src/install/utils/checkPackagesCompatibility.js +1 -1
- package/build/src/install/utils/checkPackagesCompatibility.js.map +1 -1
- package/build/src/lint/ESlintPrerequisite.js +2 -2
- package/build/src/lint/ESlintPrerequisite.js.map +1 -1
- package/build/src/lint/index.js +45 -47
- package/build/src/lint/index.js.map +1 -1
- package/build/src/lint/lintAsync.js +150 -4
- package/build/src/lint/lintAsync.js.map +1 -1
- package/build/src/lint/resolveOptions.js +115 -0
- package/build/src/lint/resolveOptions.js.map +1 -0
- package/build/src/prebuild/renameTemplateAppName.js +4 -1
- package/build/src/prebuild/renameTemplateAppName.js.map +1 -1
- package/build/src/run/android/runAndroidAsync.js +20 -19
- package/build/src/run/android/runAndroidAsync.js.map +1 -1
- package/build/src/run/ios/runIosAsync.js +4 -2
- package/build/src/run/ios/runIosAsync.js.map +1 -1
- package/build/src/run/remoteBuildCache.js +27 -115
- package/build/src/run/remoteBuildCache.js.map +1 -1
- package/build/src/start/server/metro/log-box/formatProjectFilePath.js +15 -12
- package/build/src/start/server/metro/log-box/formatProjectFilePath.js.map +1 -1
- package/build/src/start/server/middleware/metroOptions.js +2 -1
- package/build/src/start/server/middleware/metroOptions.js.map +1 -1
- package/build/src/utils/ip.js +7 -104
- package/build/src/utils/ip.js.map +1 -1
- package/build/src/utils/remote-build-cache-providers/eas.js +147 -0
- package/build/src/utils/remote-build-cache-providers/eas.js.map +1 -0
- package/build/src/utils/remote-build-cache-providers/helpers.js +25 -0
- package/build/src/utils/remote-build-cache-providers/helpers.js.map +1 -0
- package/build/src/utils/resolveArgs.js +8 -0
- package/build/src/utils/resolveArgs.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/build/src/utils/variadic.js +63 -6
- package/build/src/utils/variadic.js.map +1 -1
- package/package.json +9 -9
package/build/bin/cli
CHANGED
|
@@ -27,7 +27,7 @@ function _interop_require_default(obj) {
|
|
|
27
27
|
const ERROR_MESSAGE = 'Unable to fetch compatibility data from React Native Directory. Skipping check.';
|
|
28
28
|
async function checkPackagesCompatibility(packages) {
|
|
29
29
|
try {
|
|
30
|
-
const packagesToCheck = packages.filter((packageName)=>!packageName.startsWith('@expo-google-fonts/'));
|
|
30
|
+
const packagesToCheck = packages.filter((packageName)=>!packageName.startsWith('@expo/') && !packageName.startsWith('@expo-google-fonts/'));
|
|
31
31
|
if (!packagesToCheck.length) {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/install/utils/checkPackagesCompatibility.ts"],"sourcesContent":["// note(Simek): https://github.com/react-native-community/directory/blob/main/pages/api/libraries/check.ts\nimport chalk from 'chalk';\n\nimport { Log } from '../../log';\nimport { fetch } from '../../utils/fetch';\nimport { learnMore } from '../../utils/link';\n\nexport type ReactNativeDirectoryCheckResult = {\n unmaintained: boolean;\n newArchitecture: 'supported' | 'unsupported' | 'untested';\n};\n\nconst ERROR_MESSAGE =\n 'Unable to fetch compatibility data from React Native Directory. Skipping check.';\n\nexport async function checkPackagesCompatibility(packages: string[]) {\n try {\n const packagesToCheck = packages.filter(\n (packageName)
|
|
1
|
+
{"version":3,"sources":["../../../../src/install/utils/checkPackagesCompatibility.ts"],"sourcesContent":["// note(Simek): https://github.com/react-native-community/directory/blob/main/pages/api/libraries/check.ts\nimport chalk from 'chalk';\n\nimport { Log } from '../../log';\nimport { fetch } from '../../utils/fetch';\nimport { learnMore } from '../../utils/link';\n\nexport type ReactNativeDirectoryCheckResult = {\n unmaintained: boolean;\n newArchitecture: 'supported' | 'unsupported' | 'untested';\n};\n\nconst ERROR_MESSAGE =\n 'Unable to fetch compatibility data from React Native Directory. Skipping check.';\n\nexport async function checkPackagesCompatibility(packages: string[]) {\n try {\n const packagesToCheck = packages.filter(\n (packageName) =>\n !packageName.startsWith('@expo/') && !packageName.startsWith('@expo-google-fonts/')\n );\n\n if (!packagesToCheck.length) {\n return;\n }\n\n const response = await fetch('https://reactnative.directory/api/libraries/check', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ packages: packagesToCheck }),\n });\n\n if (!response.ok) {\n Log.log(chalk.gray(ERROR_MESSAGE));\n }\n\n const packageMetadata = (await response.json()) as Record<\n string,\n ReactNativeDirectoryCheckResult\n >;\n\n const incompatiblePackages = packagesToCheck.filter(\n (packageName) => packageMetadata[packageName]?.newArchitecture === 'unsupported'\n );\n\n if (incompatiblePackages.length) {\n Log.warn(\n chalk.yellow(\n `${chalk.bold('Warning')}: ${formatPackageNames(incompatiblePackages)} do${incompatiblePackages.length > 1 ? '' : 'es'} not support the New Architecture. ${learnMore('https://docs.expo.dev/guides/new-architecture/')}`\n )\n );\n }\n } catch {\n Log.log(chalk.gray(ERROR_MESSAGE));\n }\n}\n\nfunction formatPackageNames(incompatiblePackages: string[]) {\n if (incompatiblePackages.length === 1) {\n return incompatiblePackages.join();\n }\n\n const lastPackage = incompatiblePackages.pop();\n return `${incompatiblePackages.join(', ')} and ${lastPackage}`;\n}\n"],"names":["checkPackagesCompatibility","ERROR_MESSAGE","packages","packagesToCheck","filter","packageName","startsWith","length","response","fetch","method","headers","body","JSON","stringify","ok","Log","log","chalk","gray","packageMetadata","json","incompatiblePackages","newArchitecture","warn","yellow","bold","formatPackageNames","learnMore","join","lastPackage","pop"],"mappings":"AAAA,0GAA0G;;;;;+BAepFA;;;eAAAA;;;;gEAdJ;;;;;;qBAEE;uBACE;sBACI;;;;;;AAO1B,MAAMC,gBACJ;AAEK,eAAeD,2BAA2BE,QAAkB;IACjE,IAAI;QACF,MAAMC,kBAAkBD,SAASE,MAAM,CACrC,CAACC,cACC,CAACA,YAAYC,UAAU,CAAC,aAAa,CAACD,YAAYC,UAAU,CAAC;QAGjE,IAAI,CAACH,gBAAgBI,MAAM,EAAE;YAC3B;QACF;QAEA,MAAMC,WAAW,MAAMC,IAAAA,YAAK,EAAC,qDAAqD;YAChFC,QAAQ;YACRC,SAAS;gBACP,gBAAgB;YAClB;YACAC,MAAMC,KAAKC,SAAS,CAAC;gBAAEZ,UAAUC;YAAgB;QACnD;QAEA,IAAI,CAACK,SAASO,EAAE,EAAE;YAChBC,QAAG,CAACC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAClB;QACrB;QAEA,MAAMmB,kBAAmB,MAAMZ,SAASa,IAAI;QAK5C,MAAMC,uBAAuBnB,gBAAgBC,MAAM,CACjD,CAACC;gBAAgBe;mBAAAA,EAAAA,+BAAAA,eAAe,CAACf,YAAY,qBAA5Be,6BAA8BG,eAAe,MAAK;;QAGrE,IAAID,qBAAqBf,MAAM,EAAE;YAC/BS,QAAG,CAACQ,IAAI,CACNN,gBAAK,CAACO,MAAM,CACV,GAAGP,gBAAK,CAACQ,IAAI,CAAC,WAAW,EAAE,EAAEC,mBAAmBL,sBAAsB,GAAG,EAAEA,qBAAqBf,MAAM,GAAG,IAAI,KAAK,KAAK,mCAAmC,EAAEqB,IAAAA,eAAS,EAAC,mDAAmD;QAG/N;IACF,EAAE,OAAM;QACNZ,QAAG,CAACC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAClB;IACrB;AACF;AAEA,SAAS0B,mBAAmBL,oBAA8B;IACxD,IAAIA,qBAAqBf,MAAM,KAAK,GAAG;QACrC,OAAOe,qBAAqBO,IAAI;IAClC;IAEA,MAAMC,cAAcR,qBAAqBS,GAAG;IAC5C,OAAO,GAAGT,qBAAqBO,IAAI,CAAC,MAAM,KAAK,EAAEC,aAAa;AAChE"}
|
|
@@ -76,9 +76,9 @@ class ESLintProjectPrerequisite extends _Prerequisite.ProjectPrerequisite {
|
|
|
76
76
|
const scripts = _jsonfile().default.read(_path().default.join(this.projectRoot, 'package.json')).scripts;
|
|
77
77
|
await _jsonfile().default.setAsync(_path().default.join(this.projectRoot, 'package.json'), 'scripts', typeof scripts === 'object' ? {
|
|
78
78
|
...scripts,
|
|
79
|
-
lint: '
|
|
79
|
+
lint: 'expo lint'
|
|
80
80
|
} : {
|
|
81
|
-
lint: '
|
|
81
|
+
lint: 'expo lint'
|
|
82
82
|
}, {
|
|
83
83
|
json5: false
|
|
84
84
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lint/ESlintPrerequisite.ts"],"sourcesContent":["import JsonFile, { JSONObject } from '@expo/json-file';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nimport { Log } from '../log';\nimport { PrerequisiteCommandError, ProjectPrerequisite } from '../start/doctor/Prerequisite';\nimport { ensureDependenciesAsync } from '../start/doctor/dependencies/ensureDependenciesAsync';\nimport { findFileInParents } from '../utils/findUp';\nimport { isInteractive } from '../utils/interactive';\nimport { confirmAsync } from '../utils/prompts';\n\nconst debug = require('debug')('expo:lint') as typeof console.log;\n\n/** Ensure the project has the required ESLint config. */\nexport class ESLintProjectPrerequisite extends ProjectPrerequisite<boolean> {\n async assertImplementation(): Promise<boolean> {\n const hasEslintConfig = await isEslintConfigured(this.projectRoot);\n const hasLegacyConfig = await isLegacyEslintConfigured(this.projectRoot);\n const hasLintScript = await lintScriptIsConfigured(this.projectRoot);\n\n if (hasLegacyConfig) {\n Log.warn(`Using legacy ESLint config. Consider upgrading to flat config.`);\n }\n\n return (hasEslintConfig || hasLegacyConfig) && hasLintScript;\n }\n\n async bootstrapAsync(): Promise<boolean> {\n debug('Setting up ESLint');\n\n const hasEslintConfig = await isEslintConfigured(this.projectRoot);\n if (!hasEslintConfig) {\n if (!isInteractive()) {\n Log.warn(`No ESLint config found. Configuring automatically.`);\n } else {\n const shouldSetupLint = await confirmAsync({\n message: 'No ESLint config found. Install and configure ESLint in this project?',\n });\n if (!shouldSetupLint) {\n throw new PrerequisiteCommandError('ESLint is not configured for this project.');\n }\n }\n\n await this._ensureDependenciesInstalledAsync({ skipPrompt: true, isProjectMutable: true });\n\n await fs.writeFile(\n path.join(this.projectRoot, 'eslint.config.js'),\n await fs.readFile(require.resolve(`@expo/cli/static/template/eslint.config.js`), 'utf8'),\n 'utf8'\n );\n }\n\n const hasLintScript = await lintScriptIsConfigured(this.projectRoot);\n if (!hasLintScript) {\n const scripts = JsonFile.read(path.join(this.projectRoot, 'package.json')).scripts;\n await JsonFile.setAsync(\n path.join(this.projectRoot, 'package.json'),\n 'scripts',\n typeof scripts === 'object' ? { ...scripts, lint: '
|
|
1
|
+
{"version":3,"sources":["../../../src/lint/ESlintPrerequisite.ts"],"sourcesContent":["import JsonFile, { JSONObject } from '@expo/json-file';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nimport { Log } from '../log';\nimport { PrerequisiteCommandError, ProjectPrerequisite } from '../start/doctor/Prerequisite';\nimport { ensureDependenciesAsync } from '../start/doctor/dependencies/ensureDependenciesAsync';\nimport { findFileInParents } from '../utils/findUp';\nimport { isInteractive } from '../utils/interactive';\nimport { confirmAsync } from '../utils/prompts';\n\nconst debug = require('debug')('expo:lint') as typeof console.log;\n\n/** Ensure the project has the required ESLint config. */\nexport class ESLintProjectPrerequisite extends ProjectPrerequisite<boolean> {\n async assertImplementation(): Promise<boolean> {\n const hasEslintConfig = await isEslintConfigured(this.projectRoot);\n const hasLegacyConfig = await isLegacyEslintConfigured(this.projectRoot);\n const hasLintScript = await lintScriptIsConfigured(this.projectRoot);\n\n if (hasLegacyConfig) {\n Log.warn(`Using legacy ESLint config. Consider upgrading to flat config.`);\n }\n\n return (hasEslintConfig || hasLegacyConfig) && hasLintScript;\n }\n\n async bootstrapAsync(): Promise<boolean> {\n debug('Setting up ESLint');\n\n const hasEslintConfig = await isEslintConfigured(this.projectRoot);\n if (!hasEslintConfig) {\n if (!isInteractive()) {\n Log.warn(`No ESLint config found. Configuring automatically.`);\n } else {\n const shouldSetupLint = await confirmAsync({\n message: 'No ESLint config found. Install and configure ESLint in this project?',\n });\n if (!shouldSetupLint) {\n throw new PrerequisiteCommandError('ESLint is not configured for this project.');\n }\n }\n\n await this._ensureDependenciesInstalledAsync({ skipPrompt: true, isProjectMutable: true });\n\n await fs.writeFile(\n path.join(this.projectRoot, 'eslint.config.js'),\n await fs.readFile(require.resolve(`@expo/cli/static/template/eslint.config.js`), 'utf8'),\n 'utf8'\n );\n }\n\n const hasLintScript = await lintScriptIsConfigured(this.projectRoot);\n if (!hasLintScript) {\n const scripts = JsonFile.read(path.join(this.projectRoot, 'package.json')).scripts;\n await JsonFile.setAsync(\n path.join(this.projectRoot, 'package.json'),\n 'scripts',\n typeof scripts === 'object' ? { ...scripts, lint: 'expo lint' } : { lint: 'expo lint' },\n { json5: false }\n );\n }\n\n Log.log();\n Log.log('ESLint has been configured 🎉');\n Log.log();\n\n return true;\n }\n\n async _ensureDependenciesInstalledAsync({\n skipPrompt,\n isProjectMutable,\n }: {\n skipPrompt?: boolean;\n isProjectMutable?: boolean;\n }): Promise<boolean> {\n try {\n return await ensureDependenciesAsync(this.projectRoot, {\n skipPrompt,\n isProjectMutable,\n installMessage: 'ESLint is required to lint your project.',\n warningMessage: 'ESLint not installed, unable to set up linting for your project.',\n requiredPackages: [\n { version: '^9.0.0', pkg: 'eslint', file: 'eslint/package.json', dev: true },\n {\n pkg: 'eslint-config-expo',\n file: 'eslint-config-expo/package.json',\n dev: true,\n },\n ],\n });\n } catch (error) {\n this.resetAssertion();\n throw error;\n }\n }\n}\n\nasync function isLegacyEslintConfigured(projectRoot: string) {\n debug('Checking for legacy ESLint configuration', projectRoot);\n\n const packageFile = await JsonFile.readAsync(path.join(projectRoot, 'package.json'));\n if (\n typeof packageFile.eslintConfig === 'object' &&\n Object.keys(packageFile.eslintConfig as JSONObject).length > 0\n ) {\n debug('Found legacy ESLint config in package.json');\n return true;\n }\n\n const eslintConfigFiles = [\n '.eslintrc.js',\n '.eslintrc.cjs',\n '.eslintrc.yaml',\n '.eslintrc.yml',\n '.eslintrc.json',\n ];\n for (const configFile of eslintConfigFiles) {\n const configPath = findFileInParents(projectRoot, configFile);\n\n if (configPath) {\n debug('Found ESLint config file:', configPath);\n return true;\n }\n }\n\n return false;\n}\n\n/** Check for flat config. */\nasync function isEslintConfigured(projectRoot: string) {\n debug('Ensuring ESLint is configured in', projectRoot);\n\n const eslintConfigFiles = ['eslint.config.js', 'eslint.config.mjs', 'eslint.config.cjs'];\n for (const configFile of eslintConfigFiles) {\n const configPath = findFileInParents(projectRoot, configFile);\n\n if (configPath) {\n debug('Found ESLint config file:', configPath);\n return true;\n }\n }\n\n return false;\n}\n\nasync function lintScriptIsConfigured(projectRoot: string) {\n const packageFile = await JsonFile.readAsync(path.join(projectRoot, 'package.json'));\n return typeof (packageFile.scripts as JSONObject | undefined)?.lint === 'string';\n}\n"],"names":["ESLintProjectPrerequisite","debug","require","ProjectPrerequisite","assertImplementation","hasEslintConfig","isEslintConfigured","projectRoot","hasLegacyConfig","isLegacyEslintConfigured","hasLintScript","lintScriptIsConfigured","Log","warn","bootstrapAsync","isInteractive","shouldSetupLint","confirmAsync","message","PrerequisiteCommandError","_ensureDependenciesInstalledAsync","skipPrompt","isProjectMutable","fs","writeFile","path","join","readFile","resolve","scripts","JsonFile","read","setAsync","lint","json5","log","ensureDependenciesAsync","installMessage","warningMessage","requiredPackages","version","pkg","file","dev","error","resetAssertion","packageFile","readAsync","eslintConfig","Object","keys","length","eslintConfigFiles","configFile","configPath","findFileInParents"],"mappings":"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"}
|
package/build/src/lint/index.js
CHANGED
|
@@ -8,63 +8,61 @@ Object.defineProperty(exports, "expoLint", {
|
|
|
8
8
|
return expoLint;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
18
|
-
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
19
|
-
})(nodeInterop);
|
|
11
|
+
function _chalk() {
|
|
12
|
+
const data = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
13
|
+
_chalk = function() {
|
|
14
|
+
return data;
|
|
15
|
+
};
|
|
16
|
+
return data;
|
|
20
17
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
26
|
-
return {
|
|
27
|
-
default: obj
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
var cache = _getRequireWildcardCache(nodeInterop);
|
|
31
|
-
if (cache && cache.has(obj)) {
|
|
32
|
-
return cache.get(obj);
|
|
33
|
-
}
|
|
34
|
-
var newObj = {
|
|
35
|
-
__proto__: null
|
|
18
|
+
const _args = require("../utils/args");
|
|
19
|
+
function _interop_require_default(obj) {
|
|
20
|
+
return obj && obj.__esModule ? obj : {
|
|
21
|
+
default: obj
|
|
36
22
|
};
|
|
37
|
-
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
38
|
-
for(var key in obj){
|
|
39
|
-
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
40
|
-
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
41
|
-
if (desc && (desc.get || desc.set)) {
|
|
42
|
-
Object.defineProperty(newObj, key, desc);
|
|
43
|
-
} else {
|
|
44
|
-
newObj[key] = obj[key];
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
newObj.default = obj;
|
|
49
|
-
if (cache) {
|
|
50
|
-
cache.set(obj, newObj);
|
|
51
|
-
}
|
|
52
|
-
return newObj;
|
|
53
23
|
}
|
|
54
24
|
const expoLint = async (argv)=>{
|
|
55
|
-
const args = (0, _args.
|
|
56
|
-
//
|
|
25
|
+
const args = (0, _args.assertWithOptionsArgs)({
|
|
26
|
+
// Other options are parsed manually.
|
|
57
27
|
'--help': Boolean,
|
|
28
|
+
'--no-cache': Boolean,
|
|
29
|
+
'--fix': Boolean,
|
|
30
|
+
'--quiet': Boolean,
|
|
31
|
+
'--no-ignore': Boolean,
|
|
58
32
|
// Aliases
|
|
59
33
|
'-h': '--help'
|
|
60
|
-
},
|
|
34
|
+
}, {
|
|
35
|
+
argv,
|
|
36
|
+
// Allow other options, we'll throw an error if unexpected values are passed.
|
|
37
|
+
permissive: true
|
|
38
|
+
});
|
|
61
39
|
if (args['--help']) {
|
|
62
|
-
(0, _args.printHelp)(
|
|
40
|
+
(0, _args.printHelp)((0, _chalk().default)`Lint all files in {bold /src}, {bold /app}, {bold /components} directories with ESLint`, (0, _chalk().default)`npx expo lint {dim [path...] -- [eslint options]}`, [
|
|
41
|
+
(0, _chalk().default)`[path...] List of files and directories to lint`,
|
|
42
|
+
(0, _chalk().default)`--ext {dim <string>} Additional file extensions to lint. {dim Default: .js, .jsx, .ts, .tsx, .mjs, .cjs}`,
|
|
43
|
+
(0, _chalk().default)`--config {dim <path>} Custom ESLint config file`,
|
|
44
|
+
`--no-cache Check all files, instead of changes between runs`,
|
|
45
|
+
`--fix Automatically fix problems`,
|
|
46
|
+
(0, _chalk().default)`--fix-type {dim <string>} Specify the types of fixes to apply. {dim Example: problem, suggestion, layout}`,
|
|
47
|
+
`--no-ignore Disable use of ignore files and patterns`,
|
|
48
|
+
(0, _chalk().default)`--ignore-pattern {dim <string>} Patterns of files to ignore`,
|
|
49
|
+
`--quiet Only report errors`,
|
|
50
|
+
(0, _chalk().default)`--max-warnings {dim <number>} Number of warnings to trigger nonzero exit code`,
|
|
51
|
+
`-h, --help Usage info`
|
|
52
|
+
].join('\n'), [
|
|
53
|
+
'',
|
|
54
|
+
(0, _chalk().default)` Additional options can be passed to {bold npx eslint} by using {bold --}`,
|
|
55
|
+
(0, _chalk().default)` {dim $} npx expo lint -- --no-error-on-unmatched-pattern`,
|
|
56
|
+
(0, _chalk().default)` {dim >} npx eslint --no-error-on-unmatched-pattern {dim ...}`,
|
|
57
|
+
''
|
|
58
|
+
].join('\n'));
|
|
63
59
|
}
|
|
64
60
|
// Load modules after the help prompt so `npx expo lint -h` shows as fast as possible.
|
|
65
|
-
const { lintAsync } =
|
|
66
|
-
const
|
|
67
|
-
|
|
61
|
+
const { lintAsync } = require('./lintAsync');
|
|
62
|
+
const { logCmdError } = require('../utils/errors');
|
|
63
|
+
const { resolveArgsAsync } = require('./resolveOptions');
|
|
64
|
+
const { variadic, options, extras } = await resolveArgsAsync(process.argv.slice(3)).catch(logCmdError);
|
|
65
|
+
return lintAsync(variadic, options, extras).catch(logCmdError);
|
|
68
66
|
};
|
|
69
67
|
|
|
70
68
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lint/index.ts"],"sourcesContent":["import type { Command } from '../../bin/cli';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/lint/index.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport type { Command } from '../../bin/cli';\nimport { assertWithOptionsArgs, printHelp } from '../utils/args';\n\nexport const expoLint: Command = async (argv) => {\n const args = assertWithOptionsArgs(\n {\n // Other options are parsed manually.\n '--help': Boolean,\n '--no-cache': Boolean,\n '--fix': Boolean,\n '--quiet': Boolean,\n '--no-ignore': Boolean,\n\n // Aliases\n '-h': '--help',\n },\n {\n argv,\n // Allow other options, we'll throw an error if unexpected values are passed.\n permissive: true,\n }\n );\n\n if (args['--help']) {\n printHelp(\n chalk`Lint all files in {bold /src}, {bold /app}, {bold /components} directories with ESLint`,\n chalk`npx expo lint {dim [path...] -- [eslint options]}`,\n\n [\n chalk`[path...] List of files and directories to lint`,\n chalk`--ext {dim <string>} Additional file extensions to lint. {dim Default: .js, .jsx, .ts, .tsx, .mjs, .cjs}`,\n chalk`--config {dim <path>} Custom ESLint config file`,\n `--no-cache Check all files, instead of changes between runs`,\n `--fix Automatically fix problems`,\n chalk`--fix-type {dim <string>} Specify the types of fixes to apply. {dim Example: problem, suggestion, layout}`,\n `--no-ignore Disable use of ignore files and patterns`,\n chalk`--ignore-pattern {dim <string>} Patterns of files to ignore`,\n `--quiet Only report errors`,\n chalk`--max-warnings {dim <number>} Number of warnings to trigger nonzero exit code`,\n `-h, --help Usage info`,\n ].join('\\n'),\n [\n '',\n chalk` Additional options can be passed to {bold npx eslint} by using {bold --}`,\n chalk` {dim $} npx expo lint -- --no-error-on-unmatched-pattern`,\n chalk` {dim >} npx eslint --no-error-on-unmatched-pattern {dim ...}`,\n '',\n ].join('\\n')\n );\n }\n\n // Load modules after the help prompt so `npx expo lint -h` shows as fast as possible.\n const { lintAsync } = require('./lintAsync') as typeof import('./lintAsync');\n const { logCmdError } = require('../utils/errors') as typeof import('../utils/errors');\n const { resolveArgsAsync } = require('./resolveOptions') as typeof import('./resolveOptions');\n\n const { variadic, options, extras } = await resolveArgsAsync(process.argv.slice(3)).catch(\n logCmdError\n );\n return lintAsync(variadic, options, extras).catch(logCmdError);\n};\n"],"names":["expoLint","argv","args","assertWithOptionsArgs","Boolean","permissive","printHelp","chalk","join","lintAsync","require","logCmdError","resolveArgsAsync","variadic","options","extras","process","slice","catch"],"mappings":";;;;+BAKaA;;;eAAAA;;;;gEALK;;;;;;sBAG+B;;;;;;AAE1C,MAAMA,WAAoB,OAAOC;IACtC,MAAMC,OAAOC,IAAAA,2BAAqB,EAChC;QACE,qCAAqC;QACrC,UAAUC;QACV,cAAcA;QACd,SAASA;QACT,WAAWA;QACX,eAAeA;QAEf,UAAU;QACV,MAAM;IACR,GACA;QACEH;QACA,6EAA6E;QAC7EI,YAAY;IACd;IAGF,IAAIH,IAAI,CAAC,SAAS,EAAE;QAClBI,IAAAA,eAAS,EACPC,IAAAA,gBAAK,CAAA,CAAC,sFAAsF,CAAC,EAC7FA,IAAAA,gBAAK,CAAA,CAAC,iDAAiD,CAAC,EAExD;YACEA,IAAAA,gBAAK,CAAA,CAAC,gEAAgE,CAAC;YACvEA,IAAAA,gBAAK,CAAA,CAAC,oHAAoH,CAAC;YAC3HA,IAAAA,gBAAK,CAAA,CAAC,0DAA0D,CAAC;YACjE,CAAC,2EAA2E,CAAC;YAC7E,CAAC,qDAAqD,CAAC;YACvDA,IAAAA,gBAAK,CAAA,CAAC,gHAAgH,CAAC;YACvH,CAAC,mEAAmE,CAAC;YACrEA,IAAAA,gBAAK,CAAA,CAAC,4DAA4D,CAAC;YACnE,CAAC,6CAA6C,CAAC;YAC/CA,IAAAA,gBAAK,CAAA,CAAC,gFAAgF,CAAC;YACvF,CAAC,qCAAqC,CAAC;SACxC,CAACC,IAAI,CAAC,OACP;YACE;YACAD,IAAAA,gBAAK,CAAA,CAAC,0EAA0E,CAAC;YACjFA,IAAAA,gBAAK,CAAA,CAAC,4DAA4D,CAAC;YACnEA,IAAAA,gBAAK,CAAA,CAAC,gEAAgE,CAAC;YACvE;SACD,CAACC,IAAI,CAAC;IAEX;IAEA,sFAAsF;IACtF,MAAM,EAAEC,SAAS,EAAE,GAAGC,QAAQ;IAC9B,MAAM,EAAEC,WAAW,EAAE,GAAGD,QAAQ;IAChC,MAAM,EAAEE,gBAAgB,EAAE,GAAGF,QAAQ;IAErC,MAAM,EAAEG,QAAQ,EAAEC,OAAO,EAAEC,MAAM,EAAE,GAAG,MAAMH,iBAAiBI,QAAQf,IAAI,CAACgB,KAAK,CAAC,IAAIC,KAAK,CACvFP;IAEF,OAAOF,UAAUI,UAAUC,SAASC,QAAQG,KAAK,CAACP;AACpD"}
|
|
@@ -15,18 +15,164 @@ function _packagemanager() {
|
|
|
15
15
|
};
|
|
16
16
|
return data;
|
|
17
17
|
}
|
|
18
|
+
function _nodefs() {
|
|
19
|
+
const data = /*#__PURE__*/ _interop_require_default(require("node:fs"));
|
|
20
|
+
_nodefs = function() {
|
|
21
|
+
return data;
|
|
22
|
+
};
|
|
23
|
+
return data;
|
|
24
|
+
}
|
|
25
|
+
function _nodepath() {
|
|
26
|
+
const data = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
27
|
+
_nodepath = function() {
|
|
28
|
+
return data;
|
|
29
|
+
};
|
|
30
|
+
return data;
|
|
31
|
+
}
|
|
32
|
+
function _semver() {
|
|
33
|
+
const data = /*#__PURE__*/ _interop_require_default(require("semver"));
|
|
34
|
+
_semver = function() {
|
|
35
|
+
return data;
|
|
36
|
+
};
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
18
39
|
const _ESlintPrerequisite = require("./ESlintPrerequisite");
|
|
19
|
-
const
|
|
40
|
+
const _errors = require("../utils/errors");
|
|
41
|
+
const _findUp = require("../utils/findUp");
|
|
42
|
+
const _nodeEnv = require("../utils/nodeEnv");
|
|
43
|
+
function _interop_require_default(obj) {
|
|
44
|
+
return obj && obj.__esModule ? obj : {
|
|
45
|
+
default: obj
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
49
|
+
if (typeof WeakMap !== "function") return null;
|
|
50
|
+
var cacheBabelInterop = new WeakMap();
|
|
51
|
+
var cacheNodeInterop = new WeakMap();
|
|
52
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
53
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
54
|
+
})(nodeInterop);
|
|
55
|
+
}
|
|
56
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
57
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
58
|
+
return obj;
|
|
59
|
+
}
|
|
60
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
61
|
+
return {
|
|
62
|
+
default: obj
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
66
|
+
if (cache && cache.has(obj)) {
|
|
67
|
+
return cache.get(obj);
|
|
68
|
+
}
|
|
69
|
+
var newObj = {
|
|
70
|
+
__proto__: null
|
|
71
|
+
};
|
|
72
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
73
|
+
for(var key in obj){
|
|
74
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
75
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
76
|
+
if (desc && (desc.get || desc.set)) {
|
|
77
|
+
Object.defineProperty(newObj, key, desc);
|
|
78
|
+
} else {
|
|
79
|
+
newObj[key] = obj[key];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
newObj.default = obj;
|
|
84
|
+
if (cache) {
|
|
85
|
+
cache.set(obj, newObj);
|
|
86
|
+
}
|
|
87
|
+
return newObj;
|
|
88
|
+
}
|
|
89
|
+
const debug = require('debug')('expo:lint');
|
|
90
|
+
const DEFAULT_INPUTS = [
|
|
91
|
+
'src',
|
|
92
|
+
'app',
|
|
93
|
+
'components'
|
|
94
|
+
];
|
|
95
|
+
const lintAsync = async (inputs, options, eslintArguments = [])=>{
|
|
96
|
+
(0, _nodeEnv.setNodeEnv)('development');
|
|
97
|
+
// Locate the project root based on the process current working directory.
|
|
98
|
+
// This enables users to run `npx expo install` from a subdirectory of the project.
|
|
99
|
+
const projectRoot = (options == null ? void 0 : options.projectRoot) ?? (0, _findUp.findUpProjectRootOrAssert)(process.cwd());
|
|
100
|
+
require('@expo/env').load(projectRoot);
|
|
101
|
+
// TODO: Perhaps we should assert that TypeScript is required.
|
|
20
102
|
const prerequisite = new _ESlintPrerequisite.ESLintProjectPrerequisite(projectRoot);
|
|
21
103
|
if (!await prerequisite.assertAsync()) {
|
|
22
104
|
await prerequisite.bootstrapAsync();
|
|
23
105
|
}
|
|
24
|
-
const
|
|
106
|
+
const { loadESLint } = require('eslint');
|
|
107
|
+
const mod = await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("eslint")));
|
|
108
|
+
let ESLint;
|
|
109
|
+
// loadESLint is >= 8.57.0 (https://github.com/eslint/eslint/releases/tag/v8.57.0) https://github.com/eslint/eslint/pull/18098
|
|
110
|
+
if ('loadESLint' in mod) {
|
|
111
|
+
ESLint = await loadESLint({
|
|
112
|
+
cwd: options.projectRoot
|
|
113
|
+
});
|
|
114
|
+
} else {
|
|
115
|
+
throw new _errors.CommandError('npx expo lint requires ESLint version 8.57.0 or greater. Upgrade eslint or use npx eslint directly.');
|
|
116
|
+
}
|
|
117
|
+
const version = ESLint == null ? void 0 : ESLint.version;
|
|
118
|
+
if (!version || _semver().default.lt(version, '8.57.0')) {
|
|
119
|
+
throw new _errors.CommandError('npx expo lint requires ESLint version 8.57.0 or greater. Upgrade eslint or use npx eslint directly.');
|
|
120
|
+
}
|
|
121
|
+
if (!inputs.length) {
|
|
122
|
+
DEFAULT_INPUTS.map((input)=>{
|
|
123
|
+
const abs = _nodepath().default.join(projectRoot, input);
|
|
124
|
+
if (_nodefs().default.existsSync(abs)) {
|
|
125
|
+
inputs.push(abs);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
const eslintArgs = [];
|
|
130
|
+
inputs.forEach((input)=>{
|
|
131
|
+
eslintArgs.push(input);
|
|
132
|
+
});
|
|
133
|
+
options.ext.forEach((ext)=>{
|
|
134
|
+
eslintArgs.push('--ext', ext);
|
|
135
|
+
});
|
|
136
|
+
eslintArgs.push(`--fix=${options.fix}`);
|
|
137
|
+
eslintArgs.push(`--cache=${options.cache}`);
|
|
138
|
+
if (options.config) {
|
|
139
|
+
eslintArgs.push(`--config`, options.config);
|
|
140
|
+
}
|
|
141
|
+
if (!options.ignore) {
|
|
142
|
+
eslintArgs.push('--no-ignore');
|
|
143
|
+
}
|
|
144
|
+
options.ignorePattern.forEach((pattern)=>{
|
|
145
|
+
eslintArgs.push(`--ignore-pattern=${pattern}`);
|
|
146
|
+
});
|
|
147
|
+
eslintArgs.push(...options.fixType.map((type)=>`--fix-type=${type}`));
|
|
148
|
+
if (options.quiet) {
|
|
149
|
+
eslintArgs.push('--quiet');
|
|
150
|
+
}
|
|
151
|
+
if (options.maxWarnings != null && options.maxWarnings >= 0) {
|
|
152
|
+
eslintArgs.push(`--max-warnings=${options.maxWarnings.toString()}`);
|
|
153
|
+
}
|
|
154
|
+
const cacheDir = _nodepath().default.join(projectRoot, '.expo', 'cache', 'eslint/');
|
|
155
|
+
// Add other defaults
|
|
156
|
+
eslintArgs.push(`--cache-location=${cacheDir}`);
|
|
157
|
+
// Add passthrough arguments
|
|
158
|
+
eslintArguments.forEach((arg)=>{
|
|
159
|
+
eslintArgs.push(arg);
|
|
160
|
+
});
|
|
161
|
+
debug('Running ESLint with args: %O', eslintArgs);
|
|
162
|
+
const manager = (0, _packagemanager().createForProject)(projectRoot, {
|
|
163
|
+
silent: true
|
|
164
|
+
});
|
|
25
165
|
try {
|
|
166
|
+
// TODO: Custom logger
|
|
167
|
+
// - Use relative paths
|
|
168
|
+
// - When react-hooks/exhaustive-deps is hit, notify about enabling React Compiler.
|
|
169
|
+
// - Green check when no issues are found.
|
|
26
170
|
await manager.runBinAsync([
|
|
27
171
|
'eslint',
|
|
28
|
-
|
|
29
|
-
]
|
|
172
|
+
...eslintArgs
|
|
173
|
+
], {
|
|
174
|
+
stdio: 'inherit'
|
|
175
|
+
});
|
|
30
176
|
} catch (error) {
|
|
31
177
|
process.exit(error.status);
|
|
32
178
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lint/lintAsync.ts"],"sourcesContent":["import { createForProject } from '@expo/package-manager';\n\nimport { ESLintProjectPrerequisite } from './ESlintPrerequisite';\n\nexport const lintAsync = async (projectRoot: string) => {\n const prerequisite = new ESLintProjectPrerequisite(projectRoot);\n if (!(await prerequisite.assertAsync())) {\n await prerequisite.bootstrapAsync();\n }\n\n const manager = createForProject(projectRoot);\n try {\n await manager.runBinAsync(['eslint', '
|
|
1
|
+
{"version":3,"sources":["../../../src/lint/lintAsync.ts"],"sourcesContent":["import { createForProject } from '@expo/package-manager';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport semver from 'semver';\n\nimport { ESLintProjectPrerequisite } from './ESlintPrerequisite';\nimport type { Options } from './resolveOptions';\nimport { CommandError } from '../utils/errors';\nimport { findUpProjectRootOrAssert } from '../utils/findUp';\nimport { setNodeEnv } from '../utils/nodeEnv';\n\nconst debug = require('debug')('expo:lint');\n\nconst DEFAULT_INPUTS = ['src', 'app', 'components'];\n\nexport const lintAsync = async (\n inputs: string[],\n options: Options & { projectRoot?: string },\n eslintArguments: string[] = []\n) => {\n setNodeEnv('development');\n // Locate the project root based on the process current working directory.\n // This enables users to run `npx expo install` from a subdirectory of the project.\n const projectRoot = options?.projectRoot ?? findUpProjectRootOrAssert(process.cwd());\n require('@expo/env').load(projectRoot);\n\n // TODO: Perhaps we should assert that TypeScript is required.\n\n const prerequisite = new ESLintProjectPrerequisite(projectRoot);\n if (!(await prerequisite.assertAsync())) {\n await prerequisite.bootstrapAsync();\n }\n\n const { loadESLint } = require('eslint');\n\n const mod = await import('eslint');\n\n let ESLint: typeof import('eslint').ESLint;\n // loadESLint is >= 8.57.0 (https://github.com/eslint/eslint/releases/tag/v8.57.0) https://github.com/eslint/eslint/pull/18098\n if ('loadESLint' in mod) {\n ESLint = await loadESLint({ cwd: options.projectRoot });\n } else {\n throw new CommandError(\n 'npx expo lint requires ESLint version 8.57.0 or greater. Upgrade eslint or use npx eslint directly.'\n );\n }\n\n const version = ESLint?.version;\n\n if (!version || semver.lt(version, '8.57.0')) {\n throw new CommandError(\n 'npx expo lint requires ESLint version 8.57.0 or greater. Upgrade eslint or use npx eslint directly.'\n );\n }\n\n if (!inputs.length) {\n DEFAULT_INPUTS.map((input) => {\n const abs = path.join(projectRoot, input);\n if (fs.existsSync(abs)) {\n inputs.push(abs);\n }\n });\n }\n\n const eslintArgs: string[] = [];\n inputs.forEach((input) => {\n eslintArgs.push(input);\n });\n options.ext.forEach((ext) => {\n eslintArgs.push('--ext', ext);\n });\n\n eslintArgs.push(`--fix=${options.fix}`);\n eslintArgs.push(`--cache=${options.cache}`);\n\n if (options.config) {\n eslintArgs.push(`--config`, options.config);\n }\n if (!options.ignore) {\n eslintArgs.push('--no-ignore');\n }\n options.ignorePattern.forEach((pattern) => {\n eslintArgs.push(`--ignore-pattern=${pattern}`);\n });\n\n eslintArgs.push(...options.fixType.map((type) => `--fix-type=${type}`));\n\n if (options.quiet) {\n eslintArgs.push('--quiet');\n }\n\n if (options.maxWarnings != null && options.maxWarnings >= 0) {\n eslintArgs.push(`--max-warnings=${options.maxWarnings.toString()}`);\n }\n\n const cacheDir = path.join(projectRoot, '.expo', 'cache', 'eslint/');\n // Add other defaults\n eslintArgs.push(`--cache-location=${cacheDir}`);\n\n // Add passthrough arguments\n eslintArguments.forEach((arg) => {\n eslintArgs.push(arg);\n });\n\n debug('Running ESLint with args: %O', eslintArgs);\n\n const manager = createForProject(projectRoot, { silent: true });\n\n try {\n // TODO: Custom logger\n // - Use relative paths\n // - When react-hooks/exhaustive-deps is hit, notify about enabling React Compiler.\n // - Green check when no issues are found.\n await manager.runBinAsync(['eslint', ...eslintArgs], {\n stdio: 'inherit',\n });\n } catch (error: any) {\n process.exit(error.status);\n }\n};\n"],"names":["lintAsync","debug","require","DEFAULT_INPUTS","inputs","options","eslintArguments","setNodeEnv","projectRoot","findUpProjectRootOrAssert","process","cwd","load","prerequisite","ESLintProjectPrerequisite","assertAsync","bootstrapAsync","loadESLint","mod","ESLint","CommandError","version","semver","lt","length","map","input","abs","path","join","fs","existsSync","push","eslintArgs","forEach","ext","fix","cache","config","ignore","ignorePattern","pattern","fixType","type","quiet","maxWarnings","toString","cacheDir","arg","manager","createForProject","silent","runBinAsync","stdio","error","exit","status"],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "resolveArgsAsync", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return resolveArgsAsync;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _errors = require("../utils/errors");
|
|
12
|
+
const _resolveArgs = require("../utils/resolveArgs");
|
|
13
|
+
const _variadic = require("../utils/variadic");
|
|
14
|
+
function splitCommaSeparatedList(argName, list) {
|
|
15
|
+
if (list == null) return [];
|
|
16
|
+
(0, _resolveArgs.assertNonBooleanArg)(argName, list);
|
|
17
|
+
if (typeof list === 'string') {
|
|
18
|
+
return list.split(',').map((item)=>item.trim());
|
|
19
|
+
}
|
|
20
|
+
if (Array.isArray(list)) {
|
|
21
|
+
return list.map((item)=>splitCommaSeparatedList(argName, item)).flat();
|
|
22
|
+
}
|
|
23
|
+
if (typeof list === 'boolean') {
|
|
24
|
+
throw new _errors.CommandError(`Expected a string input for arg ${argName}`);
|
|
25
|
+
}
|
|
26
|
+
throw new _errors.CommandError(`Expected a string or an array for arg ${argName}, but got: ${typeof list}`);
|
|
27
|
+
}
|
|
28
|
+
function resolveOptions(options) {
|
|
29
|
+
return {
|
|
30
|
+
...options,
|
|
31
|
+
ext: splitCommaSeparatedList('--ext', options.ext),
|
|
32
|
+
fixType: splitCommaSeparatedList('--fix-type', options.fixType),
|
|
33
|
+
config: options.config
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async function resolveArgsAsync(argv) {
|
|
37
|
+
const knownFlags = [
|
|
38
|
+
'--ext',
|
|
39
|
+
'--config',
|
|
40
|
+
'--no-cache',
|
|
41
|
+
'--fix',
|
|
42
|
+
'--fix-type',
|
|
43
|
+
'--no-ignore',
|
|
44
|
+
'--ignore-pattern',
|
|
45
|
+
'--quiet',
|
|
46
|
+
'--max-warnings'
|
|
47
|
+
];
|
|
48
|
+
const { variadic, extras, flags } = (0, _variadic.parseVariadicArguments)(argv, [
|
|
49
|
+
// Just non-boolean flags
|
|
50
|
+
'--ext',
|
|
51
|
+
'--config',
|
|
52
|
+
'--fix-type',
|
|
53
|
+
'--ignore-pattern',
|
|
54
|
+
'--max-warnings'
|
|
55
|
+
]);
|
|
56
|
+
(0, _variadic.assertUnexpectedVariadicFlags)(knownFlags, {
|
|
57
|
+
variadic,
|
|
58
|
+
extras,
|
|
59
|
+
flags
|
|
60
|
+
}, 'npx expo lint');
|
|
61
|
+
const config = flags['--config'];
|
|
62
|
+
assertSingleStringInput('--config', config);
|
|
63
|
+
return {
|
|
64
|
+
// Variadic arguments like `npx expo install react react-dom` -> ['react', 'react-dom']
|
|
65
|
+
variadic,
|
|
66
|
+
options: resolveOptions({
|
|
67
|
+
ext: splitCommaSeparatedList('--ext', flags['--ext']),
|
|
68
|
+
config: assertSingleStringInput('--config', config),
|
|
69
|
+
cache: !getBooleanArg('--no-cache', flags['--no-cache']),
|
|
70
|
+
fix: !!getBooleanArg('--fix', flags['--fix']),
|
|
71
|
+
fixType: splitCommaSeparatedList('--fix-type', flags['--fix-type']),
|
|
72
|
+
ignore: !getBooleanArg('--no-ignore', flags['--no-ignore']),
|
|
73
|
+
ignorePattern: splitCommaSeparatedList('--ignore-pattern', flags['--ignore-pattern']),
|
|
74
|
+
quiet: !!getBooleanArg('--quiet', flags['--quiet']),
|
|
75
|
+
maxWarnings: Number(flags['--max-warnings']) ?? -1
|
|
76
|
+
}),
|
|
77
|
+
extras
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function assertSingleStringInput(argName, arg) {
|
|
81
|
+
if (!arg) {
|
|
82
|
+
return arg;
|
|
83
|
+
}
|
|
84
|
+
(0, _resolveArgs.assertNonBooleanArg)(argName, arg);
|
|
85
|
+
if (Array.isArray(arg) && arg.length > 1) {
|
|
86
|
+
throw new _errors.CommandError('BAD_ARGS', `Too many values provided for arg ${argName}. Provide only one of: ${arg.join(', ')}`);
|
|
87
|
+
}
|
|
88
|
+
return arg;
|
|
89
|
+
}
|
|
90
|
+
function getBooleanArg(argName, arg) {
|
|
91
|
+
if (arg == null) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
if (typeof arg === 'boolean') {
|
|
95
|
+
return arg;
|
|
96
|
+
}
|
|
97
|
+
if (typeof arg === 'string') {
|
|
98
|
+
if (arg === 'true' || arg === '1' || arg === '') {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
if (arg === 'false' || arg === '0') {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (Array.isArray(arg)) {
|
|
106
|
+
if (arg.length > 1) {
|
|
107
|
+
throw new _errors.CommandError('BAD_ARGS', `Too many ${argName} args provided.`);
|
|
108
|
+
} else {
|
|
109
|
+
return getBooleanArg(argName, arg[0]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
throw new _errors.CommandError('BAD_ARGS', `Expected a boolean input for arg ${argName}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//# sourceMappingURL=resolveOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lint/resolveOptions.ts"],"sourcesContent":["import { CommandError } from '../utils/errors';\nimport { assertNonBooleanArg } from '../utils/resolveArgs';\nimport { assertUnexpectedVariadicFlags, parseVariadicArguments } from '../utils/variadic';\n\nexport type Options = {\n ext: string[];\n config?: string;\n cache: boolean;\n fix: boolean;\n fixType: string[];\n ignore: boolean;\n ignorePattern: string[];\n quiet: boolean;\n maxWarnings: number;\n};\n\nfunction splitCommaSeparatedList(argName: string, list: any): string[] {\n if (list == null) return [];\n assertNonBooleanArg(argName, list);\n\n if (typeof list === 'string') {\n return list.split(',').map((item) => item.trim());\n }\n if (Array.isArray(list)) {\n return list.map((item) => splitCommaSeparatedList(argName, item)).flat();\n }\n if (typeof list === 'boolean') {\n throw new CommandError(`Expected a string input for arg ${argName}`);\n }\n\n throw new CommandError(\n `Expected a string or an array for arg ${argName}, but got: ${typeof list}`\n );\n}\n\nfunction resolveOptions(options: Options): Options {\n return {\n ...options,\n ext: splitCommaSeparatedList('--ext', options.ext),\n fixType: splitCommaSeparatedList('--fix-type', options.fixType),\n config: options.config,\n };\n}\n\nexport async function resolveArgsAsync(\n argv: string[]\n): Promise<{ variadic: string[]; options: Options; extras: string[] }> {\n const knownFlags = [\n '--ext',\n '--config',\n '--no-cache',\n '--fix',\n '--fix-type',\n '--no-ignore',\n '--ignore-pattern',\n '--quiet',\n '--max-warnings',\n ];\n\n const { variadic, extras, flags } = parseVariadicArguments(argv, [\n // Just non-boolean flags\n '--ext',\n '--config',\n '--fix-type',\n '--ignore-pattern',\n '--max-warnings',\n ]);\n\n assertUnexpectedVariadicFlags(knownFlags, { variadic, extras, flags }, 'npx expo lint');\n\n const config = flags['--config'];\n assertSingleStringInput('--config', config);\n\n return {\n // Variadic arguments like `npx expo install react react-dom` -> ['react', 'react-dom']\n variadic,\n options: resolveOptions({\n ext: splitCommaSeparatedList('--ext', flags['--ext']),\n config: assertSingleStringInput('--config', config),\n cache: !getBooleanArg('--no-cache', flags['--no-cache']),\n fix: !!getBooleanArg('--fix', flags['--fix']),\n\n fixType: splitCommaSeparatedList('--fix-type', flags['--fix-type']),\n ignore: !getBooleanArg('--no-ignore', flags['--no-ignore']),\n ignorePattern: splitCommaSeparatedList('--ignore-pattern', flags['--ignore-pattern']),\n quiet: !!getBooleanArg('--quiet', flags['--quiet']),\n maxWarnings: Number(flags['--max-warnings']) ?? -1,\n }),\n extras,\n };\n}\n\nfunction assertSingleStringInput(argName: string, arg: any): string | undefined {\n if (!arg) {\n return arg;\n }\n assertNonBooleanArg(argName, arg);\n if (Array.isArray(arg) && arg.length > 1) {\n throw new CommandError(\n 'BAD_ARGS',\n `Too many values provided for arg ${argName}. Provide only one of: ${arg.join(', ')}`\n );\n }\n return arg as string;\n}\n\nfunction getBooleanArg(argName: string, arg: any): boolean | undefined {\n if (arg == null) {\n return undefined;\n }\n\n if (typeof arg === 'boolean') {\n return arg;\n }\n if (typeof arg === 'string') {\n if (arg === 'true' || arg === '1' || arg === '') {\n return true;\n }\n if (arg === 'false' || arg === '0') {\n return false;\n }\n }\n if (Array.isArray(arg)) {\n if (arg.length > 1) {\n throw new CommandError('BAD_ARGS', `Too many ${argName} args provided.`);\n } else {\n return getBooleanArg(argName, arg[0]);\n }\n }\n throw new CommandError('BAD_ARGS', `Expected a boolean input for arg ${argName}`);\n}\n"],"names":["resolveArgsAsync","splitCommaSeparatedList","argName","list","assertNonBooleanArg","split","map","item","trim","Array","isArray","flat","CommandError","resolveOptions","options","ext","fixType","config","argv","knownFlags","variadic","extras","flags","parseVariadicArguments","assertUnexpectedVariadicFlags","assertSingleStringInput","cache","getBooleanArg","fix","ignore","ignorePattern","quiet","maxWarnings","Number","arg","length","join","undefined"],"mappings":"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"}
|
|
@@ -97,7 +97,10 @@ async function getTemplateFilesToRenameAsync({ cwd, /**
|
|
|
97
97
|
dot: true,
|
|
98
98
|
// Prevent climbing out of the template directory in case a template
|
|
99
99
|
// includes a symlink to an external directory.
|
|
100
|
-
follow: false
|
|
100
|
+
follow: false,
|
|
101
|
+
// Do not match on directories, only files
|
|
102
|
+
// Without this patterns like `android/**/*.gradle` actually match the folder `android/.gradle`
|
|
103
|
+
nodir: true
|
|
101
104
|
});
|
|
102
105
|
}
|
|
103
106
|
async function renameTemplateAppNameAsync({ cwd, name, files }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/prebuild/renameTemplateAppName.ts"],"sourcesContent":["import { IOSConfig } from '@expo/config-plugins';\nimport fs from 'fs';\nimport { glob } from 'glob';\nimport path from 'path';\n\nimport { ExtractProps } from '../utils/npm';\n\nconst debug = require('debug')('expo:prebuild:copyTemplateFiles') as typeof console.log;\n\nfunction escapeXMLCharacters(original: string): string {\n const noAmps = original.replace('&', '&');\n const noLt = noAmps.replace('<', '<');\n const noGt = noLt.replace('>', '>');\n const noApos = noGt.replace('\"', '\\\\\"');\n return noApos.replace(\"'\", \"\\\\'\");\n}\n\n/**\n * # Background\n *\n * `@expo/cli` and `create-expo` extract a template from a tarball (whether from\n * a local npm project or a GitHub repository), but these templates have a\n * static name that needs to be updated to match whatever app name the user\n * specified.\n *\n * By convention, the app name of all templates is \"HelloWorld\". During\n * extraction, filepaths are transformed via `createEntryResolver()` in\n * `createFileTransform.ts`, but the contents of files are left untouched.\n * Technically, the contents used to be transformed during extraction as well,\n * but due to poor configurability, we've moved to a post-extraction approach.\n *\n * # The new approach: Renaming the app post-extraction\n *\n * In this new approach, we take a list of file patterns, otherwise known as the\n * \"rename config\" to determine explicitly which files – relative to the root of\n * the template – to perform find-and-replace on, to update the app name.\n *\n * ## The rename config\n *\n * The rename config can be passed directly as a string array to\n * `getTemplateFilesToRenameAsync()`.\n *\n * The file patterns are formatted as glob expressions to be interpreted by\n * [glob](https://github.com/isaacs/node-glob). Comments are supported with\n * the `#` symbol, both in the plain-text file and string array formats.\n * Whitespace is trimmed and whitespace-only lines are ignored.\n *\n * If no rename config has been passed directly to\n * `getTemplateFilesToRenameAsync()` then this default rename config will be\n * used instead.\n */\nexport const defaultRenameConfig = [\n // Common\n '!**/node_modules',\n 'app.json',\n\n // Android\n 'android/**/*.gradle',\n 'android/app/BUCK',\n 'android/app/src/**/*.java',\n 'android/app/src/**/*.kt',\n 'android/app/src/**/*.xml',\n\n // iOS\n 'ios/Podfile',\n 'ios/**/*.xcodeproj/project.pbxproj',\n 'ios/**/*.xcodeproj/xcshareddata/xcschemes/*.xcscheme',\n 'ios/**/*.xcworkspace/contents.xcworkspacedata',\n\n // macOS\n 'macos/Podfile',\n 'macos/**/*.xcodeproj/project.pbxproj',\n 'macos/**/*.xcodeproj/xcshareddata/xcschemes/*.xcscheme',\n 'macos/**/*.xcworkspace/contents.xcworkspacedata',\n] as const;\n\n/**\n * Returns a list of files within a template matched by the resolved rename\n * config.\n *\n * The rename config is resolved in the order of preference:\n * Config provided as function param > defaultRenameConfig\n */\nexport async function getTemplateFilesToRenameAsync({\n cwd,\n /**\n * An array of patterns following the rename config format. If omitted, then\n * we fall back to defaultRenameConfig.\n * @see defaultRenameConfig\n */\n renameConfig: userConfig,\n}: Pick<ExtractProps, 'cwd'> & { renameConfig?: string[] }) {\n let config = userConfig ?? defaultRenameConfig;\n\n // Strip comments, trim whitespace, and remove empty lines.\n config = config.map((line) => line.split(/(?<!\\\\)#/, 2)[0].trim()).filter((line) => line !== '');\n\n return await glob(config, {\n cwd,\n // `true` is consistent with .gitignore. Allows `*.xml` to match .xml files\n // in all subdirs.\n matchBase: true,\n dot: true,\n // Prevent climbing out of the template directory in case a template\n // includes a symlink to an external directory.\n follow: false,\n });\n}\n\nexport async function renameTemplateAppNameAsync({\n cwd,\n name,\n files,\n}: Pick<ExtractProps, 'cwd' | 'name'> & {\n /**\n * An array of files to transform. Usually provided by calling\n * getTemplateFilesToRenameAsync().\n * @see getTemplateFilesToRenameAsync\n */\n files: string[];\n}) {\n debug(`Got files to transform: ${JSON.stringify(files)}`);\n\n await Promise.all(\n files.map(async (file) => {\n const absoluteFilePath = path.resolve(cwd, file);\n\n let contents: string;\n try {\n contents = await fs.promises.readFile(absoluteFilePath, { encoding: 'utf-8' });\n } catch (error) {\n throw new Error(\n `Failed to read template file: \"${absoluteFilePath}\". Was it removed mid-operation?`,\n { cause: error }\n );\n }\n\n debug(`Renaming app name in file: ${absoluteFilePath}`);\n\n const safeName = ['.xml', '.plist'].includes(path.extname(file))\n ? escapeXMLCharacters(name)\n : name;\n\n try {\n const replacement = contents\n .replace(/Hello App Display Name/g, safeName)\n .replace(/HelloWorld/g, IOSConfig.XcodeUtils.sanitizedName(safeName))\n .replace(/helloworld/g, IOSConfig.XcodeUtils.sanitizedName(safeName.toLowerCase()));\n\n if (replacement === contents) {\n return;\n }\n\n await fs.promises.writeFile(absoluteFilePath, replacement);\n } catch (error) {\n throw new Error(\n `Failed to overwrite template file: \"${absoluteFilePath}\". Was it removed mid-operation?`,\n { cause: error }\n );\n }\n })\n );\n}\n"],"names":["defaultRenameConfig","getTemplateFilesToRenameAsync","renameTemplateAppNameAsync","debug","require","escapeXMLCharacters","original","noAmps","replace","noLt","noGt","noApos","cwd","renameConfig","userConfig","config","map","line","split","trim","filter","glob","matchBase","dot","follow","name","files","JSON","stringify","Promise","all","file","absoluteFilePath","path","resolve","contents","fs","promises","readFile","encoding","error","Error","cause","safeName","includes","extname","replacement","IOSConfig","XcodeUtils","sanitizedName","toLowerCase","writeFile"],"mappings":";;;;;;;;;;;IAmDaA,mBAAmB;eAAnBA;;IAgCSC,6BAA6B;eAA7BA;;
|
|
1
|
+
{"version":3,"sources":["../../../src/prebuild/renameTemplateAppName.ts"],"sourcesContent":["import { IOSConfig } from '@expo/config-plugins';\nimport fs from 'fs';\nimport { glob } from 'glob';\nimport path from 'path';\n\nimport { ExtractProps } from '../utils/npm';\n\nconst debug = require('debug')('expo:prebuild:copyTemplateFiles') as typeof console.log;\n\nfunction escapeXMLCharacters(original: string): string {\n const noAmps = original.replace('&', '&');\n const noLt = noAmps.replace('<', '<');\n const noGt = noLt.replace('>', '>');\n const noApos = noGt.replace('\"', '\\\\\"');\n return noApos.replace(\"'\", \"\\\\'\");\n}\n\n/**\n * # Background\n *\n * `@expo/cli` and `create-expo` extract a template from a tarball (whether from\n * a local npm project or a GitHub repository), but these templates have a\n * static name that needs to be updated to match whatever app name the user\n * specified.\n *\n * By convention, the app name of all templates is \"HelloWorld\". During\n * extraction, filepaths are transformed via `createEntryResolver()` in\n * `createFileTransform.ts`, but the contents of files are left untouched.\n * Technically, the contents used to be transformed during extraction as well,\n * but due to poor configurability, we've moved to a post-extraction approach.\n *\n * # The new approach: Renaming the app post-extraction\n *\n * In this new approach, we take a list of file patterns, otherwise known as the\n * \"rename config\" to determine explicitly which files – relative to the root of\n * the template – to perform find-and-replace on, to update the app name.\n *\n * ## The rename config\n *\n * The rename config can be passed directly as a string array to\n * `getTemplateFilesToRenameAsync()`.\n *\n * The file patterns are formatted as glob expressions to be interpreted by\n * [glob](https://github.com/isaacs/node-glob). Comments are supported with\n * the `#` symbol, both in the plain-text file and string array formats.\n * Whitespace is trimmed and whitespace-only lines are ignored.\n *\n * If no rename config has been passed directly to\n * `getTemplateFilesToRenameAsync()` then this default rename config will be\n * used instead.\n */\nexport const defaultRenameConfig = [\n // Common\n '!**/node_modules',\n 'app.json',\n\n // Android\n 'android/**/*.gradle',\n 'android/app/BUCK',\n 'android/app/src/**/*.java',\n 'android/app/src/**/*.kt',\n 'android/app/src/**/*.xml',\n\n // iOS\n 'ios/Podfile',\n 'ios/**/*.xcodeproj/project.pbxproj',\n 'ios/**/*.xcodeproj/xcshareddata/xcschemes/*.xcscheme',\n 'ios/**/*.xcworkspace/contents.xcworkspacedata',\n\n // macOS\n 'macos/Podfile',\n 'macos/**/*.xcodeproj/project.pbxproj',\n 'macos/**/*.xcodeproj/xcshareddata/xcschemes/*.xcscheme',\n 'macos/**/*.xcworkspace/contents.xcworkspacedata',\n] as const;\n\n/**\n * Returns a list of files within a template matched by the resolved rename\n * config.\n *\n * The rename config is resolved in the order of preference:\n * Config provided as function param > defaultRenameConfig\n */\nexport async function getTemplateFilesToRenameAsync({\n cwd,\n /**\n * An array of patterns following the rename config format. If omitted, then\n * we fall back to defaultRenameConfig.\n * @see defaultRenameConfig\n */\n renameConfig: userConfig,\n}: Pick<ExtractProps, 'cwd'> & { renameConfig?: string[] }) {\n let config = userConfig ?? defaultRenameConfig;\n\n // Strip comments, trim whitespace, and remove empty lines.\n config = config.map((line) => line.split(/(?<!\\\\)#/, 2)[0].trim()).filter((line) => line !== '');\n\n return await glob(config, {\n cwd,\n // `true` is consistent with .gitignore. Allows `*.xml` to match .xml files\n // in all subdirs.\n matchBase: true,\n dot: true,\n // Prevent climbing out of the template directory in case a template\n // includes a symlink to an external directory.\n follow: false,\n // Do not match on directories, only files\n // Without this patterns like `android/**/*.gradle` actually match the folder `android/.gradle`\n nodir: true,\n });\n}\n\nexport async function renameTemplateAppNameAsync({\n cwd,\n name,\n files,\n}: Pick<ExtractProps, 'cwd' | 'name'> & {\n /**\n * An array of files to transform. Usually provided by calling\n * getTemplateFilesToRenameAsync().\n * @see getTemplateFilesToRenameAsync\n */\n files: string[];\n}) {\n debug(`Got files to transform: ${JSON.stringify(files)}`);\n\n await Promise.all(\n files.map(async (file) => {\n const absoluteFilePath = path.resolve(cwd, file);\n\n let contents: string;\n try {\n contents = await fs.promises.readFile(absoluteFilePath, { encoding: 'utf-8' });\n } catch (error) {\n throw new Error(\n `Failed to read template file: \"${absoluteFilePath}\". Was it removed mid-operation?`,\n { cause: error }\n );\n }\n\n debug(`Renaming app name in file: ${absoluteFilePath}`);\n\n const safeName = ['.xml', '.plist'].includes(path.extname(file))\n ? escapeXMLCharacters(name)\n : name;\n\n try {\n const replacement = contents\n .replace(/Hello App Display Name/g, safeName)\n .replace(/HelloWorld/g, IOSConfig.XcodeUtils.sanitizedName(safeName))\n .replace(/helloworld/g, IOSConfig.XcodeUtils.sanitizedName(safeName.toLowerCase()));\n\n if (replacement === contents) {\n return;\n }\n\n await fs.promises.writeFile(absoluteFilePath, replacement);\n } catch (error) {\n throw new Error(\n `Failed to overwrite template file: \"${absoluteFilePath}\". Was it removed mid-operation?`,\n { cause: error }\n );\n }\n })\n );\n}\n"],"names":["defaultRenameConfig","getTemplateFilesToRenameAsync","renameTemplateAppNameAsync","debug","require","escapeXMLCharacters","original","noAmps","replace","noLt","noGt","noApos","cwd","renameConfig","userConfig","config","map","line","split","trim","filter","glob","matchBase","dot","follow","nodir","name","files","JSON","stringify","Promise","all","file","absoluteFilePath","path","resolve","contents","fs","promises","readFile","encoding","error","Error","cause","safeName","includes","extname","replacement","IOSConfig","XcodeUtils","sanitizedName","toLowerCase","writeFile"],"mappings":";;;;;;;;;;;IAmDaA,mBAAmB;eAAnBA;;IAgCSC,6BAA6B;eAA7BA;;IA6BAC,0BAA0B;eAA1BA;;;;yBAhHI;;;;;;;gEACX;;;;;;;yBACM;;;;;;;gEACJ;;;;;;;;;;;AAIjB,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,SAASC,oBAAoBC,QAAgB;IAC3C,MAAMC,SAASD,SAASE,OAAO,CAAC,KAAK;IACrC,MAAMC,OAAOF,OAAOC,OAAO,CAAC,KAAK;IACjC,MAAME,OAAOD,KAAKD,OAAO,CAAC,KAAK;IAC/B,MAAMG,SAASD,KAAKF,OAAO,CAAC,KAAK;IACjC,OAAOG,OAAOH,OAAO,CAAC,KAAK;AAC7B;AAoCO,MAAMR,sBAAsB;IACjC,SAAS;IACT;IACA;IAEA,UAAU;IACV;IACA;IACA;IACA;IACA;IAEA,MAAM;IACN;IACA;IACA;IACA;IAEA,QAAQ;IACR;IACA;IACA;IACA;CACD;AASM,eAAeC,8BAA8B,EAClDW,GAAG,EACH;;;;GAIC,GACDC,cAAcC,UAAU,EACgC;IACxD,IAAIC,SAASD,cAAcd;IAE3B,2DAA2D;IAC3De,SAASA,OAAOC,GAAG,CAAC,CAACC,OAASA,KAAKC,KAAK,CAAC,YAAY,EAAE,CAAC,EAAE,CAACC,IAAI,IAAIC,MAAM,CAAC,CAACH,OAASA,SAAS;IAE7F,OAAO,MAAMI,IAAAA,YAAI,EAACN,QAAQ;QACxBH;QACA,2EAA2E;QAC3E,kBAAkB;QAClBU,WAAW;QACXC,KAAK;QACL,oEAAoE;QACpE,+CAA+C;QAC/CC,QAAQ;QACR,0CAA0C;QAC1C,+FAA+F;QAC/FC,OAAO;IACT;AACF;AAEO,eAAevB,2BAA2B,EAC/CU,GAAG,EACHc,IAAI,EACJC,KAAK,EAQN;IACCxB,MAAM,CAAC,wBAAwB,EAAEyB,KAAKC,SAAS,CAACF,QAAQ;IAExD,MAAMG,QAAQC,GAAG,CACfJ,MAAMX,GAAG,CAAC,OAAOgB;QACf,MAAMC,mBAAmBC,eAAI,CAACC,OAAO,CAACvB,KAAKoB;QAE3C,IAAII;QACJ,IAAI;YACFA,WAAW,MAAMC,aAAE,CAACC,QAAQ,CAACC,QAAQ,CAACN,kBAAkB;gBAAEO,UAAU;YAAQ;QAC9E,EAAE,OAAOC,OAAO;YACd,MAAM,IAAIC,MACR,CAAC,+BAA+B,EAAET,iBAAiB,gCAAgC,CAAC,EACpF;gBAAEU,OAAOF;YAAM;QAEnB;QAEAtC,MAAM,CAAC,2BAA2B,EAAE8B,kBAAkB;QAEtD,MAAMW,WAAW;YAAC;YAAQ;SAAS,CAACC,QAAQ,CAACX,eAAI,CAACY,OAAO,CAACd,SACtD3B,oBAAoBqB,QACpBA;QAEJ,IAAI;YACF,MAAMqB,cAAcX,SACjB5B,OAAO,CAAC,2BAA2BoC,UACnCpC,OAAO,CAAC,eAAewC,0BAAS,CAACC,UAAU,CAACC,aAAa,CAACN,WAC1DpC,OAAO,CAAC,eAAewC,0BAAS,CAACC,UAAU,CAACC,aAAa,CAACN,SAASO,WAAW;YAEjF,IAAIJ,gBAAgBX,UAAU;gBAC5B;YACF;YAEA,MAAMC,aAAE,CAACC,QAAQ,CAACc,SAAS,CAACnB,kBAAkBc;QAChD,EAAE,OAAON,OAAO;YACd,MAAM,IAAIC,MACR,CAAC,oCAAoC,EAAET,iBAAiB,gCAAgC,CAAC,EACzF;gBAAEU,OAAOF;YAAM;QAEnB;IACF;AAEJ"}
|