@shopify/cli-kit 3.28.0 → 3.30.0

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.
Files changed (106) hide show
  1. package/dist/api/admin.js +5 -11
  2. package/dist/api/admin.js.map +1 -1
  3. package/dist/api/common.d.ts +1 -1
  4. package/dist/api/common.js +7 -4
  5. package/dist/api/common.js.map +1 -1
  6. package/dist/api/graphql/find_org.js +2 -2
  7. package/dist/api/graphql/find_org.js.map +1 -1
  8. package/dist/api/identity.js +14 -4
  9. package/dist/api/identity.js.map +1 -1
  10. package/dist/api/partners.d.ts +0 -6
  11. package/dist/api/partners.js +0 -32
  12. package/dist/api/partners.js.map +1 -1
  13. package/dist/http/fetch.js +13 -0
  14. package/dist/http/fetch.js.map +1 -1
  15. package/dist/index.d.ts +0 -1
  16. package/dist/index.js +0 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/metadata.d.ts +2 -2
  19. package/dist/output.js +1 -3
  20. package/dist/output.js.map +1 -1
  21. package/dist/path.d.ts +4 -1
  22. package/dist/path.js +9 -1
  23. package/dist/path.js.map +1 -1
  24. package/dist/private/node/ui/components/Command.js.map +1 -1
  25. package/dist/private/node/ui/components/ConcurrentOutput.js +5 -1
  26. package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
  27. package/dist/{testing/fixtures/render-concurrent.d.ts → private/node/ui/components/ConcurrentOutput.test.d.ts} +0 -0
  28. package/dist/private/node/ui/components/ConcurrentOutput.test.js +53 -0
  29. package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -0
  30. package/dist/private/node/ui/components/FullScreen.js +2 -2
  31. package/dist/private/node/ui/components/FullScreen.js.map +1 -1
  32. package/dist/private/node/ui/components/Link.js.map +1 -1
  33. package/dist/private/node/ui/components/Prompt.d.ts +10 -0
  34. package/dist/private/node/ui/components/Prompt.js +23 -0
  35. package/dist/private/node/ui/components/Prompt.js.map +1 -0
  36. package/dist/private/node/ui/components/Prompt.test.d.ts +1 -0
  37. package/dist/private/node/ui/components/Prompt.test.js +71 -0
  38. package/dist/private/node/ui/components/Prompt.test.js.map +1 -0
  39. package/dist/private/node/ui/components/SelectInput.d.ts +12 -0
  40. package/dist/private/node/ui/components/SelectInput.js +93 -0
  41. package/dist/private/node/ui/components/SelectInput.js.map +1 -0
  42. package/dist/private/node/ui/components/SelectInput.test.d.ts +1 -0
  43. package/dist/private/node/ui/components/SelectInput.test.js +200 -0
  44. package/dist/private/node/ui/components/SelectInput.test.js.map +1 -0
  45. package/dist/private/node/ui/components/Table.d.ts +8 -0
  46. package/dist/private/node/ui/components/Table.js +17 -0
  47. package/dist/private/node/ui/components/Table.js.map +1 -0
  48. package/dist/private/node/ui/components/TextAnimation.js +1 -1
  49. package/dist/private/node/ui/components/TextAnimation.js.map +1 -1
  50. package/dist/private/node/ui.d.ts +2 -0
  51. package/dist/private/node/ui.js +14 -0
  52. package/dist/private/node/ui.js.map +1 -1
  53. package/dist/public/common/array.d.ts +1 -1
  54. package/dist/public/common/array.js.map +1 -1
  55. package/dist/public/node/base-command.d.ts +2 -2
  56. package/dist/public/node/base-command.js +2 -4
  57. package/dist/public/node/base-command.js.map +1 -1
  58. package/dist/public/node/checksum.d.ts +1 -1
  59. package/dist/public/node/checksum.js +1 -1
  60. package/dist/public/node/checksum.js.map +1 -1
  61. package/dist/public/node/cli.js.map +1 -1
  62. package/dist/public/node/dot-env.js.map +1 -1
  63. package/dist/public/node/error-handler.d.ts +5 -1
  64. package/dist/public/node/error-handler.js.map +1 -1
  65. package/dist/public/node/framework.js.map +1 -1
  66. package/dist/public/node/hooks/prerun.js.map +1 -1
  67. package/dist/public/node/node-package-manager.d.ts +1 -0
  68. package/dist/public/node/node-package-manager.js.map +1 -1
  69. package/dist/public/node/ruby.js +2 -2
  70. package/dist/public/node/ruby.js.map +1 -1
  71. package/dist/public/node/ui.d.ts +42 -0
  72. package/dist/public/node/ui.js +60 -6
  73. package/dist/public/node/ui.js.map +1 -1
  74. package/dist/session/exchange.js +4 -2
  75. package/dist/session/exchange.js.map +1 -1
  76. package/dist/session/validate.js +3 -13
  77. package/dist/session/validate.js.map +1 -1
  78. package/dist/session.d.ts +1 -1
  79. package/dist/session.js +3 -1
  80. package/dist/session.js.map +1 -1
  81. package/dist/string.d.ts +1 -0
  82. package/dist/string.js +3 -0
  83. package/dist/string.js.map +1 -1
  84. package/dist/system.d.ts +2 -2
  85. package/dist/system.js +17 -2
  86. package/dist/system.js.map +1 -1
  87. package/dist/testing/ui.d.ts +4 -8
  88. package/dist/testing/ui.js +17 -17
  89. package/dist/testing/ui.js.map +1 -1
  90. package/dist/tsconfig.tsbuildinfo +1 -1
  91. package/dist/ui/executor.js +7 -5
  92. package/dist/ui/executor.js.map +1 -1
  93. package/dist/ui/inquirer/autocomplete.js +13 -4
  94. package/dist/ui/inquirer/autocomplete.js.map +1 -1
  95. package/dist/ui.d.ts +6 -0
  96. package/dist/ui.js +0 -11
  97. package/dist/ui.js.map +1 -1
  98. package/package.json +35 -6
  99. package/dist/log.d.ts +0 -30
  100. package/dist/log.js +0 -169
  101. package/dist/log.js.map +0 -1
  102. package/dist/private/node/ui/error.d.ts +0 -2
  103. package/dist/private/node/ui/error.js +0 -8
  104. package/dist/private/node/ui/error.js.map +0 -1
  105. package/dist/testing/fixtures/render-concurrent.js +0 -26
  106. package/dist/testing/fixtures/render-concurrent.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"node-package-manager.js","sourceRoot":"","sources":["../../../src/public/node/node-package-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortError, BugError} from './error.js'\nimport {Version} from './semver.js'\nimport {exec} from '../../system.js'\nimport {exists as fileExists, read as readFile, write as writeFile} from '../../file.js'\nimport {glob, dirname, join as pathJoin, findUp, moduleDirectory} from '../../path.js'\nimport {token, content, debug} from '../../output.js'\nimport {Bug} from '../../error.js'\nimport {AbortController, AbortSignal} from 'abort-controller'\nimport latestVersion from 'latest-version'\nimport type {Writable} from 'node:stream'\nimport type {ExecOptions} from '../../system.js'\n\n/** The name of the Yarn lock file */\nexport const yarnLockfile = 'yarn.lock'\n\n/** The name of the npm lock file */\nexport const npmLockfile = 'package-lock.json'\n\n/** The name of the pnpm lock file */\nexport const pnpmLockfile = 'pnpm-lock.yaml'\n\n/** The name of the pnpm workspace file */\nexport const pnpmWorkspaceFile = 'pnpm-workspace.yaml'\n\n/** An array containing the lockfiles from all the package managers */\nexport const lockfiles: Lockfile[] = [yarnLockfile, pnpmLockfile, npmLockfile]\nexport type Lockfile = 'yarn.lock' | 'package-lock.json' | 'pnpm-lock.yaml'\n\n/**\n * A union type that represents the type of dependencies in the package.json\n * - dev: devDependencies\n * - prod: dependencies\n * - peer: peerDependencies\n */\nexport type DependencyType = 'dev' | 'prod' | 'peer'\n\n/**\n * A union that represents the package managers available.\n */\nexport const packageManager = ['yarn', 'npm', 'pnpm'] as const\nexport type PackageManager = typeof packageManager[number]\n\n/**\n * Returns an abort error that's thrown when a directory that's expected to have\n * a package.json doesn't have it.\n * @param directory - The path to the directory that should contain a package.json\n * @returns An abort error.\n */\nexport const PackageJsonNotFoundError = (directory: string) => {\n return new AbortError(`The directory ${directory} doesn't have a package.json.`)\n}\n\n/**\n * Returns a bug error that's thrown when the lookup of the package.json traversing the directory\n * hierarchy up can't find a package.json\n * @param directory - The directory from which the traverse has been done\n * @returns An abort error.\n */\nexport const FindUpAndReadPackageJsonNotFoundError = (directory: string) => {\n return new BugError(content`Couldn't find a a package.json traversing directories from ${token.path(directory)}`)\n}\n\n/**\n * Returns the dependency manager used to run the create workflow.\n * @param env - The environment variables of the process in which the CLI runs.\n * @returns The dependency manager\n */\nexport function packageManagerUsedForCreating(env = process.env): PackageManager | 'unknown' {\n if (env.npm_config_user_agent?.includes('yarn')) {\n return 'yarn'\n } else if (env.npm_config_user_agent?.includes('pnpm')) {\n return 'pnpm'\n } else if (env.npm_config_user_agent?.includes('npm')) {\n return 'npm'\n }\n return 'unknown'\n}\n\n/**\n * Returns the dependency manager used by an existing project.\n * @param directory - The root directory of the project.\n * @returns The dependency manager\n */\nexport async function getPackageManager(directory: string): Promise<PackageManager> {\n debug(content`Obtaining the dependency manager in directory ${token.path(directory)}...`)\n const yarnLockPath = pathJoin(directory, yarnLockfile)\n const pnpmLockPath = pathJoin(directory, pnpmLockfile)\n if (await fileExists(yarnLockPath)) {\n return 'yarn'\n } else if (await fileExists(pnpmLockPath)) {\n return 'pnpm'\n } else {\n return 'npm'\n }\n}\n\ninterface InstallNPMDependenciesRecursivelyOptions {\n /**\n * The dependency manager to use to install the dependencies.\n */\n packageManager: PackageManager\n /**\n * The directory from where we'll find package.json's recursively\n */\n directory: string\n\n /**\n * Specifies the maximum depth of the glob search.\n */\n deep?: number\n}\n\n/**\n * This function traverses down a directory tree to find directories containing a package.json\n * and installs the dependencies if needed. To know if it's needed, it uses the \"check\" command\n * provided by dependency managers.\n * @param options - Options to install dependencies recursively.\n */\nexport async function installNPMDependenciesRecursively(options: InstallNPMDependenciesRecursivelyOptions) {\n const packageJsons = await glob(pathJoin(options.directory, '**/package.json'), {\n ignore: [pathJoin(options.directory, 'node_modules/**/package.json')],\n cwd: options.directory,\n onlyFiles: true,\n deep: options.deep,\n })\n const abortController = new AbortController()\n try {\n await Promise.all(\n packageJsons.map(async (packageJsonPath) => {\n const directory = dirname(packageJsonPath)\n await installNodeModules({\n directory,\n packageManager: options.packageManager,\n stdout: undefined,\n stderr: undefined,\n signal: abortController.signal,\n args: [],\n })\n }),\n )\n } catch (error) {\n abortController.abort()\n throw error\n }\n}\n\ninterface InstallNodeModulesOptions {\n directory: string\n args: string[]\n packageManager: PackageManager\n stdout?: Writable\n stderr?: Writable\n signal?: AbortSignal\n}\n\nexport async function installNodeModules(options: InstallNodeModulesOptions) {\n const execOptions: ExecOptions = {\n cwd: options.directory,\n stdin: undefined,\n stdout: options.stdout,\n stderr: options.stderr,\n signal: options.signal,\n }\n let args = ['install']\n if (options.args) {\n args = args.concat(options.args)\n }\n await exec(options.packageManager, args, execOptions)\n}\n\n/**\n * Returns the name of the package configured in its package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the name.\n */\nexport async function getPackageName(packageJsonPath: string): Promise<string | undefined> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n return packageJsonContent.name\n}\n\n/**\n * Returns the list of production and dev dependencies of a package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the list of dependencies.\n */\nexport async function getDependencies(packageJsonPath: string): Promise<{[key: string]: string}> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n const dependencies: {[key: string]: string} = packageJsonContent.dependencies ?? {}\n const devDependencies: {[key: string]: string} = packageJsonContent.devDependencies ?? {}\n\n return {...dependencies, ...devDependencies}\n}\n\n/**\n * Returns true if the app uses workspaces, false otherwise.\n * @param packageJsonPath - Path to the package.json file\n * @param pnpmWorkspacePath - Path to the pnpm-workspace.yaml file\n * @returns A promise that resolves with true if the app uses workspaces, false otherwise.\n */\nexport async function usesWorkspaces(appDirectory: string): Promise<boolean> {\n const packageJsonPath = pathJoin(appDirectory, 'package.json')\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n const pnpmWorkspacePath = pathJoin(appDirectory, pnpmWorkspaceFile)\n return Boolean(packageJsonContent.workspaces) || fileExists(pnpmWorkspacePath)\n}\n\n/**\n * Given an NPM dependency, it checks if there's a more recent version, and if there is, it returns its value.\n * @param dependency - The dependency name (e.g. react)\n * @param currentVersion - The current version.\n * @returns A promise that resolves with a more recent version or undefined if there's no more recent version.\n */\nexport async function checkForNewVersion(dependency: string, currentVersion: string): Promise<string | undefined> {\n debug(content`Checking if there's a version of ${dependency} newer than ${currentVersion}`)\n try {\n const lastVersion = await getLatestNPMPackageVersion(dependency)\n if (lastVersion && new Version(currentVersion).compare(lastVersion) < 0) {\n return lastVersion\n } else {\n return undefined\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return undefined\n }\n}\n\n/**\n * An interface that represents a package.json\n */\nexport interface PackageJson {\n /**\n * The name attribute of the package.json\n */\n name?: string\n\n /**\n * The version attribute of the package.json\n */\n version?: string\n\n /**\n * The dependencies attribute of the package.json\n */\n dependencies?: {[key: string]: string}\n\n /**\n * The devDependencies attribute of the package.json\n */\n devDependencies?: {[key: string]: string}\n\n /**\n * The optional oclif settings attribute of the package.json\n */\n oclif?: {\n plugins?: string[]\n }\n\n /**\n * The workspaces attribute of the package.json\n */\n workspaces?: string[]\n\n /**\n * The resolutions attribute of the package.json. Only useful when using yarn as package manager\n */\n resolutions?: {[key: string]: string}\n\n /**\n * The overrides attribute of the package.json. Only useful when using npm o npmn as package managers\n */\n overrides?: {[key: string]: string}\n}\n\n/**\n * Reads and parses a package.json\n * @param packageJsonPath - Path to the package.json\n * @returns An promise that resolves with an in-memory representation\n * of the package.json or rejects with an error if the file is not found or the content is\n * not decodable.\n */\nexport async function readAndParsePackageJson(packageJsonPath: string): Promise<PackageJson> {\n if (!(await fileExists(packageJsonPath))) {\n throw PackageJsonNotFoundError(dirname(packageJsonPath))\n }\n return JSON.parse(await readFile(packageJsonPath))\n}\n\ninterface AddNPMDependenciesIfNeededOptions {\n /** How dependencies should be added */\n type: DependencyType\n\n /** The dependency manager to use to add dependencies */\n packageManager: PackageManager\n\n /** The directory that contains the package.json where dependencies will be added */\n directory: string\n\n /** Standard output coming from the underlying installation process */\n stdout?: Writable\n\n /** Standard error coming from the underlying installation process */\n stderr?: Writable\n\n /** Abort signal to stop the process */\n signal?: AbortSignal\n}\n\n/**\n * An interface that represents a dependency name with its version\n */\nexport interface DependencyVersion {\n /**\n * The name of the NPM dependency as it's reflected in the package.json:\n *\n * @example\n * In the example below name would be \"react\"\n * ```\n * {\n * \"react\": \"1.2.3\"\n * }\n * ```\n */\n name: string\n\n /**\n * The version of the NPM dependency as it's reflected in the package.json:\n *\n * @example\n * In the example below version would be \"1.2.3\"\n * ```\n * {\n * \"react\": \"1.2.3\"\n * }\n * ```\n */\n version: string | undefined\n}\n\n/**\n * Adds dependencies to a Node project (i.e. a project that has a package.json)\n * @param dependencies - List of dependencies to be added.\n * @param options - Options for adding dependencies.\n */\nexport async function addNPMDependenciesIfNeeded(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n) {\n debug(content`Adding the following dependencies if needed:\n${token.json(dependencies)}\nWith options:\n${token.json(options)}\n `)\n const packageJsonPath = pathJoin(options.directory, 'package.json')\n if (!(await fileExists(packageJsonPath))) {\n throw PackageJsonNotFoundError(options.directory)\n }\n const existingDependencies = Object.keys(await getDependencies(packageJsonPath))\n let dependenciesToAdd = dependencies\n dependenciesToAdd = dependencies.filter((dep) => {\n return !existingDependencies.includes(dep.name)\n })\n if (dependenciesToAdd.length === 0) {\n return\n }\n await addNPMDependencies(dependenciesToAdd, options)\n}\n\nexport async function addNPMDependencies(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n) {\n let args: string[]\n const depedenciesWithVersion = dependencies.map((dep) => {\n return dep.version ? `${dep.name}@${dep.version}` : dep.name\n })\n switch (options.packageManager) {\n case 'npm':\n args = argumentsToAddDependenciesWithNPM(depedenciesWithVersion, options.type)\n break\n case 'yarn':\n args = argumentsToAddDependenciesWithYarn(depedenciesWithVersion, options.type)\n break\n case 'pnpm':\n args = argumentsToAddDependenciesWithPNPM(depedenciesWithVersion, options.type)\n break\n }\n options.stdout?.write(`Executing... ${[options.packageManager, ...args].join(' ')}`)\n await exec(options.packageManager, args, {\n cwd: options.directory,\n stdout: options.stdout,\n stderr: options.stderr,\n signal: options.signal,\n })\n}\n\nexport async function addNPMDependenciesWithoutVersionIfNeeded(\n dependencies: string[],\n options: AddNPMDependenciesIfNeededOptions,\n) {\n await addNPMDependenciesIfNeeded(\n dependencies.map((dependency) => {\n return {name: dependency, version: undefined}\n }),\n options,\n )\n}\n\n/**\n * Returns the arguments to add dependencies using NPM.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithNPM(dependencies: string[], type: DependencyType): string[] {\n let command = ['install']\n command = command.concat(dependencies)\n switch (type) {\n case 'dev':\n command.push('--save-dev')\n break\n case 'peer':\n command.push('--save-peer')\n break\n case 'prod':\n command.push('--save-prod')\n break\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using Yarn.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithYarn(dependencies: string[], type: DependencyType): string[] {\n let command = ['add']\n command = command.concat(dependencies)\n switch (type) {\n case 'dev':\n command.push('--dev')\n break\n case 'peer':\n command.push('--peer')\n break\n case 'prod':\n command.push('--prod')\n break\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using PNPM.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithPNPM(dependencies: string[], type: DependencyType): string[] {\n let command = ['add']\n command = command.concat(dependencies)\n switch (type) {\n case 'dev':\n command.push('--save-dev')\n break\n case 'peer':\n command.push('--save-peer')\n break\n case 'prod':\n command.push('--save-prod')\n break\n }\n return command\n}\n\n/**\n * Given a directory it traverses the directory up looking for a package.json and if found, it reads it\n * decodes the JSON, and returns its content as a Javascript object.\n * @param options - The directory from which traverse up.\n * @returns If found, the promise resolves with the path to the\n * package.json and its content. If not found, it throws a FindUpAndReadPackageJsonNotFoundError error.\n */\nexport async function findUpAndReadPackageJson(fromDirectory: string): Promise<{path: string; content: unknown}> {\n const packageJsonPath = await findUp('package.json', {cwd: fromDirectory, type: 'file'})\n if (packageJsonPath) {\n const packageJson = JSON.parse(await readFile(packageJsonPath))\n return {path: packageJsonPath, content: packageJson}\n } else {\n throw FindUpAndReadPackageJsonNotFoundError(fromDirectory)\n }\n}\n\nexport async function addResolutionOrOverride(directory: string, dependencies: {[key: string]: string}) {\n const packageManager = await getPackageManager(directory)\n const packageJsonPath = pathJoin(directory, 'package.json')\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n\n if (packageManager === 'yarn') {\n packageJsonContent.resolutions = packageJsonContent.resolutions\n ? {...packageJsonContent.resolutions, ...dependencies}\n : dependencies\n }\n if (packageManager === 'npm' || packageManager === 'pnpm') {\n packageJsonContent.overrides = packageJsonContent.overrides\n ? {...packageJsonContent.overrides, ...dependencies}\n : dependencies\n }\n\n await writeFile(packageJsonPath, JSON.stringify(packageJsonContent, null, 2))\n}\n\n/**\n * Returns the latest available version of an NPM package.\n * @param name - The name of the NPM package.\n * @returns A promise to get the latest available version of a package.\n */\nasync function getLatestNPMPackageVersion(name: string) {\n debug(content`Getting the latest version of NPM package: ${token.raw(name)}`)\n return latestVersion(name)\n}\n\ninterface FindPackageVersionUpOptions {\n fromModuleURL: URL | string\n}\n\n/**\n * Given a module URL, it traverses the directory hierarchy up until it finds a package.json\n * and then it returns the version in it.\n * @param options - Options\n * @returns The version if it can find the package.json and it exists. An error otherwise.\n */\nexport async function findPackageVersionUp(options: FindPackageVersionUpOptions): Promise<string> {\n const fromDirectory = moduleDirectory(options.fromModuleURL)\n const packageJson = await findUpAndReadPackageJson(fromDirectory)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const version = (packageJson.content as any).version\n if (!version) {\n throw new Bug(content`The package.json at path ${token.path(packageJson.path)} doesn't contain a version`)\n }\n return version\n}\n"]}
1
+ {"version":3,"file":"node-package-manager.js","sourceRoot":"","sources":["../../../src/public/node/node-package-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AACnC,OAAO,EAAC,IAAI,EAAC,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAC,MAAM,IAAI,UAAU,EAAE,IAAI,IAAI,QAAQ,EAAE,KAAK,IAAI,SAAS,EAAC,MAAM,eAAe,CAAA;AACxF,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAC,MAAM,eAAe,CAAA;AACtF,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAC,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAC,GAAG,EAAC,MAAM,gBAAgB,CAAA;AAClC,OAAO,EAAC,eAAe,EAAc,MAAM,kBAAkB,CAAA;AAC7D,OAAO,aAAa,MAAM,gBAAgB,CAAA;AAI1C,qCAAqC;AACrC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAA;AAEvC,oCAAoC;AACpC,MAAM,CAAC,MAAM,WAAW,GAAG,mBAAmB,CAAA;AAE9C,qCAAqC;AACrC,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAA;AAE5C,0CAA0C;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,qBAAqB,CAAA;AAEtD,sEAAsE;AACtE,MAAM,CAAC,MAAM,SAAS,GAAe,CAAC,YAAY,EAAE,YAAY,EAAE,WAAW,CAAC,CAAA;AAW9E;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAU,CAAA;AAG9D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,SAAiB,EAAc,EAAE;IACxE,OAAO,IAAI,UAAU,CAAC,iBAAiB,SAAS,+BAA+B,CAAC,CAAA;AAClF,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC,SAAiB,EAAY,EAAE;IACnF,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAA,8DAA8D,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;AACnH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC7D,IAAI,GAAG,CAAC,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE;QAC/C,OAAO,MAAM,CAAA;KACd;SAAM,IAAI,GAAG,CAAC,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE;QACtD,OAAO,MAAM,CAAA;KACd;SAAM,IAAI,GAAG,CAAC,qBAAqB,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;QACrD,OAAO,KAAK,CAAA;KACb;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IACvD,KAAK,CAAC,OAAO,CAAA,iDAAiD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IACzF,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IACtD,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IACtD,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE;QAClC,OAAO,MAAM,CAAA;KACd;SAAM,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE;QACzC,OAAO,MAAM,CAAA;KACd;SAAM;QACL,OAAO,KAAK,CAAA;KACb;AACH,CAAC;AAkBD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,OAAiD;IAEjD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE;QAC9E,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,8BAA8B,CAAC,CAAC;QACrE,GAAG,EAAE,OAAO,CAAC,SAAS;QACtB,SAAS,EAAE,IAAI;QACf,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAA;IACF,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;IAC7C,IAAI;QACF,MAAM,OAAO,CAAC,GAAG,CACf,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE;YACzC,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;YAC1C,MAAM,kBAAkB,CAAC;gBACvB,SAAS;gBACT,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,eAAe,CAAC,MAAM;gBAC9B,IAAI,EAAE,EAAE;aACT,CAAC,CAAA;QACJ,CAAC,CAAC,CACH,CAAA;KACF;IAAC,OAAO,KAAK,EAAE;QACd,eAAe,CAAC,KAAK,EAAE,CAAA;QACvB,MAAM,KAAK,CAAA;KACZ;AACH,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAkC;IACzE,MAAM,WAAW,GAAgB;QAC/B,GAAG,EAAE,OAAO,CAAC,SAAS;QACtB,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAA;IACD,IAAI,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;IACtB,IAAI,OAAO,CAAC,IAAI,EAAE;QAChB,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;KACjC;IACD,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,WAAW,CAAC,CAAA;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,eAAuB;IAC1D,MAAM,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,eAAe,CAAC,CAAA;IACzE,OAAO,kBAAkB,CAAC,IAAI,CAAA;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,eAAuB;IAC3D,MAAM,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,eAAe,CAAC,CAAA;IACzE,MAAM,YAAY,GAA4B,kBAAkB,CAAC,YAAY,IAAI,EAAE,CAAA;IACnF,MAAM,eAAe,GAA4B,kBAAkB,CAAC,eAAe,IAAI,EAAE,CAAA;IAEzF,OAAO,EAAC,GAAG,YAAY,EAAE,GAAG,eAAe,EAAC,CAAA;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,YAAoB;IACvD,MAAM,eAAe,GAAG,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IAC9D,MAAM,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,eAAe,CAAC,CAAA;IACzE,MAAM,iBAAiB,GAAG,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAA;IACnE,OAAO,OAAO,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,iBAAiB,CAAC,CAAA;AAChF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAkB,EAAE,cAAsB;IACjF,KAAK,CAAC,OAAO,CAAA,oCAAoC,UAAU,eAAe,cAAc,EAAE,CAAC,CAAA;IAC3F,IAAI;QACF,MAAM,WAAW,GAAG,MAAM,0BAA0B,CAAC,UAAU,CAAC,CAAA;QAChE,IAAI,WAAW,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE;YACvE,OAAO,WAAW,CAAA;SACnB;aAAM;YACL,OAAO,SAAS,CAAA;SACjB;QACD,qDAAqD;KACtD;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,SAAS,CAAA;KACjB;AACH,CAAC;AAiDD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,eAAuB;IACnE,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,eAAe,CAAC,CAAC,EAAE;QACxC,MAAM,wBAAwB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;KACzD;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAA;AACpD,CAAC;AAqDD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,YAAiC,EACjC,OAA0C;IAE1C,KAAK,CAAC,OAAO,CAAA;EACb,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC;;EAExB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;GAClB,CAAC,CAAA;IACF,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;IACnE,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,eAAe,CAAC,CAAC,EAAE;QACxC,MAAM,wBAAwB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;KAClD;IACD,MAAM,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,eAAe,CAAC,eAAe,CAAC,CAAC,CAAA;IAChF,IAAI,iBAAiB,GAAG,YAAY,CAAA;IACpC,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QAC9C,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IACF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE;QAClC,OAAM;KACP;IACD,MAAM,kBAAkB,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,YAAiC,EACjC,OAA0C;IAE1C,IAAI,IAAc,CAAA;IAClB,MAAM,sBAAsB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACtD,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAA;IAC9D,CAAC,CAAC,CAAA;IACF,QAAQ,OAAO,CAAC,cAAc,EAAE;QAC9B,KAAK,KAAK;YACR,IAAI,GAAG,iCAAiC,CAAC,sBAAsB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAC9E,MAAK;QACP,KAAK,MAAM;YACT,IAAI,GAAG,kCAAkC,CAAC,sBAAsB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAC/E,MAAK;QACP,KAAK,MAAM;YACT,IAAI,GAAG,kCAAkC,CAAC,sBAAsB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAC/E,MAAK;KACR;IACD,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACpF,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE;QACvC,GAAG,EAAE,OAAO,CAAC,SAAS;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wCAAwC,CAC5D,YAAsB,EACtB,OAA0C;IAE1C,MAAM,0BAA0B,CAC9B,YAAY,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QAC9B,OAAO,EAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAC,CAAA;IAC/C,CAAC,CAAC,EACF,OAAO,CACR,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,iCAAiC,CAAC,YAAsB,EAAE,IAAoB;IACrF,IAAI,OAAO,GAAG,CAAC,SAAS,CAAC,CAAA;IACzB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACtC,QAAQ,IAAI,EAAE;QACZ,KAAK,KAAK;YACR,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAC1B,MAAK;QACP,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC3B,MAAK;QACP,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC3B,MAAK;KACR;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAS,kCAAkC,CAAC,YAAsB,EAAE,IAAoB;IACtF,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,CAAA;IACrB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACtC,QAAQ,IAAI,EAAE;QACZ,KAAK,KAAK;YACR,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACrB,MAAK;QACP,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACtB,MAAK;QACP,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACtB,MAAK;KACR;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAS,kCAAkC,CAAC,YAAsB,EAAE,IAAoB;IACtF,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,CAAA;IACrB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACtC,QAAQ,IAAI,EAAE;QACZ,KAAK,KAAK;YACR,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAC1B,MAAK;QACP,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC3B,MAAK;QACP,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC3B,MAAK;KACR;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,aAAqB;IAClE,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,EAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAC,CAAC,CAAA;IACxF,IAAI,eAAe,EAAE;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAA;QAC/D,OAAO,EAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,WAAW,EAAC,CAAA;KACrD;SAAM;QACL,MAAM,qCAAqC,CAAC,aAAa,CAAC,CAAA;KAC3D;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,SAAiB,EAAE,YAAqC;IACpG,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAA;IACzD,MAAM,eAAe,GAAG,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;IAC3D,MAAM,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,eAAe,CAAC,CAAA;IAEzE,IAAI,cAAc,KAAK,MAAM,EAAE;QAC7B,kBAAkB,CAAC,WAAW,GAAG,kBAAkB,CAAC,WAAW;YAC7D,CAAC,CAAC,EAAC,GAAG,kBAAkB,CAAC,WAAW,EAAE,GAAG,YAAY,EAAC;YACtD,CAAC,CAAC,YAAY,CAAA;KACjB;IACD,IAAI,cAAc,KAAK,KAAK,IAAI,cAAc,KAAK,MAAM,EAAE;QACzD,kBAAkB,CAAC,SAAS,GAAG,kBAAkB,CAAC,SAAS;YACzD,CAAC,CAAC,EAAC,GAAG,kBAAkB,CAAC,SAAS,EAAE,GAAG,YAAY,EAAC;YACpD,CAAC,CAAC,YAAY,CAAA;KACjB;IAED,MAAM,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AAC/E,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,0BAA0B,CAAC,IAAY;IACpD,KAAK,CAAC,OAAO,CAAA,8CAA8C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC7E,OAAO,aAAa,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC;AAMD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAoC;IAC7E,MAAM,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;IAC5D,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,aAAa,CAAC,CAAA;IACjE,8DAA8D;IAC9D,MAAM,OAAO,GAAI,WAAW,CAAC,OAAe,CAAC,OAAO,CAAA;IACpD,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,GAAG,CAAC,OAAO,CAAA,4BAA4B,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;KAC3G;IACD,OAAO,OAAO,CAAA;AAChB,CAAC","sourcesContent":["import {AbortError, BugError} from './error.js'\nimport {Version} from './semver.js'\nimport {exec} from '../../system.js'\nimport {exists as fileExists, read as readFile, write as writeFile} from '../../file.js'\nimport {glob, dirname, join as pathJoin, findUp, moduleDirectory} from '../../path.js'\nimport {token, content, debug} from '../../output.js'\nimport {Bug} from '../../error.js'\nimport {AbortController, AbortSignal} from 'abort-controller'\nimport latestVersion from 'latest-version'\nimport type {Writable} from 'node:stream'\nimport type {ExecOptions} from '../../system.js'\n\n/** The name of the Yarn lock file */\nexport const yarnLockfile = 'yarn.lock'\n\n/** The name of the npm lock file */\nexport const npmLockfile = 'package-lock.json'\n\n/** The name of the pnpm lock file */\nexport const pnpmLockfile = 'pnpm-lock.yaml'\n\n/** The name of the pnpm workspace file */\nexport const pnpmWorkspaceFile = 'pnpm-workspace.yaml'\n\n/** An array containing the lockfiles from all the package managers */\nexport const lockfiles: Lockfile[] = [yarnLockfile, pnpmLockfile, npmLockfile]\nexport type Lockfile = 'yarn.lock' | 'package-lock.json' | 'pnpm-lock.yaml'\n\n/**\n * A union type that represents the type of dependencies in the package.json\n * - dev: devDependencies\n * - prod: dependencies\n * - peer: peerDependencies\n */\nexport type DependencyType = 'dev' | 'prod' | 'peer'\n\n/**\n * A union that represents the package managers available.\n */\nexport const packageManager = ['yarn', 'npm', 'pnpm'] as const\nexport type PackageManager = typeof packageManager[number]\n\n/**\n * Returns an abort error that's thrown when a directory that's expected to have\n * a package.json doesn't have it.\n * @param directory - The path to the directory that should contain a package.json\n * @returns An abort error.\n */\nexport const PackageJsonNotFoundError = (directory: string): AbortError => {\n return new AbortError(`The directory ${directory} doesn't have a package.json.`)\n}\n\n/**\n * Returns a bug error that's thrown when the lookup of the package.json traversing the directory\n * hierarchy up can't find a package.json\n * @param directory - The directory from which the traverse has been done\n * @returns An abort error.\n */\nexport const FindUpAndReadPackageJsonNotFoundError = (directory: string): BugError => {\n return new BugError(content`Couldn't find a a package.json traversing directories from ${token.path(directory)}`)\n}\n\n/**\n * Returns the dependency manager used to run the create workflow.\n * @param env - The environment variables of the process in which the CLI runs.\n * @returns The dependency manager\n */\nexport function packageManagerUsedForCreating(env = process.env): PackageManager | 'unknown' {\n if (env.npm_config_user_agent?.includes('yarn')) {\n return 'yarn'\n } else if (env.npm_config_user_agent?.includes('pnpm')) {\n return 'pnpm'\n } else if (env.npm_config_user_agent?.includes('npm')) {\n return 'npm'\n }\n return 'unknown'\n}\n\n/**\n * Returns the dependency manager used by an existing project.\n * @param directory - The root directory of the project.\n * @returns The dependency manager\n */\nexport async function getPackageManager(directory: string): Promise<PackageManager> {\n debug(content`Obtaining the dependency manager in directory ${token.path(directory)}...`)\n const yarnLockPath = pathJoin(directory, yarnLockfile)\n const pnpmLockPath = pathJoin(directory, pnpmLockfile)\n if (await fileExists(yarnLockPath)) {\n return 'yarn'\n } else if (await fileExists(pnpmLockPath)) {\n return 'pnpm'\n } else {\n return 'npm'\n }\n}\n\ninterface InstallNPMDependenciesRecursivelyOptions {\n /**\n * The dependency manager to use to install the dependencies.\n */\n packageManager: PackageManager\n /**\n * The directory from where we'll find package.json's recursively\n */\n directory: string\n\n /**\n * Specifies the maximum depth of the glob search.\n */\n deep?: number\n}\n\n/**\n * This function traverses down a directory tree to find directories containing a package.json\n * and installs the dependencies if needed. To know if it's needed, it uses the \"check\" command\n * provided by dependency managers.\n * @param options - Options to install dependencies recursively.\n */\nexport async function installNPMDependenciesRecursively(\n options: InstallNPMDependenciesRecursivelyOptions,\n): Promise<void> {\n const packageJsons = await glob(pathJoin(options.directory, '**/package.json'), {\n ignore: [pathJoin(options.directory, 'node_modules/**/package.json')],\n cwd: options.directory,\n onlyFiles: true,\n deep: options.deep,\n })\n const abortController = new AbortController()\n try {\n await Promise.all(\n packageJsons.map(async (packageJsonPath) => {\n const directory = dirname(packageJsonPath)\n await installNodeModules({\n directory,\n packageManager: options.packageManager,\n stdout: undefined,\n stderr: undefined,\n signal: abortController.signal,\n args: [],\n })\n }),\n )\n } catch (error) {\n abortController.abort()\n throw error\n }\n}\n\ninterface InstallNodeModulesOptions {\n directory: string\n args: string[]\n packageManager: PackageManager\n stdout?: Writable\n stderr?: Writable\n signal?: AbortSignal\n}\n\nexport async function installNodeModules(options: InstallNodeModulesOptions): Promise<void> {\n const execOptions: ExecOptions = {\n cwd: options.directory,\n stdin: undefined,\n stdout: options.stdout,\n stderr: options.stderr,\n signal: options.signal,\n }\n let args = ['install']\n if (options.args) {\n args = args.concat(options.args)\n }\n await exec(options.packageManager, args, execOptions)\n}\n\n/**\n * Returns the name of the package configured in its package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the name.\n */\nexport async function getPackageName(packageJsonPath: string): Promise<string | undefined> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n return packageJsonContent.name\n}\n\n/**\n * Returns the list of production and dev dependencies of a package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the list of dependencies.\n */\nexport async function getDependencies(packageJsonPath: string): Promise<{[key: string]: string}> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n const dependencies: {[key: string]: string} = packageJsonContent.dependencies ?? {}\n const devDependencies: {[key: string]: string} = packageJsonContent.devDependencies ?? {}\n\n return {...dependencies, ...devDependencies}\n}\n\n/**\n * Returns true if the app uses workspaces, false otherwise.\n * @param packageJsonPath - Path to the package.json file\n * @param pnpmWorkspacePath - Path to the pnpm-workspace.yaml file\n * @returns A promise that resolves with true if the app uses workspaces, false otherwise.\n */\nexport async function usesWorkspaces(appDirectory: string): Promise<boolean> {\n const packageJsonPath = pathJoin(appDirectory, 'package.json')\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n const pnpmWorkspacePath = pathJoin(appDirectory, pnpmWorkspaceFile)\n return Boolean(packageJsonContent.workspaces) || fileExists(pnpmWorkspacePath)\n}\n\n/**\n * Given an NPM dependency, it checks if there's a more recent version, and if there is, it returns its value.\n * @param dependency - The dependency name (e.g. react)\n * @param currentVersion - The current version.\n * @returns A promise that resolves with a more recent version or undefined if there's no more recent version.\n */\nexport async function checkForNewVersion(dependency: string, currentVersion: string): Promise<string | undefined> {\n debug(content`Checking if there's a version of ${dependency} newer than ${currentVersion}`)\n try {\n const lastVersion = await getLatestNPMPackageVersion(dependency)\n if (lastVersion && new Version(currentVersion).compare(lastVersion) < 0) {\n return lastVersion\n } else {\n return undefined\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return undefined\n }\n}\n\n/**\n * An interface that represents a package.json\n */\nexport interface PackageJson {\n /**\n * The name attribute of the package.json\n */\n name?: string\n\n /**\n * The version attribute of the package.json\n */\n version?: string\n\n /**\n * The dependencies attribute of the package.json\n */\n dependencies?: {[key: string]: string}\n\n /**\n * The devDependencies attribute of the package.json\n */\n devDependencies?: {[key: string]: string}\n\n /**\n * The optional oclif settings attribute of the package.json\n */\n oclif?: {\n plugins?: string[]\n }\n\n /**\n * The workspaces attribute of the package.json\n */\n workspaces?: string[]\n\n /**\n * The resolutions attribute of the package.json. Only useful when using yarn as package manager\n */\n resolutions?: {[key: string]: string}\n\n /**\n * The overrides attribute of the package.json. Only useful when using npm o npmn as package managers\n */\n overrides?: {[key: string]: string}\n}\n\n/**\n * Reads and parses a package.json\n * @param packageJsonPath - Path to the package.json\n * @returns An promise that resolves with an in-memory representation\n * of the package.json or rejects with an error if the file is not found or the content is\n * not decodable.\n */\nexport async function readAndParsePackageJson(packageJsonPath: string): Promise<PackageJson> {\n if (!(await fileExists(packageJsonPath))) {\n throw PackageJsonNotFoundError(dirname(packageJsonPath))\n }\n return JSON.parse(await readFile(packageJsonPath))\n}\n\ninterface AddNPMDependenciesIfNeededOptions {\n /** How dependencies should be added */\n type: DependencyType\n\n /** The dependency manager to use to add dependencies */\n packageManager: PackageManager\n\n /** The directory that contains the package.json where dependencies will be added */\n directory: string\n\n /** Standard output coming from the underlying installation process */\n stdout?: Writable\n\n /** Standard error coming from the underlying installation process */\n stderr?: Writable\n\n /** Abort signal to stop the process */\n signal?: AbortSignal\n}\n\n/**\n * An interface that represents a dependency name with its version\n */\nexport interface DependencyVersion {\n /**\n * The name of the NPM dependency as it's reflected in the package.json:\n *\n * @example\n * In the example below name would be \"react\"\n * ```\n * {\n * \"react\": \"1.2.3\"\n * }\n * ```\n */\n name: string\n\n /**\n * The version of the NPM dependency as it's reflected in the package.json:\n *\n * @example\n * In the example below version would be \"1.2.3\"\n * ```\n * {\n * \"react\": \"1.2.3\"\n * }\n * ```\n */\n version: string | undefined\n}\n\n/**\n * Adds dependencies to a Node project (i.e. a project that has a package.json)\n * @param dependencies - List of dependencies to be added.\n * @param options - Options for adding dependencies.\n */\nexport async function addNPMDependenciesIfNeeded(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n debug(content`Adding the following dependencies if needed:\n${token.json(dependencies)}\nWith options:\n${token.json(options)}\n `)\n const packageJsonPath = pathJoin(options.directory, 'package.json')\n if (!(await fileExists(packageJsonPath))) {\n throw PackageJsonNotFoundError(options.directory)\n }\n const existingDependencies = Object.keys(await getDependencies(packageJsonPath))\n let dependenciesToAdd = dependencies\n dependenciesToAdd = dependencies.filter((dep) => {\n return !existingDependencies.includes(dep.name)\n })\n if (dependenciesToAdd.length === 0) {\n return\n }\n await addNPMDependencies(dependenciesToAdd, options)\n}\n\nexport async function addNPMDependencies(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n let args: string[]\n const depedenciesWithVersion = dependencies.map((dep) => {\n return dep.version ? `${dep.name}@${dep.version}` : dep.name\n })\n switch (options.packageManager) {\n case 'npm':\n args = argumentsToAddDependenciesWithNPM(depedenciesWithVersion, options.type)\n break\n case 'yarn':\n args = argumentsToAddDependenciesWithYarn(depedenciesWithVersion, options.type)\n break\n case 'pnpm':\n args = argumentsToAddDependenciesWithPNPM(depedenciesWithVersion, options.type)\n break\n }\n options.stdout?.write(`Executing... ${[options.packageManager, ...args].join(' ')}`)\n await exec(options.packageManager, args, {\n cwd: options.directory,\n stdout: options.stdout,\n stderr: options.stderr,\n signal: options.signal,\n })\n}\n\nexport async function addNPMDependenciesWithoutVersionIfNeeded(\n dependencies: string[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n await addNPMDependenciesIfNeeded(\n dependencies.map((dependency) => {\n return {name: dependency, version: undefined}\n }),\n options,\n )\n}\n\n/**\n * Returns the arguments to add dependencies using NPM.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithNPM(dependencies: string[], type: DependencyType): string[] {\n let command = ['install']\n command = command.concat(dependencies)\n switch (type) {\n case 'dev':\n command.push('--save-dev')\n break\n case 'peer':\n command.push('--save-peer')\n break\n case 'prod':\n command.push('--save-prod')\n break\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using Yarn.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithYarn(dependencies: string[], type: DependencyType): string[] {\n let command = ['add']\n command = command.concat(dependencies)\n switch (type) {\n case 'dev':\n command.push('--dev')\n break\n case 'peer':\n command.push('--peer')\n break\n case 'prod':\n command.push('--prod')\n break\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using PNPM.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithPNPM(dependencies: string[], type: DependencyType): string[] {\n let command = ['add']\n command = command.concat(dependencies)\n switch (type) {\n case 'dev':\n command.push('--save-dev')\n break\n case 'peer':\n command.push('--save-peer')\n break\n case 'prod':\n command.push('--save-prod')\n break\n }\n return command\n}\n\n/**\n * Given a directory it traverses the directory up looking for a package.json and if found, it reads it\n * decodes the JSON, and returns its content as a Javascript object.\n * @param options - The directory from which traverse up.\n * @returns If found, the promise resolves with the path to the\n * package.json and its content. If not found, it throws a FindUpAndReadPackageJsonNotFoundError error.\n */\nexport async function findUpAndReadPackageJson(fromDirectory: string): Promise<{path: string; content: unknown}> {\n const packageJsonPath = await findUp('package.json', {cwd: fromDirectory, type: 'file'})\n if (packageJsonPath) {\n const packageJson = JSON.parse(await readFile(packageJsonPath))\n return {path: packageJsonPath, content: packageJson}\n } else {\n throw FindUpAndReadPackageJsonNotFoundError(fromDirectory)\n }\n}\n\nexport async function addResolutionOrOverride(directory: string, dependencies: {[key: string]: string}): Promise<void> {\n const packageManager = await getPackageManager(directory)\n const packageJsonPath = pathJoin(directory, 'package.json')\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n\n if (packageManager === 'yarn') {\n packageJsonContent.resolutions = packageJsonContent.resolutions\n ? {...packageJsonContent.resolutions, ...dependencies}\n : dependencies\n }\n if (packageManager === 'npm' || packageManager === 'pnpm') {\n packageJsonContent.overrides = packageJsonContent.overrides\n ? {...packageJsonContent.overrides, ...dependencies}\n : dependencies\n }\n\n await writeFile(packageJsonPath, JSON.stringify(packageJsonContent, null, 2))\n}\n\n/**\n * Returns the latest available version of an NPM package.\n * @param name - The name of the NPM package.\n * @returns A promise to get the latest available version of a package.\n */\nasync function getLatestNPMPackageVersion(name: string) {\n debug(content`Getting the latest version of NPM package: ${token.raw(name)}`)\n return latestVersion(name)\n}\n\ninterface FindPackageVersionUpOptions {\n fromModuleURL: URL | string\n}\n\n/**\n * Given a module URL, it traverses the directory hierarchy up until it finds a package.json\n * and then it returns the version in it.\n * @param options - Options\n * @returns The version if it can find the package.json and it exists. An error otherwise.\n */\nexport async function findPackageVersionUp(options: FindPackageVersionUpOptions): Promise<string> {\n const fromDirectory = moduleDirectory(options.fromModuleURL)\n const packageJson = await findUpAndReadPackageJson(fromDirectory)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const version = (packageJson.content as any).version\n if (!version) {\n throw new Bug(content`The package.json at path ${token.path(packageJson.path)} doesn't contain a version`)\n }\n return version\n}\n"]}
@@ -8,8 +8,8 @@ import constants from '../../constants.js';
8
8
  import { content, token } from '../../output.js';
9
9
  import { platformAndArch } from '../../os.js';
10
10
  import { Writable } from 'node:stream';
11
- const RubyCLIVersion = '2.32.0';
12
- const ThemeCheckVersion = '1.10.3';
11
+ const RubyCLIVersion = '2.33.0';
12
+ const ThemeCheckVersion = '1.12.1';
13
13
  const MinBundlerVersion = '2.3.8';
14
14
  const MinRubyVersion = '2.7.5';
15
15
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../../src/public/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import {coerceSemverVersion} from './semver.js'\nimport * as file from '../../file.js'\nimport * as ui from '../../ui.js'\nimport * as system from '../../system.js'\nimport {Abort, AbortSilent} from '../../error.js'\nimport {glob, join} from '../../path.js'\nimport constants from '../../constants.js'\nimport {AdminSession} from '../../session.js'\nimport {content, token} from '../../output.js'\nimport {platformAndArch} from '../../os.js'\nimport {AbortSignal} from 'abort-controller'\nimport {Writable} from 'node:stream'\n\nconst RubyCLIVersion = '2.32.0'\nconst ThemeCheckVersion = '1.10.3'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.7.5'\n\ninterface ExecCLI2Options {\n // Contains token and store to pass to CLI 2.0, which will be set as environment variables\n adminSession?: AdminSession\n // Contains token for storefront access to pass to CLI 2.0 as environment variable\n storefrontToken?: string\n // Contains token for partners access to pass to CLI 2.0 as environment variable\n token?: string\n // Directory in which to execute the command. Otherwise the current directory will be used.\n directory?: string\n\n signal?: AbortSignal\n}\n/**\n * Execute CLI 2.0 commands.\n * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.\n * User must have a valid ruby+bundler environment to run any command.\n *\n * @param args - List of argumets to execute. (ex: ['theme', 'pull'])\n * @param options - Options to customize the execution of cli2.\n */\nexport async function execCLI2(\n args: string[],\n {adminSession, storefrontToken, token, directory, signal}: ExecCLI2Options = {},\n) {\n await installCLIDependencies()\n const env = {\n ...process.env,\n SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: storefrontToken,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,\n SHOPIFY_SHOP: adminSession?.storeFqdn,\n SHOPIFY_CLI_AUTH_TOKEN: token,\n SHOPIFY_CLI_RUN_AS_SUBPROCESS: 'true',\n // Bundler uses this Gemfile to understand which gems are available in the\n // environment. We use this to specify our own Gemfile for CLI2, which exists\n // outside the user's project directory.\n BUNDLE_GEMFILE: join(shopifyCLIDirectory(), 'Gemfile'),\n }\n\n try {\n await system.exec(bundleExecutable(), ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: directory ?? process.cwd(),\n env,\n signal,\n })\n } catch (error) {\n // CLI2 will show it's own errors, we don't need to show an additional CLI3 error\n throw new AbortSilent()\n }\n}\n\ninterface ExecThemeCheckCLIOptions {\n /** A list of directories in which theme-check should run */\n directories: string[]\n /** Arguments to pass to the theme-check CLI */\n args?: string[]\n /** Writable to send standard output content through */\n stdout: Writable\n /** Writable to send standard error content through */\n stderr: Writable\n}\n\n/**\n * A function that installs (if needed) and runs the theme-check CLI.\n * @param options - Options to customize the execution of theme-check.\n * @returns A promise that resolves or rejects depending on the result of the underlying theme-check process.\n */\nexport async function execThemeCheckCLI({\n directories,\n args,\n stdout,\n stderr,\n}: ExecThemeCheckCLIOptions): Promise<void[]> {\n await installThemeCheckCLIDependencies(stdout)\n\n const processes = directories.map(async (directory): Promise<void> => {\n // Check that there are files aside from the extension TOML config file,\n // otherwise theme-check will return a false failure.\n const files = await glob(join(directory, '/**/*'))\n const fileCount = files.filter((file) => !file.match(/\\.toml$/)).length\n if (fileCount === 0) return\n\n const customStderr = new Writable({\n write(chunk, ...args) {\n // For some reason, theme-check reports this initial status line to stderr\n // See https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/diagnostics_engine.rb#L31\n // which leads to https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/io_messenger.rb#L65\n if (chunk.toString('ascii').match(/^Checking/)) {\n stdout.write(chunk, ...args)\n } else {\n stderr.write(chunk, ...args)\n }\n },\n })\n await system.exec(bundleExecutable(), ['exec', 'theme-check'].concat([directory, ...(args || [])]), {\n stdout,\n stderr: customStderr,\n cwd: themeCheckDirectory(),\n })\n })\n return Promise.all(processes)\n}\n\n/**\n * Validate Ruby Enviroment\n * Install Theme Check CLI and its dependencies\n * Shows a loading message if it's the first time installing dependencies\n * or if we are installing a new version of Theme Check CLI\n */\nasync function installThemeCheckCLIDependencies(stdout: Writable) {\n const exists = await file.exists(themeCheckDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n await validateRubyEnv()\n await createThemeCheckCLIWorkingDirectory()\n await createThemeCheckGemfile()\n await bundleInstallThemeCheck()\n },\n },\n ],\n {renderer: 'silent'},\n )\n await list.run()\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * Validate Ruby Enviroment\n * Install RubyCLI and its dependencies\n * Shows a loading spinner if it's the first time installing dependencies\n * or if we are installing a new version of RubyCLI\n */\nasync function installCLIDependencies() {\n const exists = await file.exists(shopifyCLIDirectory())\n const renderer = exists ? 'silent' : 'default'\n\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n const usingLocalCLI2 = Boolean(process.env.SHOPIFY_CLI_2_0_DIRECTORY)\n await validateRubyEnv()\n if (usingLocalCLI2) {\n await bundleInstallLocalShopifyCLI()\n } else {\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n }\n },\n },\n ],\n {renderer},\n )\n await list.run()\n}\n\nasync function validateRubyEnv() {\n await validateRuby()\n await validateBundler()\n}\n\nasync function validateRuby() {\n let version\n try {\n const stdout = await system.captureOutput(rubyExecutable(), ['-v'])\n version = coerceSemverVersion(stdout)\n } catch {\n throw new Abort(\n 'Ruby environment not found',\n `Make sure you have Ruby installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinRubyVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Ruby version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\nasync function validateBundler() {\n let version\n try {\n const stdout = await system.captureOutput(bundleExecutable(), ['-v'])\n version = coerceSemverVersion(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinBundlerVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Bundler version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `To update to the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n}\n\nfunction createShopifyCLIWorkingDirectory() {\n return file.mkdir(shopifyCLIDirectory())\n}\n\nfunction createThemeCheckCLIWorkingDirectory() {\n return file.mkdir(themeCheckDirectory())\n}\n\nasync function createShopifyCLIGemfile() {\n const gemPath = join(shopifyCLIDirectory(), 'Gemfile')\n const gemFileContent = [\"source 'https://rubygems.org'\", `gem 'shopify-cli', '${RubyCLIVersion}'`]\n const {platform} = platformAndArch()\n if (platform === 'windows') {\n // 'wdm' is required by 'listen', see https://github.com/Shopify/cli/issues/780\n gemFileContent.push(\"gem 'wdm', '>= 0.1.0'\")\n }\n await file.write(gemPath, gemFileContent.join('\\n'))\n}\n\nasync function createThemeCheckGemfile() {\n const gemPath = join(themeCheckDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'theme-check', '${ThemeCheckVersion}'`)\n}\n\nasync function bundleInstallLocalShopifyCLI() {\n await system.exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallShopifyCLI() {\n await system.exec(bundleExecutable(), ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {\n cwd: shopifyCLIDirectory(),\n })\n await system.exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallThemeCheck() {\n await system.exec(bundleExecutable(), ['config', 'set', '--local', 'path', themeCheckDirectory()], {\n cwd: themeCheckDirectory(),\n })\n await system.exec(bundleExecutable(), ['install'], {cwd: themeCheckDirectory()})\n}\n\nfunction shopifyCLIDirectory() {\n return (\n process.env.SHOPIFY_CLI_2_0_DIRECTORY ??\n join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\n )\n}\n\nfunction themeCheckDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion)\n}\n\nexport async function version(): Promise<string | undefined> {\n const parseOutput = (version: string) => version.match(/ruby (\\d+\\.\\d+\\.\\d+)/)?.[1]\n return system\n .captureOutput(rubyExecutable(), ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n\nfunction getRubyBinDir(): string | undefined {\n return process.env.SHOPIFY_RUBY_BINDIR\n}\n\nfunction rubyExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'ruby') : 'ruby'\n}\n\nfunction bundleExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'bundle') : 'bundle'\n}\n\nfunction gemExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'gem') : 'gem'\n}\n"]}
1
+ {"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../../src/public/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import {coerceSemverVersion} from './semver.js'\nimport * as file from '../../file.js'\nimport * as ui from '../../ui.js'\nimport * as system from '../../system.js'\nimport {Abort, AbortSilent} from '../../error.js'\nimport {glob, join} from '../../path.js'\nimport constants from '../../constants.js'\nimport {AdminSession} from '../../session.js'\nimport {content, token} from '../../output.js'\nimport {platformAndArch} from '../../os.js'\nimport {AbortSignal} from 'abort-controller'\nimport {Writable} from 'node:stream'\n\nconst RubyCLIVersion = '2.33.0'\nconst ThemeCheckVersion = '1.12.1'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.7.5'\n\ninterface ExecCLI2Options {\n // Contains token and store to pass to CLI 2.0, which will be set as environment variables\n adminSession?: AdminSession\n // Contains token for storefront access to pass to CLI 2.0 as environment variable\n storefrontToken?: string\n // Contains token for partners access to pass to CLI 2.0 as environment variable\n token?: string\n // Directory in which to execute the command. Otherwise the current directory will be used.\n directory?: string\n\n signal?: AbortSignal\n}\n/**\n * Execute CLI 2.0 commands.\n * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.\n * User must have a valid ruby+bundler environment to run any command.\n *\n * @param args - List of argumets to execute. (ex: ['theme', 'pull'])\n * @param options - Options to customize the execution of cli2.\n */\nexport async function execCLI2(\n args: string[],\n {adminSession, storefrontToken, token, directory, signal}: ExecCLI2Options = {},\n): Promise<void> {\n await installCLIDependencies()\n const env = {\n ...process.env,\n SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: storefrontToken,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,\n SHOPIFY_SHOP: adminSession?.storeFqdn,\n SHOPIFY_CLI_AUTH_TOKEN: token,\n SHOPIFY_CLI_RUN_AS_SUBPROCESS: 'true',\n // Bundler uses this Gemfile to understand which gems are available in the\n // environment. We use this to specify our own Gemfile for CLI2, which exists\n // outside the user's project directory.\n BUNDLE_GEMFILE: join(shopifyCLIDirectory(), 'Gemfile'),\n }\n\n try {\n await system.exec(bundleExecutable(), ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: directory ?? process.cwd(),\n env,\n signal,\n })\n } catch (error) {\n // CLI2 will show it's own errors, we don't need to show an additional CLI3 error\n throw new AbortSilent()\n }\n}\n\ninterface ExecThemeCheckCLIOptions {\n /** A list of directories in which theme-check should run */\n directories: string[]\n /** Arguments to pass to the theme-check CLI */\n args?: string[]\n /** Writable to send standard output content through */\n stdout: Writable\n /** Writable to send standard error content through */\n stderr: Writable\n}\n\n/**\n * A function that installs (if needed) and runs the theme-check CLI.\n * @param options - Options to customize the execution of theme-check.\n * @returns A promise that resolves or rejects depending on the result of the underlying theme-check process.\n */\nexport async function execThemeCheckCLI({\n directories,\n args,\n stdout,\n stderr,\n}: ExecThemeCheckCLIOptions): Promise<void[]> {\n await installThemeCheckCLIDependencies(stdout)\n\n const processes = directories.map(async (directory): Promise<void> => {\n // Check that there are files aside from the extension TOML config file,\n // otherwise theme-check will return a false failure.\n const files = await glob(join(directory, '/**/*'))\n const fileCount = files.filter((file) => !file.match(/\\.toml$/)).length\n if (fileCount === 0) return\n\n const customStderr = new Writable({\n write(chunk, ...args) {\n // For some reason, theme-check reports this initial status line to stderr\n // See https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/diagnostics_engine.rb#L31\n // which leads to https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/io_messenger.rb#L65\n if (chunk.toString('ascii').match(/^Checking/)) {\n stdout.write(chunk, ...args)\n } else {\n stderr.write(chunk, ...args)\n }\n },\n })\n await system.exec(bundleExecutable(), ['exec', 'theme-check'].concat([directory, ...(args || [])]), {\n stdout,\n stderr: customStderr,\n cwd: themeCheckDirectory(),\n })\n })\n return Promise.all(processes)\n}\n\n/**\n * Validate Ruby Enviroment\n * Install Theme Check CLI and its dependencies\n * Shows a loading message if it's the first time installing dependencies\n * or if we are installing a new version of Theme Check CLI\n */\nasync function installThemeCheckCLIDependencies(stdout: Writable) {\n const exists = await file.exists(themeCheckDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n await validateRubyEnv()\n await createThemeCheckCLIWorkingDirectory()\n await createThemeCheckGemfile()\n await bundleInstallThemeCheck()\n },\n },\n ],\n {renderer: 'silent'},\n )\n await list.run()\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * Validate Ruby Enviroment\n * Install RubyCLI and its dependencies\n * Shows a loading spinner if it's the first time installing dependencies\n * or if we are installing a new version of RubyCLI\n */\nasync function installCLIDependencies() {\n const exists = await file.exists(shopifyCLIDirectory())\n const renderer = exists ? 'silent' : 'default'\n\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n const usingLocalCLI2 = Boolean(process.env.SHOPIFY_CLI_2_0_DIRECTORY)\n await validateRubyEnv()\n if (usingLocalCLI2) {\n await bundleInstallLocalShopifyCLI()\n } else {\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n }\n },\n },\n ],\n {renderer},\n )\n await list.run()\n}\n\nasync function validateRubyEnv() {\n await validateRuby()\n await validateBundler()\n}\n\nasync function validateRuby() {\n let version\n try {\n const stdout = await system.captureOutput(rubyExecutable(), ['-v'])\n version = coerceSemverVersion(stdout)\n } catch {\n throw new Abort(\n 'Ruby environment not found',\n `Make sure you have Ruby installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinRubyVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Ruby version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\nasync function validateBundler() {\n let version\n try {\n const stdout = await system.captureOutput(bundleExecutable(), ['-v'])\n version = coerceSemverVersion(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinBundlerVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Bundler version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `To update to the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n}\n\nfunction createShopifyCLIWorkingDirectory() {\n return file.mkdir(shopifyCLIDirectory())\n}\n\nfunction createThemeCheckCLIWorkingDirectory() {\n return file.mkdir(themeCheckDirectory())\n}\n\nasync function createShopifyCLIGemfile() {\n const gemPath = join(shopifyCLIDirectory(), 'Gemfile')\n const gemFileContent = [\"source 'https://rubygems.org'\", `gem 'shopify-cli', '${RubyCLIVersion}'`]\n const {platform} = platformAndArch()\n if (platform === 'windows') {\n // 'wdm' is required by 'listen', see https://github.com/Shopify/cli/issues/780\n gemFileContent.push(\"gem 'wdm', '>= 0.1.0'\")\n }\n await file.write(gemPath, gemFileContent.join('\\n'))\n}\n\nasync function createThemeCheckGemfile() {\n const gemPath = join(themeCheckDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'theme-check', '${ThemeCheckVersion}'`)\n}\n\nasync function bundleInstallLocalShopifyCLI() {\n await system.exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallShopifyCLI() {\n await system.exec(bundleExecutable(), ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {\n cwd: shopifyCLIDirectory(),\n })\n await system.exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallThemeCheck() {\n await system.exec(bundleExecutable(), ['config', 'set', '--local', 'path', themeCheckDirectory()], {\n cwd: themeCheckDirectory(),\n })\n await system.exec(bundleExecutable(), ['install'], {cwd: themeCheckDirectory()})\n}\n\nfunction shopifyCLIDirectory() {\n return (\n process.env.SHOPIFY_CLI_2_0_DIRECTORY ??\n join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\n )\n}\n\nfunction themeCheckDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion)\n}\n\nexport async function version(): Promise<string | undefined> {\n const parseOutput = (version: string) => version.match(/ruby (\\d+\\.\\d+\\.\\d+)/)?.[1]\n return system\n .captureOutput(rubyExecutable(), ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n\nfunction getRubyBinDir(): string | undefined {\n return process.env.SHOPIFY_RUBY_BINDIR\n}\n\nfunction rubyExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'ruby') : 'ruby'\n}\n\nfunction bundleExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'bundle') : 'bundle'\n}\n\nfunction gemExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'gem') : 'gem'\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { OutputProcess } from '../../output.js';
2
2
  import { Fatal } from '../../error.js';
3
3
  import { AlertProps } from '../../private/node/ui/components/Alert.js';
4
+ import { Props as PromptProps } from '../../private/node/ui/components/Prompt.js';
4
5
  import { AbortController } from 'abort-controller';
5
6
  import { RenderOptions } from 'ink';
6
7
  interface RenderConcurrentOptions {
@@ -139,4 +140,45 @@ export declare function renderWarning(options: RenderAlertOptions): void;
139
140
  * ```
140
141
  */
141
142
  export declare function renderFatalError(error: Fatal): void;
143
+ /**
144
+ * Renders a select prompt to the console.
145
+ *
146
+ * ? Associate your project with the org Castile Ventures?
147
+ *
148
+ * Add: • new-ext
149
+ * Remove: • integrated-demand-ext
150
+ * • order-discount
151
+
152
+ * \> (f) first
153
+ * (s) second
154
+ * (3) third
155
+ * (4) fourth
156
+ * (5) seventh
157
+ * (6) tenth
158
+
159
+ * Automations
160
+ * (7) fifth
161
+ * (8) sixth
162
+
163
+ * Merchant Admin
164
+ * (9) eighth
165
+ * (10) ninth
166
+
167
+ * navigate with arrows, enter to select
168
+ */
169
+ export declare function renderPrompt<T>(options: Omit<PromptProps<T>, 'onChoose'>): Promise<T>;
170
+ interface ConfirmationProps {
171
+ question: string;
172
+ infoTable?: PromptProps<boolean>['infoTable'];
173
+ }
174
+ /**
175
+ * Renders a confirmation prompt to the console.
176
+ *
177
+ * ? Push the following changes to your Partners Dashboard?
178
+ * \> (y) Yes, confirm
179
+ * (c) Cancel
180
+ *
181
+ * navigate with arrows, enter to select
182
+ */
183
+ export declare function renderConfirmation({ question, infoTable }: ConfirmationProps): Promise<boolean>;
142
184
  export {};
@@ -1,7 +1,8 @@
1
1
  import ConcurrentOutput from '../../private/node/ui/components/ConcurrentOutput.js';
2
- import { render } from '../../private/node/ui.js';
2
+ import { consoleError } from '../../output.js';
3
+ import { prompt, render, renderOnce } from '../../private/node/ui.js';
3
4
  import { alert } from '../../private/node/ui/alert.js';
4
- import { fatalError } from '../../private/node/ui/error.js';
5
+ import { FatalError } from '../../private/node/ui/components/FatalError.js';
5
6
  import React from 'react';
6
7
  import { AbortController } from 'abort-controller';
7
8
  /**
@@ -47,7 +48,7 @@ export async function renderConcurrent({ processes, abortController, showTimesta
47
48
  * ```
48
49
  */
49
50
  export function renderInfo(options) {
50
- alert({ ...options, type: 'info' });
51
+ return alert({ ...options, type: 'info' });
51
52
  }
52
53
  /**
53
54
  * Renders a success banner to the console.
@@ -86,7 +87,7 @@ export function renderInfo(options) {
86
87
  * ```
87
88
  */
88
89
  export function renderSuccess(options) {
89
- alert({ ...options, type: 'success' });
90
+ return alert({ ...options, type: 'success' });
90
91
  }
91
92
  /**
92
93
  * Renders a warning banner to the console.
@@ -125,7 +126,7 @@ export function renderSuccess(options) {
125
126
  * ```
126
127
  */
127
128
  export function renderWarning(options) {
128
- alert({ ...options, type: 'warning' });
129
+ return alert({ ...options, type: 'warning' });
129
130
  }
130
131
  /**
131
132
  * Renders a Fatal error to the console inside a banner.
@@ -141,6 +142,59 @@ export function renderWarning(options) {
141
142
  * ```
142
143
  */
143
144
  export function renderFatalError(error) {
144
- fatalError(error);
145
+ return renderOnce(React.createElement(FatalError, { error: error }), 'error', consoleError);
146
+ }
147
+ /**
148
+ * Renders a select prompt to the console.
149
+ *
150
+ * ? Associate your project with the org Castile Ventures?
151
+ *
152
+ * Add: • new-ext
153
+ * Remove: • integrated-demand-ext
154
+ * • order-discount
155
+
156
+ * \> (f) first
157
+ * (s) second
158
+ * (3) third
159
+ * (4) fourth
160
+ * (5) seventh
161
+ * (6) tenth
162
+
163
+ * Automations
164
+ * (7) fifth
165
+ * (8) sixth
166
+
167
+ * Merchant Admin
168
+ * (9) eighth
169
+ * (10) ninth
170
+
171
+ * navigate with arrows, enter to select
172
+ */
173
+ export async function renderPrompt(options) {
174
+ return prompt(options);
175
+ }
176
+ /**
177
+ * Renders a confirmation prompt to the console.
178
+ *
179
+ * ? Push the following changes to your Partners Dashboard?
180
+ * \> (y) Yes, confirm
181
+ * (c) Cancel
182
+ *
183
+ * navigate with arrows, enter to select
184
+ */
185
+ export async function renderConfirmation({ question, infoTable }) {
186
+ const choices = [
187
+ {
188
+ label: 'Yes, confirm',
189
+ value: true,
190
+ key: 'y',
191
+ },
192
+ {
193
+ label: 'Cancel',
194
+ value: false,
195
+ key: 'c',
196
+ },
197
+ ];
198
+ return prompt({ message: question, choices, infoTable });
145
199
  }
146
200
  //# sourceMappingURL=ui.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/public/node/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,MAAM,sDAAsD,CAAA;AAEnF,OAAO,EAAC,MAAM,EAAC,MAAM,0BAA0B,CAAA;AAE/C,OAAO,EAAC,KAAK,EAAC,MAAM,gCAAgC,CAAA;AACpD,OAAO,EAAC,UAAU,EAAC,MAAM,gCAAgC,CAAA;AAEzD,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAUhD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,SAAS,EACT,eAAe,EACf,cAAc,GAAG,IAAI,EACrB,aAAa,GAAG,EAAE,GACM;IACxB,OAAO,MAAM,CACX,oBAAC,gBAAgB,IACf,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,eAAe,IAAI,IAAI,eAAe,EAAE,EACzD,cAAc,EAAE,cAAc,GAC9B,EACF,aAAa,CACd,CAAA;AACH,CAAC;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,UAAU,CAAC,OAA2B;IACpD,KAAK,CAAC,EAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAC,CAAC,CAAA;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,aAAa,CAAC,OAA2B;IACvD,KAAK,CAAC,EAAC,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAC,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,aAAa,CAAC,OAA2B;IACvD,KAAK,CAAC,EAAC,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAC,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY;IAC3C,UAAU,CAAC,KAAK,CAAC,CAAA;AACnB,CAAC","sourcesContent":["import ConcurrentOutput from '../../private/node/ui/components/ConcurrentOutput.js'\nimport {OutputProcess} from '../../output.js'\nimport {render} from '../../private/node/ui.js'\nimport {Fatal} from '../../error.js'\nimport {alert} from '../../private/node/ui/alert.js'\nimport {fatalError} from '../../private/node/ui/error.js'\nimport {AlertProps} from '../../private/node/ui/components/Alert.js'\nimport React from 'react'\nimport {AbortController} from 'abort-controller'\nimport {RenderOptions} from 'ink'\n\ninterface RenderConcurrentOptions {\n processes: OutputProcess[]\n abortController?: AbortController\n showTimestamps?: boolean\n renderOptions?: RenderOptions\n}\n\n/**\n * Renders output from concurrent processes to the terminal with {@link ConcurrentOutput}.\n */\nexport async function renderConcurrent({\n processes,\n abortController,\n showTimestamps = true,\n renderOptions = {},\n}: RenderConcurrentOptions) {\n return render(\n <ConcurrentOutput\n processes={processes}\n abortController={abortController ?? new AbortController()}\n showTimestamps={showTimestamps}\n />,\n renderOptions,\n )\n}\n\ntype RenderAlertOptions = Omit<AlertProps, 'type'>\n\n/**\n * Renders an information banner to the console.\n *\n * Basic:\n *\n * ```\n * ╭─ info ───────────────────────────────────────────────────╮\n * │ │\n * │ Body │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n *\n * Complete:\n * ```\n * ╭─ info ───────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * │ Body │\n * │ │\n * │ Next steps │\n * │ • Run `cd santorini-goods` │\n * │ • To preview your project, run `npm app dev` │\n * │ • To add extensions, run `npm generate extension` │\n * │ │\n * │ Reference │\n * │ • Run `npm shopify help` │\n * │ • Press 'return' to open the dev docs: │\n * │ https://shopify.dev │\n * │ │\n * │ Link: https://shopify.com │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n */\nexport function renderInfo(options: RenderAlertOptions) {\n alert({...options, type: 'info'})\n}\n\n/**\n * Renders a success banner to the console.\n *\n * Basic:\n *\n * ```\n * ╭─ success ────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n *\n * Complete:\n * ```\n * ╭─ success ────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * │ Body │\n * │ │\n * │ Next steps │\n * │ • Run `cd santorini-goods` │\n * │ • To preview your project, run `npm app dev` │\n * │ • To add extensions, run `npm generate extension` │\n * │ │\n * │ Reference │\n * │ • Run `npm shopify help` │\n * │ • Press 'return' to open the dev docs: │\n * │ https://shopify.dev │\n * │ │\n * │ Link: https://shopify.com │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n */\nexport function renderSuccess(options: RenderAlertOptions) {\n alert({...options, type: 'success'})\n}\n\n/**\n * Renders a warning banner to the console.\n *\n * Basic:\n *\n * ```\n * ╭─ warning ────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n *\n * Complete:\n * ```\n * ╭─ warning ────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * │ Body │\n * │ │\n * │ Next steps │\n * │ • Run `cd santorini-goods` │\n * │ • To preview your project, run `npm app dev` │\n * │ • To add extensions, run `npm generate extension` │\n * │ │\n * │ Reference │\n * │ • Run `npm shopify help` │\n * │ • Press 'return' to open the dev docs: │\n * │ https://shopify.dev │\n * │ │\n * │ Link: https://shopify.com │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n */\nexport function renderWarning(options: RenderAlertOptions) {\n alert({...options, type: 'warning'})\n}\n\n/**\n * Renders a Fatal error to the console inside a banner.\n *\n * ```\n * ╭─ error ──────────────────────────────────────────────────╮\n * │ │\n * │ Couldn't connect to the Shopify Partner Dashboard. │\n * │ │\n * │ Check your internet connection and try again. │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n */\nexport function renderFatalError(error: Fatal) {\n fatalError(error)\n}\n"]}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/public/node/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,MAAM,sDAAsD,CAAA;AACnF,OAAO,EAAC,YAAY,EAAgB,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,0BAA0B,CAAA;AAEnE,OAAO,EAAC,KAAK,EAAC,MAAM,gCAAgC,CAAA;AAEpD,OAAO,EAAC,UAAU,EAAC,MAAM,gDAAgD,CAAA;AAEzE,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAUhD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,SAAS,EACT,eAAe,EACf,cAAc,GAAG,IAAI,EACrB,aAAa,GAAG,EAAE,GACM;IACxB,OAAO,MAAM,CACX,oBAAC,gBAAgB,IACf,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,eAAe,IAAI,IAAI,eAAe,EAAE,EACzD,cAAc,EAAE,cAAc,GAC9B,EACF,aAAa,CACd,CAAA;AACH,CAAC;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,UAAU,CAAC,OAA2B;IACpD,OAAO,KAAK,CAAC,EAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAC,CAAC,CAAA;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,aAAa,CAAC,OAA2B;IACvD,OAAO,KAAK,CAAC,EAAC,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAC,CAAC,CAAA;AAC7C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,aAAa,CAAC,OAA2B;IACvD,OAAO,KAAK,CAAC,EAAC,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAC,CAAC,CAAA;AAC7C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY;IAC3C,OAAO,UAAU,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAA;AACxE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,OAAyC;IAC7E,OAAO,MAAM,CAAC,OAAO,CAAC,CAAA;AACxB,CAAC;AAOD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAC,QAAQ,EAAE,SAAS,EAAoB;IAC/E,MAAM,OAAO,GAAG;QACd;YACE,KAAK,EAAE,cAAc;YACrB,KAAK,EAAE,IAAI;YACX,GAAG,EAAE,GAAG;SACT;QACD;YACE,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,GAAG;SACT;KACF,CAAA;IAED,OAAO,MAAM,CAAC,EAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAC,CAAC,CAAA;AACxD,CAAC","sourcesContent":["import ConcurrentOutput from '../../private/node/ui/components/ConcurrentOutput.js'\nimport {consoleError, OutputProcess} from '../../output.js'\nimport {prompt, render, renderOnce} from '../../private/node/ui.js'\nimport {Fatal} from '../../error.js'\nimport {alert} from '../../private/node/ui/alert.js'\nimport {AlertProps} from '../../private/node/ui/components/Alert.js'\nimport {FatalError} from '../../private/node/ui/components/FatalError.js'\nimport Prompt, {Props as PromptProps} from '../../private/node/ui/components/Prompt.js'\nimport React from 'react'\nimport {AbortController} from 'abort-controller'\nimport {RenderOptions} from 'ink'\n\ninterface RenderConcurrentOptions {\n processes: OutputProcess[]\n abortController?: AbortController\n showTimestamps?: boolean\n renderOptions?: RenderOptions\n}\n\n/**\n * Renders output from concurrent processes to the terminal with {@link ConcurrentOutput}.\n */\nexport async function renderConcurrent({\n processes,\n abortController,\n showTimestamps = true,\n renderOptions = {},\n}: RenderConcurrentOptions) {\n return render(\n <ConcurrentOutput\n processes={processes}\n abortController={abortController ?? new AbortController()}\n showTimestamps={showTimestamps}\n />,\n renderOptions,\n )\n}\n\ntype RenderAlertOptions = Omit<AlertProps, 'type'>\n\n/**\n * Renders an information banner to the console.\n *\n * Basic:\n *\n * ```\n * ╭─ info ───────────────────────────────────────────────────╮\n * │ │\n * │ Body │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n *\n * Complete:\n * ```\n * ╭─ info ───────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * │ Body │\n * │ │\n * │ Next steps │\n * │ • Run `cd santorini-goods` │\n * │ • To preview your project, run `npm app dev` │\n * │ • To add extensions, run `npm generate extension` │\n * │ │\n * │ Reference │\n * │ • Run `npm shopify help` │\n * │ • Press 'return' to open the dev docs: │\n * │ https://shopify.dev │\n * │ │\n * │ Link: https://shopify.com │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n */\nexport function renderInfo(options: RenderAlertOptions) {\n return alert({...options, type: 'info'})\n}\n\n/**\n * Renders a success banner to the console.\n *\n * Basic:\n *\n * ```\n * ╭─ success ────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n *\n * Complete:\n * ```\n * ╭─ success ────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * │ Body │\n * │ │\n * │ Next steps │\n * │ • Run `cd santorini-goods` │\n * │ • To preview your project, run `npm app dev` │\n * │ • To add extensions, run `npm generate extension` │\n * │ │\n * │ Reference │\n * │ • Run `npm shopify help` │\n * │ • Press 'return' to open the dev docs: │\n * │ https://shopify.dev │\n * │ │\n * │ Link: https://shopify.com │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n */\nexport function renderSuccess(options: RenderAlertOptions) {\n return alert({...options, type: 'success'})\n}\n\n/**\n * Renders a warning banner to the console.\n *\n * Basic:\n *\n * ```\n * ╭─ warning ────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n *\n * Complete:\n * ```\n * ╭─ warning ────────────────────────────────────────────────╮\n * │ │\n * │ Title │\n * │ │\n * │ Body │\n * │ │\n * │ Next steps │\n * │ • Run `cd santorini-goods` │\n * │ • To preview your project, run `npm app dev` │\n * │ • To add extensions, run `npm generate extension` │\n * │ │\n * │ Reference │\n * │ • Run `npm shopify help` │\n * │ • Press 'return' to open the dev docs: │\n * │ https://shopify.dev │\n * │ │\n * │ Link: https://shopify.com │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n */\nexport function renderWarning(options: RenderAlertOptions) {\n return alert({...options, type: 'warning'})\n}\n\n/**\n * Renders a Fatal error to the console inside a banner.\n *\n * ```\n * ╭─ error ──────────────────────────────────────────────────╮\n * │ │\n * │ Couldn't connect to the Shopify Partner Dashboard. │\n * │ │\n * │ Check your internet connection and try again. │\n * │ │\n * ╰──────────────────────────────────────────────────────────╯\n * ```\n */\nexport function renderFatalError(error: Fatal) {\n return renderOnce(<FatalError error={error} />, 'error', consoleError)\n}\n\n/**\n * Renders a select prompt to the console.\n *\n * ? Associate your project with the org Castile Ventures?\n *\n * Add: • new-ext\n * Remove: • integrated-demand-ext\n * • order-discount\n\n * \\> (f) first\n * (s) second\n * (3) third\n * (4) fourth\n * (5) seventh\n * (6) tenth\n\n * Automations\n * (7) fifth\n * (8) sixth\n\n * Merchant Admin\n * (9) eighth\n * (10) ninth\n\n * navigate with arrows, enter to select\n */\nexport async function renderPrompt<T>(options: Omit<PromptProps<T>, 'onChoose'>) {\n return prompt(options)\n}\n\ninterface ConfirmationProps {\n question: string\n infoTable?: PromptProps<boolean>['infoTable']\n}\n\n/**\n * Renders a confirmation prompt to the console.\n *\n * ? Push the following changes to your Partners Dashboard?\n * \\> (y) Yes, confirm\n * (c) Cancel\n *\n * navigate with arrows, enter to select\n */\nexport async function renderConfirmation({question, infoTable}: ConfirmationProps) {\n const choices = [\n {\n label: 'Yes, confirm',\n value: true,\n key: 'y',\n },\n {\n label: 'Cancel',\n value: false,\n key: 'c',\n },\n ]\n\n return prompt({message: question, choices, infoTable})\n}\n"]}
@@ -35,8 +35,10 @@ export async function exchangeCodeForAccessToken(codeData) {
35
35
  */
36
36
  export async function exchangeAccessForApplicationTokens(identityToken, scopes, store) {
37
37
  const token = identityToken.accessToken;
38
- const partners = await requestAppToken('partners', token, scopes.partners);
39
- const storefront = await requestAppToken('storefront-renderer', token, scopes.storefront);
38
+ const [partners, storefront] = await Promise.all([
39
+ requestAppToken('partners', token, scopes.partners),
40
+ requestAppToken('storefront-renderer', token, scopes.storefront),
41
+ ]);
40
42
  const result = {
41
43
  ...partners,
42
44
  ...storefront,
@@ -1 +1 @@
1
- {"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../src/session/exchange.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAE,QAAQ,IAAI,mBAAmB,EAAC,MAAM,eAAe,CAAA;AAE5E,OAAO,KAAK,WAAW,MAAM,YAAY,CAAA;AACzC,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AAEjC,OAAO,EAAC,QAAQ,IAAI,YAAY,EAAC,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,EAAC,GAAG,EAAE,EAAE,EAAS,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAA;AAElD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;CAAG;AAE/C,MAAM,oBAAoB,GAAG,GAAG,EAAE,CAChC,IAAI,KAAK,CAAC,iCAAiC,EAAE,qDAAqD,CAAC,CAAA;AAOrG;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,QAAwB;IACvE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,oBAAoB;QAChC,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,YAAY,EAAE,uBAAuB;QACrC,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE,QAAQ,CAAC,YAAY;KACrC,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,UAAU,EAAE,CAAA;IACzE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAA;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,aAA4B,EAC5B,MAAsB,EACtB,KAAc;IAEd,MAAM,KAAK,GAAG,aAAa,CAAC,WAAW,CAAA;IAEvC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC1E,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,qBAAqB,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;IAEzF,MAAM,MAAM,GAAG;QACb,GAAG,QAAQ;QACX,GAAG,UAAU;KACd,CAAA;IAED,IAAI,KAAK,EAAE;QACT,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QACxE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;KAC7B;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,YAA2B;IAClE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,eAAe;QAC3B,YAAY,EAAE,YAAY,CAAC,WAAW;QACtC,aAAa,EAAE,YAAY,CAAC,YAAY;QACxC,SAAS,EAAE,QAAQ;KACpB,CAAA;IACD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,UAAU,EAAE,CAAA;IACzE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAA;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,KAAa;IAC5D,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IACvC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,sDAAsD,CAAC,CAAC,CAAA;IACnH,OAAO,QAAQ,CAAC,KAAK,CAAE,CAAA;AACzB,CAAC;AASD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,UAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAE5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,8CAA8C;QAC1D,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,QAAQ;KACpB,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,IAAI,WAAW,CAAC,KAAK,EAAE,EAAE;QACvB,OAAO,GAAG,CAAC,WAAW,CAAC,KAA4B,CAAC,CAAA;KACrD;IACD,MAAM,aAAa,GAAG,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAC3D,OAAO,EAAE,CAAC,aAAa,CAAC,CAAA;AAC1B,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,GAAQ,EACR,KAAa,EACb,SAAmB,EAAE,EACrB,KAAc;IAEd,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAE5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,iDAAiD;QAC7D,oBAAoB,EAAE,+CAA+C;QACrE,kBAAkB,EAAE,+CAA+C;QACnE,SAAS,EAAE,QAAQ;QACnB,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,aAAa,EAAE,KAAK;QACpB,GAAG,CAAC,GAAG,KAAK,OAAO,IAAI,EAAC,WAAW,EAAE,WAAW,KAAK,QAAQ,EAAC,CAAC;KAChE,CAAA;IAED,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,IAAI,GAAG,KAAK,OAAO,IAAI,KAAK,EAAE;QAC5B,UAAU,GAAG,GAAG,KAAK,IAAI,KAAK,EAAE,CAAA;KACjC;IACD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,UAAU,EAAE,CAAA;IACzE,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAA;IACnD,OAAO,EAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAC,CAAA;AACjC,CAAC;AASD,KAAK,UAAU,wBAAwB,CAAC,KAAa;IACnD,IAAI,KAAK,KAAK,eAAe,EAAE;QAC7B,6FAA6F;QAC7F,oGAAoG;QACpG,OAAO,IAAI,iBAAiB,EAAE,CAAA;KAC/B;IACD,IAAI,KAAK,KAAK,iBAAiB,EAAE;QAC/B,iGAAiG;QACjG,mGAAmG;QACnG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAA;QAC1B,OAAO,IAAI,UAAU,CAAC,iCAAiC,EAAE,qDAAqD,CAAC,CAAA;KAChH;IACD,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,MAA+B;IACzD,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,IAAI,cAAc,CAAC,CAAA;IAClD,GAAG,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACnE,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAC,MAAM,EAAE,MAAM,EAAC,CAAC,CAAA;IAC1D,8DAA8D;IAC9D,MAAM,OAAO,GAAQ,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;IAErC,IAAI,GAAG,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAA;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC;AAED,SAAS,kBAAkB,CAAC,MAA0B;IACpD,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,YAAY;QAChC,YAAY,EAAE,MAAM,CAAC,aAAa;QAClC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1D,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;KAChC,CAAA;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,MAA0B;IACvD,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,YAAY;QAChC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1D,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;KAChC,CAAA;AACH,CAAC","sourcesContent":["import {ApplicationToken, IdentityToken} from './schema.js'\nimport {applicationId, clientId as getIdentityClientId} from './identity.js'\nimport {CodeAuthResult} from './authorize.js'\nimport * as secureStore from './store.js'\nimport {Abort} from '../error.js'\nimport {API} from '../network/api.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport {shopifyFetch} from '../http.js'\nimport {err, ok, Result} from '../public/node/result.js'\nimport {AbortError} from '../public/node/error.js'\n\nexport class InvalidGrantError extends Error {}\n\nconst InvalidIdentityError = () =>\n new Abort('\\nError validating auth session', \"We've cleared the current session, please try again\")\n\nexport interface ExchangeScopes {\n admin: string[]\n partners: string[]\n storefront: string[]\n}\n/**\n * Given a valid authorization code, request an identity access token.\n * This token can then be used to get API specific tokens.\n * @param codeData - code and codeVerifier from the authorize endpoint\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeCodeForAccessToken(codeData: CodeAuthResult): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'authorization_code',\n code: codeData.code,\n redirect_uri: 'http://127.0.0.1:3456',\n client_id: clientId,\n code_verifier: codeData.codeVerifier,\n }\n\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n return buildIdentityToken(value)\n}\n\n/**\n * Given an identity token, request an application token.\n * @param identityToken - access token obtained in a previous step\n * @param store - the store to use, only needed for admin API\n * @returns An array with the application access tokens.\n */\nexport async function exchangeAccessForApplicationTokens(\n identityToken: IdentityToken,\n scopes: ExchangeScopes,\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const token = identityToken.accessToken\n\n const partners = await requestAppToken('partners', token, scopes.partners)\n const storefront = await requestAppToken('storefront-renderer', token, scopes.storefront)\n\n const result = {\n ...partners,\n ...storefront,\n }\n\n if (store) {\n const admin = await requestAppToken('admin', token, scopes.admin, store)\n Object.assign(result, admin)\n }\n return result\n}\n\n/**\n * Given an expired access token, refresh it to get a new one.\n */\nexport async function refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'refresh_token',\n access_token: currentToken.accessToken,\n refresh_token: currentToken.refreshToken,\n client_id: clientId,\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n return buildIdentityToken(value)\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid partners API token\n * This token does not accept extra scopes, just the cli one.\n * @param token - The CLI token passed as ENV variable\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCustomPartnerToken(token: string): Promise<ApplicationToken> {\n const appId = applicationId('partners')\n const newToken = await requestAppToken('partners', token, ['https://api.shopify.com/auth/partners.app.cli.access'])\n return newToken[appId]!\n}\n\nexport type IdentityDeviceError =\n | 'authorization_pending'\n | 'access_denied'\n | 'expired_token'\n | 'slow_down'\n | 'unknown_failure'\n\n/**\n * Given a deviceCode obtained after starting a device identity flow, request an identity token.\n * @param deviceCode - The device code obtained after starting a device identity flow\n * @param scopes - The scopes to request\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeDeviceCodeForAccessToken(\n deviceCode: string,\n): Promise<Result<IdentityToken, IdentityDeviceError>> {\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: clientId,\n }\n\n const tokenResult = await tokenRequest(params)\n if (tokenResult.isErr()) {\n return err(tokenResult.error as IdentityDeviceError)\n }\n const identityToken = buildIdentityToken(tokenResult.value)\n return ok(identityToken)\n}\n\nasync function requestAppToken(\n api: API,\n token: string,\n scopes: string[] = [],\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const appId = applicationId(api)\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',\n requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n client_id: clientId,\n audience: appId,\n scope: scopes.join(' '),\n subject_token: token,\n ...(api === 'admin' && {destination: `https://${store}/admin`}),\n }\n\n let identifier = appId\n if (api === 'admin' && store) {\n identifier = `${store}-${appId}`\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n const appToken = await buildApplicationToken(value)\n return {[identifier]: appToken}\n}\n\ninterface TokenRequestResult {\n access_token: string\n expires_in: number\n refresh_token: string\n scope: string\n}\n\nasync function tokenRequestErrorHandler(error: string) {\n if (error === 'invalid_grant') {\n // There's an scenario when Identity returns \"invalid_grant\" when trying to refresh the token\n // using a valid refresh token. When that happens, we take the user through the authentication flow.\n return new InvalidGrantError()\n }\n if (error === 'invalid_request') {\n // There's an scenario when Identity returns \"invalid_request\" when exchanging an identity token.\n // This means the token is invalid. We clear the session and throw an error to let the caller know.\n await secureStore.remove()\n return new AbortError('\\nError validating auth session', \"We've cleared the current session, please try again\")\n }\n return new AbortError(error)\n}\n\nasync function tokenRequest(params: {[key: string]: string}): Promise<Result<TokenRequestResult, string>> {\n const fqdn = await identityFqdn()\n const url = new URL(`https://${fqdn}/oauth/token`)\n url.search = new URLSearchParams(Object.entries(params)).toString()\n const res = await shopifyFetch(url.href, {method: 'POST'})\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const payload: any = await res.json()\n\n if (res.ok) return ok(payload)\n return err(payload.error)\n}\n\nfunction buildIdentityToken(result: TokenRequestResult): IdentityToken {\n return {\n accessToken: result.access_token,\n refreshToken: result.refresh_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n\nfunction buildApplicationToken(result: TokenRequestResult): ApplicationToken {\n return {\n accessToken: result.access_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n"]}
1
+ {"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../src/session/exchange.ts"],"names":[],"mappings":"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","sourcesContent":["import {ApplicationToken, IdentityToken} from './schema.js'\nimport {applicationId, clientId as getIdentityClientId} from './identity.js'\nimport {CodeAuthResult} from './authorize.js'\nimport * as secureStore from './store.js'\nimport {Abort} from '../error.js'\nimport {API} from '../network/api.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport {shopifyFetch} from '../http.js'\nimport {err, ok, Result} from '../public/node/result.js'\nimport {AbortError} from '../public/node/error.js'\n\nexport class InvalidGrantError extends Error {}\n\nconst InvalidIdentityError = () =>\n new Abort('\\nError validating auth session', \"We've cleared the current session, please try again\")\n\nexport interface ExchangeScopes {\n admin: string[]\n partners: string[]\n storefront: string[]\n}\n/**\n * Given a valid authorization code, request an identity access token.\n * This token can then be used to get API specific tokens.\n * @param codeData - code and codeVerifier from the authorize endpoint\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeCodeForAccessToken(codeData: CodeAuthResult): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'authorization_code',\n code: codeData.code,\n redirect_uri: 'http://127.0.0.1:3456',\n client_id: clientId,\n code_verifier: codeData.codeVerifier,\n }\n\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n return buildIdentityToken(value)\n}\n\n/**\n * Given an identity token, request an application token.\n * @param identityToken - access token obtained in a previous step\n * @param store - the store to use, only needed for admin API\n * @returns An array with the application access tokens.\n */\nexport async function exchangeAccessForApplicationTokens(\n identityToken: IdentityToken,\n scopes: ExchangeScopes,\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const token = identityToken.accessToken\n\n const [partners, storefront] = await Promise.all([\n requestAppToken('partners', token, scopes.partners),\n requestAppToken('storefront-renderer', token, scopes.storefront),\n ])\n\n const result = {\n ...partners,\n ...storefront,\n }\n\n if (store) {\n const admin = await requestAppToken('admin', token, scopes.admin, store)\n Object.assign(result, admin)\n }\n return result\n}\n\n/**\n * Given an expired access token, refresh it to get a new one.\n */\nexport async function refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'refresh_token',\n access_token: currentToken.accessToken,\n refresh_token: currentToken.refreshToken,\n client_id: clientId,\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n return buildIdentityToken(value)\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid partners API token\n * This token does not accept extra scopes, just the cli one.\n * @param token - The CLI token passed as ENV variable\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCustomPartnerToken(token: string): Promise<ApplicationToken> {\n const appId = applicationId('partners')\n const newToken = await requestAppToken('partners', token, ['https://api.shopify.com/auth/partners.app.cli.access'])\n return newToken[appId]!\n}\n\nexport type IdentityDeviceError =\n | 'authorization_pending'\n | 'access_denied'\n | 'expired_token'\n | 'slow_down'\n | 'unknown_failure'\n\n/**\n * Given a deviceCode obtained after starting a device identity flow, request an identity token.\n * @param deviceCode - The device code obtained after starting a device identity flow\n * @param scopes - The scopes to request\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeDeviceCodeForAccessToken(\n deviceCode: string,\n): Promise<Result<IdentityToken, IdentityDeviceError>> {\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: clientId,\n }\n\n const tokenResult = await tokenRequest(params)\n if (tokenResult.isErr()) {\n return err(tokenResult.error as IdentityDeviceError)\n }\n const identityToken = buildIdentityToken(tokenResult.value)\n return ok(identityToken)\n}\n\nasync function requestAppToken(\n api: API,\n token: string,\n scopes: string[] = [],\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const appId = applicationId(api)\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',\n requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n client_id: clientId,\n audience: appId,\n scope: scopes.join(' '),\n subject_token: token,\n ...(api === 'admin' && {destination: `https://${store}/admin`}),\n }\n\n let identifier = appId\n if (api === 'admin' && store) {\n identifier = `${store}-${appId}`\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n const appToken = await buildApplicationToken(value)\n return {[identifier]: appToken}\n}\n\ninterface TokenRequestResult {\n access_token: string\n expires_in: number\n refresh_token: string\n scope: string\n}\n\nasync function tokenRequestErrorHandler(error: string) {\n if (error === 'invalid_grant') {\n // There's an scenario when Identity returns \"invalid_grant\" when trying to refresh the token\n // using a valid refresh token. When that happens, we take the user through the authentication flow.\n return new InvalidGrantError()\n }\n if (error === 'invalid_request') {\n // There's an scenario when Identity returns \"invalid_request\" when exchanging an identity token.\n // This means the token is invalid. We clear the session and throw an error to let the caller know.\n await secureStore.remove()\n return new AbortError('\\nError validating auth session', \"We've cleared the current session, please try again\")\n }\n return new AbortError(error)\n}\n\nasync function tokenRequest(params: {[key: string]: string}): Promise<Result<TokenRequestResult, string>> {\n const fqdn = await identityFqdn()\n const url = new URL(`https://${fqdn}/oauth/token`)\n url.search = new URLSearchParams(Object.entries(params)).toString()\n const res = await shopifyFetch(url.href, {method: 'POST'})\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const payload: any = await res.json()\n\n if (res.ok) return ok(payload)\n return err(payload.error)\n}\n\nfunction buildIdentityToken(result: TokenRequestResult): IdentityToken {\n return {\n accessToken: result.access_token,\n refreshToken: result.refresh_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n\nfunction buildApplicationToken(result: TokenRequestResult): ApplicationToken {\n return {\n accessToken: result.access_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { applicationId } from './identity.js';
2
2
  import constants from '../constants.js';
3
- import { identity, partners } from '../api.js';
3
+ import { identity } from '../api.js';
4
4
  import { debug } from '../output.js';
5
5
  import { firstPartyDev } from '../environment/local.js';
6
6
  /**
@@ -27,11 +27,9 @@ export async function validateSession(scopes, applications, session) {
27
27
  if (!scopesAreValid)
28
28
  return 'needs_full_auth';
29
29
  let tokensAreExpired = isTokenExpired(session.identity);
30
- let tokensAreRevoked = false;
31
30
  if (applications.partnersApi) {
32
31
  const appId = applicationId('partners');
33
32
  const token = session.applications[appId];
34
- tokensAreRevoked = tokensAreRevoked || (await isPartnersTokenRevoked(token));
35
33
  tokensAreExpired = tokensAreExpired || isTokenExpired(token);
36
34
  }
37
35
  if (applications.storefrontRendererApi) {
@@ -48,15 +46,12 @@ export async function validateSession(scopes, applications, session) {
48
46
  debug(`
49
47
  The validation of the token for application/identity completed with the following results:
50
48
  - It's expired: ${tokensAreExpired}
51
- - It's been revoked: ${tokensAreRevoked}
52
49
  - It's invalid in identity: ${!identityIsValid}
53
50
  `);
54
- if (tokensAreRevoked)
55
- return 'needs_full_auth';
56
- if (!identityIsValid)
57
- return 'needs_full_auth';
58
51
  if (tokensAreExpired)
59
52
  return 'needs_refresh';
53
+ if (!identityIsValid)
54
+ return 'needs_full_auth';
60
55
  return 'ok';
61
56
  }
62
57
  function isTokenExpired(token) {
@@ -64,11 +59,6 @@ function isTokenExpired(token) {
64
59
  return true;
65
60
  return token.expiresAt < expireThreshold();
66
61
  }
67
- async function isPartnersTokenRevoked(token) {
68
- if (!token)
69
- return false;
70
- return partners.checkIfTokenIsRevoked(token.accessToken);
71
- }
72
62
  function expireThreshold() {
73
63
  return new Date(Date.now() + constants.session.expirationTimeMarginInMinutes * 60 * 1000);
74
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/session/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAE3C,OAAO,SAAS,MAAM,iBAAiB,CAAA;AAEvC,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAC,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAA;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAIrD;;GAEG;AACH,SAAS,cAAc,CAAC,eAAyB,EAAE,QAAuB;IACxE,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAA;IACrC,IAAI,aAAa,EAAE,KAAK,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAA;IACxE,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;AACxE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAgB,EAChB,YAA+B,EAC/B,OAGC;IAED,IAAI,CAAC,OAAO;QAAE,OAAO,iBAAiB,CAAA;IACtC,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/D,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC1F,IAAI,CAAC,cAAc;QAAE,OAAO,iBAAiB,CAAA;IAC7C,IAAI,gBAAgB,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACvD,IAAI,gBAAgB,GAAG,KAAK,CAAA;IAE5B,IAAI,YAAY,CAAC,WAAW,EAAE;QAC5B,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAE,CAAA;QAC1C,gBAAgB,GAAG,gBAAgB,IAAI,CAAC,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5E,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,IAAI,YAAY,CAAC,qBAAqB,EAAE;QACtC,MAAM,KAAK,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAE,CAAA;QAC1C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,IAAI,YAAY,CAAC,QAAQ,EAAE;QACzB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QACpC,MAAM,SAAS,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,IAAI,KAAK,EAAE,CAAA;QAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAE,CAAA;QAC9C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,KAAK,CAAC;;kBAEU,gBAAgB;uBACX,gBAAgB;8BACT,CAAC,eAAe;GAC3C,CAAC,CAAA;IAEF,IAAI,gBAAgB;QAAE,OAAO,iBAAiB,CAAA;IAC9C,IAAI,CAAC,eAAe;QAAE,OAAO,iBAAiB,CAAA;IAC9C,IAAI,gBAAgB;QAAE,OAAO,eAAe,CAAA;IAC5C,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,cAAc,CAAC,KAAuB;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,SAAS,GAAG,eAAe,EAAE,CAAA;AAC5C,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,KAAuB;IAC3D,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACxB,OAAO,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;AAC1D,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,6BAA6B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;AAC3F,CAAC","sourcesContent":["import {applicationId} from './identity.js'\nimport {ApplicationToken, IdentityToken} from './schema.js'\nimport constants from '../constants.js'\nimport {OAuthApplications} from '../session.js'\nimport {identity, partners} from '../api.js'\nimport {debug} from '../output.js'\nimport {firstPartyDev} from '../environment/local.js'\n\ntype ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok'\n\n/**\n * Validate if an identity token is valid for the requested scopes\n */\nfunction validateScopes(requestedScopes: string[], identity: IdentityToken) {\n const currentScopes = identity.scopes\n if (firstPartyDev() !== currentScopes.includes('employee')) return false\n return requestedScopes.every((scope) => currentScopes.includes(scope))\n}\n\n/**\n * Validate if the current session is valid or we need to refresh/re-authenticate\n * @param scopes - requested scopes to validate\n * @param applications - requested applications\n * @param session - current session with identity and application tokens\n * @returns 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session\n */\nexport async function validateSession(\n scopes: string[],\n applications: OAuthApplications,\n session: {\n identity: IdentityToken\n applications: {[x: string]: ApplicationToken}\n },\n): Promise<ValidationResult> {\n if (!session) return 'needs_full_auth'\n const scopesAreValid = validateScopes(scopes, session.identity)\n const identityIsValid = await identity.validateIdentityToken(session.identity.accessToken)\n if (!scopesAreValid) return 'needs_full_auth'\n let tokensAreExpired = isTokenExpired(session.identity)\n let tokensAreRevoked = false\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n const token = session.applications[appId]!\n tokensAreRevoked = tokensAreRevoked || (await isPartnersTokenRevoked(token))\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n debug(`\nThe validation of the token for application/identity completed with the following results:\n- It's expired: ${tokensAreExpired}\n- It's been revoked: ${tokensAreRevoked}\n- It's invalid in identity: ${!identityIsValid}\n `)\n\n if (tokensAreRevoked) return 'needs_full_auth'\n if (!identityIsValid) return 'needs_full_auth'\n if (tokensAreExpired) return 'needs_refresh'\n return 'ok'\n}\n\nfunction isTokenExpired(token: ApplicationToken): boolean {\n if (!token) return true\n return token.expiresAt < expireThreshold()\n}\n\nasync function isPartnersTokenRevoked(token: ApplicationToken) {\n if (!token) return false\n return partners.checkIfTokenIsRevoked(token.accessToken)\n}\n\nfunction expireThreshold(): Date {\n return new Date(Date.now() + constants.session.expirationTimeMarginInMinutes * 60 * 1000)\n}\n"]}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/session/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAE3C,OAAO,SAAS,MAAM,iBAAiB,CAAA;AAEvC,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAA;AAClC,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAA;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAIrD;;GAEG;AACH,SAAS,cAAc,CAAC,eAAyB,EAAE,QAAuB;IACxE,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAA;IACrC,IAAI,aAAa,EAAE,KAAK,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAA;IACxE,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;AACxE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAgB,EAChB,YAA+B,EAC/B,OAGC;IAED,IAAI,CAAC,OAAO;QAAE,OAAO,iBAAiB,CAAA;IACtC,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/D,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC1F,IAAI,CAAC,cAAc;QAAE,OAAO,iBAAiB,CAAA;IAC7C,IAAI,gBAAgB,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAEvD,IAAI,YAAY,CAAC,WAAW,EAAE;QAC5B,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAE,CAAA;QAC1C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,IAAI,YAAY,CAAC,qBAAqB,EAAE;QACtC,MAAM,KAAK,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAE,CAAA;QAC1C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,IAAI,YAAY,CAAC,QAAQ,EAAE;QACzB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QACpC,MAAM,SAAS,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,IAAI,KAAK,EAAE,CAAA;QAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAE,CAAA;QAC9C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,KAAK,CAAC;;kBAEU,gBAAgB;8BACJ,CAAC,eAAe;GAC3C,CAAC,CAAA;IAEF,IAAI,gBAAgB;QAAE,OAAO,eAAe,CAAA;IAC5C,IAAI,CAAC,eAAe;QAAE,OAAO,iBAAiB,CAAA;IAC9C,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,cAAc,CAAC,KAAuB;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,SAAS,GAAG,eAAe,EAAE,CAAA;AAC5C,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,6BAA6B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;AAC3F,CAAC","sourcesContent":["import {applicationId} from './identity.js'\nimport {ApplicationToken, IdentityToken} from './schema.js'\nimport constants from '../constants.js'\nimport {OAuthApplications} from '../session.js'\nimport {identity} from '../api.js'\nimport {debug} from '../output.js'\nimport {firstPartyDev} from '../environment/local.js'\n\ntype ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok'\n\n/**\n * Validate if an identity token is valid for the requested scopes\n */\nfunction validateScopes(requestedScopes: string[], identity: IdentityToken) {\n const currentScopes = identity.scopes\n if (firstPartyDev() !== currentScopes.includes('employee')) return false\n return requestedScopes.every((scope) => currentScopes.includes(scope))\n}\n\n/**\n * Validate if the current session is valid or we need to refresh/re-authenticate\n * @param scopes - requested scopes to validate\n * @param applications - requested applications\n * @param session - current session with identity and application tokens\n * @returns 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session\n */\nexport async function validateSession(\n scopes: string[],\n applications: OAuthApplications,\n session: {\n identity: IdentityToken\n applications: {[x: string]: ApplicationToken}\n },\n): Promise<ValidationResult> {\n if (!session) return 'needs_full_auth'\n const scopesAreValid = validateScopes(scopes, session.identity)\n const identityIsValid = await identity.validateIdentityToken(session.identity.accessToken)\n if (!scopesAreValid) return 'needs_full_auth'\n let tokensAreExpired = isTokenExpired(session.identity)\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n debug(`\nThe validation of the token for application/identity completed with the following results:\n- It's expired: ${tokensAreExpired}\n- It's invalid in identity: ${!identityIsValid}\n `)\n\n if (tokensAreExpired) return 'needs_refresh'\n if (!identityIsValid) return 'needs_full_auth'\n return 'ok'\n}\n\nfunction isTokenExpired(token: ApplicationToken): boolean {\n if (!token) return true\n return token.expiresAt < expireThreshold()\n}\n\nfunction expireThreshold(): Date {\n return new Date(Date.now() + constants.session.expirationTimeMarginInMinutes * 60 * 1000)\n}\n"]}