@shopify/cli-kit 3.0.27 → 3.3.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 (56) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/analytics.d.ts +3 -1
  3. package/dist/analytics.js +19 -4
  4. package/dist/analytics.js.map +1 -1
  5. package/dist/api/graphql/find_store_by_domain.d.ts +21 -0
  6. package/dist/api/graphql/find_store_by_domain.js +24 -0
  7. package/dist/api/graphql/find_store_by_domain.js.map +1 -0
  8. package/dist/api/graphql/index.d.ts +1 -0
  9. package/dist/api/graphql/index.js +1 -0
  10. package/dist/api/graphql/index.js.map +1 -1
  11. package/dist/error.js +4 -0
  12. package/dist/error.js.map +1 -1
  13. package/dist/index.d.ts +0 -1
  14. package/dist/index.js +0 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/node/base-command.d.ts +6 -0
  17. package/dist/node/base-command.js +9 -0
  18. package/dist/node/base-command.js.map +1 -0
  19. package/dist/node/cli.js +5 -45
  20. package/dist/node/cli.js.map +1 -1
  21. package/dist/{colors.d.ts → node/colors.d.ts} +0 -0
  22. package/dist/{colors.js → node/colors.js} +0 -0
  23. package/dist/node/colors.js.map +1 -0
  24. package/dist/node/error-handler.d.ts +3 -0
  25. package/dist/node/error-handler.js +79 -0
  26. package/dist/node/error-handler.js.map +1 -0
  27. package/dist/node/hooks/postrun.d.ts +2 -0
  28. package/dist/node/hooks/postrun.js +6 -0
  29. package/dist/node/hooks/postrun.js.map +1 -0
  30. package/dist/node/hooks/prerun.d.ts +2 -0
  31. package/dist/node/hooks/prerun.js +9 -0
  32. package/dist/node/hooks/prerun.js.map +1 -0
  33. package/dist/{dependency.d.ts → node/node-package-manager.d.ts} +92 -23
  34. package/dist/{dependency.js → node/node-package-manager.js} +56 -49
  35. package/dist/node/node-package-manager.js.map +1 -0
  36. package/dist/node/ruby.js +1 -1
  37. package/dist/node/ruby.js.map +1 -1
  38. package/dist/output.d.ts +9 -2
  39. package/dist/output.js +17 -7
  40. package/dist/output.js.map +1 -1
  41. package/dist/port.js +23 -1
  42. package/dist/port.js.map +1 -1
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/dist/ui/autocomplete.js +1 -1
  45. package/dist/ui/autocomplete.js.map +1 -1
  46. package/dist/ui/input.js +1 -1
  47. package/dist/ui/input.js.map +1 -1
  48. package/dist/ui/select.js +1 -1
  49. package/dist/ui/select.js.map +1 -1
  50. package/dist/ui.js +3 -3
  51. package/dist/ui.js.map +1 -1
  52. package/dist/version.js +1 -1
  53. package/dist/version.js.map +1 -1
  54. package/package.json +8 -4
  55. package/dist/colors.js.map +0 -1
  56. package/dist/dependency.js.map +0 -1
@@ -1,37 +1,57 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { Abort, Bug } from './error.js';
3
+ import { Abort, Bug } from '../error.js';
4
4
  import { AbortSignal } from 'abort-controller';
5
5
  import type { Writable } from 'node:stream';
6
- export declare const genericConfigurationFileNames: {
7
- readonly yarn: {
8
- readonly lockfile: "yarn.lock";
9
- };
10
- readonly pnpm: {
11
- readonly lockfile: "pnpm-lock.yaml";
12
- };
13
- };
14
- export declare const dependencyManager: readonly ["yarn", "npm", "pnpm"];
15
- export declare type DependencyManager = typeof dependencyManager[number];
6
+ /** The name of the Yarn lock file */
7
+ export declare const yarnLockfile = "yarn.lock";
8
+ /** The name of the pnpm lock file */
9
+ export declare const pnpmLockfile = "pnpm-lock.yaml";
10
+ /** An array containing the lockfiles from all the package managers */
11
+ export declare const lockfiles: string[];
12
+ /**
13
+ * A union type that represents the type of dependencies in the package.json
14
+ * - dev: devDependencies
15
+ * - prod: dependencies
16
+ * - peer: peerDependencies
17
+ */
18
+ export declare type DependencyType = 'dev' | 'prod' | 'peer';
19
+ /**
20
+ * A union that represents the package managers available.
21
+ */
22
+ export declare const packageManager: readonly ["yarn", "npm", "pnpm"];
23
+ export declare type PackageManager = typeof packageManager[number];
24
+ /**
25
+ * Returns an abort error that's thrown when a directory that's expected to have
26
+ * a package.json doesn't have it.
27
+ * @param directory {string} The path to the directory that should contain a package.json
28
+ * @returns {Abort} An abort error.
29
+ */
16
30
  export declare const PackageJsonNotFoundError: (directory: string) => Abort;
31
+ /**
32
+ * Returns a bug error that's thrown when the lookup of the package.json traversing the directory
33
+ * hierarchy up can't find a package.json
34
+ * @param directory {string} The directory from which the traverse has been done
35
+ * @returns {Abort} An abort error.
36
+ */
17
37
  export declare const FindUpAndReadPackageJsonNotFoundError: (directory: string) => Bug;
18
38
  /**
19
39
  * Returns the dependency manager used to run the create workflow.
20
40
  * @param env {Object} The environment variables of the process in which the CLI runs.
21
41
  * @returns The dependency manager
22
42
  */
23
- export declare function dependencyManagerUsedForCreating(env?: NodeJS.ProcessEnv): DependencyManager;
43
+ export declare function packageManagerUsedForCreating(env?: NodeJS.ProcessEnv): PackageManager;
24
44
  /**
25
45
  * Returns the dependency manager used by an existing project.
26
46
  * @param directory {string} The root directory of the project.
27
47
  * @returns The dependency manager
28
48
  */
29
- export declare function getDependencyManager(directory: string): Promise<DependencyManager>;
49
+ export declare function getPackageManager(directory: string): Promise<PackageManager>;
30
50
  interface InstallNPMDependenciesRecursivelyOptions {
31
51
  /**
32
52
  * The dependency manager to use to install the dependencies.
33
53
  */
34
- dependencyManager: DependencyManager;
54
+ packageManager: PackageManager;
35
55
  /**
36
56
  * The directory from where we'll find package.json's recursively
37
57
  */
@@ -51,13 +71,13 @@ export declare function installNPMDependenciesRecursively(options: InstallNPMDep
51
71
  /**
52
72
  * Installs the dependencies in the given directory.
53
73
  * @param directory {string} The directory that contains the package.json
54
- * @param dependencyManager {DependencyManager} The dependency manager to use to install the dependencies.
74
+ * @param packageManager {PackageManager} The package manager to use to install the dependencies.
55
75
  * @param stdout {Writable} Standard output stream.
56
76
  * @param stderr {Writable} Standard error stream.
57
77
  * @param signal {AbortSignal} Abort signal.
58
78
  * @returns stderr {Writable} Standard error stream.
59
79
  */
60
- export declare function install(directory: string, dependencyManager: DependencyManager, stdout?: Writable, stderr?: Writable, signal?: AbortSignal): Promise<void>;
80
+ export declare function installNodeModules(directory: string, packageManager: PackageManager, stdout?: Writable, stderr?: Writable, signal?: AbortSignal): Promise<void>;
61
81
  /**
62
82
  * Returns the name of the package configured in its package.json
63
83
  * @param packageJsonPath {string} Path to the package.json file
@@ -72,25 +92,55 @@ export declare function getPackageName(packageJsonPath: string): Promise<string>
72
92
  export declare function getDependencies(packageJsonPath: string): Promise<{
73
93
  [key: string]: string;
74
94
  }>;
95
+ /**
96
+ * Given an NPM dependency, it checks if there's a more recent version, and if there is, it returns its value.
97
+ * @param dependency {string} The dependency name (e.g. react)
98
+ * @param currentVersion {string} The current version.
99
+ * @returns {Promise<string>} A promise that resolves with a more recent version or undefined if there's no more recent version.
100
+ */
75
101
  export declare function checkForNewVersion(dependency: string, currentVersion: string): Promise<string | undefined>;
76
- export declare function getOutputUpdateCLIReminder(dependencyManager: DependencyManager, version: string): string;
77
- interface PackageJSONContents {
102
+ /**
103
+ * An interface that represents a package.json
104
+ */
105
+ interface PackageJson {
106
+ /**
107
+ * The absolute path to the package.json
108
+ */
109
+ path: string;
110
+ /**
111
+ * The name attribute of the package.json
112
+ */
78
113
  name: string;
114
+ /**
115
+ * The version attribute of the package.json
116
+ */
79
117
  version?: string;
118
+ /**
119
+ * The dependencies attribute of the package.json
120
+ */
80
121
  dependencies?: {
81
122
  [key: string]: string;
82
123
  };
124
+ /**
125
+ * The devDependencies attribute of the package.json
126
+ */
83
127
  devDependencies?: {
84
128
  [key: string]: string;
85
129
  };
86
130
  }
87
- export declare function packageJSONContents(packageJsonPath: string): Promise<PackageJSONContents>;
88
- export declare type DependencyType = 'dev' | 'prod' | 'peer';
131
+ /**
132
+ * Reads and parses a package.json
133
+ * @param packageJsonPath {string} Path to the package.json
134
+ * @returns {Promise<PackageJson>} An promise that resolves with an in-memory representation
135
+ * of the package.json or rejects with an error if the file is not found or the content is
136
+ * not decodable.
137
+ */
138
+ export declare function readAndParsePackageJson(packageJsonPath: string): Promise<PackageJson>;
89
139
  interface AddNPMDependenciesIfNeededOptions {
90
140
  /** How dependencies should be added */
91
141
  type: DependencyType;
92
142
  /** The dependency manager to use to add dependencies */
93
- dependencyManager: DependencyManager;
143
+ packageManager: PackageManager;
94
144
  /** The directory that contains the package.json where dependencies will be added */
95
145
  directory: string;
96
146
  /** Standard output coming from the underlying installation process */
@@ -100,8 +150,29 @@ interface AddNPMDependenciesIfNeededOptions {
100
150
  /** Abort signal to stop the process */
101
151
  signal?: AbortSignal;
102
152
  }
153
+ /**
154
+ * An interface that represents a dependency name with its version
155
+ */
103
156
  export interface DependencyVersion {
157
+ /**
158
+ * The name of the NPM dependency as it's reflected in the package.json:
159
+ *
160
+ * @example
161
+ * In the example below name would be "react"
162
+ * {
163
+ * "react": "1.2.3"
164
+ * }
165
+ */
104
166
  name: string;
167
+ /**
168
+ * The version of the NPM dependency as it's reflected in the package.json:
169
+ *
170
+ * @example
171
+ * In the example below version would be "1.2.3"
172
+ * {
173
+ * "react": "1.2.3"
174
+ * }
175
+ */
105
176
  version: string | undefined;
106
177
  }
107
178
  /**
@@ -112,8 +183,6 @@ export interface DependencyVersion {
112
183
  export declare function addNPMDependenciesIfNeeded(dependencies: DependencyVersion[], options: AddNPMDependenciesIfNeededOptions, force?: boolean): Promise<void>;
113
184
  export declare function addNPMDependenciesWithoutVersionIfNeeded(dependencies: string[], options: AddNPMDependenciesIfNeededOptions): Promise<void>;
114
185
  export declare function addLatestNPMDependencies(dependencies: string[], options: AddNPMDependenciesIfNeededOptions): Promise<void>;
115
- export declare type ProjectType = 'node' | 'php' | 'ruby' | undefined;
116
- export declare function getProjectType(directory: string): Promise<ProjectType>;
117
186
  /**
118
187
  * Given a directory it traverses the directory up looking for a package.json and if found, it reads it
119
188
  * decodes the JSON, and returns its content as a Javascript object.
@@ -1,23 +1,36 @@
1
- import { exec } from './system.js';
2
- import { exists as fileExists, read as readFile } from './file.js';
3
- import { glob, dirname, join as pathJoin, findUp } from './path.js';
4
- import { Abort, Bug } from './error.js';
5
- import { latestNpmPackageVersion } from './version.js';
6
- import { Version } from './semver.js';
7
- import { content, token, debug } from './output.js';
1
+ import { exec } from '../system.js';
2
+ import { exists as fileExists, read as readFile } from '../file.js';
3
+ import { glob, dirname, join as pathJoin, findUp } from '../path.js';
4
+ import { Abort, Bug } from '../error.js';
5
+ import { latestNpmPackageVersion } from '../version.js';
6
+ import { Version } from '../semver.js';
7
+ import { content, token, debug } from '../output.js';
8
8
  import { AbortController } from 'abort-controller';
9
- export const genericConfigurationFileNames = {
10
- yarn: {
11
- lockfile: 'yarn.lock',
12
- },
13
- pnpm: {
14
- lockfile: 'pnpm-lock.yaml',
15
- },
16
- };
17
- export const dependencyManager = ['yarn', 'npm', 'pnpm'];
9
+ /** The name of the Yarn lock file */
10
+ export const yarnLockfile = 'yarn.lock';
11
+ /** The name of the pnpm lock file */
12
+ export const pnpmLockfile = 'pnpm-lock.yaml';
13
+ /** An array containing the lockfiles from all the package managers */
14
+ export const lockfiles = [yarnLockfile, pnpmLockfile];
15
+ /**
16
+ * A union that represents the package managers available.
17
+ */
18
+ export const packageManager = ['yarn', 'npm', 'pnpm'];
19
+ /**
20
+ * Returns an abort error that's thrown when a directory that's expected to have
21
+ * a package.json doesn't have it.
22
+ * @param directory {string} The path to the directory that should contain a package.json
23
+ * @returns {Abort} An abort error.
24
+ */
18
25
  export const PackageJsonNotFoundError = (directory) => {
19
26
  return new Abort(`The directory ${directory} doesn't have a package.json.`);
20
27
  };
28
+ /**
29
+ * Returns a bug error that's thrown when the lookup of the package.json traversing the directory
30
+ * hierarchy up can't find a package.json
31
+ * @param directory {string} The directory from which the traverse has been done
32
+ * @returns {Abort} An abort error.
33
+ */
21
34
  export const FindUpAndReadPackageJsonNotFoundError = (directory) => {
22
35
  return new Bug(content `Couldn't find a a package.json traversing directories from ${token.path(directory)}`);
23
36
  };
@@ -26,7 +39,7 @@ export const FindUpAndReadPackageJsonNotFoundError = (directory) => {
26
39
  * @param env {Object} The environment variables of the process in which the CLI runs.
27
40
  * @returns The dependency manager
28
41
  */
29
- export function dependencyManagerUsedForCreating(env = process.env) {
42
+ export function packageManagerUsedForCreating(env = process.env) {
30
43
  if (env.npm_config_user_agent?.includes('yarn')) {
31
44
  return 'yarn';
32
45
  }
@@ -42,10 +55,10 @@ export function dependencyManagerUsedForCreating(env = process.env) {
42
55
  * @param directory {string} The root directory of the project.
43
56
  * @returns The dependency manager
44
57
  */
45
- export async function getDependencyManager(directory) {
58
+ export async function getPackageManager(directory) {
46
59
  debug(content `Obtaining the dependency manager in directory ${token.path(directory)}...`);
47
- const yarnLockPath = pathJoin(directory, genericConfigurationFileNames.yarn.lockfile);
48
- const pnpmLockPath = pathJoin(directory, genericConfigurationFileNames.pnpm.lockfile);
60
+ const yarnLockPath = pathJoin(directory, yarnLockfile);
61
+ const pnpmLockPath = pathJoin(directory, pnpmLockfile);
49
62
  if (await fileExists(yarnLockPath)) {
50
63
  return 'yarn';
51
64
  }
@@ -73,7 +86,7 @@ export async function installNPMDependenciesRecursively(options) {
73
86
  try {
74
87
  await Promise.all(packageJsons.map(async (packageJsonPath) => {
75
88
  const directory = dirname(packageJsonPath);
76
- await install(directory, options.dependencyManager, undefined, undefined, abortController.signal);
89
+ await installNodeModules(directory, options.packageManager, undefined, undefined, abortController.signal);
77
90
  }));
78
91
  }
79
92
  catch (error) {
@@ -84,15 +97,15 @@ export async function installNPMDependenciesRecursively(options) {
84
97
  /**
85
98
  * Installs the dependencies in the given directory.
86
99
  * @param directory {string} The directory that contains the package.json
87
- * @param dependencyManager {DependencyManager} The dependency manager to use to install the dependencies.
100
+ * @param packageManager {PackageManager} The package manager to use to install the dependencies.
88
101
  * @param stdout {Writable} Standard output stream.
89
102
  * @param stderr {Writable} Standard error stream.
90
103
  * @param signal {AbortSignal} Abort signal.
91
104
  * @returns stderr {Writable} Standard error stream.
92
105
  */
93
- export async function install(directory, dependencyManager, stdout, stderr, signal) {
106
+ export async function installNodeModules(directory, packageManager, stdout, stderr, signal) {
94
107
  const options = { cwd: directory, stdin: undefined, stdout, stderr, signal };
95
- await exec(dependencyManager, ['install'], options);
108
+ await exec(packageManager, ['install'], options);
96
109
  }
97
110
  /**
98
111
  * Returns the name of the package configured in its package.json
@@ -100,7 +113,7 @@ export async function install(directory, dependencyManager, stdout, stderr, sign
100
113
  * @returns A promise that resolves with the name.
101
114
  */
102
115
  export async function getPackageName(packageJsonPath) {
103
- const packageJsonContent = await packageJSONContents(packageJsonPath);
116
+ const packageJsonContent = await readAndParsePackageJson(packageJsonPath);
104
117
  return packageJsonContent.name;
105
118
  }
106
119
  /**
@@ -109,11 +122,17 @@ export async function getPackageName(packageJsonPath) {
109
122
  * @returns A promise that resolves with the list of dependencies.
110
123
  */
111
124
  export async function getDependencies(packageJsonPath) {
112
- const packageJsonContent = await packageJSONContents(packageJsonPath);
125
+ const packageJsonContent = await readAndParsePackageJson(packageJsonPath);
113
126
  const dependencies = packageJsonContent.dependencies ?? {};
114
127
  const devDependencies = packageJsonContent.devDependencies ?? {};
115
128
  return { ...dependencies, ...devDependencies };
116
129
  }
130
+ /**
131
+ * Given an NPM dependency, it checks if there's a more recent version, and if there is, it returns its value.
132
+ * @param dependency {string} The dependency name (e.g. react)
133
+ * @param currentVersion {string} The current version.
134
+ * @returns {Promise<string>} A promise that resolves with a more recent version or undefined if there's no more recent version.
135
+ */
117
136
  export async function checkForNewVersion(dependency, currentVersion) {
118
137
  debug(content `Checking if there's a version of ${dependency} newer than ${currentVersion}`);
119
138
  try {
@@ -130,11 +149,14 @@ export async function checkForNewVersion(dependency, currentVersion) {
130
149
  return undefined;
131
150
  }
132
151
  }
133
- export function getOutputUpdateCLIReminder(dependencyManager, version) {
134
- const updateCommand = token.packagejsonScript(dependencyManager, 'shopify', 'upgrade');
135
- return content `💡 Version ${version} available! Run ${updateCommand}`.value;
136
- }
137
- export async function packageJSONContents(packageJsonPath) {
152
+ /**
153
+ * Reads and parses a package.json
154
+ * @param packageJsonPath {string} Path to the package.json
155
+ * @returns {Promise<PackageJson>} An promise that resolves with an in-memory representation
156
+ * of the package.json or rejects with an error if the file is not found or the content is
157
+ * not decodable.
158
+ */
159
+ export async function readAndParsePackageJson(packageJsonPath) {
138
160
  if (!(await fileExists(packageJsonPath))) {
139
161
  throw PackageJsonNotFoundError(dirname(packageJsonPath));
140
162
  }
@@ -169,7 +191,7 @@ ${token.json(options)}
169
191
  const depedenciesWithVersion = dependenciesToAdd.map((dep) => {
170
192
  return dep.version ? `${dep.name}@${dep.version}` : dep.name;
171
193
  });
172
- switch (options.dependencyManager) {
194
+ switch (options.packageManager) {
173
195
  case 'npm':
174
196
  args = argumentsToAddDependenciesWithNPM(depedenciesWithVersion, options.type);
175
197
  break;
@@ -181,7 +203,7 @@ ${token.json(options)}
181
203
  break;
182
204
  }
183
205
  options.stdout?.write(`Executing...${args.join(' ')}`);
184
- await exec(options.dependencyManager, args, {
206
+ await exec(options.packageManager, args, {
185
207
  cwd: options.directory,
186
208
  stdout: options.stdout,
187
209
  stderr: options.stderr,
@@ -267,21 +289,6 @@ function argumentsToAddDependenciesWithPNPM(dependencies, type) {
267
289
  }
268
290
  return command;
269
291
  }
270
- export async function getProjectType(directory) {
271
- const nodeConfigFile = pathJoin(directory, 'package.json');
272
- const rubyConfigFile = pathJoin(directory, 'Gemfile');
273
- const phpConfigFile = pathJoin(directory, 'composer.json');
274
- if (await fileExists(nodeConfigFile)) {
275
- return 'node';
276
- }
277
- else if (await fileExists(rubyConfigFile)) {
278
- return 'ruby';
279
- }
280
- else if (await fileExists(phpConfigFile)) {
281
- return 'php';
282
- }
283
- return undefined;
284
- }
285
292
  /**
286
293
  * Given a directory it traverses the directory up looking for a package.json and if found, it reads it
287
294
  * decodes the JSON, and returns its content as a Javascript object.
@@ -299,4 +306,4 @@ export async function findUpAndReadPackageJson(fromDirectory) {
299
306
  throw FindUpAndReadPackageJsonNotFoundError(fromDirectory);
300
307
  }
301
308
  }
302
- //# sourceMappingURL=dependency.js.map
309
+ //# sourceMappingURL=node-package-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-package-manager.js","sourceRoot":"","sources":["../../src/node/node-package-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,cAAc,CAAA;AACjC,OAAO,EAAC,MAAM,IAAI,UAAU,EAAE,IAAI,IAAI,QAAQ,EAAC,MAAM,YAAY,CAAA;AACjE,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,EAAC,MAAM,YAAY,CAAA;AAClE,OAAO,EAAC,KAAK,EAAE,GAAG,EAAC,MAAM,aAAa,CAAA;AACtC,OAAO,EAAC,uBAAuB,EAAC,MAAM,eAAe,CAAA;AACrD,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AACpC,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AAClD,OAAO,EAAC,eAAe,EAAc,MAAM,kBAAkB,CAAA;AAI7D,qCAAqC;AACrC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAA;AAEvC,qCAAqC;AACrC,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAA;AAE5C,sEAAsE;AACtE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;AAUrD;;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,EAAE,EAAE;IAC5D,OAAO,IAAI,KAAK,CAAC,iBAAiB,SAAS,+BAA+B,CAAC,CAAA;AAC7E,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC,SAAiB,EAAE,EAAE;IACzE,OAAO,IAAI,GAAG,CAAC,OAAO,CAAA,8DAA8D,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;AAC9G,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;QACL,OAAO,KAAK,CAAA;KACb;AACH,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,CAAC,OAAiD;IACvG,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,SAAS,EAAE,OAAO,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,CAAC,MAAM,CAAC,CAAA;QAC3G,CAAC,CAAC,CACH,CAAA;KACF;IAAC,OAAO,KAAK,EAAE;QACd,eAAe,CAAC,KAAK,EAAE,CAAA;QACvB,MAAM,KAAK,CAAA;KACZ;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,cAA8B,EAC9B,MAAiB,EACjB,MAAiB,EACjB,MAAoB;IAEpB,MAAM,OAAO,GAAgB,EAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAC,CAAA;IACvF,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAA;AAClD,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,kBAAkB,CAAC,UAAkB,EAAE,cAAsB;IACjF,KAAK,CAAC,OAAO,CAAA,oCAAoC,UAAU,eAAe,cAAc,EAAE,CAAC,CAAA;IAC3F,IAAI;QACF,MAAM,WAAW,GAAG,MAAM,uBAAuB,CAAC,UAAU,CAAC,CAAA;QAC7D,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;AAgCD;;;;;;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;AAiDD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,YAAiC,EACjC,OAA0C,EAC1C,KAAK,GAAG,KAAK;IAEb,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,IAAI,CAAC,KAAK,EAAE;QACV,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YAC9C,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjD,CAAC,CAAC,CAAA;KACH;IACD,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE;QAClC,OAAM;KACP;IACD,IAAI,IAAc,CAAA;IAClB,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3D,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,eAAe,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACtD,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,+CAA+C;AAC/C,+EAA+E;AAC/E,wDAAwD;AACxD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,YAAsB,EAAE,OAA0C;IAC/G,MAAM,0BAA0B,CAC9B,YAAY,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QAC9B,OAAO,EAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAC,CAAA;IAC9C,CAAC,CAAC,EACF,OAAO,EACP,IAAI,CACL,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","sourcesContent":["import {exec} from '../system.js'\nimport {exists as fileExists, read as readFile} from '../file.js'\nimport {glob, dirname, join as pathJoin, findUp} from '../path.js'\nimport {Abort, Bug} from '../error.js'\nimport {latestNpmPackageVersion} from '../version.js'\nimport {Version} from '../semver.js'\nimport {content, token, debug} from '../output.js'\nimport {AbortController, AbortSignal} from 'abort-controller'\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 pnpm lock file */\nexport const pnpmLockfile = 'pnpm-lock.yaml'\n\n/** An array containing the lockfiles from all the package managers */\nexport const lockfiles = [yarnLockfile, pnpmLockfile]\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 {string} The path to the directory that should contain a package.json\n * @returns {Abort} An abort error.\n */\nexport const PackageJsonNotFoundError = (directory: string) => {\n return new Abort(`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 {string} The directory from which the traverse has been done\n * @returns {Abort} An abort error.\n */\nexport const FindUpAndReadPackageJsonNotFoundError = (directory: string) => {\n return new Bug(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 {Object} The environment variables of the process in which the CLI runs.\n * @returns The dependency manager\n */\nexport function packageManagerUsedForCreating(env = process.env): PackageManager {\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 {\n return 'npm'\n }\n}\n\n/**\n * Returns the dependency manager used by an existing project.\n * @param directory {string} 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 {InstallNPMDependenciesRecursivelyOptions} 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(directory, options.packageManager, undefined, undefined, abortController.signal)\n }),\n )\n } catch (error) {\n abortController.abort()\n throw error\n }\n}\n\n/**\n * Installs the dependencies in the given directory.\n * @param directory {string} The directory that contains the package.json\n * @param packageManager {PackageManager} The package manager to use to install the dependencies.\n * @param stdout {Writable} Standard output stream.\n * @param stderr {Writable} Standard error stream.\n * @param signal {AbortSignal} Abort signal.\n * @returns stderr {Writable} Standard error stream.\n */\nexport async function installNodeModules(\n directory: string,\n packageManager: PackageManager,\n stdout?: Writable,\n stderr?: Writable,\n signal?: AbortSignal,\n) {\n const options: ExecOptions = {cwd: directory, stdin: undefined, stdout, stderr, signal}\n await exec(packageManager, ['install'], options)\n}\n\n/**\n * Returns the name of the package configured in its package.json\n * @param packageJsonPath {string} Path to the package.json file\n * @returns A promise that resolves with the name.\n */\nexport async function getPackageName(packageJsonPath: string): Promise<string> {\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 {string} 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 * Given an NPM dependency, it checks if there's a more recent version, and if there is, it returns its value.\n * @param dependency {string} The dependency name (e.g. react)\n * @param currentVersion {string} The current version.\n * @returns {Promise<string>} 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 latestNpmPackageVersion(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 */\ninterface PackageJson {\n /**\n * The absolute path to the package.json\n */\n path: string\n\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/**\n * Reads and parses a package.json\n * @param packageJsonPath {string} Path to the package.json\n * @returns {Promise<PackageJson>} 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 * \"react\": \"1.2.3\"\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 * \"react\": \"1.2.3\"\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 {string[]} List of dependencies to be added.\n * @param options {AddNPMDependenciesIfNeededOptions} Options for adding dependencies.\n */\nexport async function addNPMDependenciesIfNeeded(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n force = false,\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 if (!force) {\n dependenciesToAdd = dependencies.filter((dep) => {\n return !existingDependencies.includes(dep.name)\n })\n }\n if (dependenciesToAdd.length === 0) {\n return\n }\n let args: string[]\n const depedenciesWithVersion = dependenciesToAdd.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...${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// eslint-disable-next-line no-warning-comments\n// TODO: Switch it around so add-if-needed depends on this, rather than calling\n// if-needed with force: true which is counterintuitive.\nexport async function addLatestNPMDependencies(dependencies: string[], options: AddNPMDependenciesIfNeededOptions) {\n await addNPMDependenciesIfNeeded(\n dependencies.map((dependency) => {\n return {name: dependency, version: 'latest'}\n }),\n options,\n true,\n )\n}\n\n/**\n * Returns the arguments to add dependencies using NPM.\n * @param dependencies {string[]} The list of dependencies to add\n * @param type {DependencyType} The dependency type.\n * @returns {string[]} 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 {string[]} The list of dependencies to add\n * @param type {DependencyType} The dependency type.\n * @returns {string[]} 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 {string[]} The list of dependencies to add\n * @param type {DependencyType} The dependency type.\n * @returns {string[]} 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 {string} The directory from which traverse up.\n * @returns {Promise<{path: string; content: unknown}>} 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"]}
package/dist/node/ruby.js CHANGED
@@ -10,7 +10,7 @@ import { content, token } from '../output.js';
10
10
  import { spawn } from 'child_process';
11
11
  import { Writable } from 'node:stream';
12
12
  const RubyCLIVersion = '2.16.0';
13
- const ThemeCheckVersion = '1.10.2';
13
+ const ThemeCheckVersion = '1.10.3';
14
14
  const MinBundlerVersion = '2.3.8';
15
15
  const MinRubyVersion = '2.3.0';
16
16
  const MinRubyGemVersion = '2.5.0';
@@ -1 +1 @@
1
- {"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../src/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import * as file from '../file.js'\nimport * as ui from '../ui.js'\nimport * as system from '../system.js'\nimport {Abort} from '../error.js'\nimport {glob, join} from '../path.js'\nimport constants from '../constants.js'\nimport {coerce} from '../semver.js'\nimport {AdminSession} from '../session.js'\nimport {content, token} from '../output.js'\n// eslint-disable-next-line no-restricted-imports\nimport {spawn} from 'child_process'\nimport {Writable} from 'node:stream'\n\nconst RubyCLIVersion = '2.16.0'\nconst ThemeCheckVersion = '1.10.2'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.3.0'\nconst MinRubyGemVersion = '2.5.0'\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 {string[]} List of argumets to execute. (ex: ['theme', 'pull'])\n * @param adminSession {AdminSession} Contains token and store to pass to CLI 2.0, which will be set as environment variables\n */\nexport async function execCLI2(args: string[], adminSession?: AdminSession) {\n await installCLIDependencies()\n const env = {\n ...process.env,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,\n SHOPIFY_CLI_STORE: adminSession?.storeFqdn,\n }\n\n spawn('bundle', ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: shopifyCLIDirectory(),\n shell: true,\n env,\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 {ExecThemeCheckCLIOptions} Options to customize the execution of theme-check.\n * @returns {Promise<void>} 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('bundle', ['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 await validateRubyEnv()\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n },\n },\n ],\n {renderer},\n )\n await list.run()\n}\n\nasync function validateRubyEnv() {\n await validateRuby()\n await validateRubyGems()\n await validateBundler()\n}\n\nasync function validateRuby() {\n let version\n try {\n const stdout = await system.captureOutput('ruby', ['-v'])\n version = coerce(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('', '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('', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\nasync function validateRubyGems() {\n const stdout = await system.captureOutput('gem', ['-v'])\n const version = coerce(stdout)\n\n const isValid = version?.compare(MinRubyGemVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `RubyGems version ${content`${token.yellow(version!.raw)}`.value} is not supported`,\n `To update to the latest version of RubyGems, run ${\n content`${token.genericShellCommand('gem update --system')}`.value\n }`,\n )\n }\n}\n\nasync function validateBundler() {\n let version\n try {\n const stdout = await system.captureOutput('bundler', ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand('gem 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('gem 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 await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'shopify-cli', '${RubyCLIVersion}'`)\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 bundleInstallShopifyCLI() {\n await system.exec('bundle', ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {cwd: shopifyCLIDirectory()})\n await system.exec('bundle', ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallThemeCheck() {\n await system.exec('bundle', ['config', 'set', '--local', 'path', themeCheckDirectory()], {cwd: themeCheckDirectory()})\n await system.exec('bundle', ['install'], {cwd: themeCheckDirectory()})\n}\n\nfunction shopifyCLIDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\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('ruby', ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n"]}
1
+ {"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../src/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import * as file from '../file.js'\nimport * as ui from '../ui.js'\nimport * as system from '../system.js'\nimport {Abort} from '../error.js'\nimport {glob, join} from '../path.js'\nimport constants from '../constants.js'\nimport {coerce} from '../semver.js'\nimport {AdminSession} from '../session.js'\nimport {content, token} from '../output.js'\n// eslint-disable-next-line no-restricted-imports\nimport {spawn} from 'child_process'\nimport {Writable} from 'node:stream'\n\nconst RubyCLIVersion = '2.16.0'\nconst ThemeCheckVersion = '1.10.3'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.3.0'\nconst MinRubyGemVersion = '2.5.0'\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 {string[]} List of argumets to execute. (ex: ['theme', 'pull'])\n * @param adminSession {AdminSession} Contains token and store to pass to CLI 2.0, which will be set as environment variables\n */\nexport async function execCLI2(args: string[], adminSession?: AdminSession) {\n await installCLIDependencies()\n const env = {\n ...process.env,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,\n SHOPIFY_CLI_STORE: adminSession?.storeFqdn,\n }\n\n spawn('bundle', ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: shopifyCLIDirectory(),\n shell: true,\n env,\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 {ExecThemeCheckCLIOptions} Options to customize the execution of theme-check.\n * @returns {Promise<void>} 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('bundle', ['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 await validateRubyEnv()\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n },\n },\n ],\n {renderer},\n )\n await list.run()\n}\n\nasync function validateRubyEnv() {\n await validateRuby()\n await validateRubyGems()\n await validateBundler()\n}\n\nasync function validateRuby() {\n let version\n try {\n const stdout = await system.captureOutput('ruby', ['-v'])\n version = coerce(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('', '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('', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\nasync function validateRubyGems() {\n const stdout = await system.captureOutput('gem', ['-v'])\n const version = coerce(stdout)\n\n const isValid = version?.compare(MinRubyGemVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `RubyGems version ${content`${token.yellow(version!.raw)}`.value} is not supported`,\n `To update to the latest version of RubyGems, run ${\n content`${token.genericShellCommand('gem update --system')}`.value\n }`,\n )\n }\n}\n\nasync function validateBundler() {\n let version\n try {\n const stdout = await system.captureOutput('bundler', ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand('gem 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('gem 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 await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'shopify-cli', '${RubyCLIVersion}'`)\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 bundleInstallShopifyCLI() {\n await system.exec('bundle', ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {cwd: shopifyCLIDirectory()})\n await system.exec('bundle', ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallThemeCheck() {\n await system.exec('bundle', ['config', 'set', '--local', 'path', themeCheckDirectory()], {cwd: themeCheckDirectory()})\n await system.exec('bundle', ['install'], {cwd: themeCheckDirectory()})\n}\n\nfunction shopifyCLIDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\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('ruby', ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n"]}
package/dist/output.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { Fatal } from './error.js';
3
- import { DependencyManager } from './dependency.js';
3
+ import { PackageManager } from './node/node-package-manager.js';
4
4
  import { AbortSignal } from 'abort-controller';
5
5
  import { Writable } from 'node:stream';
6
6
  export declare function initiateLogging({ logDir, filename, }: {
@@ -45,7 +45,7 @@ export declare const token: {
45
45
  yellow: (value: Message) => ContentToken;
46
46
  magenta: (value: Message) => ContentToken;
47
47
  green: (value: Message) => ContentToken;
48
- packagejsonScript: (dependencyManager: DependencyManager, scriptName: string, ...scriptArgs: string[]) => ContentToken;
48
+ packagejsonScript: (packageManager: PackageManager, scriptName: string, ...scriptArgs: string[]) => ContentToken;
49
49
  successIcon: () => ContentToken;
50
50
  failIcon: () => ContentToken;
51
51
  };
@@ -139,4 +139,11 @@ export declare function logToFile(message: string, logLevel: string): void;
139
139
  export declare function unstyled(message: string): string;
140
140
  export declare function shouldDisplayColors(): boolean;
141
141
  export declare function pageLogs(): Promise<void>;
142
+ /**
143
+ *
144
+ * @param packageManager {PackageManager} The package manager that is being used.
145
+ * @param version {string} The version to update to
146
+ * @returns {te}
147
+ */
148
+ export declare function getOutputUpdateCLIReminder(packageManager: PackageManager, version: string): string;
142
149
  export {};
package/dist/output.js CHANGED
@@ -5,7 +5,7 @@ import constants from './constants.js';
5
5
  import { append as fileAppend, mkdirSync as fileMkdirSync, readSync as fileReadSync, sizeSync as fileSizeSync, writeSync as fileWriteSync, touchSync as fileTouchSync, } from './file.js';
6
6
  import { join as pathJoin, relativize as relativizePath } from './path.js';
7
7
  import { page } from './system.js';
8
- import { colors } from './colors.js';
8
+ import { colors } from './node/colors.js';
9
9
  import terminalLink from 'terminal-link';
10
10
  import StackTracey from 'stacktracey';
11
11
  import { AbortController } from 'abort-controller';
@@ -99,8 +99,8 @@ export const token = {
99
99
  green: (value) => {
100
100
  return new ContentToken(value, {}, ContentTokenType.Green);
101
101
  },
102
- packagejsonScript: (dependencyManager, scriptName, ...scriptArgs) => {
103
- return new ContentToken(formatPackageManagerCommand(dependencyManager, scriptName, scriptArgs), {}, ContentTokenType.Command);
102
+ packagejsonScript: (packageManager, scriptName, ...scriptArgs) => {
103
+ return new ContentToken(formatPackageManagerCommand(packageManager, scriptName, scriptArgs), {}, ContentTokenType.Command);
104
104
  },
105
105
  successIcon: () => {
106
106
  return new ContentToken('✔', {}, ContentTokenType.Green);
@@ -109,15 +109,15 @@ export const token = {
109
109
  return new ContentToken('✖', {}, ContentTokenType.ErrorText);
110
110
  },
111
111
  };
112
- function formatPackageManagerCommand(dependencyManager, scriptName, scriptArgs) {
113
- switch (dependencyManager) {
112
+ function formatPackageManagerCommand(packageManager, scriptName, scriptArgs) {
113
+ switch (packageManager) {
114
114
  case 'yarn': {
115
115
  const pieces = ['yarn', scriptName, ...scriptArgs];
116
116
  return pieces.join(' ');
117
117
  }
118
118
  case 'pnpm':
119
119
  case 'npm': {
120
- const pieces = [dependencyManager, 'run', scriptName];
120
+ const pieces = [packageManager, 'run', scriptName];
121
121
  if (scriptArgs.length > 0) {
122
122
  pieces.push('--');
123
123
  pieces.push(...scriptArgs);
@@ -363,7 +363,7 @@ export const error = async (content) => {
363
363
  });
364
364
  if (content instanceof Bug) {
365
365
  if (stack.items.length !== 0) {
366
- outputString += `\n${padding}${colors.bold('Stack trace:')}`;
366
+ outputString += `\n${padding}${colors.bold('Stack trace:')}\n`;
367
367
  const stackLines = stack.asTable({}).split('\n');
368
368
  for (const stackLine of stackLines) {
369
369
  outputString += `${padding}${stackLine}\n`;
@@ -501,5 +501,15 @@ export function shouldDisplayColors() {
501
501
  export async function pageLogs() {
502
502
  await page(logFile);
503
503
  }
504
+ /**
505
+ *
506
+ * @param packageManager {PackageManager} The package manager that is being used.
507
+ * @param version {string} The version to update to
508
+ * @returns {te}
509
+ */
510
+ export function getOutputUpdateCLIReminder(packageManager, version) {
511
+ const updateCommand = token.packagejsonScript(packageManager, 'shopify', 'upgrade');
512
+ return content `💡 Version ${version} available! Run ${updateCommand}`.value;
513
+ }
504
514
  /* eslint-enable no-console */
505
515
  //# sourceMappingURL=output.js.map