@shopify/cli-kit 3.49.7 → 3.50.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.
- package/assets/cli-ruby/lib/project_types/theme/commands/console.rb +3 -1
- package/assets/cli-ruby/lib/shopify_cli/theme/file.rb +2 -0
- package/assets/cli-ruby/lib/shopify_cli/theme/repl/auth_dev_server.rb +2 -4
- package/assets/cli-ruby/lib/shopify_cli/theme/repl/remote_evaluator.rb +3 -0
- package/assets/cli-ruby/lib/shopify_cli/theme/repl.rb +4 -3
- package/dist/private/node/constants.d.ts +2 -0
- package/dist/private/node/constants.js +2 -0
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/context/utilities.js +2 -3
- package/dist/private/node/context/utilities.js.map +1 -1
- package/dist/private/node/otel-metrics.d.ts +32 -0
- package/dist/private/node/otel-metrics.js +131 -0
- package/dist/private/node/otel-metrics.js.map +1 -0
- package/dist/private/node/session/authorize.js +8 -5
- package/dist/private/node/session/authorize.js.map +1 -1
- package/dist/private/node/testing/ui.d.ts +4 -2
- package/dist/private/node/testing/ui.js +10 -3
- package/dist/private/node/testing/ui.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.js +6 -2
- package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.test.js +5 -3
- package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/DangerousConfirmationPrompt.js +12 -6
- package/dist/private/node/ui/components/DangerousConfirmationPrompt.js.map +1 -1
- package/dist/private/node/ui/components/DangerousConfirmationPrompt.test.js +1 -1
- package/dist/private/node/ui/components/DangerousConfirmationPrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/Prompts/GitDiff.test.js +18 -11
- package/dist/private/node/ui/components/Prompts/GitDiff.test.js.map +1 -1
- package/dist/private/node/ui/components/SelectPrompt.js +8 -4
- package/dist/private/node/ui/components/SelectPrompt.js.map +1 -1
- package/dist/private/node/ui/components/SelectPrompt.test.js +5 -3
- package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.js +8 -1
- package/dist/private/node/ui/components/Tasks.js.map +1 -1
- package/dist/private/node/ui/components/TextPrompt.js +7 -3
- package/dist/private/node/ui/components/TextPrompt.js.map +1 -1
- package/dist/private/node/ui/components/TokenizedText.d.ts +10 -1
- package/dist/private/node/ui/components/TokenizedText.js +18 -0
- package/dist/private/node/ui/components/TokenizedText.js.map +1 -1
- package/dist/private/node/ui/components/TokenizedText.test.js +10 -1
- package/dist/private/node/ui/components/TokenizedText.test.js.map +1 -1
- package/dist/private/node/ui/utilities.d.ts +1 -1
- package/dist/public/common/version.d.ts +1 -1
- package/dist/public/common/version.js +1 -1
- package/dist/public/common/version.js.map +1 -1
- package/dist/public/node/analytics.d.ts +2 -0
- package/dist/public/node/analytics.js +48 -10
- package/dist/public/node/analytics.js.map +1 -1
- package/dist/public/node/api/graphql.js +8 -5
- package/dist/public/node/api/graphql.js.map +1 -1
- package/dist/public/node/base-command.js +4 -3
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/cli.js +5 -2
- package/dist/public/node/cli.js.map +1 -1
- package/dist/public/node/context/local.d.ts +16 -0
- package/dist/public/node/context/local.js +23 -0
- package/dist/public/node/context/local.js.map +1 -1
- package/dist/public/node/error-handler.d.ts +4 -1
- package/dist/public/node/error-handler.js +26 -18
- package/dist/public/node/error-handler.js.map +1 -1
- package/dist/public/node/error.d.ts +1 -1
- package/dist/public/node/error.js +1 -1
- package/dist/public/node/error.js.map +1 -1
- package/dist/public/node/hooks/postrun.js +1 -1
- package/dist/public/node/hooks/postrun.js.map +1 -1
- package/dist/public/node/http.js +27 -22
- package/dist/public/node/http.js.map +1 -1
- package/dist/public/node/metadata.d.ts +12 -4
- package/dist/public/node/metadata.js +52 -4
- package/dist/public/node/metadata.js.map +1 -1
- package/dist/public/node/monorail.d.ts +8 -1
- package/dist/public/node/monorail.js +1 -1
- package/dist/public/node/monorail.js.map +1 -1
- package/dist/public/node/node-package-manager.d.ts +6 -0
- package/dist/public/node/node-package-manager.js +16 -2
- package/dist/public/node/node-package-manager.js.map +1 -1
- package/dist/public/node/testing/ui.d.ts +1 -1
- package/dist/public/node/testing/ui.js +1 -1
- package/dist/public/node/testing/ui.js.map +1 -1
- package/dist/public/node/ui.d.ts +1 -1
- package/dist/public/node/ui.js +63 -56
- package/dist/public/node/ui.js.map +1 -1
- package/dist/public/node/vendor/otel-js/export/InstantaneousMetricReader.d.ts +18 -0
- package/dist/public/node/vendor/otel-js/export/InstantaneousMetricReader.js +36 -0
- package/dist/public/node/vendor/otel-js/export/InstantaneousMetricReader.js.map +1 -0
- package/dist/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.d.ts +46 -0
- package/dist/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.js +112 -0
- package/dist/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.js.map +1 -0
- package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultMeterProvider.d.ts +13 -0
- package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultMeterProvider.js +36 -0
- package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultMeterProvider.js.map +1 -0
- package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.d.ts +24 -0
- package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.js +33 -0
- package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.js.map +1 -0
- package/dist/public/node/vendor/otel-js/service/types.d.ts +43 -0
- package/dist/public/node/vendor/otel-js/service/types.js +7 -0
- package/dist/public/node/vendor/otel-js/service/types.js.map +1 -0
- package/dist/public/node/vendor/otel-js/utils/throttle.d.ts +7 -0
- package/dist/public/node/vendor/otel-js/utils/throttle.js +42 -0
- package/dist/public/node/vendor/otel-js/utils/throttle.js.map +1 -0
- package/dist/public/node/vendor/otel-js/utils/validators.d.ts +1 -0
- package/dist/public/node/vendor/otel-js/utils/validators.js +11 -0
- package/dist/public/node/vendor/otel-js/utils/validators.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -16
- package/assets/cli-ruby/RELEASING.md +0 -72
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../src/public/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {reportAnalyticsEvent} from './analytics.js'\nimport * as path from './path.js'\nimport {fanoutHooks} from './plugins.js'\nimport * as metadata from './metadata.js'\nimport {\n AbortSilentError,\n CancelExecution,\n errorMapper,\n shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from './error.js'\nimport {getEnvironmentData} from '../../private/node/analytics.js'\nimport {outputDebug, outputInfo} from '../../public/node/output.js'\nimport {bugsnagApiKey} from '../../private/node/constants.js'\nimport {printEventsJson} from '../../private/node/demo-recorder.js'\nimport {CLI_KIT_VERSION} from '../common/version.js'\nimport {Bugsnag} from '../../private/node/error-handler.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(\n error: (CancelExecution | AbortSilentError) & {exitCode?: number | undefined},\n config?: Interfaces.Config,\n): void\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config): Promise<void>\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config): unknown {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n outputInfo(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilentError) {\n exit(1)\n } else {\n return errorMapper(error)\n .then((error) => {\n return handler(error)\n })\n .then((mappedError) => reportError(mappedError, config))\n .then(() => {\n exit(1)\n })\n }\n}\n\nfunction exit(code: number) {\n printEventsJson()\n process.exit(code)\n}\n\nconst reportError = async (error: unknown, config?: Interfaces.Config): Promise<void> => {\n if (config !== undefined) {\n // Log an analytics event when there's an error\n await reportAnalyticsEvent({config, errorMessage: error instanceof Error ? error.message : undefined})\n }\n await sendErrorToBugsnag(error)\n}\n\n/**\n * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.\n *\n * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not\n */\nexport async function sendErrorToBugsnag(\n error: unknown,\n): Promise<{reported: false; error: unknown} | {error: Error; reported: true}> {\n if (settings.debug || !shouldReportError(error)) return {reported: false, error}\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n if (error instanceof Error) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && error.trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n initializeBugsnag()\n await new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n Bugsnag.notify(reportableError, undefined, (error, event) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n })\n })\n }\n return {error: reportableError, reported: report}\n}\n\n/**\n * If the given file path is within a node_modules folder, remove prefix up\n * to and including the node_modules folder.\n *\n * This gives us very consistent paths for errors generated by the CLI.\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolutePath(currentFilePath)\n ? currentFilePath\n : path.joinPath(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.joinPath(matchingPluginPath.name, path.relativePath(matchingPluginPath.pluginPath, fullLocation))\n }\n\n // strip prefix up to node_modules folder, so we can normalize error reporting\n return currentFilePath.replace(/.*node_modules\\//, '')\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(config: Interfaces.Config): Promise<void> {\n // Bugsnag have their own plug-ins that use this private field\n\n const bugsnagConfigProjectRoot: string = Bugsnag?._client?._config?.projectRoot ?? path.cwd()\n const projectRoot = path.normalizePath(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n config.plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalizePath(followSymlinks)}\n }),\n )\n initializeBugsnag()\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n Bugsnag.addOnError(async (event) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n event.errors.forEach((error: any) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error.stacktrace.forEach((stackFrame: any) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n try {\n await addBugsnagMetadata(event, config)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (metadataError) {\n outputDebug(`There was an error adding metadata to the Bugsnag report; Ignoring and carrying on ${metadataError}`)\n }\n })\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\nexport async function addBugsnagMetadata(event: any, config: Interfaces.Config): Promise<void> {\n const publicData = metadata.getAllPublicMetadata()\n const {commandStartOptions} = metadata.getAllSensitiveMetadata()\n const {startCommand} = commandStartOptions ?? {}\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n\n const environment = await getEnvironmentData(config)\n\n const allMetadata = {\n command: startCommand,\n ...appPublic,\n ...publicData,\n ...environment,\n pluginData: otherPluginsPublic,\n }\n\n const appData = {} as {[key: string]: unknown}\n const commandData = {} as {[key: string]: unknown}\n const environmentData = {} as {[key: string]: unknown}\n const miscData = {} as {[key: string]: unknown}\n const appKeys = ['api_key', 'partner_id', 'project_type']\n const commandKeys = ['command']\n const environmentKeys = ['cli_version', 'node_version', 'ruby_version', 'uname']\n\n Object.entries(allMetadata).forEach(([key, value]) => {\n if (key.startsWith('app_') || appKeys.includes(key)) {\n appData[key] = value\n } else if (key.startsWith('cmd_') || commandKeys.includes(key)) {\n commandData[key] = value\n } else if (key.startsWith('env_') || environmentKeys) {\n environmentData[key] = value\n } else {\n miscData[key] = value\n }\n })\n\n // app, command, environment, misc\n const bugsnagMetadata = {\n 'Shopify App': appData,\n Command: commandData,\n Environment: environmentData,\n Misc: miscData,\n }\n Object.entries(bugsnagMetadata).forEach(([section, values]) => {\n event.addMetadata(section, values)\n })\n}\n\nfunction initializeBugsnag() {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (Bugsnag.isStarted()) {\n return\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n Bugsnag.start({\n appType: 'node',\n apiKey: bugsnagApiKey,\n logger: null,\n appVersion: CLI_KIT_VERSION,\n autoTrackSessions: false,\n autoDetectErrors: false,\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../src/public/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {CommandExitMode, reportAnalyticsEvent} from './analytics.js'\nimport * as path from './path.js'\nimport {fanoutHooks} from './plugins.js'\nimport * as metadata from './metadata.js'\nimport {\n AbortSilentError,\n CancelExecution,\n errorMapper,\n shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from './error.js'\nimport {getEnvironmentData} from '../../private/node/analytics.js'\nimport {outputDebug, outputInfo} from '../../public/node/output.js'\nimport {bugsnagApiKey} from '../../private/node/constants.js'\nimport {printEventsJson} from '../../private/node/demo-recorder.js'\nimport {CLI_KIT_VERSION} from '../common/version.js'\nimport {Bugsnag} from '../../private/node/error-handler.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport {Event} from '@bugsnag/js'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(\n error: (CancelExecution | AbortSilentError) & {exitCode?: number | undefined},\n config?: Interfaces.Config,\n): void\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config): Promise<void>\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config): unknown {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n outputInfo(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilentError) {\n printEventsJson()\n } else {\n return errorMapper(error)\n .then((error) => {\n return handler(error)\n })\n .then((mappedError) => {\n printEventsJson()\n return reportError(mappedError, config)\n })\n }\n}\n\nconst reportError = async (error: unknown, config?: Interfaces.Config): Promise<void> => {\n // categorise the error first\n let exitMode: CommandExitMode = 'expected_error'\n if (shouldReportError(error)) exitMode = 'unexpected_error'\n\n if (config !== undefined) {\n // Log an analytics event when there's an error\n await reportAnalyticsEvent({config, errorMessage: error instanceof Error ? error.message : undefined, exitMode})\n }\n await sendErrorToBugsnag(error, exitMode)\n}\n\n/**\n * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.\n *\n * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not\n */\nexport async function sendErrorToBugsnag(\n error: unknown,\n exitMode: Omit<CommandExitMode, 'ok'>,\n): Promise<{reported: false; error: unknown; unhandled: unknown} | {error: Error; reported: true; unhandled: boolean}> {\n if (settings.debug) {\n outputDebug(`Skipping Bugsnag report`)\n return {reported: false, error, unhandled: undefined}\n }\n\n // If the error was unexpected, we flag it as \"unhandled\" in Bugsnag. This is a helpful distinction.\n const unhandled = exitMode === 'unexpected_error'\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n if (error instanceof Error) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && error.trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n initializeBugsnag()\n await new Promise((resolve, reject) => {\n outputDebug(`Reporting ${unhandled ? 'unhandled' : 'handled'} error to Bugsnag: ${reportableError.message}`)\n const eventHandler = (event: Event) => {\n event.severity = 'error'\n event.unhandled = unhandled\n }\n const errorHandler = (error: unknown) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n }\n Bugsnag.notify(reportableError, eventHandler, errorHandler)\n })\n }\n return {error: reportableError, reported: report, unhandled}\n}\n\n/**\n * If the given file path is within a node_modules folder, remove prefix up\n * to and including the node_modules folder.\n *\n * This gives us very consistent paths for errors generated by the CLI.\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolutePath(currentFilePath)\n ? currentFilePath\n : path.joinPath(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.joinPath(matchingPluginPath.name, path.relativePath(matchingPluginPath.pluginPath, fullLocation))\n }\n\n // strip prefix up to node_modules folder, so we can normalize error reporting\n return currentFilePath.replace(/.*node_modules\\//, '')\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(config: Interfaces.Config): Promise<void> {\n // Bugsnag have their own plug-ins that use this private field\n\n const bugsnagConfigProjectRoot: string = Bugsnag?._client?._config?.projectRoot ?? path.cwd()\n const projectRoot = path.normalizePath(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n config.plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalizePath(followSymlinks)}\n }),\n )\n initializeBugsnag()\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n Bugsnag.addOnError(async (event) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n event.errors.forEach((error: any) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error.stacktrace.forEach((stackFrame: any) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n try {\n await addBugsnagMetadata(event, config)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (metadataError) {\n outputDebug(`There was an error adding metadata to the Bugsnag report; Ignoring and carrying on ${metadataError}`)\n }\n })\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\nexport async function addBugsnagMetadata(event: any, config: Interfaces.Config): Promise<void> {\n const publicData = metadata.getAllPublicMetadata()\n const {commandStartOptions} = metadata.getAllSensitiveMetadata()\n const {startCommand} = commandStartOptions ?? {}\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n\n const environment = await getEnvironmentData(config)\n\n const allMetadata = {\n command: startCommand,\n ...appPublic,\n ...publicData,\n ...environment,\n pluginData: otherPluginsPublic,\n }\n\n const appData = {} as {[key: string]: unknown}\n const commandData = {} as {[key: string]: unknown}\n const environmentData = {} as {[key: string]: unknown}\n const miscData = {} as {[key: string]: unknown}\n const appKeys = ['api_key', 'partner_id', 'project_type']\n const commandKeys = ['command']\n const environmentKeys = ['cli_version', 'node_version', 'ruby_version', 'uname']\n\n Object.entries(allMetadata).forEach(([key, value]) => {\n if (key.startsWith('app_') || appKeys.includes(key)) {\n appData[key] = value\n } else if (key.startsWith('cmd_') || commandKeys.includes(key)) {\n commandData[key] = value\n } else if (key.startsWith('env_') || environmentKeys) {\n environmentData[key] = value\n } else {\n miscData[key] = value\n }\n })\n\n // app, command, environment, misc\n const bugsnagMetadata = {\n 'Shopify App': appData,\n Command: commandData,\n Environment: environmentData,\n Misc: miscData,\n }\n Object.entries(bugsnagMetadata).forEach(([section, values]) => {\n event.addMetadata(section, values)\n })\n}\n\nfunction initializeBugsnag() {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (Bugsnag.isStarted()) {\n return\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n Bugsnag.start({\n appType: 'node',\n apiKey: bugsnagApiKey,\n logger: null,\n appVersion: CLI_KIT_VERSION,\n autoTrackSessions: false,\n autoDetectErrors: false,\n })\n}\n"]}
|
|
@@ -74,7 +74,7 @@ export declare function handler(error: unknown): Promise<unknown>;
|
|
|
74
74
|
*/
|
|
75
75
|
export declare function errorMapper(error: unknown): Promise<unknown>;
|
|
76
76
|
/**
|
|
77
|
-
* A function that checks if an error should be reported.
|
|
77
|
+
* A function that checks if an error should be reported as unhandled.
|
|
78
78
|
*
|
|
79
79
|
* @param error - Error to be checked.
|
|
80
80
|
* @returns A boolean indicating if the error should be reported.
|
|
@@ -145,7 +145,7 @@ function isFatal(error) {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
/**
|
|
148
|
-
* A function that checks if an error should be reported.
|
|
148
|
+
* A function that checks if an error should be reported as unhandled.
|
|
149
149
|
*
|
|
150
150
|
* @param error - Error to be checked.
|
|
151
151
|
* @returns A boolean indicating if the error should be reported.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/public/node/error.ts"],"names":[],"mappings":"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","sourcesContent":["import {AlertCustomSection, renderFatalError} from './ui.js'\nimport {OutputMessage, stringifyMessage, TokenizedString} from '../../public/node/output.js'\nimport {normalizePath} from '../../public/node/path.js'\nimport {InlineToken, TokenItem, tokenItemToString} from '../../private/node/ui/components/TokenizedText.js'\nimport {Errors} from '@oclif/core'\n\nexport {ExtendableError} from 'ts-error'\n\nexport enum FatalErrorType {\n Abort,\n AbortSilent,\n Bug,\n}\n\nexport class CancelExecution extends Error {}\n\n/**\n * A fatal error represents an error shouldn't be rescued and that causes the execution to terminate.\n * There shouldn't be code that catches fatal errors.\n */\nexport abstract class FatalError extends Error {\n tryMessage: TokenItem | null\n type: FatalErrorType\n nextSteps?: TokenItem<InlineToken>[]\n formattedMessage?: TokenItem\n customSections?: AlertCustomSection[]\n /**\n * Creates a new FatalError error.\n *\n * @param message - The error message.\n * @param type - The type of fatal error.\n * @param tryMessage - The message that recommends next steps to the user.\n * You can pass a string a {@link TokenizedString} or a {@link TokenItem}\n * if you need to style the message inside the error Banner component.\n * @param nextSteps - Message to show as \"next steps\" with suggestions to solve the issue.\n * @param customSections - Custom sections to show in the error banner. To be used if nextSteps is not enough.\n */\n constructor(\n message: TokenItem | OutputMessage,\n type: FatalErrorType,\n tryMessage: TokenItem | OutputMessage | null = null,\n nextSteps?: TokenItem<InlineToken>[],\n customSections?: AlertCustomSection[],\n ) {\n const messageIsOutputMessage = typeof message === 'string' || 'value' in message\n super(messageIsOutputMessage ? stringifyMessage(message) : tokenItemToString(message))\n\n if (tryMessage) {\n if (tryMessage instanceof TokenizedString) {\n this.tryMessage = stringifyMessage(tryMessage)\n } else {\n this.tryMessage = tryMessage\n }\n } else {\n this.tryMessage = null\n }\n\n this.type = type\n this.nextSteps = nextSteps\n this.customSections = customSections\n\n if (!messageIsOutputMessage) {\n this.formattedMessage = message\n }\n }\n}\n\n/**\n * An abort error is a fatal error that shouldn't be reported as a bug.\n * Those usually represent unexpected scenarios that we can't handle and that usually require some action from the developer.\n */\nexport class AbortError extends FatalError {\n nextSteps?: TokenItem<InlineToken>[]\n customSections?: AlertCustomSection[]\n constructor(\n message: TokenItem | OutputMessage,\n tryMessage: TokenItem | OutputMessage | null = null,\n nextSteps?: TokenItem<InlineToken>[],\n customSections?: AlertCustomSection[],\n ) {\n super(message, FatalErrorType.Abort, tryMessage, nextSteps, customSections)\n }\n}\n\n/**\n * An external error is similar to Abort but has extra command and args attributes.\n * This is useful to represent errors coming from external commands, usually executed by execa.\n */\nexport class ExternalError extends FatalError {\n command: string\n args: string[]\n\n constructor(\n message: OutputMessage,\n command: string,\n args: string[],\n tryMessage: TokenItem | OutputMessage | null = null,\n ) {\n super(message, FatalErrorType.Abort, tryMessage)\n this.command = command\n this.args = args\n }\n}\n\nexport class AbortSilentError extends FatalError {\n constructor() {\n super('', FatalErrorType.AbortSilent)\n }\n}\n\n/**\n * A bug error is an error that represents a bug and therefore should be reported.\n */\nexport class BugError extends FatalError {\n constructor(message: TokenItem | OutputMessage, tryMessage: TokenItem | OutputMessage | null = null) {\n super(message, FatalErrorType.Bug, tryMessage)\n }\n}\n\n/**\n * A function that handles errors that blow up in the CLI.\n *\n * @param error - Error to be handled.\n * @returns A promise that resolves with the error passed.\n */\nexport async function handler(error: unknown): Promise<unknown> {\n let fatal: FatalError\n if (isFatal(error)) {\n fatal = error\n } else if (typeof error === 'string') {\n fatal = new BugError(error)\n } else if (error instanceof Error) {\n fatal = new BugError(error.message)\n fatal.stack = error.stack\n } else {\n // errors can come in all shapes and sizes...\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeError = error as any\n fatal = new BugError(maybeError?.message ?? 'Unknown error')\n if (maybeError?.stack) {\n fatal.stack = maybeError?.stack\n }\n }\n\n renderFatalError(fatal)\n return Promise.resolve(error)\n}\n\n/**\n * A function that maps an error to an Abort with the stack trace when coming from the CLI.\n *\n * @param error - Error to be mapped.\n * @returns A promise that resolves with the new error object.\n */\nexport function errorMapper(error: unknown): Promise<unknown> {\n if (error instanceof Errors.CLIError) {\n const mappedError = new AbortError(error.message)\n mappedError.stack = error.stack\n return Promise.resolve(mappedError)\n } else {\n return Promise.resolve(error)\n }\n}\n\n/**\n * A function that checks if an error is a fatal one.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error is a fatal one.\n */\nfunction isFatal(error: unknown): error is FatalError {\n try {\n return Object.prototype.hasOwnProperty.call(error, 'type')\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * A function that checks if an error should be reported.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error should be reported.\n */\nexport function shouldReportError(error: unknown): boolean {\n if (!isFatal(error)) {\n return true\n }\n if (error.type === FatalErrorType.Bug) {\n return true\n }\n return false\n}\n\n/**\n * Stack traces usually have file:// - we strip that and also remove the Windows drive designation.\n *\n * @param filePath - Path to be cleaned.\n * @returns The cleaned path.\n */\nexport function cleanSingleStackTracePath(filePath: string): string {\n return normalizePath(filePath)\n .replace('file:/', '/')\n .replace(/^\\/?[A-Z]:/, '')\n}\n"]}
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/public/node/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,gBAAgB,EAAC,MAAM,SAAS,CAAA;AAC5D,OAAO,EAAgB,gBAAgB,EAAE,eAAe,EAAC,MAAM,6BAA6B,CAAA;AAC5F,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAA;AACvD,OAAO,EAAyB,iBAAiB,EAAC,MAAM,mDAAmD,CAAA;AAC3G,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAElC,OAAO,EAAC,eAAe,EAAC,MAAM,UAAU,CAAA;AAExC,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,qDAAK,CAAA;IACL,iEAAW,CAAA;IACX,iDAAG,CAAA;AACL,CAAC,EAJW,cAAc,KAAd,cAAc,QAIzB;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;CAAG;AAE7C;;;GAGG;AACH,MAAM,OAAgB,UAAW,SAAQ,KAAK;IAM5C;;;;;;;;;;OAUG;IACH,YACE,OAAkC,EAClC,IAAoB,EACpB,aAA+C,IAAI,EACnD,SAAoC,EACpC,cAAqC;QAErC,MAAM,sBAAsB,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,OAAO,CAAA;QAChF,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAA;QAEtF,IAAI,UAAU,EAAE;YACd,IAAI,UAAU,YAAY,eAAe,EAAE;gBACzC,IAAI,CAAC,UAAU,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAA;aAC/C;iBAAM;gBACL,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;aAC7B;SACF;aAAM;YACL,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;SACvB;QAED,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAA;QAEpC,IAAI,CAAC,sBAAsB,EAAE;YAC3B,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAA;SAChC;IACH,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,UAAW,SAAQ,UAAU;IAGxC,YACE,OAAkC,EAClC,aAA+C,IAAI,EACnD,SAAoC,EACpC,cAAqC;QAErC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,CAAA;IAC7E,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,UAAU;IAI3C,YACE,OAAsB,EACtB,OAAe,EACf,IAAc,EACd,aAA+C,IAAI;QAEnD,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;QAChD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C;QACE,KAAK,CAAC,EAAE,EAAE,cAAc,CAAC,WAAW,CAAC,CAAA;IACvC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,UAAU;IACtC,YAAY,OAAkC,EAAE,aAA+C,IAAI;QACjG,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;IAChD,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAc;IAC1C,IAAI,KAAiB,CAAA;IACrB,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;QAClB,KAAK,GAAG,KAAK,CAAA;KACd;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACpC,KAAK,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAA;KAC5B;SAAM,IAAI,KAAK,YAAY,KAAK,EAAE;QACjC,KAAK,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACnC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;KAC1B;SAAM;QACL,6CAA6C;QAC7C,8DAA8D;QAC9D,MAAM,UAAU,GAAG,KAAY,CAAA;QAC/B,KAAK,GAAG,IAAI,QAAQ,CAAC,UAAU,EAAE,OAAO,IAAI,eAAe,CAAC,CAAA;QAC5D,IAAI,UAAU,EAAE,KAAK,EAAE;YACrB,KAAK,CAAC,KAAK,GAAG,UAAU,EAAE,KAAK,CAAA;SAChC;KACF;IAED,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACvB,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,MAAM,CAAC,QAAQ,EAAE;QACpC,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACjD,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;QAC/B,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;KACpC;SAAM;QACL,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;KAC9B;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI;QACF,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC1D,qDAAqD;KACtD;IAAC,MAAM;QACN,OAAO,KAAK,CAAA;KACb;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACnB,OAAO,IAAI,CAAA;KACZ;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,GAAG,EAAE;QACrC,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAAgB;IACxD,OAAO,aAAa,CAAC,QAAQ,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;AAC9B,CAAC","sourcesContent":["import {AlertCustomSection, renderFatalError} from './ui.js'\nimport {OutputMessage, stringifyMessage, TokenizedString} from '../../public/node/output.js'\nimport {normalizePath} from '../../public/node/path.js'\nimport {InlineToken, TokenItem, tokenItemToString} from '../../private/node/ui/components/TokenizedText.js'\nimport {Errors} from '@oclif/core'\n\nexport {ExtendableError} from 'ts-error'\n\nexport enum FatalErrorType {\n Abort,\n AbortSilent,\n Bug,\n}\n\nexport class CancelExecution extends Error {}\n\n/**\n * A fatal error represents an error shouldn't be rescued and that causes the execution to terminate.\n * There shouldn't be code that catches fatal errors.\n */\nexport abstract class FatalError extends Error {\n tryMessage: TokenItem | null\n type: FatalErrorType\n nextSteps?: TokenItem<InlineToken>[]\n formattedMessage?: TokenItem\n customSections?: AlertCustomSection[]\n /**\n * Creates a new FatalError error.\n *\n * @param message - The error message.\n * @param type - The type of fatal error.\n * @param tryMessage - The message that recommends next steps to the user.\n * You can pass a string a {@link TokenizedString} or a {@link TokenItem}\n * if you need to style the message inside the error Banner component.\n * @param nextSteps - Message to show as \"next steps\" with suggestions to solve the issue.\n * @param customSections - Custom sections to show in the error banner. To be used if nextSteps is not enough.\n */\n constructor(\n message: TokenItem | OutputMessage,\n type: FatalErrorType,\n tryMessage: TokenItem | OutputMessage | null = null,\n nextSteps?: TokenItem<InlineToken>[],\n customSections?: AlertCustomSection[],\n ) {\n const messageIsOutputMessage = typeof message === 'string' || 'value' in message\n super(messageIsOutputMessage ? stringifyMessage(message) : tokenItemToString(message))\n\n if (tryMessage) {\n if (tryMessage instanceof TokenizedString) {\n this.tryMessage = stringifyMessage(tryMessage)\n } else {\n this.tryMessage = tryMessage\n }\n } else {\n this.tryMessage = null\n }\n\n this.type = type\n this.nextSteps = nextSteps\n this.customSections = customSections\n\n if (!messageIsOutputMessage) {\n this.formattedMessage = message\n }\n }\n}\n\n/**\n * An abort error is a fatal error that shouldn't be reported as a bug.\n * Those usually represent unexpected scenarios that we can't handle and that usually require some action from the developer.\n */\nexport class AbortError extends FatalError {\n nextSteps?: TokenItem<InlineToken>[]\n customSections?: AlertCustomSection[]\n constructor(\n message: TokenItem | OutputMessage,\n tryMessage: TokenItem | OutputMessage | null = null,\n nextSteps?: TokenItem<InlineToken>[],\n customSections?: AlertCustomSection[],\n ) {\n super(message, FatalErrorType.Abort, tryMessage, nextSteps, customSections)\n }\n}\n\n/**\n * An external error is similar to Abort but has extra command and args attributes.\n * This is useful to represent errors coming from external commands, usually executed by execa.\n */\nexport class ExternalError extends FatalError {\n command: string\n args: string[]\n\n constructor(\n message: OutputMessage,\n command: string,\n args: string[],\n tryMessage: TokenItem | OutputMessage | null = null,\n ) {\n super(message, FatalErrorType.Abort, tryMessage)\n this.command = command\n this.args = args\n }\n}\n\nexport class AbortSilentError extends FatalError {\n constructor() {\n super('', FatalErrorType.AbortSilent)\n }\n}\n\n/**\n * A bug error is an error that represents a bug and therefore should be reported.\n */\nexport class BugError extends FatalError {\n constructor(message: TokenItem | OutputMessage, tryMessage: TokenItem | OutputMessage | null = null) {\n super(message, FatalErrorType.Bug, tryMessage)\n }\n}\n\n/**\n * A function that handles errors that blow up in the CLI.\n *\n * @param error - Error to be handled.\n * @returns A promise that resolves with the error passed.\n */\nexport async function handler(error: unknown): Promise<unknown> {\n let fatal: FatalError\n if (isFatal(error)) {\n fatal = error\n } else if (typeof error === 'string') {\n fatal = new BugError(error)\n } else if (error instanceof Error) {\n fatal = new BugError(error.message)\n fatal.stack = error.stack\n } else {\n // errors can come in all shapes and sizes...\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeError = error as any\n fatal = new BugError(maybeError?.message ?? 'Unknown error')\n if (maybeError?.stack) {\n fatal.stack = maybeError?.stack\n }\n }\n\n renderFatalError(fatal)\n return Promise.resolve(error)\n}\n\n/**\n * A function that maps an error to an Abort with the stack trace when coming from the CLI.\n *\n * @param error - Error to be mapped.\n * @returns A promise that resolves with the new error object.\n */\nexport function errorMapper(error: unknown): Promise<unknown> {\n if (error instanceof Errors.CLIError) {\n const mappedError = new AbortError(error.message)\n mappedError.stack = error.stack\n return Promise.resolve(mappedError)\n } else {\n return Promise.resolve(error)\n }\n}\n\n/**\n * A function that checks if an error is a fatal one.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error is a fatal one.\n */\nfunction isFatal(error: unknown): error is FatalError {\n try {\n return Object.prototype.hasOwnProperty.call(error, 'type')\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * A function that checks if an error should be reported as unhandled.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error should be reported.\n */\nexport function shouldReportError(error: unknown): boolean {\n if (!isFatal(error)) {\n return true\n }\n if (error.type === FatalErrorType.Bug) {\n return true\n }\n return false\n}\n\n/**\n * Stack traces usually have file:// - we strip that and also remove the Windows drive designation.\n *\n * @param filePath - Path to be cleaned.\n * @returns The cleaned path.\n */\nexport function cleanSingleStackTracePath(filePath: string): string {\n return normalizePath(filePath)\n .replace('file:/', '/')\n .replace(/^\\/?[A-Z]:/, '')\n}\n"]}
|
|
@@ -5,7 +5,7 @@ import * as metadata from '../../../public/node/metadata.js';
|
|
|
5
5
|
// This hook is called after each successful command run. More info: https://oclif.io/docs/hooks
|
|
6
6
|
export const hook = async ({ config, Command }) => {
|
|
7
7
|
await detectStopCommand(Command);
|
|
8
|
-
await reportAnalyticsEvent({ config });
|
|
8
|
+
await reportAnalyticsEvent({ config, exitMode: 'ok' });
|
|
9
9
|
deprecationsHook(Command);
|
|
10
10
|
const command = Command?.id?.replace(/:/g, ' ');
|
|
11
11
|
outputDebug(`Completed command ${command}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postrun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/postrun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAA;AAE1D,OAAO,KAAK,QAAQ,MAAM,kCAAkC,CAAA;AAG5D,gGAAgG;AAChG,MAAM,CAAC,MAAM,IAAI,GAAiB,KAAK,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC,EAAE,EAAE;IAC5D,MAAM,iBAAiB,CAAC,OAAoC,CAAC,CAAA;IAC7D,MAAM,oBAAoB,CAAC,EAAC,MAAM,EAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"postrun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/postrun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAA;AAE1D,OAAO,KAAK,QAAQ,MAAM,kCAAkC,CAAA;AAG5D,gGAAgG;AAChG,MAAM,CAAC,MAAM,IAAI,GAAiB,KAAK,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC,EAAE,EAAE;IAC5D,MAAM,iBAAiB,CAAC,OAAoC,CAAC,CAAA;IAC7D,MAAM,oBAAoB,CAAC,EAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAA;IACpD,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAEzB,MAAM,OAAO,GAAG,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAC/C,WAAW,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAA;AAC7C,CAAC,CAAA;AAED;;;;GAIG;AACH,KAAK,UAAU,iBAAiB,CAAC,YAAgD;IAC/E,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;IACxC,IAAI,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,sBAAsB,CAAC,EAAE;QAC9F,MAAM,WAAW,GAAI,YAAmC,CAAC,oBAAoB,EAAE,CAAA;QAC/E,IAAI,WAAW,EAAE;YACf,MAAM,EAAC,mBAAmB,EAAC,GAAG,QAAQ,CAAC,uBAAuB,EAAE,CAAA;YAChE,MAAM,QAAQ,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,CAAC;gBACzC,mBAAmB,EAAE;oBACnB,GAAG,mBAAoB;oBACvB,SAAS,EAAE,WAAW;oBACtB,YAAY,EAAE,WAAW;iBAC1B;aACF,CAAC,CAAC,CAAA;SACJ;KACF;AACH,CAAC","sourcesContent":["import {postrun as deprecationsHook} from './deprecations.js'\nimport {reportAnalyticsEvent} from '../analytics.js'\nimport {outputDebug} from '../../../public/node/output.js'\nimport BaseCommand from '../base-command.js'\nimport * as metadata from '../../../public/node/metadata.js'\nimport {Command, Hook} from '@oclif/core'\n\n// This hook is called after each successful command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Postrun = async ({config, Command}) => {\n await detectStopCommand(Command as unknown as typeof Command)\n await reportAnalyticsEvent({config, exitMode: 'ok'})\n deprecationsHook(Command)\n\n const command = Command?.id?.replace(/:/g, ' ')\n outputDebug(`Completed command ${command}`)\n}\n\n/**\n * Override the command name with the stop one for analytics purposes.\n *\n * @param commandClass - Oclif command class.\n */\nasync function detectStopCommand(commandClass: Command.Class | typeof BaseCommand): Promise<void> {\n const currentTime = new Date().getTime()\n if (commandClass && Object.prototype.hasOwnProperty.call(commandClass, 'analyticsStopCommand')) {\n const stopCommand = (commandClass as typeof BaseCommand).analyticsStopCommand()\n if (stopCommand) {\n const {commandStartOptions} = metadata.getAllSensitiveMetadata()\n await metadata.addSensitiveMetadata(() => ({\n commandStartOptions: {\n ...commandStartOptions!,\n startTime: currentTime,\n startCommand: stopCommand,\n },\n }))\n }\n }\n}\n"]}
|
package/dist/public/node/http.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { dirname } from './path.js';
|
|
2
2
|
import { createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync } from './fs.js';
|
|
3
|
+
import { runWithTimer } from './metadata.js';
|
|
3
4
|
import { buildHeaders, httpsAgent, sanitizedHeadersOutput } from '../../private/node/api/headers.js';
|
|
4
5
|
import { sanitizeURL } from '../../private/node/api/urls.js';
|
|
5
6
|
import { outputContent, outputDebug } from '../../public/node/output.js';
|
|
@@ -28,7 +29,7 @@ export function formData() {
|
|
|
28
29
|
* @returns A promise that resolves with the response.
|
|
29
30
|
*/
|
|
30
31
|
export async function fetch(url, init) {
|
|
31
|
-
return debugLogResponseInfo({ url: url.toString(), request: nodeFetch(url, init) });
|
|
32
|
+
return runWithTimer('cmd_all_timing_network_ms')(() => debugLogResponseInfo({ url: url.toString(), request: nodeFetch(url, init) }));
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
34
35
|
* A fetch function to use with Shopify services. The function ensures the right
|
|
@@ -52,7 +53,9 @@ export async function shopifyFetch(url, init) {
|
|
|
52
53
|
With request headers:
|
|
53
54
|
${sanitizedHeadersOutput((options?.headers ?? {}))}
|
|
54
55
|
`);
|
|
55
|
-
return
|
|
56
|
+
return runWithTimer('cmd_all_timing_network_ms')(async () => {
|
|
57
|
+
return debugLogResponseInfo({ url: url.toString(), request: nodeFetch(url, { ...init, agent: await httpsAgent() }) });
|
|
58
|
+
});
|
|
56
59
|
}
|
|
57
60
|
/**
|
|
58
61
|
* Download a file from a URL to a local path.
|
|
@@ -64,26 +67,28 @@ ${sanitizedHeadersOutput((options?.headers ?? {}))}
|
|
|
64
67
|
export function downloadFile(url, to) {
|
|
65
68
|
const sanitizedUrl = sanitizeURL(url);
|
|
66
69
|
outputDebug(`Downloading ${sanitizedUrl} to ${to}`);
|
|
67
|
-
return
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
file.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
70
|
+
return runWithTimer('cmd_all_timing_network_ms')(() => {
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
if (!fileExistsSync(dirname(to))) {
|
|
73
|
+
mkdirSync(dirname(to));
|
|
74
|
+
}
|
|
75
|
+
const file = createFileWriteStream(to);
|
|
76
|
+
file.on('finish', () => {
|
|
77
|
+
file.close();
|
|
78
|
+
resolve(to);
|
|
79
|
+
});
|
|
80
|
+
file.on('error', (err) => {
|
|
81
|
+
unlinkFileSync(to);
|
|
82
|
+
reject(err);
|
|
83
|
+
});
|
|
84
|
+
nodeFetch(url, { redirect: 'follow' })
|
|
85
|
+
.then((res) => {
|
|
86
|
+
res.body?.pipe(file);
|
|
87
|
+
})
|
|
88
|
+
.catch((err) => {
|
|
89
|
+
unlinkFileSync(to);
|
|
90
|
+
reject(err);
|
|
91
|
+
});
|
|
87
92
|
});
|
|
88
93
|
});
|
|
89
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/node/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,qBAAqB,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAC,MAAM,SAAS,CAAA;AACxF,OAAO,EAAC,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAC,MAAM,mCAAmC,CAAA;AAClG,OAAO,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAA;AAC1D,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACtE,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAA;AAC9D,OAAO,QAAQ,MAAM,WAAW,CAAA;AAChC,OAAO,SAAqC,MAAM,YAAY,CAAA;AAE9D,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AAErC;;;;GAIG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,QAAQ,EAAE,CAAA;AACvB,CAAC;AAID;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,GAAgB,EAAE,IAAkB;IAC9D,OAAO,oBAAoB,CAAC,EAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,EAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/node/http.ts"],"names":[],"mappings":"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","sourcesContent":["import {dirname} from './path.js'\nimport {createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync} from './fs.js'\nimport {runWithTimer} from './metadata.js'\nimport {buildHeaders, httpsAgent, sanitizedHeadersOutput} from '../../private/node/api/headers.js'\nimport {sanitizeURL} from '../../private/node/api/urls.js'\nimport {outputContent, outputDebug} from '../../public/node/output.js'\nimport {debugLogResponseInfo} from '../../private/node/api.js'\nimport FormData from 'form-data'\nimport nodeFetch, {RequestInfo, RequestInit} from 'node-fetch'\n\nexport {FetchError} from 'node-fetch'\n\n/**\n * Create a new FormData object.\n *\n * @returns A FormData object.\n */\nexport function formData(): FormData {\n return new FormData()\n}\n\nexport type Response = ReturnType<typeof nodeFetch>\n\n/**\n * An interface that abstracts way node-fetch. When Node has built-in\n * support for \"fetch\" in the standard library, we can drop the node-fetch\n * dependency from here.\n * Note that we are exposing types from \"node-fetch\". The reason being is that\n * they are consistent with the Web API so if we drop node-fetch in the future\n * it won't require changes from the callers.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @returns A promise that resolves with the response.\n */\nexport async function fetch(url: RequestInfo, init?: RequestInit): Response {\n return runWithTimer('cmd_all_timing_network_ms')(() =>\n debugLogResponseInfo({url: url.toString(), request: nodeFetch(url, init)}),\n )\n}\n\n/**\n * A fetch function to use with Shopify services. The function ensures the right\n * TLS configuragion is used based on the environment in which the service is running\n * (e.g. Spin).\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @returns A promise that resolves with the response.\n */\nexport async function shopifyFetch(url: RequestInfo, init?: RequestInit): Response {\n const sanitizedUrl = sanitizeURL(url.toString())\n const options: RequestInit = {\n ...(init ?? {}),\n headers: {\n ...(await buildHeaders()),\n ...(init?.headers ?? {}),\n },\n }\n\n outputDebug(outputContent`Sending ${options.method ?? 'GET'} request to URL ${sanitizedUrl}\nWith request headers:\n${sanitizedHeadersOutput((options?.headers ?? {}) as {[header: string]: string})}\n`)\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return debugLogResponseInfo({url: url.toString(), request: nodeFetch(url, {...init, agent: await httpsAgent()})})\n })\n}\n\n/**\n * Download a file from a URL to a local path.\n *\n * @param url - The URL to download from.\n * @param to - The local path to download to.\n * @returns - A promise that resolves with the local path.\n */\nexport function downloadFile(url: string, to: string): Promise<string> {\n const sanitizedUrl = sanitizeURL(url)\n outputDebug(`Downloading ${sanitizedUrl} to ${to}`)\n\n return runWithTimer('cmd_all_timing_network_ms')(() => {\n return new Promise<string>((resolve, reject) => {\n if (!fileExistsSync(dirname(to))) {\n mkdirSync(dirname(to))\n }\n\n const file = createFileWriteStream(to)\n\n file.on('finish', () => {\n file.close()\n resolve(to)\n })\n\n file.on('error', (err) => {\n unlinkFileSync(to)\n reject(err)\n })\n\n nodeFetch(url, {redirect: 'follow'})\n .then((res) => {\n res.body?.pipe(file)\n })\n .catch((err) => {\n unlinkFileSync(to)\n reject(err)\n })\n })\n })\n}\n"]}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { PickByPrefix } from '../common/ts/pick-by-prefix.js';
|
|
2
|
+
import type { AnyJson } from '../../private/common/json.js';
|
|
3
|
+
import type { MonorailEventPublic } from './monorail.js';
|
|
4
4
|
type ProvideMetadata<T> = () => Partial<T> | Promise<Partial<T>>;
|
|
5
5
|
type MetadataErrorHandling = 'auto' | 'mute-and-report' | 'bubble';
|
|
6
|
+
/**
|
|
7
|
+
* Any key in T that has a numeric value.
|
|
8
|
+
*/
|
|
9
|
+
type NumericKeyOf<T> = {
|
|
10
|
+
[K in keyof T]: T[K] extends number ? (K extends string ? K : never) : never;
|
|
11
|
+
}[keyof T];
|
|
6
12
|
export interface RuntimeMetadataManager<TPublic extends AnyJson, TSensitive extends AnyJson> {
|
|
7
13
|
/** Add some public metadata -- this should not contain any PII. */
|
|
8
14
|
addPublicMetadata: (getData: ProvideMetadata<TPublic>, onError?: MetadataErrorHandling) => Promise<void>;
|
|
@@ -15,6 +21,8 @@ export interface RuntimeMetadataManager<TPublic extends AnyJson, TSensitive exte
|
|
|
15
21
|
getAllPublicMetadata: () => Partial<TPublic>;
|
|
16
22
|
/** Get a snapshot of the tracked sensitive data. */
|
|
17
23
|
getAllSensitiveMetadata: () => Partial<TSensitive>;
|
|
24
|
+
/** Run a function, monitoring how long it takes, and adding the elapsed time to a running total. */
|
|
25
|
+
runWithTimer: (field: NumericKeyOf<TPublic>) => <T>(fn: () => Promise<T>) => Promise<T>;
|
|
18
26
|
}
|
|
19
27
|
export type PublicSchema<T> = T extends RuntimeMetadataManager<infer TPublic, infer _TSensitive> ? TPublic : never;
|
|
20
28
|
export type SensitiveSchema<T> = T extends RuntimeMetadataManager<infer _TPublic, infer TSensitive> ? TSensitive : never;
|
|
@@ -57,7 +65,7 @@ export declare const getAllPublicMetadata: () => Partial<CmdFieldsFromMonorail>,
|
|
|
57
65
|
};
|
|
58
66
|
} & {
|
|
59
67
|
environmentFlags: string;
|
|
60
|
-
}>, onError?: MetadataErrorHandling) => Promise<void>;
|
|
68
|
+
}>, onError?: MetadataErrorHandling) => Promise<void>, runWithTimer: (field: NumericKeyOf<CmdFieldsFromMonorail>) => <T>(fn: () => Promise<T>) => Promise<T>;
|
|
61
69
|
export type Public = PublicSchema<typeof coreData>;
|
|
62
70
|
export type Sensitive = SensitiveSchema<typeof coreData>;
|
|
63
71
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { sendErrorToBugsnag } from './error-handler.js';
|
|
2
1
|
import { isUnitTest } from './context/local.js';
|
|
2
|
+
import { performance } from 'node:perf_hooks';
|
|
3
3
|
/**
|
|
4
4
|
* Get the error handling strategy for metadata.
|
|
5
5
|
*
|
|
@@ -46,10 +46,14 @@ export function createRuntimeMetadataContainer(defaultPublicMetadata = {}) {
|
|
|
46
46
|
// eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any
|
|
47
47
|
}
|
|
48
48
|
catch (error) {
|
|
49
|
-
|
|
49
|
+
// This is very prone to becoming a circular dependency, so we import it dynamically
|
|
50
|
+
const { sendErrorToBugsnag } = await import('./error-handler.js');
|
|
51
|
+
await sendErrorToBugsnag(error, 'unexpected_error');
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
};
|
|
55
|
+
// See `runWithTimer` below.
|
|
56
|
+
const durationStack = [];
|
|
53
57
|
return {
|
|
54
58
|
getAllPublicMetadata: () => {
|
|
55
59
|
return { ...raw.public };
|
|
@@ -63,8 +67,52 @@ export function createRuntimeMetadataContainer(defaultPublicMetadata = {}) {
|
|
|
63
67
|
addSensitiveMetadata: async (getData, onError = 'auto') => {
|
|
64
68
|
return addMetadata(addSensitive, getData, onError);
|
|
65
69
|
},
|
|
70
|
+
runWithTimer: (field) => {
|
|
71
|
+
return async (fn) => {
|
|
72
|
+
/**
|
|
73
|
+
* For nested timers, we subtract the inner timer's duration from the outer timer's. We use a stack to track the
|
|
74
|
+
* cumulative durations of nested timers. On starting a timer, we push a zero onto the stack to initialize the total
|
|
75
|
+
* duration for subsequent nested timers. Before logging, we pop the stack to get the total nested timers' duration.
|
|
76
|
+
* We subtract this from the current timer's actual duration to get its measurable duration. We then add the current
|
|
77
|
+
* timer's actual duration to the stack's top, allowing any parent timer to deduct it from its own duration.
|
|
78
|
+
*/
|
|
79
|
+
// Initialise the running total duration for all nested timers
|
|
80
|
+
durationStack.push(0);
|
|
81
|
+
// Do the work, and time it
|
|
82
|
+
const start = performance.now();
|
|
83
|
+
const result = await fn();
|
|
84
|
+
let end = performance.now();
|
|
85
|
+
// For very short durations, the end time can be before the start time(!) - we flatten this out to zero.
|
|
86
|
+
end = Math.max(start, end);
|
|
87
|
+
// The top of the stack is the total time for all nested timers
|
|
88
|
+
const wallClockDuration = Math.max(end - start, 0);
|
|
89
|
+
const childDurations = durationStack.pop();
|
|
90
|
+
const duration = Math.max(wallClockDuration - childDurations, 0);
|
|
91
|
+
// If this is the topmost timer, the stack will be empty.
|
|
92
|
+
if (durationStack.length > 0) {
|
|
93
|
+
durationStack[durationStack.length - 1] += wallClockDuration;
|
|
94
|
+
}
|
|
95
|
+
// Log it -- we include it in the metadata, but also log via the standard performance API. The TS types for this library are not quite right, so we have to cast to `any` here.
|
|
96
|
+
performance.measure(`${field}#measurable`, {
|
|
97
|
+
start,
|
|
98
|
+
duration,
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
|
+
});
|
|
101
|
+
performance.measure(`${field}#wall`, {
|
|
102
|
+
start,
|
|
103
|
+
end,
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
|
+
});
|
|
106
|
+
// There might not be a value set, yet
|
|
107
|
+
let currentValue = (raw.public[field] || 0);
|
|
108
|
+
currentValue += duration;
|
|
109
|
+
// TS is not quite smart enough to realise that raw.public[field] must be a numeric type
|
|
110
|
+
raw.public[field] = currentValue;
|
|
111
|
+
return result;
|
|
112
|
+
};
|
|
113
|
+
},
|
|
66
114
|
};
|
|
67
115
|
}
|
|
68
|
-
const coreData = createRuntimeMetadataContainer();
|
|
69
|
-
export const { getAllPublicMetadata, getAllSensitiveMetadata, addPublicMetadata, addSensitiveMetadata } = coreData;
|
|
116
|
+
const coreData = createRuntimeMetadataContainer({ cmd_all_timing_network_ms: 0, cmd_all_timing_prompts_ms: 0 });
|
|
117
|
+
export const { getAllPublicMetadata, getAllSensitiveMetadata, addPublicMetadata, addSensitiveMetadata, runWithTimer } = coreData;
|
|
70
118
|
//# sourceMappingURL=metadata.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/public/node/metadata.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAA;AAc7C;;;;GAIG;AACH,SAAS,gCAAgC;IACvC,IAAI,UAAU,EAAE,EAAE;QAChB,OAAO,QAAQ,CAAA;KAChB;IACD,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AAmBD;;;;;;GAMG;AACH,MAAM,UAAU,8BAA8B,CAG5C,wBAA0C,EAAE;IAC5C,MAAM,GAAG,GAA+D;QACtE,SAAS,EAAE,EAAE;QACb,MAAM,EAAE;YACN,GAAG,qBAAqB;SACzB;KACF,CAAA;IACD,MAAM,SAAS,GAAG,CAAC,IAAsB,EAAE,EAAE;QAC3C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACjC,CAAC,CAAA;IACD,MAAM,YAAY,GAAG,CAAC,IAAyB,EAAE,EAAE;QACjD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IACpC,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EACvB,KAAiC,EACjC,KAAyB,EACzB,OAA8B,EAC9B,EAAE;QACF,MAAM,aAAa,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QACvF,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;YAC3B,MAAM,IAAI,GAAG,MAAM,KAAK,EAAE,CAAA;YAC1B,KAAK,CAAC,IAAI,CAAC,CAAA;QACb,CAAC,CAAA;QAED,IAAI,aAAa,KAAK,QAAQ,EAAE;YAC9B,MAAM,SAAS,EAAE,CAAA;SAClB;aAAM;YACL,IAAI;gBACF,MAAM,SAAS,EAAE,CAAA;gBACjB,yFAAyF;aAC1F;YAAC,OAAO,KAAU,EAAE;gBACnB,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAA;aAChC;SACF;IACH,CAAC,CAAA;IAED,OAAO;QACL,oBAAoB,EAAE,GAAG,EAAE;YACzB,OAAO,EAAC,GAAG,GAAG,CAAC,MAAM,EAAC,CAAA;QACxB,CAAC;QACD,uBAAuB,EAAE,GAAG,EAAE;YAC5B,OAAO,EAAC,GAAG,GAAG,CAAC,SAAS,EAAC,CAAA;QAC3B,CAAC;QACD,iBAAiB,EAAE,KAAK,EAAE,OAAiC,EAAE,UAAiC,MAAM,EAAE,EAAE;YACtG,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACjD,CAAC;QACD,oBAAoB,EAAE,KAAK,EAAE,OAAoC,EAAE,UAAiC,MAAM,EAAE,EAAE;YAC5G,OAAO,WAAW,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACpD,CAAC;KACF,CAAA;AACH,CAAC;AAQD,MAAM,QAAQ,GAAG,8BAA8B,EAU5C,CAAA;AAEH,MAAM,CAAC,MAAM,EAAC,oBAAoB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,oBAAoB,EAAC,GAAG,QAAQ,CAAA","sourcesContent":["import {MonorailEventPublic} from './monorail.js'\nimport {sendErrorToBugsnag} from './error-handler.js'\nimport {isUnitTest} from './context/local.js'\nimport {PickByPrefix} from '../common/ts/pick-by-prefix.js'\nimport {AnyJson} from '../../private/common/json.js'\n\ntype ProvideMetadata<T> = () => Partial<T> | Promise<Partial<T>>\n\ntype MetadataErrorHandling =\n // Mute & report errors in production, throw them whilst testing\n | 'auto'\n // Errors are not reported to the user and do not stop execution, but they are reported to Bugsnag\n | 'mute-and-report'\n // Errors are not caught and will bubble out as normal\n | 'bubble'\n\n/**\n * Get the error handling strategy for metadata.\n *\n * @returns 'mute-and-report' in production, 'bubble' in tests.\n */\nfunction getMetadataErrorHandlingStrategy(): 'mute-and-report' | 'bubble' {\n if (isUnitTest()) {\n return 'bubble'\n }\n return 'mute-and-report'\n}\n\nexport interface RuntimeMetadataManager<TPublic extends AnyJson, TSensitive extends AnyJson> {\n /** Add some public metadata -- this should not contain any PII. */\n addPublicMetadata: (getData: ProvideMetadata<TPublic>, onError?: MetadataErrorHandling) => Promise<void>\n /**\n * Add some potentially sensitive metadata -- this may include PII, but unnecessary data should never be tracked\n * (this is a good fit for command args for instance).\n */\n addSensitiveMetadata: (getData: ProvideMetadata<TSensitive>, onError?: MetadataErrorHandling) => Promise<void>\n /** Get a snapshot of the tracked public data. */\n getAllPublicMetadata: () => Partial<TPublic>\n /** Get a snapshot of the tracked sensitive data. */\n getAllSensitiveMetadata: () => Partial<TSensitive>\n}\n\nexport type PublicSchema<T> = T extends RuntimeMetadataManager<infer TPublic, infer _TSensitive> ? TPublic : never\nexport type SensitiveSchema<T> = T extends RuntimeMetadataManager<infer _TPublic, infer TSensitive> ? TSensitive : never\n\n/**\n * Creates a container for metadata collected at runtime.\n * The container provides async-safe functions for extracting the gathered metadata, and for setting it.\n *\n * @param defaultPublicMetadata - Optional, default data for the container.\n * @returns A container for the metadata.\n */\nexport function createRuntimeMetadataContainer<\n TPublic extends AnyJson,\n TSensitive extends AnyJson = {[key: string]: never},\n>(defaultPublicMetadata: Partial<TPublic> = {}): RuntimeMetadataManager<TPublic, TSensitive> {\n const raw: {sensitive: Partial<TSensitive>; public: Partial<TPublic>} = {\n sensitive: {},\n public: {\n ...defaultPublicMetadata,\n },\n }\n const addPublic = (data: Partial<TPublic>) => {\n Object.assign(raw.public, data)\n }\n const addSensitive = (data: Partial<TSensitive>) => {\n Object.assign(raw.sensitive, data)\n }\n\n const addMetadata = async <T>(\n addFn: (data: Partial<T>) => void,\n getFn: ProvideMetadata<T>,\n onError: MetadataErrorHandling,\n ) => {\n const errorHandling = onError === 'auto' ? getMetadataErrorHandlingStrategy() : onError\n const getAndSet = async () => {\n const data = await getFn()\n addFn(data)\n }\n\n if (errorHandling === 'bubble') {\n await getAndSet()\n } else {\n try {\n await getAndSet()\n // eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any\n } catch (error: any) {\n await sendErrorToBugsnag(error)\n }\n }\n }\n\n return {\n getAllPublicMetadata: () => {\n return {...raw.public}\n },\n getAllSensitiveMetadata: () => {\n return {...raw.sensitive}\n },\n addPublicMetadata: async (getData: ProvideMetadata<TPublic>, onError: MetadataErrorHandling = 'auto') => {\n return addMetadata(addPublic, getData, onError)\n },\n addSensitiveMetadata: async (getData: ProvideMetadata<TSensitive>, onError: MetadataErrorHandling = 'auto') => {\n return addMetadata(addSensitive, getData, onError)\n },\n }\n}\n\n// We want to track anything that ends up getting sent to monorail as `cmd_all_*` and\n// `cmd_app_*`\ntype CmdFieldsFromMonorail = PickByPrefix<MonorailEventPublic, 'cmd_all_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_app_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_create_app_'>\n\nconst coreData = createRuntimeMetadataContainer<\n CmdFieldsFromMonorail,\n {\n commandStartOptions: {\n startTime: number\n startCommand: string\n startTopic?: string\n startArgs: string[]\n }\n } & {environmentFlags: string}\n>()\n\nexport const {getAllPublicMetadata, getAllSensitiveMetadata, addPublicMetadata, addSensitiveMetadata} = coreData\n\nexport type Public = PublicSchema<typeof coreData>\nexport type Sensitive = SensitiveSchema<typeof coreData>\n"]}
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/public/node/metadata.ts"],"names":[],"mappings":"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","sourcesContent":["import {isUnitTest} from './context/local.js'\nimport {performance} from 'node:perf_hooks'\nimport type {PickByPrefix} from '../common/ts/pick-by-prefix.js'\nimport type {AnyJson} from '../../private/common/json.js'\nimport type {MonorailEventPublic} from './monorail.js'\n\ntype ProvideMetadata<T> = () => Partial<T> | Promise<Partial<T>>\n\ntype MetadataErrorHandling =\n // Mute & report errors in production, throw them whilst testing\n | 'auto'\n // Errors are not reported to the user and do not stop execution, but they are reported to Bugsnag\n | 'mute-and-report'\n // Errors are not caught and will bubble out as normal\n | 'bubble'\n\n/**\n * Get the error handling strategy for metadata.\n *\n * @returns 'mute-and-report' in production, 'bubble' in tests.\n */\nfunction getMetadataErrorHandlingStrategy(): 'mute-and-report' | 'bubble' {\n if (isUnitTest()) {\n return 'bubble'\n }\n return 'mute-and-report'\n}\n\n/**\n * Any key in T that has a numeric value.\n */\ntype NumericKeyOf<T> = {\n [K in keyof T]: T[K] extends number ? (K extends string ? K : never) : never\n}[keyof T]\n\nexport interface RuntimeMetadataManager<TPublic extends AnyJson, TSensitive extends AnyJson> {\n /** Add some public metadata -- this should not contain any PII. */\n addPublicMetadata: (getData: ProvideMetadata<TPublic>, onError?: MetadataErrorHandling) => Promise<void>\n /**\n * Add some potentially sensitive metadata -- this may include PII, but unnecessary data should never be tracked\n * (this is a good fit for command args for instance).\n */\n addSensitiveMetadata: (getData: ProvideMetadata<TSensitive>, onError?: MetadataErrorHandling) => Promise<void>\n /** Get a snapshot of the tracked public data. */\n getAllPublicMetadata: () => Partial<TPublic>\n /** Get a snapshot of the tracked sensitive data. */\n getAllSensitiveMetadata: () => Partial<TSensitive>\n /** Run a function, monitoring how long it takes, and adding the elapsed time to a running total. */\n runWithTimer: (field: NumericKeyOf<TPublic>) => <T>(fn: () => Promise<T>) => Promise<T>\n}\n\nexport type PublicSchema<T> = T extends RuntimeMetadataManager<infer TPublic, infer _TSensitive> ? TPublic : never\nexport type SensitiveSchema<T> = T extends RuntimeMetadataManager<infer _TPublic, infer TSensitive> ? TSensitive : never\n\n/**\n * Creates a container for metadata collected at runtime.\n * The container provides async-safe functions for extracting the gathered metadata, and for setting it.\n *\n * @param defaultPublicMetadata - Optional, default data for the container.\n * @returns A container for the metadata.\n */\nexport function createRuntimeMetadataContainer<\n TPublic extends AnyJson,\n TSensitive extends AnyJson = {[key: string]: never},\n>(defaultPublicMetadata: Partial<TPublic> = {}): RuntimeMetadataManager<TPublic, TSensitive> {\n const raw: {sensitive: Partial<TSensitive>; public: Partial<TPublic>} = {\n sensitive: {},\n public: {\n ...defaultPublicMetadata,\n },\n }\n const addPublic = (data: Partial<TPublic>) => {\n Object.assign(raw.public, data)\n }\n const addSensitive = (data: Partial<TSensitive>) => {\n Object.assign(raw.sensitive, data)\n }\n\n const addMetadata = async <T>(\n addFn: (data: Partial<T>) => void,\n getFn: ProvideMetadata<T>,\n onError: MetadataErrorHandling,\n ) => {\n const errorHandling = onError === 'auto' ? getMetadataErrorHandlingStrategy() : onError\n const getAndSet = async () => {\n const data = await getFn()\n addFn(data)\n }\n\n if (errorHandling === 'bubble') {\n await getAndSet()\n } else {\n try {\n await getAndSet()\n // eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any\n } catch (error: any) {\n // This is very prone to becoming a circular dependency, so we import it dynamically\n const {sendErrorToBugsnag} = await import('./error-handler.js')\n await sendErrorToBugsnag(error, 'unexpected_error')\n }\n }\n }\n\n // See `runWithTimer` below.\n const durationStack: number[] = []\n\n return {\n getAllPublicMetadata: () => {\n return {...raw.public}\n },\n getAllSensitiveMetadata: () => {\n return {...raw.sensitive}\n },\n addPublicMetadata: async (getData: ProvideMetadata<TPublic>, onError: MetadataErrorHandling = 'auto') => {\n return addMetadata(addPublic, getData, onError)\n },\n addSensitiveMetadata: async (getData: ProvideMetadata<TSensitive>, onError: MetadataErrorHandling = 'auto') => {\n return addMetadata(addSensitive, getData, onError)\n },\n runWithTimer: (field: NumericKeyOf<TPublic>): (<T>(fn: () => Promise<T>) => Promise<T>) => {\n return async (fn) => {\n /**\n * For nested timers, we subtract the inner timer's duration from the outer timer's. We use a stack to track the\n * cumulative durations of nested timers. On starting a timer, we push a zero onto the stack to initialize the total\n * duration for subsequent nested timers. Before logging, we pop the stack to get the total nested timers' duration.\n * We subtract this from the current timer's actual duration to get its measurable duration. We then add the current\n * timer's actual duration to the stack's top, allowing any parent timer to deduct it from its own duration.\n */\n\n // Initialise the running total duration for all nested timers\n durationStack.push(0)\n\n // Do the work, and time it\n const start = performance.now()\n const result = await fn()\n let end = performance.now()\n // For very short durations, the end time can be before the start time(!) - we flatten this out to zero.\n end = Math.max(start, end)\n\n // The top of the stack is the total time for all nested timers\n const wallClockDuration = Math.max(end - start, 0)\n const childDurations = durationStack.pop() as number\n const duration = Math.max(wallClockDuration - childDurations, 0)\n\n // If this is the topmost timer, the stack will be empty.\n if (durationStack.length > 0) {\n durationStack[durationStack.length - 1] += wallClockDuration\n }\n\n // Log it -- we include it in the metadata, but also log via the standard performance API. The TS types for this library are not quite right, so we have to cast to `any` here.\n performance.measure(`${field}#measurable`, {\n start,\n duration,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any)\n performance.measure(`${field}#wall`, {\n start,\n end,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any)\n\n // There might not be a value set, yet\n let currentValue = (raw.public[field] || 0) as number\n currentValue += duration\n\n // TS is not quite smart enough to realise that raw.public[field] must be a numeric type\n raw.public[field] = currentValue as TPublic[NumericKeyOf<TPublic>]\n return result\n }\n },\n }\n}\n\n// We want to track anything that ends up getting sent to monorail as `cmd_all_*` and\n// `cmd_app_*`\ntype CmdFieldsFromMonorail = PickByPrefix<MonorailEventPublic, 'cmd_all_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_app_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_create_app_'>\n\nconst coreData = createRuntimeMetadataContainer<\n CmdFieldsFromMonorail,\n {\n commandStartOptions: {\n startTime: number\n startCommand: string\n startTopic?: string\n startArgs: string[]\n }\n } & {environmentFlags: string}\n>({cmd_all_timing_network_ms: 0, cmd_all_timing_prompts_ms: 0})\n\nexport const {getAllPublicMetadata, getAllSensitiveMetadata, addPublicMetadata, addSensitiveMetadata, runWithTimer} =\n coreData\n\nexport type Public = PublicSchema<typeof coreData>\nexport type Sensitive = SensitiveSchema<typeof coreData>\n"]}
|
|
@@ -2,7 +2,7 @@ import { JsonMap } from '../../private/common/json.js';
|
|
|
2
2
|
import { DeepRequired } from '../common/ts/deep-required.js';
|
|
3
3
|
export { DeepRequired };
|
|
4
4
|
type Optional<T> = T | null;
|
|
5
|
-
export declare const MONORAIL_COMMAND_TOPIC: "app_cli3_command/1.
|
|
5
|
+
export declare const MONORAIL_COMMAND_TOPIC: "app_cli3_command/1.10";
|
|
6
6
|
export interface Schemas {
|
|
7
7
|
[MONORAIL_COMMAND_TOPIC]: {
|
|
8
8
|
sensitive: {
|
|
@@ -37,6 +37,10 @@ export interface Schemas {
|
|
|
37
37
|
cmd_all_plugin?: Optional<string>;
|
|
38
38
|
cmd_all_topic?: Optional<string>;
|
|
39
39
|
cmd_all_verbose?: Optional<boolean>;
|
|
40
|
+
cmd_all_exit?: Optional<string>;
|
|
41
|
+
cmd_all_timing_network_ms?: Optional<number>;
|
|
42
|
+
cmd_all_timing_prompts_ms?: Optional<number>;
|
|
43
|
+
cmd_all_timing_active_ms?: Optional<number>;
|
|
40
44
|
cmd_extensions_binary_from_source?: Optional<boolean>;
|
|
41
45
|
cmd_scaffold_required_auth?: Optional<boolean>;
|
|
42
46
|
cmd_scaffold_template_custom?: Optional<boolean>;
|
|
@@ -60,6 +64,9 @@ export interface Schemas {
|
|
|
60
64
|
cmd_dev_tunnel_type?: Optional<string>;
|
|
61
65
|
cmd_dev_tunnel_custom_hash?: Optional<string>;
|
|
62
66
|
cmd_dev_urls_updated?: Optional<boolean>;
|
|
67
|
+
cmd_dev_preview_url_opened?: Optional<boolean>;
|
|
68
|
+
cmd_dev_graphiql_opened?: Optional<boolean>;
|
|
69
|
+
cmd_dev_dev_preview_toggle_used?: Optional<boolean>;
|
|
63
70
|
cmd_create_app_template?: Optional<string>;
|
|
64
71
|
cmd_create_app_template_url?: Optional<string>;
|
|
65
72
|
cmd_deploy_flag_message_used?: Optional<boolean>;
|
|
@@ -2,7 +2,7 @@ import { fetch } from './http.js';
|
|
|
2
2
|
import { outputDebug, outputContent, outputToken } from '../../public/node/output.js';
|
|
3
3
|
const url = 'https://monorail-edge.shopifysvc.com/v1/produce';
|
|
4
4
|
// This is the topic name of the main event we log to Monorail, the command tracker
|
|
5
|
-
export const MONORAIL_COMMAND_TOPIC = 'app_cli3_command/1.
|
|
5
|
+
export const MONORAIL_COMMAND_TOPIC = 'app_cli3_command/1.10';
|
|
6
6
|
/**
|
|
7
7
|
* Publishes an event to Monorail.
|
|
8
8
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monorail.js","sourceRoot":"","sources":["../../../src/public/node/monorail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,WAAW,CAAA;AAE/B,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AAKnF,MAAM,GAAG,GAAG,iDAAiD,CAAA;AAI7D,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAAG,
|
|
1
|
+
{"version":3,"file":"monorail.js","sourceRoot":"","sources":["../../../src/public/node/monorail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,WAAW,CAAA;AAE/B,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AAKnF,MAAM,GAAG,GAAG,iDAAiD,CAAA;AAI7D,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAgC,CAAA;AAoJtE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAmB,EACnB,UAA8B,EAC9B,aAAoC;IAEpC,IAAI;QACF,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;QACxC,MAAM,OAAO,GAAG,EAAC,GAAG,UAAU,EAAE,GAAG,aAAa,EAAC,CAAA;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAC,CAAC,CAAA;QAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;QAEzC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAC,CAAC,CAAA;QAElE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;YAC3B,WAAW,CAAC,aAAa,CAAA,yBAAyB,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;YAC9E,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,CAAA;SACpB;aAAM;YACL,WAAW,CAAC,qCAAqC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;YACvE,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAC,CAAA;SACrD;QACD,qDAAqD;KACtD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,OAAO,GAAG,kCAAkC,CAAA;QAChD,IAAI,KAAK,YAAY,KAAK,EAAE;YAC1B,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;SAC/C;QACD,WAAW,CAAC,OAAO,CAAC,CAAA;QACpB,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAC,CAAA;KAChC;AACH,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,WAAmB,EAAE,EAAE;IAC3C,OAAO;QACL,cAAc,EAAE,iCAAiC;QACjD,qCAAqC,EAAE,WAAW,CAAC,QAAQ,EAAE;QAC7D,kCAAkC,EAAE,WAAW,CAAC,QAAQ,EAAE;KAC3D,CAAA;AACH,CAAC,CAAA","sourcesContent":["import {fetch} from './http.js'\nimport {JsonMap} from '../../private/common/json.js'\nimport {outputDebug, outputContent, outputToken} from '../../public/node/output.js'\nimport {DeepRequired} from '../common/ts/deep-required.js'\n\nexport {DeepRequired}\n\nconst url = 'https://monorail-edge.shopifysvc.com/v1/produce'\n\ntype Optional<T> = T | null\n\n// This is the topic name of the main event we log to Monorail, the command tracker\nexport const MONORAIL_COMMAND_TOPIC = 'app_cli3_command/1.10' as const\n\nexport interface Schemas {\n [MONORAIL_COMMAND_TOPIC]: {\n sensitive: {\n args: string\n error_message?: Optional<string>\n app_name?: Optional<string>\n metadata?: Optional<string>\n store_fqdn?: Optional<string>\n cmd_all_environment_flags?: Optional<string>\n\n // Dev related commands\n cmd_dev_tunnel_custom?: Optional<string>\n\n // Environment\n env_plugin_installed_all?: Optional<string>\n }\n public: {\n partner_id?: Optional<number>\n command: string\n project_type?: Optional<string>\n time_start: number\n time_end: number\n total_time: number\n success: boolean\n api_key?: Optional<string>\n cli_version: string\n uname: string\n ruby_version: string\n node_version: string\n is_employee: boolean\n store_fqdn_hash?: Optional<string>\n\n // Any and all commands\n cmd_all_alias_used?: Optional<string>\n cmd_all_launcher?: Optional<string>\n cmd_all_path_override?: Optional<boolean>\n cmd_all_path_override_hash?: Optional<string>\n cmd_all_plugin?: Optional<string>\n cmd_all_topic?: Optional<string>\n cmd_all_verbose?: Optional<boolean>\n cmd_all_exit?: Optional<string>\n\n cmd_all_timing_network_ms?: Optional<number>\n cmd_all_timing_prompts_ms?: Optional<number>\n cmd_all_timing_active_ms?: Optional<number>\n\n // Any extension related command\n cmd_extensions_binary_from_source?: Optional<boolean>\n\n // Scaffolding related commands\n cmd_scaffold_required_auth?: Optional<boolean>\n cmd_scaffold_template_custom?: Optional<boolean>\n cmd_scaffold_template_flavor?: Optional<string>\n cmd_scaffold_type?: Optional<string>\n cmd_scaffold_type_category?: Optional<string>\n cmd_scaffold_type_gated?: Optional<boolean>\n cmd_scaffold_type_owner?: Optional<string>\n cmd_scaffold_used_prompts_for_type?: Optional<boolean>\n\n // Used in several but not all commands\n cmd_app_dependency_installation_skipped?: Optional<boolean>\n cmd_app_reset_used?: Optional<boolean>\n cmd_app_linked_config_used?: Optional<boolean>\n cmd_app_linked_config_name?: Optional<string>\n cmd_app_linked_config_git_tracked?: Optional<boolean>\n cmd_app_all_configs_any?: Optional<boolean>\n cmd_app_all_configs_clients?: Optional<string>\n cmd_app_linked_config_source?: Optional<string>\n cmd_app_linked_config_uses_cli_managed_urls?: Optional<boolean>\n cmd_app_warning_api_key_deprecation_displayed?: Optional<boolean>\n cmd_app_deployment_mode?: Optional<string>\n\n // Dev related commands\n cmd_dev_tunnel_type?: Optional<string>\n cmd_dev_tunnel_custom_hash?: Optional<string>\n cmd_dev_urls_updated?: Optional<boolean>\n cmd_dev_preview_url_opened?: Optional<boolean>\n cmd_dev_graphiql_opened?: Optional<boolean>\n cmd_dev_dev_preview_toggle_used?: Optional<boolean>\n\n // Create-app related commands\n cmd_create_app_template?: Optional<string>\n cmd_create_app_template_url?: Optional<string>\n\n // Deploy related commands\n cmd_deploy_flag_message_used?: Optional<boolean>\n cmd_deploy_flag_version_used?: Optional<boolean>\n cmd_deploy_flag_source_url_used?: Optional<boolean>\n cmd_deploy_confirm_new_registrations?: Optional<number>\n cmd_deploy_confirm_updated_registrations?: Optional<number>\n cmd_deploy_confirm_removed_registrations?: Optional<number>\n cmd_deploy_confirm_cancelled?: Optional<boolean>\n cmd_deploy_confirm_time_to_complete_ms?: Optional<number>\n cmd_deploy_prompt_upgrade_to_unified_displayed?: Optional<boolean>\n cmd_deploy_prompt_upgrade_to_unified_response?: Optional<string>\n\n // Release related commands\n cmd_release_confirm_cancelled?: Optional<boolean>\n\n // App setup\n app_extensions_any?: Optional<boolean>\n app_extensions_breakdown?: Optional<string>\n app_extensions_count?: Optional<number>\n app_extensions_custom_layout?: Optional<boolean>\n app_extensions_function_any?: Optional<boolean>\n app_extensions_function_count?: Optional<number>\n app_extensions_function_custom_layout?: Optional<boolean>\n app_extensions_theme_any?: Optional<boolean>\n app_extensions_theme_count?: Optional<number>\n app_extensions_theme_custom_layout?: Optional<boolean>\n app_extensions_ui_any?: Optional<boolean>\n app_extensions_ui_count?: Optional<number>\n app_extensions_ui_custom_layout?: Optional<boolean>\n app_name_hash?: Optional<string>\n app_path_hash?: Optional<string>\n app_scopes?: Optional<string>\n app_web_backend_any?: Optional<boolean>\n app_web_backend_count?: Optional<number>\n app_web_custom_layout?: Optional<boolean>\n app_web_framework?: Optional<string>\n app_web_frontend_any?: Optional<boolean>\n app_web_frontend_count?: Optional<number>\n\n // Environment\n env_ci?: Optional<boolean>\n env_ci_platform?: Optional<string>\n env_device_id?: Optional<string>\n env_package_manager?: Optional<string>\n env_package_manager_workspaces?: Optional<boolean>\n env_plugin_installed_any_custom?: Optional<boolean>\n env_plugin_installed_shopify?: Optional<string>\n env_shell?: Optional<string>\n env_web_ide?: Optional<string>\n env_cloud?: Optional<string>\n }\n }\n [schemaId: string]: {sensitive: JsonMap; public: JsonMap}\n}\n\n// In reality, we're normally most interested in just this from Schemas, so export it for ease of use.\n// The monorail schema itself has lots of optional values as it must be backwards-compatible. For our schema we want mandatory values instead.\nexport type MonorailEventPublic = DeepRequired<Schemas[typeof MONORAIL_COMMAND_TOPIC]['public']>\nexport type MonorailEventSensitive = Schemas[typeof MONORAIL_COMMAND_TOPIC]['sensitive']\n\ntype MonorailResult = {type: 'ok'} | {type: 'error'; message: string}\n\n/**\n * Publishes an event to Monorail.\n *\n * @param schemaId - The schema ID of the event to publish.\n * @param publicData - The public data to publish.\n * @param sensitiveData - The sensitive data to publish.\n * @returns A result indicating whether the event was successfully published.\n */\nexport async function publishMonorailEvent<TSchemaId extends keyof Schemas, TPayload extends Schemas[TSchemaId]>(\n schemaId: TSchemaId,\n publicData: TPayload['public'],\n sensitiveData: TPayload['sensitive'],\n): Promise<MonorailResult> {\n try {\n const currentTime = new Date().getTime()\n const payload = {...publicData, ...sensitiveData}\n const body = JSON.stringify({schema_id: schemaId, payload})\n const headers = buildHeaders(currentTime)\n\n const response = await fetch(url, {method: 'POST', body, headers})\n\n if (response.status === 200) {\n outputDebug(outputContent`Analytics event sent: ${outputToken.json(payload)}`)\n return {type: 'ok'}\n } else {\n outputDebug(`Failed to report usage analytics: ${response.statusText}`)\n return {type: 'error', message: response.statusText}\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n let message = 'Failed to report usage analytics'\n if (error instanceof Error) {\n message = message.concat(`: ${error.message}`)\n }\n outputDebug(message)\n return {type: 'error', message}\n }\n}\n\nconst buildHeaders = (currentTime: number) => {\n return {\n 'Content-Type': 'application/json; charset=utf-8',\n 'X-Monorail-Edge-Event-Created-At-Ms': currentTime.toString(),\n 'X-Monorail-Edge-Event-Sent-At-Ms': currentTime.toString(),\n }\n}\n"]}
|
|
@@ -99,6 +99,12 @@ export declare function installNodeModules(options: InstallNodeModulesOptions):
|
|
|
99
99
|
* @returns A promise that resolves with the name.
|
|
100
100
|
*/
|
|
101
101
|
export declare function getPackageName(packageJsonPath: string): Promise<string | undefined>;
|
|
102
|
+
/**
|
|
103
|
+
* Returns the version of the package configured in its package.json
|
|
104
|
+
* @param packageJsonPath - Path to the package.json file
|
|
105
|
+
* @returns A promise that resolves with the version.
|
|
106
|
+
*/
|
|
107
|
+
export declare function getPackageVersion(packageJsonPath: string): Promise<string | undefined>;
|
|
102
108
|
/**
|
|
103
109
|
* Returns the list of production and dev dependencies of a package.json
|
|
104
110
|
* @param packageJsonPath - Path to the package.json file
|
|
@@ -3,6 +3,7 @@ import { AbortController } from './abort.js';
|
|
|
3
3
|
import { exec } from './system.js';
|
|
4
4
|
import { fileExists, readFile, writeFile, findPathUp, glob } from './fs.js';
|
|
5
5
|
import { dirname, joinPath } from './path.js';
|
|
6
|
+
import { runWithTimer } from './metadata.js';
|
|
6
7
|
import { outputToken, outputContent, outputDebug } from '../../public/node/output.js';
|
|
7
8
|
import { Version } from '../../private/node/semver.js';
|
|
8
9
|
import latestVersion from 'latest-version';
|
|
@@ -136,7 +137,9 @@ export async function installNodeModules(options) {
|
|
|
136
137
|
if (options.args) {
|
|
137
138
|
args = args.concat(options.args);
|
|
138
139
|
}
|
|
139
|
-
await
|
|
140
|
+
await runWithTimer('cmd_all_timing_network_ms')(async () => {
|
|
141
|
+
await exec(options.packageManager, args, execOptions);
|
|
142
|
+
});
|
|
140
143
|
}
|
|
141
144
|
/**
|
|
142
145
|
* Returns the name of the package configured in its package.json
|
|
@@ -147,6 +150,15 @@ export async function getPackageName(packageJsonPath) {
|
|
|
147
150
|
const packageJsonContent = await readAndParsePackageJson(packageJsonPath);
|
|
148
151
|
return packageJsonContent.name;
|
|
149
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Returns the version of the package configured in its package.json
|
|
155
|
+
* @param packageJsonPath - Path to the package.json file
|
|
156
|
+
* @returns A promise that resolves with the version.
|
|
157
|
+
*/
|
|
158
|
+
export async function getPackageVersion(packageJsonPath) {
|
|
159
|
+
const packageJsonContent = await readAndParsePackageJson(packageJsonPath);
|
|
160
|
+
return packageJsonContent.version;
|
|
161
|
+
}
|
|
150
162
|
/**
|
|
151
163
|
* Returns the list of production and dev dependencies of a package.json
|
|
152
164
|
* @param packageJsonPath - Path to the package.json file
|
|
@@ -385,7 +397,9 @@ export async function addResolutionOrOverride(directory, dependencies) {
|
|
|
385
397
|
*/
|
|
386
398
|
async function getLatestNPMPackageVersion(name) {
|
|
387
399
|
outputDebug(outputContent `Getting the latest version of NPM package: ${outputToken.raw(name)}`);
|
|
388
|
-
return
|
|
400
|
+
return runWithTimer('cmd_all_timing_network_ms')(() => {
|
|
401
|
+
return latestVersion(name);
|
|
402
|
+
});
|
|
389
403
|
}
|
|
390
404
|
/**
|
|
391
405
|
* Writes the package.json file to the given directory.
|