@shopify/cli-kit 3.3.3 → 3.6.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 (115) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/analytics.d.ts +11 -5
  3. package/dist/analytics.js +62 -72
  4. package/dist/analytics.js.map +1 -1
  5. package/dist/api/admin.js +20 -34
  6. package/dist/api/admin.js.map +1 -1
  7. package/dist/api/common.d.ts +11 -1
  8. package/dist/api/common.js +50 -6
  9. package/dist/api/common.js.map +1 -1
  10. package/dist/api/identity.js +3 -4
  11. package/dist/api/identity.js.map +1 -1
  12. package/dist/api/partners.d.ts +0 -5
  13. package/dist/api/partners.js +22 -43
  14. package/dist/api/partners.js.map +1 -1
  15. package/dist/array.d.ts +1 -0
  16. package/dist/array.js +4 -0
  17. package/dist/array.js.map +1 -0
  18. package/dist/constants.d.ts +1 -0
  19. package/dist/constants.js +1 -2
  20. package/dist/constants.js.map +1 -1
  21. package/dist/environment/local.d.ts +1 -0
  22. package/dist/environment/local.js +3 -0
  23. package/dist/environment/local.js.map +1 -1
  24. package/dist/environment/service.d.ts +2 -1
  25. package/dist/environment/service.js +16 -0
  26. package/dist/environment/service.js.map +1 -1
  27. package/dist/error.d.ts +5 -0
  28. package/dist/error.js +10 -4
  29. package/dist/error.js.map +1 -1
  30. package/dist/file.d.ts +3 -1
  31. package/dist/file.js +14 -2
  32. package/dist/file.js.map +1 -1
  33. package/dist/git.js +12 -5
  34. package/dist/git.js.map +1 -1
  35. package/dist/haiku.d.ts +6 -1
  36. package/dist/haiku.js +67 -6
  37. package/dist/haiku.js.map +1 -1
  38. package/dist/http/fetch.d.ts +9 -2
  39. package/dist/http/fetch.js +11 -2
  40. package/dist/http/fetch.js.map +1 -1
  41. package/dist/http/graphql.d.ts +15 -0
  42. package/dist/http/graphql.js +12 -0
  43. package/dist/http/graphql.js.map +1 -0
  44. package/dist/http.d.ts +24 -0
  45. package/dist/http.js +27 -0
  46. package/dist/http.js.map +1 -1
  47. package/dist/index.d.ts +2 -0
  48. package/dist/index.js +2 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/json.d.ts +6 -0
  51. package/dist/json.js +2 -0
  52. package/dist/json.js.map +1 -0
  53. package/dist/metadata.d.ts +51 -0
  54. package/dist/metadata.js +29 -0
  55. package/dist/metadata.js.map +1 -0
  56. package/dist/monorail.d.ts +38 -0
  57. package/dist/monorail.js +38 -0
  58. package/dist/monorail.js.map +1 -0
  59. package/dist/network/service.d.ts +1 -1
  60. package/dist/network/service.js.map +1 -1
  61. package/dist/node/archiver.d.ts +4 -1
  62. package/dist/node/archiver.js +22 -13
  63. package/dist/node/archiver.js.map +1 -1
  64. package/dist/node/base-command.d.ts +1 -0
  65. package/dist/node/base-command.js +11 -2
  66. package/dist/node/base-command.js.map +1 -1
  67. package/dist/node/cli.d.ts +0 -2
  68. package/dist/node/cli.js +0 -4
  69. package/dist/node/cli.js.map +1 -1
  70. package/dist/node/error-handler.d.ts +23 -1
  71. package/dist/node/error-handler.js +64 -8
  72. package/dist/node/error-handler.js.map +1 -1
  73. package/dist/node/hooks/init.d.ts +2 -0
  74. package/dist/node/hooks/init.js +7 -0
  75. package/dist/node/hooks/init.js.map +1 -0
  76. package/dist/node/hooks/postrun.js +5 -2
  77. package/dist/node/hooks/postrun.js.map +1 -1
  78. package/dist/node/hooks/prerun.js +2 -0
  79. package/dist/node/hooks/prerun.js.map +1 -1
  80. package/dist/node/ruby.d.ts +7 -2
  81. package/dist/node/ruby.js +22 -7
  82. package/dist/node/ruby.js.map +1 -1
  83. package/dist/output.d.ts +18 -11
  84. package/dist/output.js +96 -28
  85. package/dist/output.js.map +1 -1
  86. package/dist/path.d.ts +3 -3
  87. package/dist/path.js +2 -4
  88. package/dist/path.js.map +1 -1
  89. package/dist/plugins.d.ts +38 -2
  90. package/dist/plugins.js +11 -0
  91. package/dist/plugins.js.map +1 -1
  92. package/dist/session/authorize.js +16 -4
  93. package/dist/session/authorize.js.map +1 -1
  94. package/dist/session/exchange.js +2 -8
  95. package/dist/session/exchange.js.map +1 -1
  96. package/dist/session/validate.js +3 -0
  97. package/dist/session/validate.js.map +1 -1
  98. package/dist/session.js +7 -1
  99. package/dist/session.js.map +1 -1
  100. package/dist/store.js +0 -2
  101. package/dist/store.js.map +1 -1
  102. package/dist/string.d.ts +4 -0
  103. package/dist/string.js +13 -0
  104. package/dist/string.js.map +1 -1
  105. package/dist/tsconfig.tsbuildinfo +1 -1
  106. package/dist/typing/overloaded-parameters.d.ts +6 -0
  107. package/dist/typing/overloaded-parameters.js +2 -0
  108. package/dist/typing/overloaded-parameters.js.map +1 -0
  109. package/dist/typing/simple-definitions.d.ts +4 -0
  110. package/dist/typing/simple-definitions.js +2 -0
  111. package/dist/typing/simple-definitions.js.map +1 -0
  112. package/dist/ui.d.ts +12 -0
  113. package/dist/ui.js +57 -5
  114. package/dist/ui.js.map +1 -1
  115. package/package.json +28 -22
package/dist/output.js CHANGED
@@ -1,29 +1,37 @@
1
1
  /* eslint-disable no-console */
2
- import { Bug } from './error.js';
2
+ import { Bug, cleanSingleStackTracePath } from './error.js';
3
3
  import { isUnitTest, isVerbose } from './environment/local.js';
4
4
  import constants from './constants.js';
5
- import { append as fileAppend, mkdirSync as fileMkdirSync, readSync as fileReadSync, sizeSync as fileSizeSync, writeSync as fileWriteSync, touchSync as fileTouchSync, } from './file.js';
5
+ import { generateRandomUUID } from './id.js';
6
+ import { mkdirSync as fileMkdirSync, readSync as fileReadSync, sizeSync as fileSizeSync, writeSync as fileWriteSync, touchSync as fileTouchSync, } from './file.js';
6
7
  import { join as pathJoin, relativize as relativizePath } from './path.js';
7
8
  import { page } from './system.js';
8
9
  import { colors } from './node/colors.js';
9
10
  import terminalLink from 'terminal-link';
10
11
  import StackTracey from 'stacktracey';
11
12
  import { AbortController } from 'abort-controller';
12
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
13
- // @ts-ignore
14
13
  import cjs from 'color-json';
15
14
  import stripAnsi from 'strip-ansi';
16
15
  import { Writable } from 'node:stream';
17
- let logFile;
18
- export function initiateLogging({ logDir = constants.paths.directories.cache.path(), filename = 'shopify.log', }) {
16
+ import { createWriteStream } from 'node:fs';
17
+ export { default as logUpdate } from 'log-update';
18
+ const logFileName = 'shopify.cli.log';
19
+ let logFileStream;
20
+ let commandUuid;
21
+ export function initiateLogging(options = {}) {
22
+ if (isUnitTest())
23
+ return;
24
+ const logDir = options.logDir || constants.paths.directories.cache.path();
25
+ commandUuid = generateRandomUUID();
19
26
  fileMkdirSync(logDir);
20
- logFile = pathJoin(logDir, filename);
27
+ const logFile = pathJoin(logDir, logFileName);
21
28
  fileTouchSync(logFile);
22
- truncateLogs();
29
+ truncateLogs(logFile);
30
+ logFileStream = createWriteStream(logFile, { flags: 'a' });
23
31
  }
24
32
  // Shaves off the first 10,000 log lines (circa 1MB) if logs are over 5MB long.
25
33
  // Rescues in case the file hasn't been created yet.
26
- function truncateLogs() {
34
+ function truncateLogs(logFile) {
27
35
  try {
28
36
  if (fileSizeSync(logFile) > 5 * 1024 * 1024) {
29
37
  const contents = fileReadSync(logFile);
@@ -259,61 +267,69 @@ export const clearCollectedLogs = () => {
259
267
  collectedLogs = {};
260
268
  };
261
269
  /**
262
- * Ouputs information to the user. This is akin to "console.log"
270
+ * Ouputs information to the user.
263
271
  * Info messages don't get additional formatting.
264
272
  * Note: Info messages are sent through the standard output.
265
273
  * @param content {string} The content to be output to the user.
274
+ * @param logger {Function} The logging function to use to output to the user.
266
275
  */
267
- export const info = (content) => {
276
+ export const info = (content, logger = consoleLog) => {
277
+ const message = stringifyMessage(content);
268
278
  if (isUnitTest())
269
279
  collectLog('info', content);
270
- message(content, 'info');
280
+ outputWhereAppropriate('info', logger, message);
271
281
  };
272
282
  /**
273
283
  * Outputs a success message to the user.
274
- * Success message receive a special formatting to make them stand out in the console.
284
+ * Success messages receive a special formatting to make them stand out in the console.
275
285
  * Note: Success messages are sent through the standard output.
276
286
  * @param content {string} The content to be output to the user.
287
+ * @param logger {Function} The logging function to use to output to the user.
277
288
  */
278
- export const success = (content) => {
289
+ export const success = (content, logger = consoleLog) => {
279
290
  const message = colors.bold(`✅ Success! ${stringifyMessage(content)}.`);
280
291
  if (isUnitTest())
281
292
  collectLog('success', content);
282
- outputWhereAppropriate('info', consoleLog, message);
293
+ outputWhereAppropriate('info', logger, message);
283
294
  };
284
295
  /**
285
296
  * Outputs a completed message to the user.
286
297
  * Completed message receive a special formatting to make them stand out in the console.
287
298
  * Note: Completed messages are sent through the standard output.
288
299
  * @param content {string} The content to be output to the user.
300
+ * @param logger {Function} The logging function to use to output to the user.
289
301
  */
290
- export const completed = (content) => {
302
+ export const completed = (content, logger = consoleLog) => {
291
303
  const message = `${colors.green('✔')} ${stringifyMessage(content)}`;
292
304
  if (isUnitTest())
293
305
  collectLog('completed', content);
294
- outputWhereAppropriate('info', consoleLog, message);
306
+ outputWhereAppropriate('info', logger, message);
295
307
  };
296
308
  /**
297
309
  * Ouputs debug information to the user. By default these output is hidden unless the user calls the CLI with --verbose.
298
310
  * Debug messages don't get additional formatting.
299
311
  * Note: Debug messages are sent through the standard output.
300
312
  * @param content {string} The content to be output to the user.
313
+ * @param logger {Function} The logging function to use to output to the user.
301
314
  */
302
- export const debug = (content) => {
315
+ export const debug = (content, logger = consoleLog) => {
303
316
  if (isUnitTest())
304
317
  collectLog('debug', content);
305
- message(colors.gray(stringifyMessage(content)), 'debug');
318
+ const message = colors.gray(stringifyMessage(content));
319
+ outputWhereAppropriate('debug', logger, message);
306
320
  };
307
321
  /**
308
322
  * Outputs a warning message to the user.
309
323
  * Warning messages receive a special formatting to make them stand out in the console.
310
324
  * Note: Warning messages are sent through the standard output.
311
325
  * @param content {string} The content to be output to the user.
326
+ * @param logger {Function} The logging function to use to output to the user.
312
327
  */
313
- export const warn = (content) => {
328
+ export const warn = (content, logger = consoleWarn) => {
314
329
  if (isUnitTest())
315
330
  collectLog('warn', content);
316
- consoleWarn(colors.yellow(stringifyMessage(content)));
331
+ const message = colors.yellow(stringifyMessage(content));
332
+ outputWhereAppropriate('warn', logger, message);
317
333
  };
318
334
  /**
319
335
  * Prints a new line in the terminal.
@@ -349,7 +365,11 @@ export const error = async (content) => {
349
365
  outputString += `${padding}${line}\n`;
350
366
  }
351
367
  }
352
- let stack = await new StackTracey(content).withSourcesAsync();
368
+ let stack = new StackTracey(content);
369
+ stack.items.forEach((item) => {
370
+ item.file = cleanSingleStackTracePath(item.file);
371
+ });
372
+ stack = await stack.withSourcesAsync();
353
373
  stack = stack
354
374
  .filter((entry) => {
355
375
  return !entry.file.includes('@oclif/core');
@@ -465,14 +485,14 @@ function consoleError(message) {
465
485
  function consoleWarn(message) {
466
486
  console.warn(withOrWithoutStyle(message));
467
487
  }
468
- function outputWhereAppropriate(logLevel, logFunc, message) {
488
+ function outputWhereAppropriate(logLevel, logger, message) {
469
489
  if (shouldOutput(logLevel)) {
470
- logFunc(message);
490
+ logger(message);
471
491
  }
472
492
  logToFile(message, logLevel.toUpperCase());
473
493
  }
474
494
  export function logFileExists() {
475
- return Boolean(logFile);
495
+ return Boolean(logFileStream);
476
496
  }
477
497
  // DO NOT USE THIS FUNCTION DIRECTLY under normal circumstances.
478
498
  // It is exported purely for use in cases where output is already being logged
@@ -482,7 +502,8 @@ export function logToFile(message, logLevel) {
482
502
  if (!logFileExists())
483
503
  return;
484
504
  const timestamp = new Date().toISOString();
485
- fileAppend(logFile, `[${timestamp} ${logLevel}]: ${message}\n`);
505
+ const logContents = `[${timestamp} ${commandUuid} ${logLevel}]: ${message}\n`;
506
+ logFileStream.write(logContents);
486
507
  }
487
508
  function withOrWithoutStyle(message) {
488
509
  if (shouldDisplayColors()) {
@@ -498,8 +519,55 @@ export function unstyled(message) {
498
519
  export function shouldDisplayColors() {
499
520
  return Boolean(process.stdout.isTTY || process.env.FORCE_COLOR);
500
521
  }
501
- export async function pageLogs() {
502
- await page(logFile);
522
+ export async function pageLogs({ lastCommand }) {
523
+ const logDir = constants.paths.directories.cache.path();
524
+ const logFile = pathJoin(logDir, logFileName);
525
+ // Ensure file exists in case they deleted it or something
526
+ fileTouchSync(logFile);
527
+ if (lastCommand) {
528
+ printLastCommand(logFile);
529
+ }
530
+ else {
531
+ await page(logFile);
532
+ }
533
+ }
534
+ function printLastCommand(logFile) {
535
+ const contents = fileReadSync(logFile).split('\n');
536
+ const uuids = contents
537
+ .map(logfileLineUUID)
538
+ .filter((uuid) => uuid)
539
+ .reverse();
540
+ // 2nd unique UUID, because the currently running command will be the 1st
541
+ const relevantUuid = Array.from(new Set(uuids))[1];
542
+ if (relevantUuid) {
543
+ consoleLog(relevantLines(contents, relevantUuid).join('\n'));
544
+ }
545
+ }
546
+ function relevantLines(contents, relevantUuid) {
547
+ // We run through the file line by line, keeping track of the most recently
548
+ // encountered UUID.
549
+ //
550
+ // If the current line has a UUID, it's a new logged unit and should be
551
+ // considered. Otherwise, the line is related to the most recent UUID.
552
+ let mostRecentUuid = '';
553
+ return contents.filter((line) => {
554
+ const currentUuid = logfileLineUUID(line) || mostRecentUuid;
555
+ mostRecentUuid = currentUuid;
556
+ return currentUuid === relevantUuid;
557
+ });
558
+ }
559
+ function logfileLineUUID(line) {
560
+ // Log lines look like:
561
+ //
562
+ // timestamp UUID contents
563
+ // ===========================================================================================
564
+ // [2022-07-20T08:51:40.296Z 5288e1da-a06a-4f96-b1a6-e34fcdd7b416 DEBUG]: Running command logs
565
+ // ===========================================================================================
566
+ //
567
+ // There may be subsequent lines if the contents section is multi-line.
568
+ //
569
+ const match = line.match(/^\[\S+ ([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}) [A-Z]+\]/);
570
+ return match && match[1];
503
571
  }
504
572
  /**
505
573
  *
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport {Fatal, Bug} from './error.js'\nimport {isUnitTest, isVerbose} from './environment/local.js'\nimport constants from './constants.js'\nimport {PackageManager} from './node/node-package-manager.js'\nimport {\n append as fileAppend,\n mkdirSync as fileMkdirSync,\n readSync as fileReadSync,\n sizeSync as fileSizeSync,\n writeSync as fileWriteSync,\n touchSync as fileTouchSync,\n} from './file.js'\nimport {join as pathJoin, relativize as relativizePath} from './path.js'\nimport {page} from './system.js'\nimport {colors} from './node/colors.js'\nimport terminalLink from 'terminal-link'\nimport StackTracey from 'stacktracey'\nimport {AbortController, AbortSignal} from 'abort-controller'\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport cjs from 'color-json'\nimport stripAnsi from 'strip-ansi'\nimport {Writable} from 'node:stream'\n\nlet logFile: string\n\nexport function initiateLogging({\n logDir = constants.paths.directories.cache.path(),\n filename = 'shopify.log',\n}: {\n logDir?: string\n filename?: string\n}) {\n fileMkdirSync(logDir)\n logFile = pathJoin(logDir, filename)\n fileTouchSync(logFile)\n truncateLogs()\n}\n\n// Shaves off the first 10,000 log lines (circa 1MB) if logs are over 5MB long.\n// Rescues in case the file hasn't been created yet.\nfunction truncateLogs() {\n try {\n if (fileSizeSync(logFile) > 5 * 1024 * 1024) {\n const contents = fileReadSync(logFile)\n const splitContents = contents.split('\\n')\n const newContents = splitContents.slice(10000, splitContents.length).join('\\n')\n fileWriteSync(logFile, newContents)\n }\n // eslint-disable-next-line no-empty, no-catch-all/no-catch-all\n } catch {}\n}\n\nenum ContentTokenType {\n Raw,\n Command,\n Json,\n Path,\n Link,\n Heading,\n SubHeading,\n Italic,\n ErrorText,\n Yellow,\n Cyan,\n Magenta,\n Green,\n}\n\ninterface ContentMetadata {\n link?: string\n}\n\nclass ContentToken {\n type: ContentTokenType\n value: Message\n metadata: ContentMetadata\n\n constructor(value: Message, metadata: ContentMetadata = {}, type: ContentTokenType) {\n this.type = type\n this.value = value\n this.metadata = metadata\n }\n}\n\nexport const token = {\n raw: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Raw)\n },\n genericShellCommand: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Command)\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n json: (value: any) => {\n return new ContentToken(value, {}, ContentTokenType.Json)\n },\n path: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Path)\n },\n link: (value: Message, link: string) => {\n return new ContentToken(value, {link}, ContentTokenType.Link)\n },\n heading: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Heading)\n },\n subheading: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.SubHeading)\n },\n italic: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Italic)\n },\n errorText: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.ErrorText)\n },\n cyan: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Cyan)\n },\n yellow: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Yellow)\n },\n magenta: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Magenta)\n },\n green: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Green)\n },\n packagejsonScript: (packageManager: PackageManager, scriptName: string, ...scriptArgs: string[]) => {\n return new ContentToken(\n formatPackageManagerCommand(packageManager, scriptName, scriptArgs),\n {},\n ContentTokenType.Command,\n )\n },\n successIcon: () => {\n return new ContentToken('✔', {}, ContentTokenType.Green)\n },\n failIcon: () => {\n return new ContentToken('✖', {}, ContentTokenType.ErrorText)\n },\n}\n\nfunction formatPackageManagerCommand(packageManager: PackageManager, scriptName: string, scriptArgs: string[]): string {\n switch (packageManager) {\n case 'yarn': {\n const pieces = ['yarn', scriptName, ...scriptArgs]\n return pieces.join(' ')\n }\n case 'pnpm':\n case 'npm': {\n const pieces = [packageManager, 'run', scriptName]\n if (scriptArgs.length > 0) {\n pieces.push('--')\n pieces.push(...scriptArgs)\n }\n return pieces.join(' ')\n }\n }\n}\n\nexport class TokenizedString {\n value: string\n constructor(value: string) {\n this.value = value\n }\n}\n\nexport type Message = string | TokenizedString\n\nexport function content(strings: TemplateStringsArray, ...keys: (ContentToken | string)[]): TokenizedString {\n let output = ``\n strings.forEach((string, i) => {\n output += string\n if (i >= keys.length) {\n return\n }\n const token = keys[i]\n\n if (typeof token === 'string') {\n output += token\n } else {\n const enumToken = token as ContentToken\n switch (enumToken.type) {\n case ContentTokenType.Raw:\n output += enumToken.value\n break\n case ContentTokenType.Command:\n output += colors.bold(colors.yellow(stringifyMessage(enumToken.value)))\n break\n case ContentTokenType.Path:\n output += relativizePath(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Json:\n try {\n output += cjs(stringifyMessage(enumToken.value) ?? {})\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (_) {\n output += JSON.stringify(stringifyMessage(enumToken.value) ?? {}, null, 2)\n }\n break\n case ContentTokenType.Link:\n output += terminalLink(colors.green(stringifyMessage(enumToken.value)), enumToken.metadata.link ?? '')\n break\n case ContentTokenType.Heading:\n output += colors.bold.underline(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.SubHeading:\n output += colors.underline(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Italic:\n output += colors.italic(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.ErrorText:\n output += colors.bold.redBright(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Yellow:\n output += colors.yellow(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Cyan:\n output += colors.cyan(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Magenta:\n output += colors.magenta(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Green:\n output += colors.green(stringifyMessage(enumToken.value))\n break\n }\n }\n })\n return new TokenizedString(output)\n}\n\n/** Log levels */\nexport type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent'\n\n/**\n * It maps a level to a numeric value.\n * @param level {LogLevel} The level for which we'll return its numeric value.\n * @returns The numeric value of the level.\n */\nconst logLevelValue = (level: LogLevel): number => {\n switch (level) {\n case 'trace':\n return 10\n case 'debug':\n return 20\n case 'info':\n return 30\n case 'warn':\n return 40\n case 'error':\n return 50\n case 'fatal':\n return 60\n default:\n return 30\n }\n}\n\n/**\n *\n * @returns {LogLevel} It returns the log level set by the user.\n */\nexport const currentLogLevel = (): LogLevel => {\n if (isVerbose()) {\n return 'debug'\n } else {\n return 'info'\n }\n}\n\nexport const shouldOutput = (logLevel: LogLevel): boolean => {\n if (isUnitTest()) {\n return false\n }\n const currentLogLevelValue = logLevelValue(currentLogLevel())\n const messageLogLevelValue = logLevelValue(logLevel)\n return messageLogLevelValue >= currentLogLevelValue\n}\n\n// eslint-disable-next-line import/no-mutable-exports\nexport let collectedLogs: {[key: string]: string[]} = {}\n\n/**\n * This is only used during UnitTesting.\n * If we are in a testing context, instead of printing the logs to the console,\n * we will store them in a variable that can be accessed from the tests.\n * @param key {string} The key of the log.\n * @param content {string} The content of the log.\n */\nconst collectLog = (key: string, content: Message) => {\n const output = collectedLogs.output ?? []\n const data = collectedLogs[key] ?? []\n data.push(stripAnsi(stringifyMessage(content) ?? ''))\n output.push(stripAnsi(stringifyMessage(content) ?? ''))\n collectedLogs[key] = data\n collectedLogs.output = output\n}\n\nexport const clearCollectedLogs = () => {\n collectedLogs = {}\n}\n\n/**\n * Ouputs information to the user. This is akin to \"console.log\"\n * Info messages don't get additional formatting.\n * Note: Info messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n */\nexport const info = (content: Message) => {\n if (isUnitTest()) collectLog('info', content)\n message(content, 'info')\n}\n\n/**\n * Outputs a success message to the user.\n * Success message receive a special formatting to make them stand out in the console.\n * Note: Success messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n */\nexport const success = (content: Message) => {\n const message = colors.bold(`✅ Success! ${stringifyMessage(content)}.`)\n if (isUnitTest()) collectLog('success', content)\n outputWhereAppropriate('info', consoleLog, message)\n}\n\n/**\n * Outputs a completed message to the user.\n * Completed message receive a special formatting to make them stand out in the console.\n * Note: Completed messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n */\nexport const completed = (content: Message) => {\n const message = `${colors.green('✔')} ${stringifyMessage(content)}`\n if (isUnitTest()) collectLog('completed', content)\n outputWhereAppropriate('info', consoleLog, message)\n}\n\n/**\n * Ouputs debug information to the user. By default these output is hidden unless the user calls the CLI with --verbose.\n * Debug messages don't get additional formatting.\n * Note: Debug messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n */\nexport const debug = (content: Message) => {\n if (isUnitTest()) collectLog('debug', content)\n message(colors.gray(stringifyMessage(content)), 'debug')\n}\n\n/**\n * Outputs a warning message to the user.\n * Warning messages receive a special formatting to make them stand out in the console.\n * Note: Warning messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n */\nexport const warn = (content: Message) => {\n if (isUnitTest()) collectLog('warn', content)\n consoleWarn(colors.yellow(stringifyMessage(content)))\n}\n\n/**\n * Prints a new line in the terminal.\n */\nexport const newline = () => {\n console.log()\n}\n\n/**\n * Formats and outputs a fatal error.\n * Note: This API is not intended to be used internally. If you want to\n * abort the execution due to an error, raise a fatal error and let the\n * error handler handle and format it.\n * @param content {Fatal} The fatal error to be output.\n */\nexport const error = async (content: Fatal) => {\n if (!content.message) {\n return\n }\n let outputString = ''\n const message = content.message\n const padding = ' '\n const header = colors.redBright(`\\n━━━━━━ Error ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n`)\n const footer = colors.redBright('\\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n')\n outputString += header\n const lines = message.split('\\n')\n for (const line of lines) {\n outputString += `${padding}${line}\\n`\n }\n if (content.tryMessage) {\n outputString += `\\n${padding}${colors.bold('What to try:')}\\n`\n const lines = content.tryMessage.split('\\n')\n for (const line of lines) {\n outputString += `${padding}${line}\\n`\n }\n }\n\n let stack = await new StackTracey(content).withSourcesAsync()\n stack = stack\n .filter((entry) => {\n return !entry.file.includes('@oclif/core')\n })\n .map((item) => {\n item.calleeShort = colors.yellow(item.calleeShort)\n /** We make the paths relative to the packages/ directory */\n const fileShortComponents = item.fileShort.split('packages/')\n item.fileShort = fileShortComponents.length === 2 ? fileShortComponents[1] : fileShortComponents[0]\n return item\n })\n if (content instanceof Bug) {\n if (stack.items.length !== 0) {\n outputString += `\\n${padding}${colors.bold('Stack trace:')}\\n`\n const stackLines = stack.asTable({}).split('\\n')\n for (const stackLine of stackLines) {\n outputString += `${padding}${stackLine}\\n`\n }\n }\n }\n outputString += footer\n outputWhereAppropriate('error', consoleError, outputString)\n}\n\nexport function stringifyMessage(message: Message): string {\n if (message instanceof TokenizedString) {\n return message.value\n } else {\n return message\n }\n}\n\nconst message = (content: Message, level: LogLevel = 'info') => {\n const stringifiedMessage = stringifyMessage(content)\n outputWhereAppropriate(level, consoleLog, stringifiedMessage)\n}\n\nexport interface OutputProcess {\n /** The prefix to include in the logs\n * [vite] Output coming from Vite\n */\n prefix: string\n /**\n * A callback to invoke the process. stdout and stderr should be used\n * to send standard output and error data that gets formatted with the\n * right prefix.\n */\n action: (stdout: Writable, stderr: Writable, signal: AbortSignal) => Promise<void>\n}\n\n/**\n * Use this function when you have multiple concurrent processes that send data events\n * and we need to output them ensuring that they can visually differenciated by the user.\n *\n * @param processes {OutputProcess[]} A list of processes to run concurrently.\n */\nexport async function concurrent(\n processes: OutputProcess[],\n callback: ((signal: AbortSignal) => void) | undefined = undefined,\n) {\n const abortController = new AbortController()\n\n // eslint-disable-next-line node/callback-return\n if (callback) callback(abortController.signal)\n\n const concurrentColors = [token.yellow, token.cyan, token.magenta, token.green]\n const prefixColumnSize = Math.max(...processes.map((process) => process.prefix.length))\n\n function linePrefix(prefix: string, index: number) {\n const colorIndex = index < concurrentColors.length ? index : index % concurrentColors.length\n const color = concurrentColors[colorIndex]\n return color(`${prefix}${' '.repeat(prefixColumnSize - prefix.length)} ${colors.bold('|')} `)\n }\n\n try {\n await Promise.all(\n processes.map(async (process, index) => {\n const stdout = new Writable({\n write(chunk, _encoding, next) {\n const lines = stripAnsiEraseCursorEscapeCharacters(chunk.toString('ascii')).split(/\\n/)\n for (const line of lines) {\n info(content`${linePrefix(process.prefix, index)}${line}`)\n }\n next()\n },\n })\n const stderr = new Writable({\n write(chunk, _encoding, next) {\n const lines = stripAnsiEraseCursorEscapeCharacters(chunk.toString('ascii')).split(/\\n/)\n for (const line of lines) {\n message(content`${linePrefix(process.prefix, index)}${colors.bold(line)}`, 'error')\n }\n next()\n },\n })\n await process.action(stdout, stderr, abortController.signal)\n }),\n )\n } catch (_error) {\n // We abort any running process\n abortController.abort()\n throw _error\n }\n}\n\n/**\n * This regex can be used to find the erase cursor Ansii characters\n * to strip them from the string.\n * https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#erase-functions\n */\nconst eraseCursorAnsiRegex = [\n // Erase the entire line\n '2K',\n // Clear vertical tab stop at current line\n '1G',\n]\n .map((element) => `[\\\\u001B\\\\u009B][[\\\\]()#;?]*${element}`)\n .join('|')\n\n/**\n * The data sent through the standard pipelines of the sub-processes that we execute\n * might contain ansii escape characters to move the cursor. That causes any additional\n * formatting to break. This function takes a string and strips escape characters that\n * manage the cursor in the terminal.\n * @param value {string} String whose erase cursor escape characters will be stripped.\n * @returns {string} Stripped string.\n */\nfunction stripAnsiEraseCursorEscapeCharacters(value: string): string {\n return value.replace(/(\\n)$/, '').replace(new RegExp(eraseCursorAnsiRegex, 'g'), '')\n}\n\nfunction consoleLog(message: string): void {\n console.log(withOrWithoutStyle(message))\n}\n\nfunction consoleError(message: string): void {\n console.error(withOrWithoutStyle(message))\n}\n\nfunction consoleWarn(message: string): void {\n console.warn(withOrWithoutStyle(message))\n}\n\nfunction outputWhereAppropriate(logLevel: LogLevel, logFunc: (message: string) => void, message: string): void {\n if (shouldOutput(logLevel)) {\n logFunc(message)\n }\n logToFile(message, logLevel.toUpperCase())\n}\n\nexport function logFileExists(): boolean {\n return Boolean(logFile)\n}\n\n// DO NOT USE THIS FUNCTION DIRECTLY under normal circumstances.\n// It is exported purely for use in cases where output is already being logged\n// to the terminal but is not reflected in the logfile, e.g. Listr output.\nexport function logToFile(message: string, logLevel: string): void {\n // If file logging hasn't been initiated, skip it\n if (!logFileExists()) return\n const timestamp = new Date().toISOString()\n fileAppend(logFile, `[${timestamp} ${logLevel}]: ${message}\\n`)\n}\n\nfunction withOrWithoutStyle(message: string): string {\n if (shouldDisplayColors()) {\n return message\n } else {\n return unstyled(message)\n }\n}\n\nexport function unstyled(message: string): string {\n return colors.unstyle(message)\n}\n\nexport function shouldDisplayColors(): boolean {\n return Boolean(process.stdout.isTTY || process.env.FORCE_COLOR)\n}\n\nexport async function pageLogs() {\n await page(logFile)\n}\n\n/**\n *\n * @param packageManager {PackageManager} The package manager that is being used.\n * @param version {string} The version to update to\n * @returns {te}\n */\nexport function getOutputUpdateCLIReminder(packageManager: PackageManager, version: string): string {\n const updateCommand = token.packagejsonScript(packageManager, 'shopify', 'upgrade')\n return content`💡 Version ${version} available! Run ${updateCommand}`.value\n}\n\n/* eslint-enable no-console */\n"]}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport {Fatal, Bug, cleanSingleStackTracePath} from './error.js'\nimport {isUnitTest, isVerbose} from './environment/local.js'\nimport constants from './constants.js'\nimport {PackageManager} from './node/node-package-manager.js'\nimport {generateRandomUUID} from './id.js'\nimport {\n mkdirSync as fileMkdirSync,\n readSync as fileReadSync,\n sizeSync as fileSizeSync,\n writeSync as fileWriteSync,\n touchSync as fileTouchSync,\n} from './file.js'\nimport {join as pathJoin, relativize as relativizePath} from './path.js'\nimport {page} from './system.js'\nimport {colors} from './node/colors.js'\nimport terminalLink from 'terminal-link'\nimport StackTracey from 'stacktracey'\nimport {AbortController, AbortSignal} from 'abort-controller'\nimport cjs from 'color-json'\nimport stripAnsi from 'strip-ansi'\nimport {Writable} from 'node:stream'\nimport {WriteStream, createWriteStream} from 'node:fs'\n\nexport {default as logUpdate} from 'log-update'\n\nconst logFileName = 'shopify.cli.log'\nlet logFileStream: WriteStream\nlet commandUuid: string\n\nexport function initiateLogging(options: {logDir?: string} = {}) {\n if (isUnitTest()) return\n const logDir = options.logDir || constants.paths.directories.cache.path()\n commandUuid = generateRandomUUID()\n fileMkdirSync(logDir)\n const logFile = pathJoin(logDir, logFileName)\n fileTouchSync(logFile)\n truncateLogs(logFile)\n logFileStream = createWriteStream(logFile, {flags: 'a'})\n}\n\n// Shaves off the first 10,000 log lines (circa 1MB) if logs are over 5MB long.\n// Rescues in case the file hasn't been created yet.\nfunction truncateLogs(logFile: string): void {\n try {\n if (fileSizeSync(logFile) > 5 * 1024 * 1024) {\n const contents = fileReadSync(logFile)\n const splitContents = contents.split('\\n')\n const newContents = splitContents.slice(10000, splitContents.length).join('\\n')\n fileWriteSync(logFile, newContents)\n }\n // eslint-disable-next-line no-empty, no-catch-all/no-catch-all\n } catch {}\n}\n\nenum ContentTokenType {\n Raw,\n Command,\n Json,\n Path,\n Link,\n Heading,\n SubHeading,\n Italic,\n ErrorText,\n Yellow,\n Cyan,\n Magenta,\n Green,\n}\n\ninterface ContentMetadata {\n link?: string\n}\n\nexport type Logger = (message: string) => void\n\nclass ContentToken {\n type: ContentTokenType\n value: Message\n metadata: ContentMetadata\n\n constructor(value: Message, metadata: ContentMetadata = {}, type: ContentTokenType) {\n this.type = type\n this.value = value\n this.metadata = metadata\n }\n}\n\nexport const token = {\n raw: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Raw)\n },\n genericShellCommand: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Command)\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n json: (value: any) => {\n return new ContentToken(value, {}, ContentTokenType.Json)\n },\n path: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Path)\n },\n link: (value: Message, link: string) => {\n return new ContentToken(value, {link}, ContentTokenType.Link)\n },\n heading: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Heading)\n },\n subheading: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.SubHeading)\n },\n italic: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Italic)\n },\n errorText: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.ErrorText)\n },\n cyan: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Cyan)\n },\n yellow: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Yellow)\n },\n magenta: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Magenta)\n },\n green: (value: Message) => {\n return new ContentToken(value, {}, ContentTokenType.Green)\n },\n packagejsonScript: (packageManager: PackageManager, scriptName: string, ...scriptArgs: string[]) => {\n return new ContentToken(\n formatPackageManagerCommand(packageManager, scriptName, scriptArgs),\n {},\n ContentTokenType.Command,\n )\n },\n successIcon: () => {\n return new ContentToken('✔', {}, ContentTokenType.Green)\n },\n failIcon: () => {\n return new ContentToken('✖', {}, ContentTokenType.ErrorText)\n },\n}\n\nfunction formatPackageManagerCommand(packageManager: PackageManager, scriptName: string, scriptArgs: string[]): string {\n switch (packageManager) {\n case 'yarn': {\n const pieces = ['yarn', scriptName, ...scriptArgs]\n return pieces.join(' ')\n }\n case 'pnpm':\n case 'npm': {\n const pieces = [packageManager, 'run', scriptName]\n if (scriptArgs.length > 0) {\n pieces.push('--')\n pieces.push(...scriptArgs)\n }\n return pieces.join(' ')\n }\n }\n}\n\nexport class TokenizedString {\n value: string\n constructor(value: string) {\n this.value = value\n }\n}\n\nexport type Message = string | TokenizedString\n\nexport function content(strings: TemplateStringsArray, ...keys: (ContentToken | string)[]): TokenizedString {\n let output = ``\n strings.forEach((string, i) => {\n output += string\n if (i >= keys.length) {\n return\n }\n const token = keys[i]\n\n if (typeof token === 'string') {\n output += token\n } else {\n const enumToken = token as ContentToken\n switch (enumToken.type) {\n case ContentTokenType.Raw:\n output += enumToken.value\n break\n case ContentTokenType.Command:\n output += colors.bold(colors.yellow(stringifyMessage(enumToken.value)))\n break\n case ContentTokenType.Path:\n output += relativizePath(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Json:\n try {\n output += cjs(stringifyMessage(enumToken.value) ?? {})\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (_) {\n output += JSON.stringify(stringifyMessage(enumToken.value) ?? {}, null, 2)\n }\n break\n case ContentTokenType.Link:\n output += terminalLink(colors.green(stringifyMessage(enumToken.value)), enumToken.metadata.link ?? '')\n break\n case ContentTokenType.Heading:\n output += colors.bold.underline(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.SubHeading:\n output += colors.underline(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Italic:\n output += colors.italic(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.ErrorText:\n output += colors.bold.redBright(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Yellow:\n output += colors.yellow(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Cyan:\n output += colors.cyan(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Magenta:\n output += colors.magenta(stringifyMessage(enumToken.value))\n break\n case ContentTokenType.Green:\n output += colors.green(stringifyMessage(enumToken.value))\n break\n }\n }\n })\n return new TokenizedString(output)\n}\n\n/** Log levels */\nexport type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent'\n\n/**\n * It maps a level to a numeric value.\n * @param level {LogLevel} The level for which we'll return its numeric value.\n * @returns The numeric value of the level.\n */\nconst logLevelValue = (level: LogLevel): number => {\n switch (level) {\n case 'trace':\n return 10\n case 'debug':\n return 20\n case 'info':\n return 30\n case 'warn':\n return 40\n case 'error':\n return 50\n case 'fatal':\n return 60\n default:\n return 30\n }\n}\n\n/**\n *\n * @returns {LogLevel} It returns the log level set by the user.\n */\nexport const currentLogLevel = (): LogLevel => {\n if (isVerbose()) {\n return 'debug'\n } else {\n return 'info'\n }\n}\n\nexport const shouldOutput = (logLevel: LogLevel): boolean => {\n if (isUnitTest()) {\n return false\n }\n const currentLogLevelValue = logLevelValue(currentLogLevel())\n const messageLogLevelValue = logLevelValue(logLevel)\n return messageLogLevelValue >= currentLogLevelValue\n}\n\n// eslint-disable-next-line import/no-mutable-exports\nexport let collectedLogs: {[key: string]: string[]} = {}\n\n/**\n * This is only used during UnitTesting.\n * If we are in a testing context, instead of printing the logs to the console,\n * we will store them in a variable that can be accessed from the tests.\n * @param key {string} The key of the log.\n * @param content {string} The content of the log.\n */\nconst collectLog = (key: string, content: Message) => {\n const output = collectedLogs.output ?? []\n const data = collectedLogs[key] ?? []\n data.push(stripAnsi(stringifyMessage(content) ?? ''))\n output.push(stripAnsi(stringifyMessage(content) ?? ''))\n collectedLogs[key] = data\n collectedLogs.output = output\n}\n\nexport const clearCollectedLogs = () => {\n collectedLogs = {}\n}\n\n/**\n * Ouputs information to the user.\n * Info messages don't get additional formatting.\n * Note: Info messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n * @param logger {Function} The logging function to use to output to the user.\n */\nexport const info = (content: Message, logger: Logger = consoleLog) => {\n const message = stringifyMessage(content)\n if (isUnitTest()) collectLog('info', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Outputs a success message to the user.\n * Success messages receive a special formatting to make them stand out in the console.\n * Note: Success messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n * @param logger {Function} The logging function to use to output to the user.\n */\nexport const success = (content: Message, logger: Logger = consoleLog) => {\n const message = colors.bold(`✅ Success! ${stringifyMessage(content)}.`)\n if (isUnitTest()) collectLog('success', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Outputs a completed message to the user.\n * Completed message receive a special formatting to make them stand out in the console.\n * Note: Completed messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n * @param logger {Function} The logging function to use to output to the user.\n */\nexport const completed = (content: Message, logger: Logger = consoleLog) => {\n const message = `${colors.green('✔')} ${stringifyMessage(content)}`\n if (isUnitTest()) collectLog('completed', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Ouputs debug information to the user. By default these output is hidden unless the user calls the CLI with --verbose.\n * Debug messages don't get additional formatting.\n * Note: Debug messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n * @param logger {Function} The logging function to use to output to the user.\n */\nexport const debug = (content: Message, logger: Logger = consoleLog) => {\n if (isUnitTest()) collectLog('debug', content)\n const message = colors.gray(stringifyMessage(content))\n outputWhereAppropriate('debug', logger, message)\n}\n\n/**\n * Outputs a warning message to the user.\n * Warning messages receive a special formatting to make them stand out in the console.\n * Note: Warning messages are sent through the standard output.\n * @param content {string} The content to be output to the user.\n * @param logger {Function} The logging function to use to output to the user.\n */\nexport const warn = (content: Message, logger: Logger = consoleWarn) => {\n if (isUnitTest()) collectLog('warn', content)\n const message = colors.yellow(stringifyMessage(content))\n outputWhereAppropriate('warn', logger, message)\n}\n\n/**\n * Prints a new line in the terminal.\n */\nexport const newline = () => {\n console.log()\n}\n\n/**\n * Formats and outputs a fatal error.\n * Note: This API is not intended to be used internally. If you want to\n * abort the execution due to an error, raise a fatal error and let the\n * error handler handle and format it.\n * @param content {Fatal} The fatal error to be output.\n */\nexport const error = async (content: Fatal) => {\n if (!content.message) {\n return\n }\n let outputString = ''\n const message = content.message\n const padding = ' '\n const header = colors.redBright(`\\n━━━━━━ Error ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n`)\n const footer = colors.redBright('\\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n')\n outputString += header\n const lines = message.split('\\n')\n for (const line of lines) {\n outputString += `${padding}${line}\\n`\n }\n if (content.tryMessage) {\n outputString += `\\n${padding}${colors.bold('What to try:')}\\n`\n const lines = content.tryMessage.split('\\n')\n for (const line of lines) {\n outputString += `${padding}${line}\\n`\n }\n }\n\n let stack = new StackTracey(content)\n stack.items.forEach((item) => {\n item.file = cleanSingleStackTracePath(item.file)\n })\n\n stack = await stack.withSourcesAsync()\n stack = stack\n .filter((entry) => {\n return !entry.file.includes('@oclif/core')\n })\n .map((item) => {\n item.calleeShort = colors.yellow(item.calleeShort)\n /** We make the paths relative to the packages/ directory */\n const fileShortComponents = item.fileShort.split('packages/')\n item.fileShort = fileShortComponents.length === 2 ? fileShortComponents[1] : fileShortComponents[0]\n return item\n })\n if (content instanceof Bug) {\n if (stack.items.length !== 0) {\n outputString += `\\n${padding}${colors.bold('Stack trace:')}\\n`\n const stackLines = stack.asTable({}).split('\\n')\n for (const stackLine of stackLines) {\n outputString += `${padding}${stackLine}\\n`\n }\n }\n }\n outputString += footer\n outputWhereAppropriate('error', consoleError, outputString)\n}\n\nexport function stringifyMessage(message: Message): string {\n if (message instanceof TokenizedString) {\n return message.value\n } else {\n return message\n }\n}\n\nconst message = (content: Message, level: LogLevel = 'info') => {\n const stringifiedMessage = stringifyMessage(content)\n outputWhereAppropriate(level, consoleLog, stringifiedMessage)\n}\n\nexport interface OutputProcess {\n /** The prefix to include in the logs\n * [vite] Output coming from Vite\n */\n prefix: string\n /**\n * A callback to invoke the process. stdout and stderr should be used\n * to send standard output and error data that gets formatted with the\n * right prefix.\n */\n action: (stdout: Writable, stderr: Writable, signal: AbortSignal) => Promise<void>\n}\n\n/**\n * Use this function when you have multiple concurrent processes that send data events\n * and we need to output them ensuring that they can visually differenciated by the user.\n *\n * @param processes {OutputProcess[]} A list of processes to run concurrently.\n */\nexport async function concurrent(\n processes: OutputProcess[],\n callback: ((signal: AbortSignal) => void) | undefined = undefined,\n) {\n const abortController = new AbortController()\n\n // eslint-disable-next-line node/callback-return\n if (callback) callback(abortController.signal)\n\n const concurrentColors = [token.yellow, token.cyan, token.magenta, token.green]\n const prefixColumnSize = Math.max(...processes.map((process) => process.prefix.length))\n\n function linePrefix(prefix: string, index: number) {\n const colorIndex = index < concurrentColors.length ? index : index % concurrentColors.length\n const color = concurrentColors[colorIndex]\n return color(`${prefix}${' '.repeat(prefixColumnSize - prefix.length)} ${colors.bold('|')} `)\n }\n\n try {\n await Promise.all(\n processes.map(async (process, index) => {\n const stdout = new Writable({\n write(chunk, _encoding, next) {\n const lines = stripAnsiEraseCursorEscapeCharacters(chunk.toString('ascii')).split(/\\n/)\n for (const line of lines) {\n info(content`${linePrefix(process.prefix, index)}${line}`)\n }\n next()\n },\n })\n const stderr = new Writable({\n write(chunk, _encoding, next) {\n const lines = stripAnsiEraseCursorEscapeCharacters(chunk.toString('ascii')).split(/\\n/)\n for (const line of lines) {\n message(content`${linePrefix(process.prefix, index)}${colors.bold(line)}`, 'error')\n }\n next()\n },\n })\n await process.action(stdout, stderr, abortController.signal)\n }),\n )\n } catch (_error) {\n // We abort any running process\n abortController.abort()\n throw _error\n }\n}\n\n/**\n * This regex can be used to find the erase cursor Ansii characters\n * to strip them from the string.\n * https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#erase-functions\n */\nconst eraseCursorAnsiRegex = [\n // Erase the entire line\n '2K',\n // Clear vertical tab stop at current line\n '1G',\n]\n .map((element) => `[\\\\u001B\\\\u009B][[\\\\]()#;?]*${element}`)\n .join('|')\n\n/**\n * The data sent through the standard pipelines of the sub-processes that we execute\n * might contain ansii escape characters to move the cursor. That causes any additional\n * formatting to break. This function takes a string and strips escape characters that\n * manage the cursor in the terminal.\n * @param value {string} String whose erase cursor escape characters will be stripped.\n * @returns {string} Stripped string.\n */\nfunction stripAnsiEraseCursorEscapeCharacters(value: string): string {\n return value.replace(/(\\n)$/, '').replace(new RegExp(eraseCursorAnsiRegex, 'g'), '')\n}\n\nfunction consoleLog(message: string): void {\n console.log(withOrWithoutStyle(message))\n}\n\nfunction consoleError(message: string): void {\n console.error(withOrWithoutStyle(message))\n}\n\nfunction consoleWarn(message: string): void {\n console.warn(withOrWithoutStyle(message))\n}\n\nfunction outputWhereAppropriate(logLevel: LogLevel, logger: Logger, message: string): void {\n if (shouldOutput(logLevel)) {\n logger(message)\n }\n logToFile(message, logLevel.toUpperCase())\n}\n\nexport function logFileExists(): boolean {\n return Boolean(logFileStream)\n}\n\n// DO NOT USE THIS FUNCTION DIRECTLY under normal circumstances.\n// It is exported purely for use in cases where output is already being logged\n// to the terminal but is not reflected in the logfile, e.g. Listr output.\nexport function logToFile(message: string, logLevel: string): void {\n // If file logging hasn't been initiated, skip it\n if (!logFileExists()) return\n const timestamp = new Date().toISOString()\n const logContents = `[${timestamp} ${commandUuid} ${logLevel}]: ${message}\\n`\n logFileStream.write(logContents)\n}\n\nfunction withOrWithoutStyle(message: string): string {\n if (shouldDisplayColors()) {\n return message\n } else {\n return unstyled(message)\n }\n}\n\nexport function unstyled(message: string): string {\n return colors.unstyle(message)\n}\n\nexport function shouldDisplayColors(): boolean {\n return Boolean(process.stdout.isTTY || process.env.FORCE_COLOR)\n}\n\nexport async function pageLogs({lastCommand}: {lastCommand: boolean}) {\n const logDir = constants.paths.directories.cache.path()\n const logFile = pathJoin(logDir, logFileName)\n // Ensure file exists in case they deleted it or something\n fileTouchSync(logFile)\n if (lastCommand) {\n printLastCommand(logFile)\n } else {\n await page(logFile)\n }\n}\n\nfunction printLastCommand(logFile: string): void {\n const contents = fileReadSync(logFile).split('\\n')\n const uuids = contents\n .map(logfileLineUUID)\n .filter((uuid) => uuid)\n .reverse()\n // 2nd unique UUID, because the currently running command will be the 1st\n const relevantUuid = Array.from(new Set(uuids))[1]\n if (relevantUuid) {\n consoleLog(relevantLines(contents, relevantUuid).join('\\n'))\n }\n}\n\nfunction relevantLines(contents: string[], relevantUuid: string): string[] {\n // We run through the file line by line, keeping track of the most recently\n // encountered UUID.\n //\n // If the current line has a UUID, it's a new logged unit and should be\n // considered. Otherwise, the line is related to the most recent UUID.\n let mostRecentUuid = ''\n return contents.filter((line: string) => {\n const currentUuid = logfileLineUUID(line) || mostRecentUuid\n mostRecentUuid = currentUuid\n return currentUuid === relevantUuid\n })\n}\n\nfunction logfileLineUUID(line: string): string | null {\n // Log lines look like:\n //\n // timestamp UUID contents\n // ===========================================================================================\n // [2022-07-20T08:51:40.296Z 5288e1da-a06a-4f96-b1a6-e34fcdd7b416 DEBUG]: Running command logs\n // ===========================================================================================\n //\n // There may be subsequent lines if the contents section is multi-line.\n //\n const match = line.match(/^\\[\\S+ ([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}) [A-Z]+\\]/)\n return match && match[1]\n}\n\n/**\n *\n * @param packageManager {PackageManager} The package manager that is being used.\n * @param version {string} The version to update to\n * @returns {te}\n */\nexport function getOutputUpdateCLIReminder(packageManager: PackageManager, version: string): string {\n const updateCommand = token.packagejsonScript(packageManager, 'shopify', 'upgrade')\n return content`💡 Version ${version} available! Run ${updateCommand}`.value\n}\n\n/* eslint-enable no-console */\n"]}
package/dist/path.d.ts CHANGED
@@ -1,10 +1,10 @@
1
+ import { OverloadParameters } from './typing/overloaded-parameters.js';
1
2
  import { relative, dirname, join, normalize, resolve, basename, extname, isAbsolute } from 'pathe';
2
- import { findUp as internalFindUp, Match as FindUpMatch } from 'find-up';
3
+ import { findUp as internalFindUp } from 'find-up';
3
4
  export { join, relative, dirname, normalize, resolve, basename, extname, isAbsolute };
4
5
  export { default as glob } from 'fast-glob';
5
6
  export { pathToFileURL } from 'node:url';
6
- declare type FindUpMatcher = (directory: string) => FindUpMatch | Promise<FindUpMatch>;
7
- export declare function findUp(matcher: string | ReadonlyArray<string> | FindUpMatcher, options: Parameters<typeof internalFindUp>[1]): ReturnType<typeof internalFindUp>;
7
+ export declare function findUp(matcher: OverloadParameters<typeof internalFindUp>[0], options: OverloadParameters<typeof internalFindUp>[1]): ReturnType<typeof internalFindUp>;
8
8
  /**
9
9
  * Given an absolute filesystem path, it makes it relative to
10
10
  * the current working directory. This is useful when logging paths
package/dist/path.js CHANGED
@@ -1,5 +1,3 @@
1
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
- // @ts-ignore
3
1
  import commondir from 'commondir';
4
2
  import { relative, dirname, join, normalize, resolve, basename, extname, isAbsolute } from 'pathe';
5
3
  import { findUp as internalFindUp } from 'find-up';
@@ -8,8 +6,8 @@ export { join, relative, dirname, normalize, resolve, basename, extname, isAbsol
8
6
  export { default as glob } from 'fast-glob';
9
7
  export { pathToFileURL } from 'node:url';
10
8
  export async function findUp(matcher, options) {
11
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12
- // @ts-ignore
9
+ // findUp has odd typing
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
11
  const got = await internalFindUp(matcher, options);
14
12
  return got ? normalize(got) : undefined;
15
13
  }
package/dist/path.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"path.js","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,aAAa;AACb,OAAO,SAAS,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAC,MAAM,OAAO,CAAA;AAChG,OAAO,EAAC,MAAM,IAAI,cAAc,EAAuB,MAAM,SAAS,CAAA;AACtE,OAAO,EAAC,aAAa,EAAC,MAAM,KAAK,CAAA;AAEjC,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAC,CAAA;AAEnF,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAA;AACzC,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AAItC,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAuD,EACvD,OAA6C;IAE7C,6DAA6D;IAC7D,aAAa;IACb,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAClD,OAAO,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAA;IAClD,MAAM,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,CAAA;IACnG,IAAI,MAAM,KAAK,GAAG,IAAI,YAAY,KAAK,EAAE,IAAI,kBAAkB,GAAG,CAAC,EAAE;QACnE,OAAO,IAAI,CAAA;KACZ;SAAM;QACL,OAAO,YAAY,CAAA;KACpB;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,SAAuB;IACrD,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport commondir from 'commondir'\nimport {relative, dirname, join, normalize, resolve, basename, extname, isAbsolute} from 'pathe'\nimport {findUp as internalFindUp, Match as FindUpMatch} from 'find-up'\nimport {fileURLToPath} from 'url'\n\nexport {join, relative, dirname, normalize, resolve, basename, extname, isAbsolute}\n\nexport {default as glob} from 'fast-glob'\nexport {pathToFileURL} from 'node:url'\n\ntype FindUpMatcher = (directory: string) => FindUpMatch | Promise<FindUpMatch>\n\nexport async function findUp(\n matcher: string | ReadonlyArray<string> | FindUpMatcher,\n options: Parameters<typeof internalFindUp>[1],\n): ReturnType<typeof internalFindUp> {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const got = await internalFindUp(matcher, options)\n return got ? normalize(got) : undefined\n}\n\n/**\n * Given an absolute filesystem path, it makes it relative to\n * the current working directory. This is useful when logging paths\n * to allow the users to click on the file and let the OS open it\n * in the editor of choice.\n * @param path {string} Path to relativize\n * @returns {string} Relativized path.\n */\nexport function relativize(path: string): string {\n const result = commondir([path, process.cwd()])\n const relativePath = relative(process.cwd(), path)\n const relativeComponents = relativePath.split('/').filter((component) => component === '..').length\n if (result === '/' || relativePath === '' || relativeComponents > 2) {\n return path\n } else {\n return relativePath\n }\n}\n\n/**\n * Given a module's import.meta.url it returns the directory containing the module.\n * @param moduleURL {string} The value of import.meta.url in the context of the caller module.\n * @returns {string} The path to the directory containing the caller module.\n */\nexport function moduleDirectory(moduleURL: string | URL): string {\n return dirname(fileURLToPath(moduleURL))\n}\n"]}
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAC,MAAM,OAAO,CAAA;AAChG,OAAO,EAAC,MAAM,IAAI,cAAc,EAAuB,MAAM,SAAS,CAAA;AACtE,OAAO,EAAC,aAAa,EAAC,MAAM,KAAK,CAAA;AAEjC,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAC,CAAA;AAEnF,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAA;AACzC,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AAItC,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAqD,EACrD,OAAqD;IAErD,wBAAwB;IACxB,8DAA8D;IAC9D,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,OAAc,EAAE,OAAO,CAAC,CAAA;IACzD,OAAO,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAA;IAClD,MAAM,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,CAAA;IACnG,IAAI,MAAM,KAAK,GAAG,IAAI,YAAY,KAAK,EAAE,IAAI,kBAAkB,GAAG,CAAC,EAAE;QACnE,OAAO,IAAI,CAAA;KACZ;SAAM;QACL,OAAO,YAAY,CAAA;KACpB;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,SAAuB;IACrD,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import {OverloadParameters} from './typing/overloaded-parameters.js'\nimport commondir from 'commondir'\nimport {relative, dirname, join, normalize, resolve, basename, extname, isAbsolute} from 'pathe'\nimport {findUp as internalFindUp, Match as FindUpMatch} from 'find-up'\nimport {fileURLToPath} from 'url'\n\nexport {join, relative, dirname, normalize, resolve, basename, extname, isAbsolute}\n\nexport {default as glob} from 'fast-glob'\nexport {pathToFileURL} from 'node:url'\n\ntype FindUpMatcher = (directory: string) => FindUpMatch | Promise<FindUpMatch>\n\nexport async function findUp(\n matcher: OverloadParameters<typeof internalFindUp>[0],\n options: OverloadParameters<typeof internalFindUp>[1],\n): ReturnType<typeof internalFindUp> {\n // findUp has odd typing\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const got = await internalFindUp(matcher as any, options)\n return got ? normalize(got) : undefined\n}\n\n/**\n * Given an absolute filesystem path, it makes it relative to\n * the current working directory. This is useful when logging paths\n * to allow the users to click on the file and let the OS open it\n * in the editor of choice.\n * @param path {string} Path to relativize\n * @returns {string} Relativized path.\n */\nexport function relativize(path: string): string {\n const result = commondir([path, process.cwd()])\n const relativePath = relative(process.cwd(), path)\n const relativeComponents = relativePath.split('/').filter((component) => component === '..').length\n if (result === '/' || relativePath === '' || relativeComponents > 2) {\n return path\n } else {\n return relativePath\n }\n}\n\n/**\n * Given a module's import.meta.url it returns the directory containing the module.\n * @param moduleURL {string} The value of import.meta.url in the context of the caller module.\n * @returns {string} The path to the directory containing the caller module.\n */\nexport function moduleDirectory(moduleURL: string | URL): string {\n return dirname(fileURLToPath(moduleURL))\n}\n"]}
package/dist/plugins.d.ts CHANGED
@@ -1,9 +1,45 @@
1
- import { Plugin } from '@oclif/core/lib/interfaces';
1
+ import { Schemas } from './monorail.js';
2
+ import { Interfaces } from '@oclif/core';
2
3
  interface TunnelPlugin {
3
4
  start: (options: TunnelStartOptions) => Promise<string>;
4
5
  }
5
6
  interface TunnelStartOptions {
6
7
  port: number;
7
8
  }
8
- export declare function lookupTunnelPlugin(plugins: Plugin[]): Promise<TunnelPlugin | undefined>;
9
+ export declare function lookupTunnelPlugin(plugins: Interfaces.Plugin[]): Promise<TunnelPlugin | undefined>;
10
+ /**
11
+ * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.
12
+ *
13
+ * Responses are organised into a dictionary, keyed by plug-in name. Only plug-ins that have hooks registered for the given event, and the hooks were run successfully, are included.
14
+ */
15
+ export declare function fanoutHooks<TPluginMap extends HookReturnsPerPlugin, TEvent extends string & keyof TPluginMap>(config: Interfaces.Config, event: TEvent, options: TPluginMap[typeof event]['options'], timeout?: number): Promise<Partial<TPluginMap[typeof event]['pluginReturns']>>;
16
+ interface HookReturnsPerPlugin {
17
+ public_command_metadata: {
18
+ options: {
19
+ [key: string]: never;
20
+ };
21
+ pluginReturns: {
22
+ '@shopify/app': Partial<Pick<Schemas['app_cli3_command/1.0']['public'], 'project_type' | 'api_key' | 'partner_id'> & {
23
+ [key: string]: unknown;
24
+ }>;
25
+ [pluginName: string]: {
26
+ [key: string]: unknown;
27
+ };
28
+ };
29
+ };
30
+ [hookName: string]: {
31
+ options: {
32
+ [key: string]: unknown;
33
+ };
34
+ pluginReturns: {
35
+ [key: string]: {
36
+ [key: string]: unknown;
37
+ };
38
+ };
39
+ };
40
+ }
41
+ declare type PluginReturnsForHook<TEvent extends keyof TPluginMap, TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'], TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin> = TPluginMap[TEvent]['pluginReturns'][TPluginName];
42
+ export declare type FanoutHookFunction<TEvent extends keyof TPluginMap = string, TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'] = string, TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin> = (this: Interfaces.Hook.Context, options: TPluginMap[TEvent]['options'] & {
43
+ config: Interfaces.Config;
44
+ }) => Promise<Partial<PluginReturnsForHook<TEvent, TPluginName, TPluginMap>>>;
9
45
  export {};
package/dist/plugins.js CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
1
2
  import { join, pathToFileURL } from './path.js';
2
3
  import { debug, content } from './output.js';
3
4
  const TUNNEL_PLUGINS = ['@shopify/plugin-ngrok'];
@@ -9,4 +10,14 @@ export async function lookupTunnelPlugin(plugins) {
9
10
  const tunnelPath = pathToFileURL(join(tunnelPlugin.root, 'dist/tunnel.js')).toString();
10
11
  return import(tunnelPath).catch(() => undefined);
11
12
  }
13
+ /**
14
+ * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.
15
+ *
16
+ * Responses are organised into a dictionary, keyed by plug-in name. Only plug-ins that have hooks registered for the given event, and the hooks were run successfully, are included.
17
+ */
18
+ export async function fanoutHooks(config, event, options, timeout) {
19
+ const res = await config.runHook(event, options, timeout);
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ return Object.fromEntries(res.successes.map(({ result, plugin }) => [plugin.name, result]));
22
+ }
12
23
  //# sourceMappingURL=plugins.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,aAAa,EAAC,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAC,KAAK,EAAE,OAAO,EAAC,MAAM,aAAa,CAAA;AAG1C,MAAM,cAAc,GAAG,CAAC,uBAAuB,CAAC,CAAA;AAUhD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAiB;IACxD,KAAK,CAAC,OAAO,CAAA,uCAAuC,CAAC,CAAA;IACrD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IACnF,IAAI,CAAC,YAAY;QAAE,OAAO,SAAS,CAAA;IACnC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACtF,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;AAClD,CAAC","sourcesContent":["import {join, pathToFileURL} from './path.js'\nimport {debug, content} from './output.js'\nimport {Plugin} from '@oclif/core/lib/interfaces'\n\nconst TUNNEL_PLUGINS = ['@shopify/plugin-ngrok']\n\ninterface TunnelPlugin {\n start: (options: TunnelStartOptions) => Promise<string>\n}\n\ninterface TunnelStartOptions {\n port: number\n}\n\nexport async function lookupTunnelPlugin(plugins: Plugin[]): Promise<TunnelPlugin | undefined> {\n debug(content`Looking up the Ngrok tunnel plugin...`)\n const tunnelPlugin = plugins.find((plugin) => TUNNEL_PLUGINS.includes(plugin.name))\n if (!tunnelPlugin) return undefined\n const tunnelPath = pathToFileURL(join(tunnelPlugin.root, 'dist/tunnel.js')).toString()\n return import(tunnelPath).catch(() => undefined)\n}\n"]}
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,EAAC,IAAI,EAAE,aAAa,EAAC,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAC,KAAK,EAAE,OAAO,EAAC,MAAM,aAAa,CAAA;AAI1C,MAAM,cAAc,GAAG,CAAC,uBAAuB,CAAC,CAAA;AAUhD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA4B;IACnE,KAAK,CAAC,OAAO,CAAA,uCAAuC,CAAC,CAAA;IACrD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IACnF,IAAI,CAAC,YAAY;QAAE,OAAO,SAAS,CAAA;IACnC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACtF,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAyB,EACzB,KAAa,EACb,OAA4C,EAC5C,OAAgB;IAEhB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACzD,8DAA8D;IAC9D,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAC,MAAM,EAAE,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAQ,CAAA;AAClG,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\nimport {join, pathToFileURL} from './path.js'\nimport {debug, content} from './output.js'\nimport {Schemas} from './monorail.js'\nimport {Interfaces} from '@oclif/core'\n\nconst TUNNEL_PLUGINS = ['@shopify/plugin-ngrok']\n\ninterface TunnelPlugin {\n start: (options: TunnelStartOptions) => Promise<string>\n}\n\ninterface TunnelStartOptions {\n port: number\n}\n\nexport async function lookupTunnelPlugin(plugins: Interfaces.Plugin[]): Promise<TunnelPlugin | undefined> {\n debug(content`Looking up the Ngrok tunnel plugin...`)\n const tunnelPlugin = plugins.find((plugin) => TUNNEL_PLUGINS.includes(plugin.name))\n if (!tunnelPlugin) return undefined\n const tunnelPath = pathToFileURL(join(tunnelPlugin.root, 'dist/tunnel.js')).toString()\n return import(tunnelPath).catch(() => undefined)\n}\n\n/**\n * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.\n *\n * Responses are organised into a dictionary, keyed by plug-in name. Only plug-ins that have hooks registered for the given event, and the hooks were run successfully, are included.\n */\nexport async function fanoutHooks<TPluginMap extends HookReturnsPerPlugin, TEvent extends string & keyof TPluginMap>(\n config: Interfaces.Config,\n event: TEvent,\n options: TPluginMap[typeof event]['options'],\n timeout?: number,\n): Promise<Partial<TPluginMap[typeof event]['pluginReturns']>> {\n const res = await config.runHook(event, options, timeout)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Object.fromEntries(res.successes.map(({result, plugin}) => [plugin.name, result])) as any\n}\n\ninterface HookReturnsPerPlugin {\n public_command_metadata: {\n options: {[key: string]: never}\n pluginReturns: {\n '@shopify/app': Partial<\n Pick<Schemas['app_cli3_command/1.0']['public'], 'project_type' | 'api_key' | 'partner_id'> & {\n [key: string]: unknown\n }\n >\n [pluginName: string]: {[key: string]: unknown}\n }\n }\n [hookName: string]: {\n options: {[key: string]: unknown}\n pluginReturns: {[key: string]: {[key: string]: unknown}}\n }\n}\n\ntype PluginReturnsForHook<\n TEvent extends keyof TPluginMap,\n TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'],\n TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin,\n> = TPluginMap[TEvent]['pluginReturns'][TPluginName]\n\nexport type FanoutHookFunction<\n TEvent extends keyof TPluginMap = string,\n TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'] = string,\n TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin,\n> = (\n this: Interfaces.Hook.Context,\n options: TPluginMap[TEvent]['options'] & {config: Interfaces.Config},\n) => Promise<Partial<PluginReturnsForHook<TEvent, TPluginName, TPluginMap>>>\n"]}
@@ -2,10 +2,12 @@ import { listenRedirect } from './redirect-listener.js';
2
2
  import { clientId } from './identity.js';
3
3
  import { generateRandomChallengePair, randomHex } from '../string.js';
4
4
  import { open } from '../system.js';
5
- import { Abort } from '../error.js';
5
+ import { Abort, CancelExecution } from '../error.js';
6
6
  import { identity as identityFqdn } from '../environment/fqdn.js';
7
7
  import * as output from '../output.js';
8
- import { keypress } from '../ui.js';
8
+ import { keypress, terminateBlockingPortProcessPrompt } from '../ui.js';
9
+ import { checkPort as isPortAvailable } from 'get-port-please';
10
+ import { killPortProcess } from 'kill-port-process';
9
11
  export const MismatchStateError = new Abort("The state received from the authentication doesn't match the one that initiated the authentication process.");
10
12
  export async function authorize(scopes, state = randomHex(30)) {
11
13
  const port = 3456;
@@ -13,9 +15,9 @@ export async function authorize(scopes, state = randomHex(30)) {
13
15
  const redirectUri = `http://${host}:${port}`;
14
16
  const fqdn = await identityFqdn();
15
17
  const identityClientId = await clientId();
18
+ await validateRedirectionPortAvailability(port);
16
19
  let url = `http://${fqdn}/oauth/authorize`;
17
20
  const { codeVerifier, codeChallenge } = generateRandomChallengePair();
18
- /* eslint-disable @typescript-eslint/naming-convention */
19
21
  const params = {
20
22
  client_id: identityClientId,
21
23
  scope: scopes.join(' '),
@@ -25,7 +27,6 @@ export async function authorize(scopes, state = randomHex(30)) {
25
27
  code_challenge_method: 'S256',
26
28
  code_challenge: codeChallenge,
27
29
  };
28
- /* eslint-enable @typescript-eslint/naming-convention */
29
30
  output.info('\nTo run this command, log in to Shopify Partners.');
30
31
  output.info('👉 Press any key to open the login page on your browser');
31
32
  await keypress();
@@ -37,4 +38,15 @@ export async function authorize(scopes, state = randomHex(30)) {
37
38
  }
38
39
  return { code: result.code, codeVerifier };
39
40
  }
41
+ async function validateRedirectionPortAvailability(port) {
42
+ if (await isPortAvailable(port)) {
43
+ return;
44
+ }
45
+ if (await terminateBlockingPortProcessPrompt(port, 'Authentication')) {
46
+ await killPortProcess(port);
47
+ }
48
+ else {
49
+ throw new CancelExecution();
50
+ }
51
+ }
40
52
  //# sourceMappingURL=authorize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/session/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAA;AACtC,OAAO,EAAC,2BAA2B,EAAE,SAAS,EAAC,MAAM,cAAc,CAAA;AACnE,OAAO,EAAC,IAAI,EAAC,MAAM,cAAc,CAAA;AACjC,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,QAAQ,IAAI,YAAY,EAAC,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,EAAC,QAAQ,EAAC,MAAM,UAAU,CAAA;AAEjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,KAAK,CACzC,6GAA6G,CAC9G,CAAA;AAOD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAgB,EAAE,QAAgB,SAAS,CAAC,EAAE,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAA;IACjB,MAAM,IAAI,GAAG,WAAW,CAAA;IACxB,MAAM,WAAW,GAAG,UAAU,IAAI,IAAI,IAAI,EAAE,CAAA;IAC5C,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,gBAAgB,GAAG,MAAM,QAAQ,EAAE,CAAA;IAEzC,IAAI,GAAG,GAAG,UAAU,IAAI,kBAAkB,CAAA;IAE1C,MAAM,EAAC,YAAY,EAAE,aAAa,EAAC,GAAG,2BAA2B,EAAE,CAAA;IAEnE,yDAAyD;IACzD,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,gBAAgB;QAC3B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,YAAY,EAAE,WAAW;QACzB,KAAK;QACL,aAAa,EAAE,MAAM;QACrB,qBAAqB,EAAE,MAAM;QAC7B,cAAc,EAAE,aAAa;KAC9B,CAAA;IACD,wDAAwD;IAExD,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAA;IACjE,MAAM,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAA;IACtE,MAAM,QAAQ,EAAE,CAAA;IAEhB,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAA;IACxD,IAAI,CAAC,GAAG,CAAC,CAAA;IAET,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;IAEpD,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,EAAE;QAC1B,MAAM,kBAAkB,CAAA;KACzB;IAED,OAAO,EAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAC,CAAA;AAC1C,CAAC","sourcesContent":["import {listenRedirect} from './redirect-listener.js'\nimport {clientId} from './identity.js'\nimport {generateRandomChallengePair, randomHex} from '../string.js'\nimport {open} from '../system.js'\nimport {Abort} from '../error.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport * as output from '../output.js'\nimport {keypress} from '../ui.js'\n\nexport const MismatchStateError = new Abort(\n \"The state received from the authentication doesn't match the one that initiated the authentication process.\",\n)\n\nexport interface CodeAuthResult {\n code: string\n codeVerifier: string\n}\n\nexport async function authorize(scopes: string[], state: string = randomHex(30)): Promise<CodeAuthResult> {\n const port = 3456\n const host = '127.0.0.1'\n const redirectUri = `http://${host}:${port}`\n const fqdn = await identityFqdn()\n const identityClientId = await clientId()\n\n let url = `http://${fqdn}/oauth/authorize`\n\n const {codeVerifier, codeChallenge} = generateRandomChallengePair()\n\n /* eslint-disable @typescript-eslint/naming-convention */\n const params = {\n client_id: identityClientId,\n scope: scopes.join(' '),\n redirect_uri: redirectUri,\n state,\n response_type: 'code',\n code_challenge_method: 'S256',\n code_challenge: codeChallenge,\n }\n /* eslint-enable @typescript-eslint/naming-convention */\n\n output.info('\\nTo run this command, log in to Shopify Partners.')\n output.info('👉 Press any key to open the login page on your browser')\n await keypress()\n\n url = `${url}?${new URLSearchParams(params).toString()}`\n open(url)\n\n const result = await listenRedirect(host, port, url)\n\n if (result.state !== state) {\n throw MismatchStateError\n }\n\n return {code: result.code, codeVerifier}\n}\n"]}
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/session/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAA;AACtC,OAAO,EAAC,2BAA2B,EAAE,SAAS,EAAC,MAAM,cAAc,CAAA;AACnE,OAAO,EAAC,IAAI,EAAC,MAAM,cAAc,CAAA;AACjC,OAAO,EAAC,KAAK,EAAE,eAAe,EAAC,MAAM,aAAa,CAAA;AAClD,OAAO,EAAC,QAAQ,IAAI,YAAY,EAAC,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,EAAC,QAAQ,EAAE,kCAAkC,EAAC,MAAM,UAAU,CAAA;AACrE,OAAO,EAAC,SAAS,IAAI,eAAe,EAAC,MAAM,iBAAiB,CAAA;AAC5D,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AAEjD,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,KAAK,CACzC,6GAA6G,CAC9G,CAAA;AAOD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAgB,EAAE,QAAgB,SAAS,CAAC,EAAE,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAA;IACjB,MAAM,IAAI,GAAG,WAAW,CAAA;IACxB,MAAM,WAAW,GAAG,UAAU,IAAI,IAAI,IAAI,EAAE,CAAA;IAC5C,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,gBAAgB,GAAG,MAAM,QAAQ,EAAE,CAAA;IAEzC,MAAM,mCAAmC,CAAC,IAAI,CAAC,CAAA;IAE/C,IAAI,GAAG,GAAG,UAAU,IAAI,kBAAkB,CAAA;IAE1C,MAAM,EAAC,YAAY,EAAE,aAAa,EAAC,GAAG,2BAA2B,EAAE,CAAA;IAEnE,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,gBAAgB;QAC3B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,YAAY,EAAE,WAAW;QACzB,KAAK;QACL,aAAa,EAAE,MAAM;QACrB,qBAAqB,EAAE,MAAM;QAC7B,cAAc,EAAE,aAAa;KAC9B,CAAA;IAED,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAA;IACjE,MAAM,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAA;IACtE,MAAM,QAAQ,EAAE,CAAA;IAEhB,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAA;IACxD,IAAI,CAAC,GAAG,CAAC,CAAA;IAET,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;IAEpD,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,EAAE;QAC1B,MAAM,kBAAkB,CAAA;KACzB;IAED,OAAO,EAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAC,CAAA;AAC1C,CAAC;AAED,KAAK,UAAU,mCAAmC,CAAC,IAAY;IAC7D,IAAI,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE;QAC/B,OAAM;KACP;IAED,IAAI,MAAM,kCAAkC,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE;QACpE,MAAM,eAAe,CAAC,IAAI,CAAC,CAAA;KAC5B;SAAM;QACL,MAAM,IAAI,eAAe,EAAE,CAAA;KAC5B;AACH,CAAC","sourcesContent":["import {listenRedirect} from './redirect-listener.js'\nimport {clientId} from './identity.js'\nimport {generateRandomChallengePair, randomHex} from '../string.js'\nimport {open} from '../system.js'\nimport {Abort, CancelExecution} from '../error.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport * as output from '../output.js'\nimport {keypress, terminateBlockingPortProcessPrompt} from '../ui.js'\nimport {checkPort as isPortAvailable} from 'get-port-please'\nimport {killPortProcess} from 'kill-port-process'\n\nexport const MismatchStateError = new Abort(\n \"The state received from the authentication doesn't match the one that initiated the authentication process.\",\n)\n\nexport interface CodeAuthResult {\n code: string\n codeVerifier: string\n}\n\nexport async function authorize(scopes: string[], state: string = randomHex(30)): Promise<CodeAuthResult> {\n const port = 3456\n const host = '127.0.0.1'\n const redirectUri = `http://${host}:${port}`\n const fqdn = await identityFqdn()\n const identityClientId = await clientId()\n\n await validateRedirectionPortAvailability(port)\n\n let url = `http://${fqdn}/oauth/authorize`\n\n const {codeVerifier, codeChallenge} = generateRandomChallengePair()\n\n const params = {\n client_id: identityClientId,\n scope: scopes.join(' '),\n redirect_uri: redirectUri,\n state,\n response_type: 'code',\n code_challenge_method: 'S256',\n code_challenge: codeChallenge,\n }\n\n output.info('\\nTo run this command, log in to Shopify Partners.')\n output.info('👉 Press any key to open the login page on your browser')\n await keypress()\n\n url = `${url}?${new URLSearchParams(params).toString()}`\n open(url)\n\n const result = await listenRedirect(host, port, url)\n\n if (result.state !== state) {\n throw MismatchStateError\n }\n\n return {code: result.code, codeVerifier}\n}\n\nasync function validateRedirectionPortAvailability(port: number) {\n if (await isPortAvailable(port)) {\n return\n }\n\n if (await terminateBlockingPortProcessPrompt(port, 'Authentication')) {\n await killPortProcess(port)\n } else {\n throw new CancelExecution()\n }\n}\n"]}