@expo/cli 0.24.3 → 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 CHANGED
@@ -123,7 +123,7 @@ const args = (0, _arg().default)({
123
123
  });
124
124
  if (args['--version']) {
125
125
  // Version is added in the build script.
126
- console.log("0.24.3");
126
+ console.log("0.24.4");
127
127
  process.exit(0);
128
128
  }
129
129
  if (args['--non-interactive']) {
@@ -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: 'eslint .'
79
+ lint: 'expo lint'
80
80
  } : {
81
- lint: 'eslint .'
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: 'eslint .' } : { lint: 'eslint .' },\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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"}
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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"}
@@ -8,63 +8,61 @@ Object.defineProperty(exports, "expoLint", {
8
8
  return expoLint;
9
9
  }
10
10
  });
11
- const _args = require("../utils/args");
12
- const _errors = require("../utils/errors");
13
- function _getRequireWildcardCache(nodeInterop) {
14
- if (typeof WeakMap !== "function") return null;
15
- var cacheBabelInterop = new WeakMap();
16
- var cacheNodeInterop = new WeakMap();
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
- function _interop_require_wildcard(obj, nodeInterop) {
22
- if (!nodeInterop && obj && obj.__esModule) {
23
- return obj;
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.assertArgs)({
56
- // Types
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
- }, argv);
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)('Utility to run ESLint. Prompts to install and configure if not yet set up.', 'npx expo lint', '-h, --help Usage info');
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 } = await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("./lintAsync.js")));
66
- const projectRoot = (0, _args.getProjectRoot)(args);
67
- return lintAsync(projectRoot).catch(_errors.logCmdError);
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 { assertArgs, getProjectRoot, printHelp } from '../utils/args';\nimport { logCmdError } from '../utils/errors';\n\nexport const expoLint: Command = async (argv) => {\n const args = assertArgs(\n {\n // Types\n '--help': Boolean,\n // Aliases\n '-h': '--help',\n },\n argv\n );\n\n if (args['--help']) {\n printHelp(\n 'Utility to run ESLint. Prompts to install and configure if not yet set up.',\n 'npx expo lint',\n '-h, --help Usage info'\n );\n }\n\n // Load modules after the help prompt so `npx expo lint -h` shows as fast as possible.\n const { lintAsync } = await import('./lintAsync.js');\n const projectRoot = getProjectRoot(args);\n\n return lintAsync(projectRoot).catch(logCmdError);\n};\n"],"names":["expoLint","argv","args","assertArgs","Boolean","printHelp","lintAsync","projectRoot","getProjectRoot","catch","logCmdError"],"mappings":";;;;+BAIaA;;;eAAAA;;;sBAHyC;wBAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAErB,MAAMA,WAAoB,OAAOC;IACtC,MAAMC,OAAOC,IAAAA,gBAAU,EACrB;QACE,QAAQ;QACR,UAAUC;QACV,UAAU;QACV,MAAM;IACR,GACAH;IAGF,IAAIC,IAAI,CAAC,SAAS,EAAE;QAClBG,IAAAA,eAAS,EACP,8EACA,iBACA;IAEJ;IAEA,sFAAsF;IACtF,MAAM,EAAEC,SAAS,EAAE,GAAG,MAAM,mEAAA,QAAO;IACnC,MAAMC,cAAcC,IAAAA,oBAAc,EAACN;IAEnC,OAAOI,UAAUC,aAAaE,KAAK,CAACC,mBAAW;AACjD"}
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 lintAsync = async (projectRoot)=>{
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 manager = (0, _packagemanager().createForProject)(projectRoot);
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', '.']);\n } catch (error: any) {\n process.exit(error.status);\n }\n};\n"],"names":["lintAsync","projectRoot","prerequisite","ESLintProjectPrerequisite","assertAsync","bootstrapAsync","manager","createForProject","runBinAsync","error","process","exit","status"],"mappings":";;;;+BAIaA;;;eAAAA;;;;yBAJoB;;;;;;oCAES;AAEnC,MAAMA,YAAY,OAAOC;IAC9B,MAAMC,eAAe,IAAIC,6CAAyB,CAACF;IACnD,IAAI,CAAE,MAAMC,aAAaE,WAAW,IAAK;QACvC,MAAMF,aAAaG,cAAc;IACnC;IAEA,MAAMC,UAAUC,IAAAA,kCAAgB,EAACN;IACjC,IAAI;QACF,MAAMK,QAAQE,WAAW,CAAC;YAAC;YAAU;SAAI;IAC3C,EAAE,OAAOC,OAAY;QACnBC,QAAQC,IAAI,CAACF,MAAMG,MAAM;IAC3B;AACF"}
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('&', '&amp;');\n const noLt = noAmps.replace('<', '&lt;');\n const noGt = noLt.replace('>', '&gt;');\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;;IA0BAC,0BAA0B;eAA1BA;;;;yBA7GI;;;;;;;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;IACV;AACF;AAEO,eAAetB,2BAA2B,EAC/CU,GAAG,EACHa,IAAI,EACJC,KAAK,EAQN;IACCvB,MAAM,CAAC,wBAAwB,EAAEwB,KAAKC,SAAS,CAACF,QAAQ;IAExD,MAAMG,QAAQC,GAAG,CACfJ,MAAMV,GAAG,CAAC,OAAOe;QACf,MAAMC,mBAAmBC,eAAI,CAACC,OAAO,CAACtB,KAAKmB;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;QAEArC,MAAM,CAAC,2BAA2B,EAAE6B,kBAAkB;QAEtD,MAAMW,WAAW;YAAC;YAAQ;SAAS,CAACC,QAAQ,CAACX,eAAI,CAACY,OAAO,CAACd,SACtD1B,oBAAoBoB,QACpBA;QAEJ,IAAI;YACF,MAAMqB,cAAcX,SACjB3B,OAAO,CAAC,2BAA2BmC,UACnCnC,OAAO,CAAC,eAAeuC,0BAAS,CAACC,UAAU,CAACC,aAAa,CAACN,WAC1DnC,OAAO,CAAC,eAAeuC,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"}
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('&', '&amp;');\n const noLt = noAmps.replace('<', '&lt;');\n const noGt = noLt.replace('>', '&gt;');\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"}
@@ -15,6 +15,9 @@ _export(exports, {
15
15
  assertDuplicateArgs: function() {
16
16
  return assertDuplicateArgs;
17
17
  },
18
+ assertNonBooleanArg: function() {
19
+ return assertNonBooleanArg;
20
+ },
18
21
  assertUnknownArgs: function() {
19
22
  return assertUnknownArgs;
20
23
  },
@@ -157,5 +160,10 @@ function assertDuplicateArgs(args, argNameAliasTuple) {
157
160
  }
158
161
  }
159
162
  }
163
+ function assertNonBooleanArg(argName, arg) {
164
+ if (arg == null || typeof arg === 'boolean') {
165
+ throw new _errors.CommandError('BAD_ARGS', `Expected input for arg ${argName}`);
166
+ }
167
+ }
160
168
 
161
169
  //# sourceMappingURL=resolveArgs.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/resolveArgs.ts"],"sourcesContent":["import arg, { Spec } from 'arg';\n\nimport { replaceValue } from './array';\nimport { CommandError } from './errors';\n\n/** Split up arguments that are formatted like `--foo=bar` or `-f=\"bar\"` to `['--foo', 'bar']` */\nfunction splitArgs(args: string[]): string[] {\n const result: string[] = [];\n\n for (const arg of args) {\n if (arg.startsWith('-')) {\n const [key, ...props] = arg.split('=');\n result.push(key);\n if (props.length) {\n result.push(props.join('='));\n }\n } else {\n result.push(arg);\n }\n }\n\n return result;\n}\n\n/**\n * Enables the resolution of arguments that can either be a string or a boolean.\n *\n * @param args arguments that were passed to the command.\n * @param rawMap raw map of arguments that are passed to the command.\n * @param extraArgs extra arguments and aliases that should be resolved as string or boolean.\n * @returns parsed arguments and project root.\n */\nexport async function resolveStringOrBooleanArgsAsync(\n args: string[],\n rawMap: arg.Spec,\n extraArgs: arg.Spec\n) {\n args = splitArgs(args);\n\n // Assert any missing arguments\n assertUnknownArgs(\n {\n ...rawMap,\n ...extraArgs,\n },\n args\n );\n\n // Collapse aliases into fully qualified arguments.\n args = collapseAliases(extraArgs, args);\n\n // Resolve all of the string or boolean arguments and the project root.\n return _resolveStringOrBooleanArgs({ ...rawMap, ...extraArgs }, args);\n}\n\n/**\n * Enables the resolution of boolean arguments that can be formatted like `--foo=true` or `--foo false`\n *\n * @param args arguments that were passed to the command.\n * @param rawMap raw map of arguments that are passed to the command.\n * @param extraArgs extra arguments and aliases that should be resolved as string or boolean.\n * @returns parsed arguments and project root.\n */\nexport async function resolveCustomBooleanArgsAsync(\n args: string[],\n rawMap: arg.Spec,\n extraArgs: arg.Spec\n) {\n const results = await resolveStringOrBooleanArgsAsync(args, rawMap, extraArgs);\n\n return {\n ...results,\n args: Object.fromEntries(\n Object.entries(results.args).map(([key, value]) => {\n if (extraArgs[key]) {\n if (typeof value === 'string') {\n if (!['true', 'false'].includes(value)) {\n throw new CommandError(\n 'BAD_ARGS',\n `Invalid boolean argument: ${key}=${value}. Expected one of: true, false`\n );\n }\n return [key, value === 'true'];\n }\n }\n return [key, value];\n })\n ),\n };\n}\n\nexport function _resolveStringOrBooleanArgs(arg: Spec, args: string[]) {\n // Default project root, if a custom one is defined then it will overwrite this.\n let projectRoot: string = '.';\n // The resolved arguments.\n const settings: Record<string, string | boolean | undefined> = {};\n\n // Create a list of possible arguments, this will filter out aliases.\n const possibleArgs = Object.entries(arg)\n .filter(([, value]) => typeof value !== 'string')\n .map(([key]) => key);\n\n // Loop over arguments in reverse order so we can resolve if a value belongs to a flag.\n for (let i = args.length - 1; i > -1; i--) {\n const value = args[i];\n // At this point we should have converted all aliases to fully qualified arguments.\n if (value.startsWith('--')) {\n // If we ever find an argument then it must be a boolean because we are checking in reverse\n // and removing arguments from the array if we find a string.\n // We don't override arguments that are already set\n if (!(value in settings)) {\n settings[value] = true;\n }\n } else {\n // Get the previous argument in the array.\n const nextValue = i > 0 ? args[i - 1] : null;\n if (nextValue && possibleArgs.includes(nextValue)) {\n // We don't override arguments that are already set\n if (!(nextValue in settings)) {\n settings[nextValue] = value;\n }\n i--;\n } else if (\n // If the last value is not a flag and it doesn't have a recognized flag before it (instead having a string value or nothing)\n // then it must be the project root.\n i ===\n args.length - 1\n ) {\n projectRoot = value;\n } else {\n // This will asserts if two strings are passed in a row and not at the end of the line.\n throw new CommandError('BAD_ARGS', `Unknown argument: ${value}`);\n }\n }\n }\n\n return {\n args: settings,\n projectRoot,\n };\n}\n\n/** Convert all aliases to fully qualified flag names. */\nexport function collapseAliases(arg: Spec, args: string[]): string[] {\n const aliasMap = getAliasTuples(arg);\n\n for (const [arg, alias] of aliasMap) {\n args = replaceValue(args, arg, alias);\n }\n\n // Assert if there are duplicate flags after we collapse the aliases.\n assertDuplicateArgs(args, aliasMap);\n return args;\n}\n\n/** Assert that the spec has unknown arguments. */\nexport function assertUnknownArgs(arg: Spec, args: string[]) {\n const allowedArgs = Object.keys(arg);\n const unknownArgs = args.filter((arg) => !allowedArgs.includes(arg) && arg.startsWith('-'));\n if (unknownArgs.length > 0) {\n throw new CommandError(`Unknown arguments: ${unknownArgs.join(', ')}`);\n }\n}\n\nfunction getAliasTuples(arg: Spec): [string, string][] {\n return Object.entries(arg).filter(([, value]) => typeof value === 'string') as [string, string][];\n}\n\n/** Asserts that a duplicate flag has been used, this naively throws without knowing if an alias or flag were used as the duplicate. */\nexport function assertDuplicateArgs(args: string[], argNameAliasTuple: [string, string][]) {\n for (const [argName, argNameAlias] of argNameAliasTuple) {\n if (args.filter((a) => [argName, argNameAlias].includes(a)).length > 1) {\n throw new CommandError(\n 'BAD_ARGS',\n `Can only provide one instance of ${argName} or ${argNameAlias}`\n );\n }\n }\n}\n"],"names":["_resolveStringOrBooleanArgs","assertDuplicateArgs","assertUnknownArgs","collapseAliases","resolveCustomBooleanArgsAsync","resolveStringOrBooleanArgsAsync","splitArgs","args","result","arg","startsWith","key","props","split","push","length","join","rawMap","extraArgs","results","Object","fromEntries","entries","map","value","includes","CommandError","projectRoot","settings","possibleArgs","filter","i","nextValue","aliasMap","getAliasTuples","alias","replaceValue","allowedArgs","keys","unknownArgs","argNameAliasTuple","argName","argNameAlias","a"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/resolveArgs.ts"],"sourcesContent":["import arg, { Spec } from 'arg';\n\nimport { replaceValue } from './array';\nimport { CommandError } from './errors';\n\n/** Split up arguments that are formatted like `--foo=bar` or `-f=\"bar\"` to `['--foo', 'bar']` */\nfunction splitArgs(args: string[]): string[] {\n const result: string[] = [];\n\n for (const arg of args) {\n if (arg.startsWith('-')) {\n const [key, ...props] = arg.split('=');\n result.push(key);\n if (props.length) {\n result.push(props.join('='));\n }\n } else {\n result.push(arg);\n }\n }\n\n return result;\n}\n\n/**\n * Enables the resolution of arguments that can either be a string or a boolean.\n *\n * @param args arguments that were passed to the command.\n * @param rawMap raw map of arguments that are passed to the command.\n * @param extraArgs extra arguments and aliases that should be resolved as string or boolean.\n * @returns parsed arguments and project root.\n */\nexport async function resolveStringOrBooleanArgsAsync(\n args: string[],\n rawMap: arg.Spec,\n extraArgs: arg.Spec\n) {\n args = splitArgs(args);\n\n // Assert any missing arguments\n assertUnknownArgs(\n {\n ...rawMap,\n ...extraArgs,\n },\n args\n );\n\n // Collapse aliases into fully qualified arguments.\n args = collapseAliases(extraArgs, args);\n\n // Resolve all of the string or boolean arguments and the project root.\n return _resolveStringOrBooleanArgs({ ...rawMap, ...extraArgs }, args);\n}\n\n/**\n * Enables the resolution of boolean arguments that can be formatted like `--foo=true` or `--foo false`\n *\n * @param args arguments that were passed to the command.\n * @param rawMap raw map of arguments that are passed to the command.\n * @param extraArgs extra arguments and aliases that should be resolved as string or boolean.\n * @returns parsed arguments and project root.\n */\nexport async function resolveCustomBooleanArgsAsync(\n args: string[],\n rawMap: arg.Spec,\n extraArgs: arg.Spec\n) {\n const results = await resolveStringOrBooleanArgsAsync(args, rawMap, extraArgs);\n\n return {\n ...results,\n args: Object.fromEntries(\n Object.entries(results.args).map(([key, value]) => {\n if (extraArgs[key]) {\n if (typeof value === 'string') {\n if (!['true', 'false'].includes(value)) {\n throw new CommandError(\n 'BAD_ARGS',\n `Invalid boolean argument: ${key}=${value}. Expected one of: true, false`\n );\n }\n return [key, value === 'true'];\n }\n }\n return [key, value];\n })\n ),\n };\n}\n\nexport function _resolveStringOrBooleanArgs(arg: Spec, args: string[]) {\n // Default project root, if a custom one is defined then it will overwrite this.\n let projectRoot: string = '.';\n // The resolved arguments.\n const settings: Record<string, string | boolean | undefined> = {};\n\n // Create a list of possible arguments, this will filter out aliases.\n const possibleArgs = Object.entries(arg)\n .filter(([, value]) => typeof value !== 'string')\n .map(([key]) => key);\n\n // Loop over arguments in reverse order so we can resolve if a value belongs to a flag.\n for (let i = args.length - 1; i > -1; i--) {\n const value = args[i];\n // At this point we should have converted all aliases to fully qualified arguments.\n if (value.startsWith('--')) {\n // If we ever find an argument then it must be a boolean because we are checking in reverse\n // and removing arguments from the array if we find a string.\n // We don't override arguments that are already set\n if (!(value in settings)) {\n settings[value] = true;\n }\n } else {\n // Get the previous argument in the array.\n const nextValue = i > 0 ? args[i - 1] : null;\n if (nextValue && possibleArgs.includes(nextValue)) {\n // We don't override arguments that are already set\n if (!(nextValue in settings)) {\n settings[nextValue] = value;\n }\n i--;\n } else if (\n // If the last value is not a flag and it doesn't have a recognized flag before it (instead having a string value or nothing)\n // then it must be the project root.\n i ===\n args.length - 1\n ) {\n projectRoot = value;\n } else {\n // This will asserts if two strings are passed in a row and not at the end of the line.\n throw new CommandError('BAD_ARGS', `Unknown argument: ${value}`);\n }\n }\n }\n\n return {\n args: settings,\n projectRoot,\n };\n}\n\n/** Convert all aliases to fully qualified flag names. */\nexport function collapseAliases(arg: Spec, args: string[]): string[] {\n const aliasMap = getAliasTuples(arg);\n\n for (const [arg, alias] of aliasMap) {\n args = replaceValue(args, arg, alias);\n }\n\n // Assert if there are duplicate flags after we collapse the aliases.\n assertDuplicateArgs(args, aliasMap);\n return args;\n}\n\n/** Assert that the spec has unknown arguments. */\nexport function assertUnknownArgs(arg: Spec, args: string[]) {\n const allowedArgs = Object.keys(arg);\n const unknownArgs = args.filter((arg) => !allowedArgs.includes(arg) && arg.startsWith('-'));\n if (unknownArgs.length > 0) {\n throw new CommandError(`Unknown arguments: ${unknownArgs.join(', ')}`);\n }\n}\n\nfunction getAliasTuples(arg: Spec): [string, string][] {\n return Object.entries(arg).filter(([, value]) => typeof value === 'string') as [string, string][];\n}\n\n/** Asserts that a duplicate flag has been used, this naively throws without knowing if an alias or flag were used as the duplicate. */\nexport function assertDuplicateArgs(args: string[], argNameAliasTuple: [string, string][]) {\n for (const [argName, argNameAlias] of argNameAliasTuple) {\n if (args.filter((a) => [argName, argNameAlias].includes(a)).length > 1) {\n throw new CommandError(\n 'BAD_ARGS',\n `Can only provide one instance of ${argName} or ${argNameAlias}`\n );\n }\n }\n}\n\nexport function assertNonBooleanArg(argName: string, arg: any): asserts arg is string | string[] {\n if (arg == null || typeof arg === 'boolean') {\n throw new CommandError('BAD_ARGS', `Expected input for arg ${argName}`);\n }\n}\n"],"names":["_resolveStringOrBooleanArgs","assertDuplicateArgs","assertNonBooleanArg","assertUnknownArgs","collapseAliases","resolveCustomBooleanArgsAsync","resolveStringOrBooleanArgsAsync","splitArgs","args","result","arg","startsWith","key","props","split","push","length","join","rawMap","extraArgs","results","Object","fromEntries","entries","map","value","includes","CommandError","projectRoot","settings","possibleArgs","filter","i","nextValue","aliasMap","getAliasTuples","alias","replaceValue","allowedArgs","keys","unknownArgs","argNameAliasTuple","argName","argNameAlias","a"],"mappings":"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"}
@@ -33,7 +33,7 @@ class FetchClient {
33
33
  this.headers = {
34
34
  accept: 'application/json',
35
35
  'content-type': 'application/json',
36
- 'user-agent': `expo-cli/${"0.24.3"}`,
36
+ 'user-agent': `expo-cli/${"0.24.4"}`,
37
37
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
38
38
  };
39
39
  }
@@ -83,7 +83,7 @@ function createContext() {
83
83
  cpu: summarizeCpuInfo(),
84
84
  app: {
85
85
  name: 'expo/cli',
86
- version: "0.24.3"
86
+ version: "0.24.4"
87
87
  },
88
88
  ci: _ciinfo().isCI ? {
89
89
  name: _ciinfo().name,
@@ -21,17 +21,74 @@ _export(exports, {
21
21
  });
22
22
  const _errors = require("../utils/errors");
23
23
  const debug = require('debug')('expo:utils:variadic');
24
- function parseVariadicArguments(argv) {
24
+ function parseVariadicArguments(argv, strFlags = []) {
25
25
  const variadic = [];
26
- const flags = {};
27
- for (const arg of argv){
26
+ const parsedFlags = {};
27
+ let i = 0;
28
+ while(i < argv.length){
29
+ const arg = argv[i];
28
30
  if (!arg.startsWith('-')) {
29
31
  variadic.push(arg);
30
32
  } else if (arg === '--') {
31
33
  break;
32
34
  } else {
33
- flags[arg] = true;
35
+ const flagIndex = strFlags.indexOf(arg.split('=')[0]);
36
+ if (flagIndex !== -1) {
37
+ // Handle flags that expect a value
38
+ const [flag, value] = arg.split('=');
39
+ if (value !== undefined) {
40
+ // If the flag has a value inline (e.g., --flag=value)
41
+ if (parsedFlags[flag] === undefined) {
42
+ parsedFlags[flag] = value;
43
+ } else if (Array.isArray(parsedFlags[flag])) {
44
+ parsedFlags[flag].push(value);
45
+ } else {
46
+ parsedFlags[flag] = [
47
+ parsedFlags[flag],
48
+ value
49
+ ];
50
+ }
51
+ } else {
52
+ const nextArg = argv[i + 1];
53
+ if (nextArg && !nextArg.startsWith('-')) {
54
+ if (parsedFlags[arg] === undefined) {
55
+ parsedFlags[arg] = nextArg;
56
+ } else if (Array.isArray(parsedFlags[arg])) {
57
+ parsedFlags[arg].push(nextArg);
58
+ } else {
59
+ parsedFlags[arg] = [
60
+ parsedFlags[arg],
61
+ nextArg
62
+ ];
63
+ }
64
+ i++; // Skip the next argument since it's part of the current flag
65
+ } else {
66
+ if (parsedFlags[arg] === undefined) {
67
+ parsedFlags[arg] = true; // Flag without a value
68
+ } else if (Array.isArray(parsedFlags[arg])) {
69
+ parsedFlags[arg].push(true);
70
+ } else {
71
+ parsedFlags[arg] = [
72
+ parsedFlags[arg],
73
+ true
74
+ ];
75
+ }
76
+ }
77
+ }
78
+ } else {
79
+ if (parsedFlags[arg] === undefined) {
80
+ parsedFlags[arg] = true; // Unknown flag
81
+ } else if (Array.isArray(parsedFlags[arg])) {
82
+ parsedFlags[arg].push(true);
83
+ } else {
84
+ parsedFlags[arg] = [
85
+ parsedFlags[arg],
86
+ true
87
+ ];
88
+ }
89
+ }
34
90
  }
91
+ i++;
35
92
  }
36
93
  // Everything after `--` that is not an option is passed to the underlying install command.
37
94
  const extras = [];
@@ -44,10 +101,10 @@ function parseVariadicArguments(argv) {
44
101
  extras.push(...extraArgs);
45
102
  debug('Extra arguments: ' + extras.join(', '));
46
103
  }
47
- debug(`Parsed arguments (variadic: %O, flags: %O, extra: %O)`, variadic, flags, extras);
104
+ debug(`Parsed arguments (variadic: %O, flags: %O, extra: %O)`, variadic, parsedFlags, extras);
48
105
  return {
49
106
  variadic,
50
- flags,
107
+ flags: parsedFlags,
51
108
  extras
52
109
  };
53
110
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/variadic.ts"],"sourcesContent":["import { CommandError } from '../utils/errors';\n\nconst debug = require('debug')('expo:utils:variadic') as typeof console.log;\n\n/** Given a list of CLI args, return a sorted set of args based on categories used in a complex command. */\nexport function parseVariadicArguments(argv: string[]): {\n variadic: string[];\n extras: string[];\n flags: Record<string, boolean | undefined>;\n} {\n const variadic: string[] = [];\n const flags: Record<string, boolean> = {};\n\n for (const arg of argv) {\n if (!arg.startsWith('-')) {\n variadic.push(arg);\n } else if (arg === '--') {\n break;\n } else {\n flags[arg] = true;\n }\n }\n\n // Everything after `--` that is not an option is passed to the underlying install command.\n const extras: string[] = [];\n\n const extraOperator = argv.indexOf('--');\n if (extraOperator > -1 && argv.length > extraOperator + 1) {\n const extraArgs = argv.slice(extraOperator + 1);\n if (extraArgs.includes('--')) {\n throw new CommandError('BAD_ARGS', 'Unexpected multiple --');\n }\n extras.push(...extraArgs);\n debug('Extra arguments: ' + extras.join(', '));\n }\n\n debug(`Parsed arguments (variadic: %O, flags: %O, extra: %O)`, variadic, flags, extras);\n\n return {\n variadic,\n flags,\n extras,\n };\n}\n\nexport function assertUnexpectedObjectKeys(keys: string[], obj: Record<string, any>): void {\n const unexpectedKeys = Object.keys(obj).filter((key) => !keys.includes(key));\n if (unexpectedKeys.length > 0) {\n throw new CommandError('BAD_ARGS', `Unexpected: ${unexpectedKeys.join(', ')}`);\n }\n}\n\nexport function assertUnexpectedVariadicFlags(\n expectedFlags: string[],\n { extras, flags, variadic }: ReturnType<typeof parseVariadicArguments>,\n prefixCommand = ''\n) {\n const unexpectedFlags = Object.keys(flags).filter((key) => !expectedFlags.includes(key));\n\n if (unexpectedFlags.length > 0) {\n const intendedFlags = Object.entries(flags)\n .filter(([key]) => expectedFlags.includes(key))\n .map(([key]) => key);\n\n const cmd = [\n prefixCommand,\n ...variadic,\n ...intendedFlags,\n '--',\n ...extras.concat(unexpectedFlags),\n ].join(' ');\n\n throw new CommandError(\n 'BAD_ARGS',\n `Unexpected: ${unexpectedFlags.join(', ')}\\nDid you mean: ${cmd.trim()}`\n );\n }\n}\n"],"names":["assertUnexpectedObjectKeys","assertUnexpectedVariadicFlags","parseVariadicArguments","debug","require","argv","variadic","flags","arg","startsWith","push","extras","extraOperator","indexOf","length","extraArgs","slice","includes","CommandError","join","keys","obj","unexpectedKeys","Object","filter","key","expectedFlags","prefixCommand","unexpectedFlags","intendedFlags","entries","map","cmd","concat","trim"],"mappings":";;;;;;;;;;;IA6CgBA,0BAA0B;eAA1BA;;IAOAC,6BAA6B;eAA7BA;;IA/CAC,sBAAsB;eAAtBA;;;wBALa;AAE7B,MAAMC,QAAQC,QAAQ,SAAS;AAGxB,SAASF,uBAAuBG,IAAc;IAKnD,MAAMC,WAAqB,EAAE;IAC7B,MAAMC,QAAiC,CAAC;IAExC,KAAK,MAAMC,OAAOH,KAAM;QACtB,IAAI,CAACG,IAAIC,UAAU,CAAC,MAAM;YACxBH,SAASI,IAAI,CAACF;QAChB,OAAO,IAAIA,QAAQ,MAAM;YACvB;QACF,OAAO;YACLD,KAAK,CAACC,IAAI,GAAG;QACf;IACF;IAEA,2FAA2F;IAC3F,MAAMG,SAAmB,EAAE;IAE3B,MAAMC,gBAAgBP,KAAKQ,OAAO,CAAC;IACnC,IAAID,gBAAgB,CAAC,KAAKP,KAAKS,MAAM,GAAGF,gBAAgB,GAAG;QACzD,MAAMG,YAAYV,KAAKW,KAAK,CAACJ,gBAAgB;QAC7C,IAAIG,UAAUE,QAAQ,CAAC,OAAO;YAC5B,MAAM,IAAIC,oBAAY,CAAC,YAAY;QACrC;QACAP,OAAOD,IAAI,IAAIK;QACfZ,MAAM,sBAAsBQ,OAAOQ,IAAI,CAAC;IAC1C;IAEAhB,MAAM,CAAC,qDAAqD,CAAC,EAAEG,UAAUC,OAAOI;IAEhF,OAAO;QACLL;QACAC;QACAI;IACF;AACF;AAEO,SAASX,2BAA2BoB,IAAc,EAAEC,GAAwB;IACjF,MAAMC,iBAAiBC,OAAOH,IAAI,CAACC,KAAKG,MAAM,CAAC,CAACC,MAAQ,CAACL,KAAKH,QAAQ,CAACQ;IACvE,IAAIH,eAAeR,MAAM,GAAG,GAAG;QAC7B,MAAM,IAAII,oBAAY,CAAC,YAAY,CAAC,YAAY,EAAEI,eAAeH,IAAI,CAAC,OAAO;IAC/E;AACF;AAEO,SAASlB,8BACdyB,aAAuB,EACvB,EAAEf,MAAM,EAAEJ,KAAK,EAAED,QAAQ,EAA6C,EACtEqB,gBAAgB,EAAE;IAElB,MAAMC,kBAAkBL,OAAOH,IAAI,CAACb,OAAOiB,MAAM,CAAC,CAACC,MAAQ,CAACC,cAAcT,QAAQ,CAACQ;IAEnF,IAAIG,gBAAgBd,MAAM,GAAG,GAAG;QAC9B,MAAMe,gBAAgBN,OAAOO,OAAO,CAACvB,OAClCiB,MAAM,CAAC,CAAC,CAACC,IAAI,GAAKC,cAAcT,QAAQ,CAACQ,MACzCM,GAAG,CAAC,CAAC,CAACN,IAAI,GAAKA;QAElB,MAAMO,MAAM;YACVL;eACGrB;eACAuB;YACH;eACGlB,OAAOsB,MAAM,CAACL;SAClB,CAACT,IAAI,CAAC;QAEP,MAAM,IAAID,oBAAY,CACpB,YACA,CAAC,YAAY,EAAEU,gBAAgBT,IAAI,CAAC,MAAM,gBAAgB,EAAEa,IAAIE,IAAI,IAAI;IAE5E;AACF"}
1
+ {"version":3,"sources":["../../../src/utils/variadic.ts"],"sourcesContent":["import { CommandError } from '../utils/errors';\n\nconst debug = require('debug')('expo:utils:variadic') as typeof console.log;\n\n/** Given a list of CLI args, return a sorted set of args based on categories used in a complex command. */\nexport function parseVariadicArguments(\n argv: string[],\n strFlags: string[] = []\n): {\n variadic: string[];\n extras: string[];\n flags: Record<string, boolean | string | string[] | undefined>;\n} {\n const variadic: string[] = [];\n const parsedFlags: Record<string, boolean | string | string[]> = {};\n\n let i = 0;\n while (i < argv.length) {\n const arg = argv[i];\n\n if (!arg.startsWith('-')) {\n variadic.push(arg);\n } else if (arg === '--') {\n break;\n } else {\n const flagIndex = strFlags.indexOf(arg.split('=')[0]);\n if (flagIndex !== -1) {\n // Handle flags that expect a value\n const [flag, value] = arg.split('=');\n if (value !== undefined) {\n // If the flag has a value inline (e.g., --flag=value)\n if (parsedFlags[flag] === undefined) {\n parsedFlags[flag] = value;\n } else if (Array.isArray(parsedFlags[flag])) {\n (parsedFlags[flag] as string[]).push(value);\n } else {\n parsedFlags[flag] = [parsedFlags[flag] as string, value];\n }\n } else {\n const nextArg = argv[i + 1];\n if (nextArg && !nextArg.startsWith('-')) {\n if (parsedFlags[arg] === undefined) {\n parsedFlags[arg] = nextArg;\n } else if (Array.isArray(parsedFlags[arg])) {\n (parsedFlags[arg] as string[]).push(nextArg);\n } else {\n parsedFlags[arg] = [parsedFlags[arg] as string, nextArg];\n }\n i++; // Skip the next argument since it's part of the current flag\n } else {\n if (parsedFlags[arg] === undefined) {\n parsedFlags[arg] = true; // Flag without a value\n } else if (Array.isArray(parsedFlags[arg])) {\n (parsedFlags[arg] as (string | boolean)[]).push(true);\n } else {\n parsedFlags[arg] = [parsedFlags[arg] as any, true];\n }\n }\n }\n } else {\n if (parsedFlags[arg] === undefined) {\n parsedFlags[arg] = true; // Unknown flag\n } else if (Array.isArray(parsedFlags[arg])) {\n (parsedFlags[arg] as (string | boolean)[]).push(true);\n } else {\n parsedFlags[arg] = [parsedFlags[arg] as any, true];\n }\n }\n }\n i++;\n }\n\n // Everything after `--` that is not an option is passed to the underlying install command.\n const extras: string[] = [];\n const extraOperator = argv.indexOf('--');\n if (extraOperator > -1 && argv.length > extraOperator + 1) {\n const extraArgs = argv.slice(extraOperator + 1);\n if (extraArgs.includes('--')) {\n throw new CommandError('BAD_ARGS', 'Unexpected multiple --');\n }\n extras.push(...extraArgs);\n debug('Extra arguments: ' + extras.join(', '));\n }\n\n debug(`Parsed arguments (variadic: %O, flags: %O, extra: %O)`, variadic, parsedFlags, extras);\n\n return {\n variadic,\n flags: parsedFlags,\n extras,\n };\n}\n\nexport function assertUnexpectedObjectKeys(keys: string[], obj: Record<string, any>): void {\n const unexpectedKeys = Object.keys(obj).filter((key) => !keys.includes(key));\n if (unexpectedKeys.length > 0) {\n throw new CommandError('BAD_ARGS', `Unexpected: ${unexpectedKeys.join(', ')}`);\n }\n}\n\nexport function assertUnexpectedVariadicFlags(\n expectedFlags: string[],\n { extras, flags, variadic }: ReturnType<typeof parseVariadicArguments>,\n prefixCommand = ''\n) {\n const unexpectedFlags = Object.keys(flags).filter((key) => !expectedFlags.includes(key));\n\n if (unexpectedFlags.length > 0) {\n const intendedFlags = Object.entries(flags)\n .filter(([key]) => expectedFlags.includes(key))\n .map(([key]) => key);\n\n const cmd = [\n prefixCommand,\n ...variadic,\n ...intendedFlags,\n '--',\n ...extras.concat(unexpectedFlags),\n ].join(' ');\n\n throw new CommandError(\n 'BAD_ARGS',\n `Unexpected: ${unexpectedFlags.join(', ')}\\nDid you mean: ${cmd.trim()}`\n );\n }\n}\n"],"names":["assertUnexpectedObjectKeys","assertUnexpectedVariadicFlags","parseVariadicArguments","debug","require","argv","strFlags","variadic","parsedFlags","i","length","arg","startsWith","push","flagIndex","indexOf","split","flag","value","undefined","Array","isArray","nextArg","extras","extraOperator","extraArgs","slice","includes","CommandError","join","flags","keys","obj","unexpectedKeys","Object","filter","key","expectedFlags","prefixCommand","unexpectedFlags","intendedFlags","entries","map","cmd","concat","trim"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "0.24.3",
3
+ "version": "0.24.4",
4
4
  "description": "The Expo CLI",
5
5
  "main": "build/bin/cli",
6
6
  "bin": {
@@ -42,13 +42,13 @@
42
42
  "@0no-co/graphql.web": "^1.0.8",
43
43
  "@babel/runtime": "^7.20.0",
44
44
  "@expo/code-signing-certificates": "^0.0.5",
45
- "@expo/config": "~11.0.3",
46
- "@expo/config-plugins": "~9.1.5",
45
+ "@expo/config": "~11.0.4",
46
+ "@expo/config-plugins": "~9.1.6",
47
47
  "@expo/devcert": "^1.1.2",
48
48
  "@expo/env": "~1.0.3",
49
49
  "@expo/image-utils": "^0.7.2",
50
50
  "@expo/json-file": "^9.1.2",
51
- "@expo/metro-config": "~0.20.5",
51
+ "@expo/metro-config": "~0.20.6",
52
52
  "@expo/osascript": "^2.2.2",
53
53
  "@expo/package-manager": "^1.8.2",
54
54
  "@expo/plist": "^0.3.2",
@@ -139,7 +139,7 @@
139
139
  "@types/ws": "^8.5.4",
140
140
  "devtools-protocol": "^0.0.1113120",
141
141
  "expo-atlas": "^0.4.0",
142
- "expo-module-scripts": "^4.1.2",
142
+ "expo-module-scripts": "^4.1.4",
143
143
  "find-process": "^1.4.7",
144
144
  "jest-runner-tsd": "^6.0.0",
145
145
  "klaw-sync": "^6.0.0",
@@ -152,5 +152,5 @@
152
152
  "tree-kill": "^1.2.2",
153
153
  "tsd": "^0.28.1"
154
154
  },
155
- "gitHead": "f1394f21ff2719a9a3037d7511db170704e5c492"
155
+ "gitHead": "dd4ea2ac865a2b0c1f4ea3fc5879d90679099862"
156
156
  }