@shopify/oxygen-cli 2.0.3-unstable.202310051444.0 → 2.1.1-unstable.202310110934.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. package/README.md +10 -1
  2. package/dist/commands/oxygen/deploy.d.ts +1 -0
  3. package/dist/commands/oxygen/deploy.js +16 -0
  4. package/dist/commands/oxygen/deploy.js.map +1 -0
  5. package/dist/deploy/build-cancel.js +2 -0
  6. package/dist/deploy/build-cancel.js.map +1 -0
  7. package/dist/deploy/build-initiate.js +2 -0
  8. package/dist/deploy/build-initiate.js.map +1 -0
  9. package/dist/deploy/build-project.js +19 -1
  10. package/dist/deploy/build-project.js.map +1 -0
  11. package/dist/deploy/deployment-cancel.js +2 -0
  12. package/dist/deploy/deployment-cancel.js.map +1 -0
  13. package/dist/deploy/deployment-complete.js +2 -0
  14. package/dist/deploy/deployment-complete.js.map +1 -0
  15. package/dist/deploy/deployment-initiate.js +2 -0
  16. package/dist/deploy/deployment-initiate.js.map +1 -0
  17. package/dist/deploy/get-upload-files.js +2 -0
  18. package/dist/deploy/get-upload-files.js.map +1 -0
  19. package/dist/deploy/graphql/build-cancel.js +2 -0
  20. package/dist/deploy/graphql/build-cancel.js.map +1 -0
  21. package/dist/deploy/graphql/build-initiate.js +2 -0
  22. package/dist/deploy/graphql/build-initiate.js.map +1 -0
  23. package/dist/deploy/graphql/deployment-cancel.js +2 -0
  24. package/dist/deploy/graphql/deployment-cancel.js.map +1 -0
  25. package/dist/deploy/graphql/deployment-complete.js +2 -0
  26. package/dist/deploy/graphql/deployment-complete.js.map +1 -0
  27. package/dist/deploy/graphql/deployment-initiate.js +2 -0
  28. package/dist/deploy/graphql/deployment-initiate.js.map +1 -0
  29. package/dist/deploy/index.js +16 -0
  30. package/dist/deploy/index.js.map +1 -0
  31. package/dist/deploy/metadata.js +2 -0
  32. package/dist/deploy/metadata.js.map +1 -0
  33. package/dist/deploy/types.d.ts +1 -0
  34. package/dist/deploy/types.js +2 -0
  35. package/dist/deploy/types.js.map +1 -0
  36. package/dist/deploy/upload-files.js +2 -0
  37. package/dist/deploy/upload-files.js.map +1 -0
  38. package/dist/deploy/verify-deployment.js +2 -0
  39. package/dist/deploy/verify-deployment.js.map +1 -0
  40. package/dist/index.js +2 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/oxygen-cli.js +2 -0
  43. package/dist/oxygen-cli.js.map +1 -0
  44. package/dist/utils/bugsnag.d.ts +6 -0
  45. package/dist/utils/bugsnag.js +38 -0
  46. package/dist/utils/bugsnag.js.map +1 -0
  47. package/dist/utils/test-helper.js +3 -0
  48. package/dist/utils/test-helper.js.map +1 -0
  49. package/dist/utils/utils.js +2 -0
  50. package/dist/utils/utils.js.map +1 -0
  51. package/oclif.manifest.json +8 -1
  52. package/package.json +9 -4
package/README.md CHANGED
@@ -49,6 +49,7 @@ oxygen:deploy [options]
49
49
  - --metadataUrl <metadataUrl>: URL that links to the deployment.
50
50
  - --metadataUser <metadataUser>: User that initiated the deployment.
51
51
  - --metadataVersion <metadataVersion>: A version identifier for the deployment.
52
+ - --disableBugsnag: Disable Bugsnag error reporting.
52
53
 
53
54
  **Note**: All metadata options (--metadataDescription, --metadataUrl, --metadataUser, and --metadataVersion) have a maximum character limit of 375.
54
55
 
@@ -89,7 +90,7 @@ The following environment variables are relevant, depending on your environment:
89
90
  |- | --------- | --------| ------ | ------ |
90
91
  | User | BITBUCKET_COMMIT_AUTHOR | CIRCLE_USERNAME | GITHUB_ACTOR | GITLAB_USER_LOGIN |
91
92
  | Version | BITBUCKET_COMMIT | CIRCLE_SHA1 | GITHUB_SHA | CI_COMMIT_SHA |
92
- | URL | BITBUCKET_BUILD_URL | CIRCLE_BUILD_URL | `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}` | CI_PROJECT_URL |
93
+ | URL | `https://bitbucket.org/${envs.BITBUCKET_WORKSPACE}/${envs.BITBUCKET_REPO_SLUG}/pipelines/results/${envs.BITBUCKET_BUILD_NUMBER}` | CIRCLE_BUILD_URL | `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}` | CI_PIPELINE_URL |
93
94
 
94
95
  These values can be overridden by the command line flags `metadataUser`, `metadataUrl` and `metadataVersion` respectively.
95
96
 
@@ -105,3 +106,11 @@ The environment tag to deploy to will be derived from the following variables:
105
106
  | Gitlab | CI_COMMIT_REF_NAME |
106
107
 
107
108
  The `environmentTag` command line option can be used to override this. If not provided, or there is no environment with the specified tag, the deployment will be deployed to the default environment for the app (if one exists).
109
+
110
+ ## Error reporting with Bugsnag
111
+
112
+ `oxygen-cli` Uses Bugsnag to collect errors that occur during the deployment process. This helps Shopify diagnose and fix issues more efficiently, improving the reliability of the tool.
113
+
114
+ Bugsnag collects error reports which include stack traces, the type of error, and other relevant data that can help in diagnosing the issue. Please be aware that as part of the error reporting process, some user data related to your Continuous Integration (CI) environment may be logged. This data is used solely for the purpose of diagnosing and resolving issues.
115
+
116
+ Users who prefer not to send error reports can use the `--disableBugsnag` flag. When this flag is set, no error data will be sent to Bugsnag.
@@ -7,6 +7,7 @@ declare class Deploy extends Command {
7
7
  static flags: {
8
8
  assetsFolder: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
9
9
  buildCommand: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
10
+ disableBugsnag: _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
10
11
  environmentTag: _oclif_core_lib_interfaces_parser_js.OptionFlag<string | undefined, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
11
12
  verificationMaxDuration: _oclif_core_lib_interfaces_parser_js.OptionFlag<number, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
12
13
  path: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
@@ -1,6 +1,7 @@
1
1
  import { Command, Flags } from '@oclif/core';
2
2
  import { consoleError } from '@shopify/cli-kit/node/output';
3
3
  import { normalizePath } from '@shopify/cli-kit/node/path';
4
+ import { initializeBugsnag, getBugsnag } from '../../utils/bugsnag.js';
4
5
  import { createDeploy } from '../../deploy/index.js';
5
6
  import { deployDefaults, parseToken, verifyConfig, getBuildCommandFromLockFile } from '../../utils/utils.js';
6
7
  import { VerificationError } from '../../deploy/types.js';
@@ -25,6 +26,11 @@ class Deploy extends Command {
25
26
  return Promise.resolve(input);
26
27
  }
27
28
  }),
29
+ disableBugsnag: Flags.boolean({
30
+ description: "Disable Bugsnag error reporting",
31
+ required: false,
32
+ default: false
33
+ }),
28
34
  environmentTag: Flags.string({
29
35
  char: "e",
30
36
  description: "Tag of the environment to deploy to",
@@ -105,12 +111,16 @@ class Deploy extends Command {
105
111
  async run() {
106
112
  try {
107
113
  const { flags } = await this.parse(Deploy);
114
+ initializeBugsnag(flags.disableBugsnag);
115
+ const Bugsnag = getBugsnag();
108
116
  const deploymentUrl = (
109
117
  // eslint-disable-next-line no-process-env
110
118
  process.env.UNSAFE_OXYGEN_DEPLOYMENT_URL || "https://oxygen.shopifyapps.com"
111
119
  );
120
+ Bugsnag?.addMetadata("flags", { flags, deploymentUrl });
112
121
  const config = {
113
122
  assetsDir: normalizePath(flags.assetsFolder),
123
+ bugsnag: !flags.disableBugsnag,
114
124
  buildCommand: flags.buildCommand,
115
125
  deploymentToken: parseToken(flags.token),
116
126
  environmentTag: flags.environmentTag,
@@ -135,6 +145,10 @@ class Deploy extends Command {
135
145
  }
136
146
  await createDeploy({ config });
137
147
  } catch (error) {
148
+ const Bugsnag = getBugsnag();
149
+ if (Bugsnag && (error instanceof Error || typeof error === "string")) {
150
+ Bugsnag.notify(error);
151
+ }
138
152
  if (!(error instanceof Error)) {
139
153
  consoleError(error);
140
154
  } else if (!(error instanceof VerificationError)) {
@@ -146,3 +160,5 @@ class Deploy extends Command {
146
160
  }
147
161
 
148
162
  export { Deploy };
163
+ //# sourceMappingURL=out.js.map
164
+ //# sourceMappingURL=deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/oxygen/deploy.ts"],"names":[],"mappings":"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","sourcesContent":["import {Command, Flags} from '@oclif/core';\nimport {consoleError} from '@shopify/cli-kit/node/output';\nimport {normalizePath} from '@shopify/cli-kit/node/path';\n\nimport {getBugsnag, initializeBugsnag} from '../../utils/bugsnag.js';\nimport {createDeploy} from '../../deploy/index.js';\nimport {\n deployDefaults,\n getBuildCommandFromLockFile,\n parseToken,\n verifyConfig,\n} from '../../utils/utils.js';\nimport type {DeploymentConfig} from '../../deploy/types.js';\nimport {VerificationError} from '../../deploy/types.js';\n\nexport class Deploy extends Command {\n static description = 'Creates a deployment to Oxygen';\n static hidden = false;\n static flags = {\n assetsFolder: Flags.string({\n char: 'a',\n description: 'Assets folder',\n default: String(deployDefaults.assetsDirDefault),\n required: false,\n }),\n buildCommand: Flags.string({\n char: 'b',\n description: 'Build command',\n required: false,\n default: String(deployDefaults.buildCommandDefault!),\n parse: (input): Promise<string> => {\n this.hasCustomBuildCommand = true;\n return Promise.resolve(input);\n },\n }),\n disableBugsnag: Flags.boolean({\n description: 'Disable Bugsnag error reporting',\n required: false,\n default: false,\n }),\n environmentTag: Flags.string({\n char: 'e',\n description: 'Tag of the environment to deploy to',\n required: false,\n }),\n verificationMaxDuration: Flags.integer({\n char: 'd',\n description:\n 'the maximum duration (in seconds) that the deployment verification step is allowed to run before it is considered failed.',\n min: 10,\n max: 300,\n required: false,\n default: deployDefaults.verificationMaxDurationDefault as number,\n }),\n path: Flags.string({\n char: 'p',\n description: 'Root path',\n default: './',\n required: false,\n }),\n publicDeployment: Flags.boolean({\n env: 'OXYGEN_PUBLIC_DEPLOYMENT',\n description: 'Marks a preview deployment as publicly accessible.',\n required: false,\n default: false,\n }),\n skipBuild: Flags.boolean({\n char: 's',\n description: 'Skip running build command',\n required: false,\n default: false,\n }),\n skipVerification: Flags.boolean({\n char: 'v',\n description: 'Skip running deployment verification step',\n required: false,\n default: false,\n }),\n token: Flags.string({\n char: 't',\n description: 'Oxygen deployment token',\n env: 'OXYGEN_DEPLOYMENT_TOKEN',\n required: true,\n }),\n workerFolder: Flags.string({\n char: 'w',\n description: 'Worker folder',\n default: String(deployDefaults.workerDirDefault),\n required: false,\n }),\n workerOnly: Flags.boolean({\n char: 'o',\n description: 'Worker only deployment',\n default: false,\n required: false,\n }),\n metadataDescription: Flags.string({\n description:\n 'Description of the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_DESCRIPTION',\n }),\n metadataUrl: Flags.string({\n description:\n 'URL that links to the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_URL',\n }),\n metadataUser: Flags.string({\n description:\n 'User that initiated the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_USER',\n }),\n metadataVersion: Flags.string({\n description:\n 'A version identifier for the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_VERSION',\n }),\n };\n\n static hasCustomBuildCommand = false;\n\n async run() {\n try {\n const {flags} = await this.parse(Deploy);\n\n initializeBugsnag(flags.disableBugsnag);\n const Bugsnag = getBugsnag();\n\n const deploymentUrl =\n // eslint-disable-next-line no-process-env\n process.env.UNSAFE_OXYGEN_DEPLOYMENT_URL ||\n 'https://oxygen.shopifyapps.com';\n Bugsnag?.addMetadata('flags', {flags, deploymentUrl});\n\n const config: DeploymentConfig = {\n assetsDir: normalizePath(flags.assetsFolder),\n bugsnag: !flags.disableBugsnag,\n buildCommand: flags.buildCommand!,\n deploymentToken: parseToken(flags.token!),\n environmentTag: flags.environmentTag,\n deploymentUrl,\n verificationMaxDuration: flags.verificationMaxDuration,\n metadata: {\n description: flags.metadataDescription,\n url: flags.metadataUrl,\n user: flags.metadataUser,\n version: flags.metadataVersion,\n },\n publicDeployment: flags.publicDeployment,\n rootPath: normalizePath(flags.path),\n skipBuild: flags.skipBuild,\n skipVerification: flags.skipVerification,\n workerDir: normalizePath(flags.workerFolder),\n workerOnly: flags.workerOnly,\n };\n\n await verifyConfig({config});\n if (!Deploy.hasCustomBuildCommand && !config.skipBuild) {\n config.buildCommand = getBuildCommandFromLockFile(config);\n }\n await createDeploy({config});\n } catch (error) {\n const Bugsnag = getBugsnag();\n if (Bugsnag && (error instanceof Error || typeof error === 'string')) {\n Bugsnag.notify(error);\n }\n\n if (!(error instanceof Error)) {\n consoleError(error as string);\n } else if (!(error instanceof VerificationError)) {\n consoleError(error.message);\n }\n\n this.exit(1);\n }\n }\n}\n"]}
@@ -35,3 +35,5 @@ async function buildCancel(options) {
35
35
  }
36
36
 
37
37
  export { buildCancel };
38
+ //# sourceMappingURL=out.js.map
39
+ //# sourceMappingURL=build-cancel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/build-cancel.ts"],"names":[],"mappings":"AAAA,SAAQ,sBAAqB;AAC7B,SAAQ,kBAAiB;AACzB,SAAgB,kBAAiB;AAEjC,SAAQ,cAAc,cAAa;AAGnC;AAAA,EACE;AAAA,OAGK;AASP,eAAsB,YACpB,SAC8B;AAC9B,QAAM,EAAC,QAAQ,SAAS,QAAQ,OAAM,IAAI;AAE1C,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AACF,UAAM,WAAiC,MAAM,eAAe;AAAA,MAC1D,OAAO;AAAA,MACP,KAAK;AAAA,MACL,KAAK,GAAG,OAAO,aAAa;AAAA,MAC5B,OAAO,OAAO,gBAAgB;AAAA,MAC9B,cAAc;AAAA,QACZ,CAAC,OAAO,qBAAqB,GAAG,OAAO,gBAAgB;AAAA,MACzD;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,SAAS,YAAY,WAAW,UAAU,GAAG;AAC/C,YAAM,IAAI;AAAA,QACR,2BAA2B,SAAS,YAAY,WAAW,CAAC,GAAG,OAAO;AAAA,MACxE;AAAA,IACF;AACA,eAAW,iBAAiB,OAAO,eAAe,MAAM;AAExD,WAAO,SAAS;AAAA,EAClB,SAAS,OAAO;AACd,iBAAa,KAAK;AAElB,UAAM;AAAA,EACR;AACF","sourcesContent":["import {graphqlRequest} from '@shopify/cli-kit/node/api/graphql';\nimport {AbortError} from '@shopify/cli-kit/node/error';\nimport {Logger, outputInfo} from '@shopify/cli-kit/node/output';\n\nimport {errorHandler, Header} from '../utils/utils.js';\n\nimport type {DeploymentConfig} from './types.js';\nimport {\n BuildCancelQuery,\n BuildCancelQueryData,\n BuildCancelResponse,\n} from './graphql/build-cancel.js';\n\ninterface BuildCancelOptions {\n config: DeploymentConfig;\n buildId: string;\n reason: string;\n logger: Logger;\n}\n\nexport async function buildCancel(\n options: BuildCancelOptions,\n): Promise<BuildCancelResponse> {\n const {config, buildId, reason, logger} = options;\n\n const variables = {\n buildId,\n reason,\n };\n\n try {\n const response: BuildCancelQueryData = await graphqlRequest({\n query: BuildCancelQuery,\n api: 'Oxygen',\n url: `${config.deploymentUrl}/api/v2/admin/graphql`,\n token: config.deploymentToken.accessToken,\n addedHeaders: {\n [Header.OxygenNamespaceHandle]: config.deploymentToken.namespace,\n },\n variables,\n });\n\n if (response.buildCancel.userErrors.length >= 1) {\n throw new AbortError(\n `Failed to cancel build: ${response.buildCancel.userErrors[0]?.message}`,\n );\n }\n outputInfo(`Build with id ${buildId} cancelled.`, logger);\n\n return response.buildCancel;\n } catch (error) {\n errorHandler(error);\n\n throw error;\n }\n}\n"]}
@@ -38,3 +38,5 @@ async function buildInitiate(options) {
38
38
  }
39
39
 
40
40
  export { buildInitiate };
41
+ //# sourceMappingURL=out.js.map
42
+ //# sourceMappingURL=build-initiate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/build-initiate.ts"],"names":[],"mappings":"AAAA,SAAQ,sBAAqB;AAC7B,SAAQ,kBAAiB;AACzB,SAAgB,uBAAsB;AAEtC,SAAQ,cAAc,cAAa;AAGnC;AAAA,EACE;AAAA,OAGK;AASP,eAAsB,cACpB,SACgC;AAChC,QAAM,EAAC,QAAQ,QAAQ,aAAa,SAAS,CAAC,EAAC,IAAI;AAEnD,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AACF,UAAM,WAAmC,MAAM,eAAe;AAAA,MAC5D,OAAO;AAAA,MACP,KAAK;AAAA,MACL,KAAK,GAAG,OAAO,aAAa;AAAA,MAC5B,OAAO,OAAO,gBAAgB;AAAA,MAC9B;AAAA,MACA,cAAc;AAAA,QACZ,CAAC,OAAO,qBAAqB,GAAG,OAAO,gBAAgB;AAAA,MACzD;AAAA,IACF,CAAC;AAED,QAAI,SAAS,cAAc,WAAW,UAAU,GAAG;AACjD,YAAM,IAAI;AAAA,QACR,2BAA2B,SAAS,cAAc,WAAW,CAAC,GAAG,OAAO;AAAA,MAC1E;AAAA,IACF;AACA;AAAA,MACE,wCAAwC,SAAS,cAAc,MAAM,EAAE;AAAA,MACvE;AAAA,IACF;AAEA,WAAO,SAAS;AAAA,EAClB,SAAS,OAAO;AACd,iBAAa,KAAK;AAElB,UAAM;AAAA,EACR;AACF","sourcesContent":["import {graphqlRequest} from '@shopify/cli-kit/node/api/graphql';\nimport {AbortError} from '@shopify/cli-kit/node/error';\nimport {Logger, outputCompleted} from '@shopify/cli-kit/node/output';\n\nimport {errorHandler, Header} from '../utils/utils.js';\n\nimport {EnvironmentInput, DeploymentConfig} from './types.js';\nimport {\n BuildInitiateQuery,\n BuildInitiateQueryData,\n BuildInitiateResponse,\n} from './graphql/build-initiate.js';\n\ninterface BuildInitiateOptions {\n config: DeploymentConfig;\n logger: Logger;\n environment?: EnvironmentInput;\n labels?: string[];\n}\n\nexport async function buildInitiate(\n options: BuildInitiateOptions,\n): Promise<BuildInitiateResponse> {\n const {config, logger, environment, labels = []} = options;\n\n const variables = {\n environment,\n labels,\n };\n\n try {\n const response: BuildInitiateQueryData = await graphqlRequest({\n query: BuildInitiateQuery,\n api: 'Oxygen',\n url: `${config.deploymentUrl}/api/v2/admin/graphql`,\n token: config.deploymentToken.accessToken,\n variables,\n addedHeaders: {\n [Header.OxygenNamespaceHandle]: config.deploymentToken.namespace,\n },\n });\n\n if (response.buildInitiate.userErrors.length >= 1) {\n throw new AbortError(\n `Failed to create build. ${response.buildInitiate.userErrors[0]?.message}`,\n );\n }\n outputCompleted(\n `Build initiated successfully with id ${response.buildInitiate.build.id}.`,\n logger,\n );\n\n return response.buildInitiate;\n } catch (error) {\n errorHandler(error);\n\n throw error;\n }\n}\n"]}
@@ -1,7 +1,10 @@
1
1
  import { spawn } from 'child_process';
2
+ import { PassThrough } from 'stream';
3
+ import { getBugsnag } from '../utils/bugsnag.js';
2
4
 
3
5
  async function buildProject(options) {
4
6
  const { config, assetPath, hooks } = options;
7
+ const Bugsnag = getBugsnag();
5
8
  if (hooks?.buildFunction) {
6
9
  try {
7
10
  await hooks.buildFunction(assetPath);
@@ -13,8 +16,14 @@ async function buildProject(options) {
13
16
  const assetPathEnvironment = assetPath ? { HYDROGEN_ASSET_BASE_URL: assetPath } : {};
14
17
  try {
15
18
  await new Promise((resolve, reject) => {
19
+ let stderr = "";
20
+ const stderrStream = new PassThrough();
21
+ stderrStream.on("data", (chunk) => {
22
+ stderr += chunk;
23
+ process.stderr.write(chunk);
24
+ });
16
25
  const buildCommand = spawn(config.buildCommand, [], {
17
- stdio: ["inherit", process.stderr, "inherit"],
26
+ stdio: ["inherit", "pipe", "pipe"],
18
27
  env: {
19
28
  // eslint-disable-next-line no-process-env
20
29
  ...process.env,
@@ -23,7 +32,14 @@ async function buildProject(options) {
23
32
  cwd: config.rootPath,
24
33
  shell: true
25
34
  });
35
+ buildCommand.stderr?.pipe(stderrStream);
36
+ buildCommand.stdout?.pipe(stderrStream);
26
37
  buildCommand.on("close", (code) => {
38
+ Bugsnag?.addMetadata("buildCommand", {
39
+ command: config.buildCommand,
40
+ stderr,
41
+ code
42
+ });
27
43
  if (code !== 0) {
28
44
  reject(code);
29
45
  return;
@@ -37,3 +53,5 @@ async function buildProject(options) {
37
53
  }
38
54
 
39
55
  export { buildProject };
56
+ //# sourceMappingURL=out.js.map
57
+ //# sourceMappingURL=build-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/build-project.ts"],"names":[],"mappings":"AAAA,SAAQ,aAAY;AACpB,SAAQ,mBAA4B;AAEpC,SAAQ,kBAAiB;AAUzB,eAAsB,aAAa,SAA8B;AAC/D,QAAM,EAAC,QAAQ,WAAW,MAAK,IAAI;AACnC,QAAM,UAAU,WAAW;AAE3B,MAAI,OAAO,eAAe;AACxB,QAAI;AACF,YAAM,MAAM,cAAc,SAAS;AAAA,IACrC,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,qCAAqC,KAAK,EAAE;AAAA,IAC9D;AACA;AAAA,EACF;AAEA,QAAM,uBAAuB,YACzB,EAAC,yBAAyB,UAAS,IACnC,CAAC;AACL,MAAI;AACF,UAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACrC,UAAI,SAAS;AACb,YAAM,eAAe,IAAI,YAAY;AAErC,mBAAa,GAAG,QAAQ,CAAC,UAAU;AACjC,kBAAU;AACV,gBAAQ,OAAO,MAAM,KAAK;AAAA,MAC5B,CAAC;AAED,YAAM,eAAe,MAAM,OAAO,cAAe,CAAC,GAAG;AAAA,QACnD,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,QACjC,KAAK;AAAA;AAAA,UAEH,GAAG,QAAQ;AAAA,UACX,GAAG;AAAA,QACL;AAAA,QACA,KAAK,OAAO;AAAA,QACZ,OAAO;AAAA,MACT,CAAC;AAED,MAAC,aAAa,QAA4B,KAAK,YAAY;AAC3D,MAAC,aAAa,QAA4B,KAAK,YAAY;AAE3D,mBAAa,GAAG,SAAS,CAAC,SAAS;AACjC,iBAAS,YAAY,gBAAgB;AAAA,UACnC,SAAS,OAAO;AAAA,UAChB;AAAA,UACA;AAAA,QACF,CAAC;AACD,YAAI,SAAS,GAAG;AACd,iBAAO,IAAI;AACX;AAAA,QACF;AACA,gBAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,iCAAiC,KAAK,EAAE;AAAA,EAC1D;AACF","sourcesContent":["import {spawn} from 'child_process';\nimport {PassThrough, Readable} from 'stream';\n\nimport {getBugsnag} from '../utils/bugsnag.js';\n\nimport {DeploymentConfig, DeploymentHooks} from './types.js';\n\ninterface BuildProjectOptions {\n config: DeploymentConfig;\n assetPath?: string;\n hooks?: DeploymentHooks;\n}\n\nexport async function buildProject(options: BuildProjectOptions) {\n const {config, assetPath, hooks} = options;\n const Bugsnag = getBugsnag();\n\n if (hooks?.buildFunction) {\n try {\n await hooks.buildFunction(assetPath);\n } catch (error) {\n throw new Error(`Build function failed with error: ${error}`);\n }\n return;\n }\n\n const assetPathEnvironment = assetPath\n ? {HYDROGEN_ASSET_BASE_URL: assetPath}\n : {};\n try {\n await new Promise((resolve, reject) => {\n let stderr = '';\n const stderrStream = new PassThrough();\n\n stderrStream.on('data', (chunk) => {\n stderr += chunk;\n process.stderr.write(chunk);\n });\n\n const buildCommand = spawn(config.buildCommand!, [], {\n stdio: ['inherit', 'pipe', 'pipe'],\n env: {\n // eslint-disable-next-line no-process-env\n ...process.env,\n ...assetPathEnvironment,\n },\n cwd: config.rootPath,\n shell: true,\n });\n\n (buildCommand.stderr as Readable | null)?.pipe(stderrStream);\n (buildCommand.stdout as Readable | null)?.pipe(stderrStream);\n\n buildCommand.on('close', (code) => {\n Bugsnag?.addMetadata('buildCommand', {\n command: config.buildCommand,\n stderr,\n code,\n });\n if (code !== 0) {\n reject(code);\n return;\n }\n resolve(code);\n });\n });\n } catch (error) {\n throw new Error(`Build failed with error code: ${error}`);\n }\n}\n"]}
@@ -35,3 +35,5 @@ async function deploymentCancel(options) {
35
35
  }
36
36
 
37
37
  export { deploymentCancel };
38
+ //# sourceMappingURL=out.js.map
39
+ //# sourceMappingURL=deployment-cancel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/deployment-cancel.ts"],"names":[],"mappings":"AAAA,SAAQ,sBAAqB;AAC7B,SAAQ,kBAAiB;AACzB,SAAgB,kBAAiB;AAEjC,SAAQ,cAAc,cAAa;AAGnC;AAAA,EACE;AAAA,OAGK;AASP,eAAsB,iBACpB,SACmC;AACnC,QAAM,EAAC,QAAQ,cAAc,QAAQ,OAAM,IAAI;AAE/C,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AACF,UAAM,WAAsC,MAAM,eAAe;AAAA,MAC/D,OAAO;AAAA,MACP,KAAK;AAAA,MACL,KAAK,GAAG,OAAO,aAAa;AAAA,MAC5B,OAAO,OAAO,gBAAgB;AAAA,MAC9B;AAAA,MACA,cAAc;AAAA,QACZ,CAAC,OAAO,qBAAqB,GAAG,OAAO,gBAAgB;AAAA,MACzD;AAAA,IACF,CAAC;AAED,QAAI,SAAS,iBAAiB,WAAW,UAAU,GAAG;AACpD,YAAM,IAAI;AAAA,QACR,gCAAgC,SAAS,iBAAiB,WAAW,CAAC,GAAG,OAAO;AAAA,MAClF;AAAA,IACF;AACA,eAAW,sBAAsB,YAAY,eAAe,MAAM;AAElE,WAAO,SAAS;AAAA,EAClB,SAAS,OAAO;AACd,iBAAa,KAAK;AAElB,UAAM;AAAA,EACR;AACF","sourcesContent":["import {graphqlRequest} from '@shopify/cli-kit/node/api/graphql';\nimport {AbortError} from '@shopify/cli-kit/node/error';\nimport {Logger, outputInfo} from '@shopify/cli-kit/node/output';\n\nimport {errorHandler, Header} from '../utils/utils.js';\n\nimport type {DeploymentConfig} from './types.js';\nimport {\n DeploymentCancelQuery,\n DeploymentCancelQueryData,\n DeploymentCancelResponse,\n} from './graphql/deployment-cancel.js';\n\ninterface DeploymentCancelOptions {\n config: DeploymentConfig;\n deploymentId: string;\n reason: string;\n logger: Logger;\n}\n\nexport async function deploymentCancel(\n options: DeploymentCancelOptions,\n): Promise<DeploymentCancelResponse> {\n const {config, deploymentId, reason, logger} = options;\n\n const variables = {\n deploymentId,\n reason,\n };\n\n try {\n const response: DeploymentCancelQueryData = await graphqlRequest({\n query: DeploymentCancelQuery,\n api: 'Oxygen',\n url: `${config.deploymentUrl}/api/v2/admin/graphql`,\n token: config.deploymentToken.accessToken,\n variables,\n addedHeaders: {\n [Header.OxygenNamespaceHandle]: config.deploymentToken.namespace,\n },\n });\n\n if (response.deploymentCancel.userErrors.length >= 1) {\n throw new AbortError(\n `Failed to cancel deployment: ${response.deploymentCancel.userErrors[0]?.message}`,\n );\n }\n outputInfo(`Deployment with id ${deploymentId} cancelled.`, logger);\n\n return response.deploymentCancel;\n } catch (error) {\n errorHandler(error);\n\n throw error;\n }\n}\n"]}
@@ -31,3 +31,5 @@ async function deploymentComplete(config, deploymentId) {
31
31
  }
32
32
 
33
33
  export { deploymentComplete };
34
+ //# sourceMappingURL=out.js.map
35
+ //# sourceMappingURL=deployment-complete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/deployment-complete.ts"],"names":[],"mappings":"AAAA,SAAQ,sBAAqB;AAC7B,SAAQ,kBAAiB;AAEzB,SAAQ,cAAc,cAAa;AAEnC;AAAA,EACE;AAAA,OAGK;AAGP,eAAsB,mBACpB,QACA,cACqC;AACrC,QAAM,YAAY;AAAA,IAChB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,WAAwC,MAAM,eAAe;AAAA,MACjE,OAAO;AAAA,MACP,KAAK;AAAA,MACL,KAAK,GAAG,OAAO,aAAa;AAAA,MAC5B,OAAO,OAAO,gBAAgB;AAAA,MAC9B;AAAA,MACA,cAAc;AAAA,QACZ,CAAC,OAAO,qBAAqB,GAAG,OAAO,gBAAgB;AAAA,MACzD;AAAA,IACF,CAAC;AAED,QAAI,SAAS,mBAAmB,WAAW,UAAU,GAAG;AACtD,YAAM,IAAI;AAAA,QACR,kCAAkC,SAAS,mBAAmB,WAAW,CAAC,GAAG,OAAO;AAAA,MACtF;AAAA,IACF;AAEA,WAAO,SAAS;AAAA,EAClB,SAAS,OAAO;AACd,iBAAa,KAAK;AAElB,UAAM;AAAA,EACR;AACF","sourcesContent":["import {graphqlRequest} from '@shopify/cli-kit/node/api/graphql';\nimport {AbortError} from '@shopify/cli-kit/node/error';\n\nimport {errorHandler, Header} from '../utils/utils.js';\n\nimport {\n DeploymentCompleteQuery,\n DeploymentCompleteQueryData,\n DeploymentCompleteResponse,\n} from './graphql/deployment-complete.js';\nimport type {DeploymentConfig} from './types.js';\n\nexport async function deploymentComplete(\n config: DeploymentConfig,\n deploymentId: string,\n): Promise<DeploymentCompleteResponse> {\n const variables = {\n deploymentId,\n };\n\n try {\n const response: DeploymentCompleteQueryData = await graphqlRequest({\n query: DeploymentCompleteQuery,\n api: 'Oxygen',\n url: `${config.deploymentUrl}/api/v2/admin/graphql`,\n token: config.deploymentToken.accessToken,\n variables,\n addedHeaders: {\n [Header.OxygenNamespaceHandle]: config.deploymentToken.namespace,\n },\n });\n\n if (response.deploymentComplete.userErrors.length >= 1) {\n throw new AbortError(\n `Failed to complete deployment: ${response.deploymentComplete.userErrors[0]?.message}`,\n );\n }\n\n return response.deploymentComplete;\n } catch (error) {\n errorHandler(error);\n\n throw error;\n }\n}\n"]}
@@ -41,3 +41,5 @@ async function deploymentInitiate(options) {
41
41
  }
42
42
 
43
43
  export { deploymentInitiate };
44
+ //# sourceMappingURL=out.js.map
45
+ //# sourceMappingURL=deployment-initiate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/deployment-initiate.ts"],"names":[],"mappings":"AAAA,SAAQ,sBAAqB;AAC7B,SAAQ,kBAAiB;AACzB,SAAgB,uBAAsB;AAEtC,SAAQ,cAAc,cAAa;AAOnC;AAAA,EACE;AAAA,OAGK;AAsBP,eAAsB,mBACpB,SACqC;AACrC,QAAM,EAAC,QAAQ,OAAO,OAAM,IAAI;AAEhC,QAAM,YAAY;AAAA,IAChB,SAAS,MAAM;AAAA,IACf,aAAa,MAAM;AAAA,IACnB,OAAO,MAAM;AAAA,IACb,QAAQ,MAAM;AAAA,IACd,WAAW,CAAC,OAAO;AAAA,EACrB;AAEA,MAAI;AACF,UAAM,WAAwC,MAAM,eAAe;AAAA,MACjE,OAAO;AAAA,MACP,KAAK;AAAA,MACL,KAAK,GAAG,OAAO,aAAa;AAAA,MAC5B,OAAO,OAAO,gBAAgB;AAAA,MAC9B;AAAA,MACA,cAAc;AAAA,QACZ,CAAC,OAAO,qBAAqB,GAAG,OAAO,gBAAgB;AAAA,MACzD;AAAA,IACF,CAAC;AAED,QAAI,SAAS,mBAAmB,WAAW,UAAU,GAAG;AACtD,YAAM,IAAI;AAAA,QACR,gCAAgC,SAAS,mBAAmB,WAAW,CAAC,GAAG,OAAO;AAAA,MACpF;AAAA,IACF;AAEA;AAAA,MACE,yBAAyB,SAAS,mBAAmB,kBAAkB,MAAM;AAAA,MAC7E;AAAA,IACF;AACA,WAAO,SAAS;AAAA,EAClB,SAAS,OAAO;AACd,iBAAa,KAAK;AAElB,UAAM;AAAA,EACR;AACF","sourcesContent":["import {graphqlRequest} from '@shopify/cli-kit/node/api/graphql';\nimport {AbortError} from '@shopify/cli-kit/node/error';\nimport {Logger, outputCompleted} from '@shopify/cli-kit/node/output';\n\nimport {errorHandler, Header} from '../utils/utils.js';\n\nimport {\n DeploymentConfig,\n DeploymentManifestFile,\n EnvironmentInput,\n} from './types.js';\nimport {\n DeploymentInitiateQuery,\n DeploymentInitiateQueryData,\n DeploymentInitiateResponse,\n} from './graphql/deployment-initiate.js';\n\ntype DeploymentInitiateInput =\n | {\n buildId: string;\n environment?: never;\n labels?: string[];\n manifest: DeploymentManifestFile[];\n }\n | {\n environment?: EnvironmentInput;\n buildId?: never;\n labels?: string[];\n manifest: DeploymentManifestFile[];\n };\n\ninterface DeploymentInitiateOptions {\n config: DeploymentConfig;\n input: DeploymentInitiateInput;\n logger: Logger;\n}\n\nexport async function deploymentInitiate(\n options: DeploymentInitiateOptions,\n): Promise<DeploymentInitiateResponse> {\n const {config, input, logger} = options;\n\n const variables = {\n buildId: input.buildId,\n environment: input.environment,\n files: input.manifest,\n labels: input.labels,\n isPrivate: !config.publicDeployment,\n };\n\n try {\n const response: DeploymentInitiateQueryData = await graphqlRequest({\n query: DeploymentInitiateQuery,\n api: 'Oxygen',\n url: `${config.deploymentUrl}/api/v2/admin/graphql`,\n token: config.deploymentToken.accessToken,\n variables,\n addedHeaders: {\n [Header.OxygenNamespaceHandle]: config.deploymentToken.namespace,\n },\n });\n\n if (response.deploymentInitiate.userErrors.length >= 1) {\n throw new AbortError(\n `Failed to create deployment. ${response.deploymentInitiate.userErrors[0]?.message}`,\n );\n }\n\n outputCompleted(\n `Deployment initiated, ${response.deploymentInitiate.deploymentTargets.length} files to upload.`,\n logger,\n );\n return response.deploymentInitiate;\n } catch (error) {\n errorHandler(error);\n\n throw error;\n }\n}\n"]}
@@ -67,3 +67,5 @@ function assetFileFilter(fileName) {
67
67
  }
68
68
 
69
69
  export { getUploadFiles };
70
+ //# sourceMappingURL=out.js.map
71
+ //# sourceMappingURL=get-upload-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/get-upload-files.ts"],"names":[],"mappings":"AAAA,SAAQ,MAAM,cAAc,oBAAmB;AAC/C,SAAQ,gBAAe;AACvB,SAAQ,UAAU,oBAAmB;AACrC,SAAQ,sBAAqB;AAE7B,SAAkD,gBAAe;AAEjE,eAAsB,eACpB,QACmC;AACnC,QAAM,aAAa,SAAS,OAAO,UAAW,OAAO,SAAU;AAC/D,QAAM,cAAc,MAAM,KAAK,GAAG,UAAU,KAAK;AACjD,MAAI,WAAW,sBAAsB;AAAA,IACnC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,MAAM,SAAS;AAAA,IACf,QAAQ;AAAA,EACV,CAAC;AAED,MAAI,CAAC,OAAO,YAAY;AACtB,UAAM,YAAY,SAAS,OAAO,UAAW,OAAO,SAAU;AAC9D,UAAM,aAAa,MAAM,KAAK,GAAG,SAAS,KAAK;AAC/C,eAAW;AAAA,MACT,GAAG;AAAA,MACH,GAAG,sBAAsB;AAAA,QACvB,OAAO;AAAA,QACP,UAAU;AAAA,QACV,MAAM,SAAS;AAAA,QACf,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,WAAW,MAAsB;AACxC,QAAM,OAAO,aAAa,IAAI;AAC9B,SAAO,SAAS,IAAI;AACtB;AASA,SAAS,sBACP,QAC0B;AAC1B,QAAM,EAAC,OAAO,UAAU,MAAM,OAAM,IAAI;AACxC,QAAM,WAAqC,CAAC;AAC5C,QAAM,QAAQ,CAAC,SAAiB;AAC9B,UAAM,WAAW,aAAa,UAAU,IAAI;AAC5C,QAAI,UAAU,CAAC,OAAO,QAAQ,GAAG;AAC/B;AAAA,IACF;AAEA,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,UAAU,aAAa,IAAI;AAAA,MAC3B,UAAU,eAAe,IAAI;AAAA,MAC7B,UAAU;AAAA,MACV,UAAU,WAAW,IAAI;AAAA,IAC3B,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AACT;AAEA,SAAS,iBAAiB,UAA2B;AACnD,QAAM,oBAAoB,CAAC,WAAW,YAAY,QAAQ,OAAO,MAAM;AACvE,QAAM,mBAAmB,CAAC,OAAO;AACjC,QAAM,cAAc,KAAK,iBAAiB;AAAA,IACxC;AAAA,EACF,CAAC,KAAK,kBAAkB,KAAK,GAAG,CAAC;AACjC,QAAM,QAAQ,IAAI,OAAO,WAAW;AACpC,SAAO,MAAM,KAAK,SAAS,YAAY,CAAC;AAC1C;AAEA,SAAS,gBAAgB,UAA2B;AAClD,QAAM,uBAAuB,CAAC,MAAM;AACpC,QAAM,cAAc,IAAI,qBAAqB,KAAK,GAAG,CAAC;AACtD,QAAM,QAAQ,IAAI,OAAO,WAAW;AACpC,SAAO,CAAC,MAAM,KAAK,SAAS,YAAY,CAAC;AAC3C","sourcesContent":["import {glob, fileSizeSync, readFileSync} from '@shopify/cli-kit/node/fs';\nimport {fileHash} from '@shopify/cli-kit/node/crypto';\nimport {joinPath, relativePath} from '@shopify/cli-kit/node/path';\nimport {lookupMimeType} from '@shopify/cli-kit/node/mimes';\n\nimport {DeploymentConfig, DeploymentManifestFile, FileType} from './types.js';\n\nexport async function getUploadFiles(\n config: DeploymentConfig,\n): Promise<DeploymentManifestFile[]> {\n const workerPath = joinPath(config.rootPath!, config.workerDir!);\n const workerFiles = await glob(`${workerPath}/**`);\n let manifest = createManifestEntries({\n files: workerFiles,\n basePath: workerPath,\n type: FileType.Worker,\n filter: workerFileFilter,\n });\n\n if (!config.workerOnly) {\n const assetPath = joinPath(config.rootPath!, config.assetsDir!);\n const assetFiles = await glob(`${assetPath}/**`);\n manifest = [\n ...manifest,\n ...createManifestEntries({\n files: assetFiles,\n basePath: assetPath,\n type: FileType.Asset,\n filter: assetFileFilter,\n }),\n ];\n }\n\n return manifest;\n}\n\nfunction createHash(file: string): string {\n const buff = readFileSync(file);\n return fileHash(buff);\n}\n\ninterface CreateManifestEntriesParams {\n files: string[];\n basePath: string;\n type: FileType;\n filter?: (arg0: string) => boolean;\n}\n\nfunction createManifestEntries(\n params: CreateManifestEntriesParams,\n): DeploymentManifestFile[] {\n const {files, basePath, type, filter} = params;\n const manifest: DeploymentManifestFile[] = [];\n files.forEach((file: string) => {\n const filePath = relativePath(basePath, file);\n if (filter && !filter(filePath)) {\n return;\n }\n\n manifest.push({\n filePath,\n fileSize: fileSizeSync(file),\n mimeType: lookupMimeType(file)!,\n fileType: type,\n fileHash: createHash(file),\n });\n });\n return manifest;\n}\n\nfunction workerFileFilter(fileName: string): boolean {\n const allowedExtensions = ['.js.map', '.mjs.map', '.map', '.js', '.mjs'];\n const allowedFilenames = ['index'];\n const regexString = `^(${allowedFilenames.join(\n '|',\n )})(${allowedExtensions.join('|')})$`;\n const regex = new RegExp(regexString);\n return regex.test(fileName.toLowerCase());\n}\n\nfunction assetFileFilter(fileName: string): boolean {\n const disallowedExtensions = ['.map'];\n const regexString = `(${disallowedExtensions.join('|')})$`;\n const regex = new RegExp(regexString);\n return !regex.test(fileName.toLowerCase());\n}\n"]}
@@ -12,3 +12,5 @@ const BuildCancelQuery = `
12
12
  `;
13
13
 
14
14
  export { BuildCancelQuery };
15
+ //# sourceMappingURL=out.js.map
16
+ //# sourceMappingURL=build-cancel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/deploy/graphql/build-cancel.ts"],"names":[],"mappings":"AAEO,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["import {OxygenError} from '../types.js';\n\nexport const BuildCancelQuery = `\n mutation BuildCancel($buildId: ID!, $reason: String!) {\n buildCancel(id: $buildId, reason: $reason) {\n build {\n id\n }\n userErrors {\n message\n }\n }\n }\n`;\n\nexport interface BuildCancelQueryData {\n buildCancel: BuildCancelResponse;\n}\n\nexport interface BuildCancelResponse {\n build: {\n id: string;\n };\n userErrors: OxygenError[];\n}\n"]}
@@ -13,3 +13,5 @@ const BuildInitiateQuery = `
13
13
  `;
14
14
 
15
15
  export { BuildInitiateQuery };
16
+ //# sourceMappingURL=out.js.map
17
+ //# sourceMappingURL=build-initiate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/deploy/graphql/build-initiate.ts"],"names":[],"mappings":"AAEO,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["import {OxygenError} from '../types.js';\n\nexport const BuildInitiateQuery = `\n mutation BuildInitiate($environment: EnvironmentSelectorInput, $labels: [String!]) {\n buildInitiate(environment: $environment, labels: $labels) {\n build {\n id\n assetPath\n }\n userErrors {\n message\n }\n }\n }\n`;\n\nexport interface BuildInitiateQueryData {\n buildInitiate: BuildInitiateResponse;\n}\n\nexport interface BuildInitiateResponse {\n build: {\n id: string;\n assetPath: string;\n };\n userErrors: OxygenError[];\n}\n"]}
@@ -12,3 +12,5 @@ mutation DeploymentCancel($deploymentId: ID!, $reason: String!) {
12
12
  `;
13
13
 
14
14
  export { DeploymentCancelQuery };
15
+ //# sourceMappingURL=out.js.map
16
+ //# sourceMappingURL=deployment-cancel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/deploy/graphql/deployment-cancel.ts"],"names":[],"mappings":"AAEO,MAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["import {OxygenError} from '../types.js';\n\nexport const DeploymentCancelQuery = `\nmutation DeploymentCancel($deploymentId: ID!, $reason: String!) {\n deploymentCancel(id: $deploymentId, reason: $reason) {\n deployment {\n id\n }\n userErrors {\n message\n }\n }\n}\n`;\n\nexport interface DeploymentCancelQueryData {\n deploymentCancel: DeploymentCancelResponse;\n}\n\nexport interface DeploymentCancelResponse {\n deployment: {\n id: string;\n };\n userErrors: OxygenError[];\n}\n"]}
@@ -13,3 +13,5 @@ const DeploymentCompleteQuery = `
13
13
  `;
14
14
 
15
15
  export { DeploymentCompleteQuery };
16
+ //# sourceMappingURL=out.js.map
17
+ //# sourceMappingURL=deployment-complete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/deploy/graphql/deployment-complete.ts"],"names":[],"mappings":"AAEO,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["import {OxygenError} from '../types.js';\n\nexport const DeploymentCompleteQuery = `\n mutation DeploymentComplete($deploymentId: ID!) {\n deploymentComplete(id: $deploymentId) {\n deployment {\n id\n url\n }\n userErrors {\n message\n }\n }\n }\n`;\n\nexport interface DeploymentCompleteQueryData {\n deploymentComplete: DeploymentCompleteResponse;\n}\n\nexport interface DeploymentCompleteResponse {\n deployment: Deployment;\n userErrors: OxygenError[];\n}\n\ninterface Deployment {\n id: string;\n url: string;\n}\n"]}
@@ -22,3 +22,5 @@ const DeploymentInitiateQuery = `
22
22
  `;
23
23
 
24
24
  export { DeploymentInitiateQuery };
25
+ //# sourceMappingURL=out.js.map
26
+ //# sourceMappingURL=deployment-initiate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/deploy/graphql/deployment-initiate.ts"],"names":[],"mappings":"AAEO,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["import {OxygenError} from '../types.js';\n\nexport const DeploymentInitiateQuery = `\n mutation DeploymentInitiate($buildId: ID, $environment: EnvironmentSelectorInput, $labels: [String!], $files: [FileInput!]!, $isPrivate: Boolean) {\n deploymentInitiate(buildId: $buildId, environment: $environment, labels: $labels, files: $files, isPrivate: $isPrivate) {\n deployment {\n id\n }\n deploymentTargets {\n filePath\n fileSize\n uploadUrl\n fileType\n parameters {\n name\n value\n }\n }\n userErrors {\n message\n }\n }\n }\n`;\n\nexport interface DeploymentInitiateQueryData {\n deploymentInitiate: DeploymentInitiateResponse;\n}\n\nexport interface DeploymentInitiateResponse {\n deployment: Deployment;\n deploymentTargets: DeploymentTargetResponse[];\n userErrors: OxygenError[];\n}\n\nexport interface DeploymentTargetResponse {\n filePath: string;\n fileSize: number;\n uploadUrl: string;\n fileType: string;\n parameters: DeploymentInitiateParameters[] | null;\n}\n\ninterface Deployment {\n id: string;\n}\n\ninterface DeploymentInitiateParameters {\n name: string;\n value: string;\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { outputSuccess, outputInfo, outputWarn } from '@shopify/cli-kit/node/output';
2
2
  import { stderrLogger, verifyConfig } from '../utils/utils.js';
3
3
  export { parseToken } from '../utils/utils.js';
4
+ import { initializeBugsnag, getBugsnag } from '../utils/bugsnag.js';
4
5
  import { buildInitiate } from './build-initiate.js';
5
6
  import { buildCancel } from './build-cancel.js';
6
7
  import { getUploadFiles } from './get-upload-files.js';
@@ -14,6 +15,9 @@ import { buildProject } from './build-project.js';
14
15
  import { getMetadata, createLabels, getEnvironmentInput } from './metadata.js';
15
16
 
16
17
  async function createDeploy(options) {
18
+ initializeBugsnag(!options.config.bugsnag);
19
+ const Bugsnag = getBugsnag();
20
+ Bugsnag?.addMetadata("config", options.config);
17
21
  const { config, hooks } = options;
18
22
  const logger = options.logger ?? stderrLogger;
19
23
  const build = {};
@@ -23,6 +27,11 @@ async function createDeploy(options) {
23
27
  const metadata = await getMetadata(config, logger);
24
28
  const labels = createLabels(metadata);
25
29
  const environment = getEnvironmentInput(config, metadata);
30
+ Bugsnag?.addMetadata("metadata", {
31
+ environment,
32
+ labels,
33
+ metadata
34
+ });
26
35
  if (!config.workerOnly && !config.skipBuild) {
27
36
  const buildInitiateResponse = await buildInitiate({
28
37
  config,
@@ -43,12 +52,14 @@ async function createDeploy(options) {
43
52
  }
44
53
  buildCompleted = true;
45
54
  const manifest = await getUploadFiles(config);
55
+ Bugsnag?.addMetadata("manifest", manifest);
46
56
  const deploymentInitiateInput = build.id ? { buildId: build.id, manifest } : { environment, manifest, labels };
47
57
  deployment = await deploymentInitiate({
48
58
  config,
49
59
  input: deploymentInitiateInput,
50
60
  logger
51
61
  });
62
+ Bugsnag?.addMetadata("targets", deployment.deploymentTargets);
52
63
  await uploadFiles({
53
64
  config,
54
65
  targets: deployment.deploymentTargets,
@@ -78,6 +89,9 @@ ${urlMessage} preview URL: ${deploymentCompleteOp.deployment.url}`,
78
89
  }
79
90
  return deploymentCompleteOp.deployment.url;
80
91
  } catch (error) {
92
+ if (config.bugsnag && Bugsnag && (error instanceof Error || typeof error === "string")) {
93
+ Bugsnag.notify(error);
94
+ }
81
95
  if (!(error instanceof Error)) {
82
96
  console.error("Unknown error", error);
83
97
  return Promise.reject(new Error("Unknown error"));
@@ -120,3 +134,5 @@ ${urlMessage} preview URL: ${deploymentCompleteOp.deployment.url}`,
120
134
  }
121
135
 
122
136
  export { createDeploy };
137
+ //# sourceMappingURL=out.js.map
138
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Logger,\n outputInfo,\n outputSuccess,\n outputWarn,\n} from '@shopify/cli-kit/node/output';\n\nimport {stderrLogger, verifyConfig} from '../utils/utils.js';\nimport {getBugsnag, initializeBugsnag} from '../utils/bugsnag.js';\n\nimport {buildInitiate} from './build-initiate.js';\nimport {buildCancel} from './build-cancel.js';\nimport {getUploadFiles} from './get-upload-files.js';\nimport {deploymentInitiate} from './deployment-initiate.js';\nimport {deploymentComplete} from './deployment-complete.js';\nimport {verifyDeployment} from './verify-deployment.js';\nimport {deploymentCancel} from './deployment-cancel.js';\nimport {uploadFiles} from './upload-files.js';\nimport {\n Build,\n DeploymentConfig,\n DeploymentHooks,\n VerificationError,\n} from './types.js';\nimport {buildProject} from './build-project.js';\nimport {createLabels, getMetadata, getEnvironmentInput} from './metadata.js';\n\ninterface CreateDeployOptions {\n config: DeploymentConfig;\n hooks?: DeploymentHooks;\n logger?: Logger;\n}\n\nexport async function createDeploy(\n options: CreateDeployOptions,\n): Promise<string | undefined> {\n initializeBugsnag(!options.config.bugsnag);\n const Bugsnag = getBugsnag();\n Bugsnag?.addMetadata('config', options.config);\n\n const {config, hooks} = options;\n const logger = options.logger ?? stderrLogger;\n const build = {} as Build;\n let buildCompleted;\n let deployment;\n\n try {\n const metadata = await getMetadata(config, logger);\n const labels = createLabels(metadata);\n const environment = getEnvironmentInput(config, metadata);\n Bugsnag?.addMetadata('metadata', {\n environment,\n labels,\n metadata,\n });\n\n if (!config.workerOnly && !config.skipBuild) {\n const buildInitiateResponse = await buildInitiate({\n config,\n environment,\n labels,\n logger,\n });\n build.id = buildInitiateResponse.build.id;\n build.assetPath = buildInitiateResponse.build.assetPath;\n }\n\n if (!config.skipBuild) {\n await buildProject({\n config,\n assetPath: build.assetPath,\n hooks,\n });\n verifyConfig({config, performedBuild: true});\n }\n buildCompleted = true;\n\n const manifest = await getUploadFiles(config);\n Bugsnag?.addMetadata('manifest', manifest);\n const deploymentInitiateInput = build.id\n ? {buildId: build.id, manifest}\n : {environment, manifest, labels};\n\n deployment = await deploymentInitiate({\n config,\n input: deploymentInitiateInput,\n logger,\n });\n Bugsnag?.addMetadata('targets', deployment.deploymentTargets);\n await uploadFiles({\n config,\n targets: deployment.deploymentTargets,\n hooks,\n logger,\n });\n const deploymentCompleteOp = await deploymentComplete(\n config,\n deployment.deployment.id,\n );\n\n if (!config.skipVerification) {\n await verifyDeployment({\n config,\n url: deploymentCompleteOp.deployment.url,\n logger,\n hooks,\n });\n }\n\n const urlMessage = config.publicDeployment ? 'Public' : 'Private';\n outputSuccess(\n `Deployment complete.\\n${urlMessage} preview URL: ${deploymentCompleteOp.deployment.url}`,\n logger,\n );\n // in CI environments, we want to output the URL to stdout\n if (metadata.name !== 'none') {\n outputInfo(deploymentCompleteOp.deployment.url);\n }\n\n return deploymentCompleteOp.deployment.url;\n } catch (error) {\n if (\n config.bugsnag &&\n Bugsnag &&\n (error instanceof Error || typeof error === 'string')\n ) {\n Bugsnag.notify(error);\n }\n\n if (!(error instanceof Error)) {\n // eslint-disable-next-line no-console\n console.error('Unknown error', error);\n return Promise.reject(new Error('Unknown error'));\n }\n\n if (error instanceof VerificationError) {\n outputWarn(error.message, logger);\n } else if (build.id && !buildCompleted) {\n outputWarn(\n `Build failed with: ${error.message}, cancelling build.`,\n logger,\n );\n await buildCancel({\n config,\n buildId: build.id!,\n reason: error.message,\n logger,\n }).catch((err) => {\n if (err instanceof Error) {\n outputWarn(`Failed to cancel build: ${err.message}`, logger);\n }\n });\n } else if (deployment?.deployment.id) {\n outputWarn(\n `Deployment failed with: ${error.message}, cancelling deployment.`,\n logger,\n );\n await deploymentCancel({\n config,\n deploymentId: deployment.deployment.id,\n reason: error.message,\n logger,\n }).catch((err) => {\n if (err instanceof Error) {\n outputWarn(`Failed to cancel deployment: ${err.message}`, logger);\n }\n });\n }\n return Promise.reject(error);\n }\n}\n\nexport type {DeploymentConfig, DeploymentHooks};\nexport {parseToken} from '../utils/utils.js';\n"]}
@@ -84,3 +84,5 @@ function createLabels(metadata) {
84
84
  }
85
85
 
86
86
  export { createLabels, getEnvironmentInput, getMetadata };
87
+ //# sourceMappingURL=out.js.map
88
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/metadata.ts"],"names":["keyMapping"],"mappings":"AAAA,SAAQ,kBAA6B;AACrC,SAAQ,0BAAyB;AACjC,SAAgB,kBAAiB;AAEjC,SAAQ,sBAAqB;AAS7B,eAAsB,YACpB,QACA,QACmB;AACnB,QAAM,SAAS,WAAW;AAC1B,MAAI,WAAqB,CAAC;AAE1B,MAAI;AACF,UAAM,YAAY,MAAM,mBAAmB,OAAO,QAAQ;AAC1D,UAAM,UAAU,kBAAkB,KAAK,UAAU,IAAI,KAAK,CAAC,GAAG,CAAC;AAE/D,eAAW;AAAA,MACT,OAAO,UAAU;AAAA,MACjB;AAAA,MACA,YAAY,UAAU;AAAA,MACtB,WAAW,UAAU;AAAA,MACrB,eAAe,UAAU,QAAQ,UAAU,GAAG,cAAc;AAAA,IAC9D;AAAA,EACF,SAAS,OAAO;AACd;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,OAAO,SAAS,WAAW;AAC5C,eAAW;AAAA,MACT,GAAG;AAAA,MACH,GAAG,OAAO;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,OAAO,OAAO,OAAO,OAAO;AAAA,IAClC,GAAG;AAAA,IACH,OAAO,OAAO,SAAS,QAAQ,SAAS;AAAA,IACxC,eAAe,OAAO,SAAS,eAAe,SAAS;AAAA,IACvD,WAAW,OAAO,SAAS,WAAW,SAAS;AAAA,IAC/C,KAAK,OAAO,SAAS,OAAO,SAAS;AAAA,EACvC;AACF;AAEO,SAAS,oBACd,QACA,UAC8B;AAC9B,QAAM,MAAM,OAAO,kBAAkB,SAAS;AAC9C,SAAO,MAAM,EAAC,IAAG,IAAI;AACvB;AAEO,SAAS,aAAa,UAA8B;AACzD,QAAM,SAAmB,CAAC;AAE1B,QAAM,aAAa,CAAC,UAAkB,eAAuB;AAC3D,QAAI,WAAW,SAAS,gBAAgB;AACtC,YAAM,IAAI;AAAA,QACR,YAAY,QAAQ,yCAAyC,cAAc;AAAA,MAC7E;AAAA,IACF;AACA,UAAM,QAAQ,GAAG,QAAQ,IAAI,KAAK,UAAU,UAAU,CAAC;AACvD,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,MAAI,SAAS,SAAS,WAAW;AAC/B,UAAMA,cAAa;AAAA,MACjB,SAAS;AAAA,MACT,KAAK;AAAA,IACP;AAEA,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQA,WAAU,GAAG;AACrD,YAAM,cAAc;AACpB,UAAI,SAAS,WAAW,GAAG;AACzB,eAAO;AAAA,UACL,GAAG,SAAS,IAAI,IAAI,KAAK,IAAI,KAAK,UAAU,SAAS,WAAW,CAAC,CAAC;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa;AAAA,IACjB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,WAAW;AAAA,IACX,KAAK;AAAA,EACP;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,UAAM,cAAc;AACpB,QAAI,SAAS,WAAW,GAAG;AACzB,iBAAW,OAAO,SAAS,WAAW,CAAE;AAAA,IAC1C;AAAA,EACF;AAEA,SAAO;AACT","sourcesContent":["import {ciPlatform, CIMetadata} from '@shopify/cli-kit/node/context/local';\nimport {getLatestGitCommit} from '@shopify/cli-kit/node/git';\nimport {Logger, outputWarn} from '@shopify/cli-kit/node/output';\n\nimport {maxLabelLength} from '../utils/utils.js';\n\nimport {DeploymentConfig, EnvironmentInput} from './types.js';\n\ntype Metadata = CIMetadata & {\n commitDate?: string;\n name?: string;\n};\n\nexport async function getMetadata(\n config: DeploymentConfig,\n logger: Logger,\n): Promise<Metadata> {\n const ciInfo = ciPlatform();\n let metadata: Metadata = {};\n\n try {\n const gitCommit = await getLatestGitCommit(config.rootPath);\n const branch = (/HEAD -> ([^,]*)/.exec(gitCommit.refs) || [])[1];\n\n metadata = {\n actor: gitCommit.author_name,\n branch,\n commitDate: gitCommit.date,\n commitSha: gitCommit.hash,\n commitMessage: gitCommit.message.substring(0, maxLabelLength),\n };\n } catch (error) {\n outputWarn(\n 'Could not retrieve Git history, commit message will be unavailable.',\n logger,\n );\n }\n\n if (ciInfo.isCI && ciInfo.name !== 'unknown') {\n metadata = {\n ...metadata,\n ...ciInfo.metadata,\n };\n }\n\n return {\n name: ciInfo.isCI ? ciInfo.name : 'none',\n ...metadata,\n actor: config.metadata.user ?? metadata.actor,\n commitMessage: config.metadata.description ?? metadata.commitMessage,\n commitSha: config.metadata.version ?? metadata.commitSha,\n url: config.metadata.url ?? metadata.url,\n };\n}\n\nexport function getEnvironmentInput(\n config: DeploymentConfig,\n metadata: CIMetadata,\n): EnvironmentInput | undefined {\n const tag = config.environmentTag || metadata.branch;\n return tag ? {tag} : undefined;\n}\n\nexport function createLabels(metadata: Metadata): string[] {\n const labels: string[] = [];\n\n const checkLabel = (labelKey: string, labelValue: string) => {\n if (labelValue.length > maxLabelLength) {\n throw new Error(\n `Provided ${labelKey} metadata exceeds maximum length (max ${maxLabelLength} characters).`,\n );\n }\n const label = `${labelKey}=${JSON.stringify(labelValue)}`;\n labels.push(label);\n };\n\n if (metadata.name !== 'unknown') {\n const keyMapping = {\n attempt: 'attempt',\n run: 'runId',\n };\n\n for (const [key, value] of Object.entries(keyMapping)) {\n const metadataKey = key as keyof Metadata;\n if (metadata[metadataKey]) {\n labels.push(\n `${metadata.name}-${value}=${JSON.stringify(metadata[metadataKey])}`,\n );\n }\n }\n }\n\n const keyMapping = {\n actor: 'user',\n branch: 'branch',\n commitDate: 'commit-date',\n commitMessage: 'description',\n commitSha: 'version',\n url: 'url',\n };\n\n for (const [key, value] of Object.entries(keyMapping)) {\n const metadataKey = key as keyof Metadata;\n if (metadata[metadataKey]) {\n checkLabel(value, metadata[metadataKey]!);\n }\n }\n\n return labels;\n}\n"]}
@@ -16,6 +16,7 @@ interface DeploymentHooks {
16
16
  }
17
17
  interface DeploymentConfig {
18
18
  assetsDir?: string;
19
+ bugsnag: boolean;
19
20
  buildCommand?: string;
20
21
  deploymentToken: DeploymentToken;
21
22
  deploymentUrl: string;
@@ -7,3 +7,5 @@ class VerificationError extends Error {
7
7
  }
8
8
 
9
9
  export { FileType, VerificationError };
10
+ //# sourceMappingURL=out.js.map
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/types.ts"],"names":["FileType"],"mappings":"AAgEO,IAAK,WAAL,kBAAKA,cAAL;AACL,EAAAA,UAAA,YAAS;AACT,EAAAA,UAAA,WAAQ;AAFE,SAAAA;AAAA,GAAA;AASL,MAAM,0BAA0B,MAAM;AAAC","sourcesContent":["export interface Build {\n id: string;\n assetPath: string;\n}\n\nexport interface ClientError extends Error {\n statusCode: number;\n}\n\nexport interface DeploymentHooks {\n buildFunction?: (urlPath?: string) => Promise<void>;\n onVerificationStart?: () => void;\n onVerificationComplete?: () => void;\n onVerificationError?: (error: Error) => void;\n onUploadFilesStart?: () => void;\n onUploadFilesError?: (error: Error) => void;\n onUploadFilesComplete?: () => void;\n}\n\nexport interface DeploymentConfig {\n assetsDir?: string;\n bugsnag: boolean;\n buildCommand?: string;\n deploymentToken: DeploymentToken;\n deploymentUrl: string;\n environmentTag?: string;\n metadata: {\n description?: string;\n user?: string;\n version?: string;\n url?: string;\n };\n publicDeployment: boolean;\n rootPath?: string;\n skipBuild: boolean;\n skipVerification: boolean;\n verificationMaxDuration: number;\n workerDir?: string;\n workerOnly: boolean;\n}\n\nexport interface DeploymentToken {\n accessToken: string;\n allowedResource: string;\n appId: string;\n client: string;\n expiresAt: string;\n namespace: string;\n namespaceId: string;\n}\n\nexport interface DeploymentManifestFile {\n filePath: string;\n fileSize: number;\n mimeType: string;\n fileHash: string;\n fileType: string;\n}\n\nexport interface EnvironmentInput {\n handle?: string;\n tag?: string;\n}\n\nexport enum FileType {\n Worker = 'WORKER',\n Asset = 'ASSET',\n}\n\nexport interface OxygenError {\n message: string;\n}\n\nexport class VerificationError extends Error {}\n"]}
@@ -160,3 +160,5 @@ function isErrorCode(err, code) {
160
160
  }
161
161
 
162
162
  export { uploadFiles };
163
+ //# sourceMappingURL=out.js.map
164
+ //# sourceMappingURL=upload-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/upload-files.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\nimport {fetch, formData} from '@shopify/cli-kit/node/http';\nimport {createFileReadStream} from '@shopify/cli-kit/node/fs';\nimport {\n Logger,\n outputCompleted,\n outputInfo,\n} from '@shopify/cli-kit/node/output';\nimport {joinPath} from '@shopify/cli-kit/node/path';\nimport {mapLimit} from 'async';\n\nimport {deployDefaults} from '../utils/utils.js';\n\nimport {DeploymentConfig, DeploymentHooks} from './types.js';\nimport {DeploymentTargetResponse} from './graphql/deployment-initiate.js';\n\ninterface InitiateResumableResponse {\n target: DeploymentTargetResponse;\n sessionUri: string;\n location: string;\n}\n\ninterface ResumableUploadStatus {\n complete: boolean;\n lastReceivedByte: number;\n}\n\ninterface UploadFilesOptions {\n config: DeploymentConfig;\n hooks?: DeploymentHooks;\n logger: Logger;\n targets: DeploymentTargetResponse[];\n}\n\nexport async function uploadFiles(options: UploadFilesOptions): Promise<void> {\n const {config, logger, targets, hooks} = options;\n outputInfo(`Uploading ${targets.length} files...`, logger);\n hooks?.onUploadFilesStart?.();\n return mapLimit(targets, 6, async (target: DeploymentTargetResponse) => {\n await uploadFile(config, target);\n })\n .then(() => {\n hooks?.onUploadFilesComplete?.();\n outputCompleted(`Files uploaded successfully`, logger);\n })\n .catch((err) => {\n hooks?.onUploadFilesError?.(err);\n throw err;\n });\n}\n\nasync function uploadFile(\n config: DeploymentConfig,\n target: DeploymentTargetResponse,\n) {\n const localFolderPath =\n target.fileType === 'WORKER'\n ? joinPath(config.rootPath!, config.workerDir!)\n : joinPath(config.rootPath!, config.assetsDir!);\n\n if (target.parameters !== null && target.parameters.length > 0) {\n // If parameters exist perform a form upload\n const form = formData();\n target.parameters.forEach((param) => {\n form.append(param.name, param.value);\n });\n form.append(\n 'file',\n createFileReadStream(joinPath(localFolderPath, target.filePath)),\n );\n await formUpload(form, target);\n } else {\n // If no parameters exist perform a resumable upload\n const initData = await initiateResumableUpload(target);\n await performResumableUpload(\n joinPath(localFolderPath, target.filePath),\n initData,\n );\n }\n}\n\nasync function formUpload(\n form: ReturnType<typeof formData>,\n target: DeploymentTargetResponse,\n attemptNumber = 0,\n) {\n try {\n const timeoutDuration = 60000;\n const controller = new AbortController();\n const timeout = setTimeout(() => {\n controller.abort();\n }, timeoutDuration);\n\n const response = await fetch(target.uploadUrl, {\n method: 'POST',\n body: form,\n signal: controller.signal,\n headers: {\n Connection: 'keep-alive',\n },\n });\n clearTimeout(timeout);\n\n if (!response.ok) {\n throw new Error(`${response.status}`);\n }\n } catch (err) {\n if (isErrorCode(err, 'ENOENT')) {\n throw new Error(`File not found: ${target.filePath}`);\n }\n\n if (attemptNumber < Number(deployDefaults.maxUploadAttempts)) {\n await formUpload(form, target, attemptNumber + 1);\n } else {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error(`Request timeout whilst uploading ${target.filePath}`);\n }\n throw new Error(`Failed to upload file ${target.filePath}`);\n }\n }\n}\n\nasync function initiateResumableUpload(\n target: DeploymentTargetResponse,\n): Promise<InitiateResumableResponse> {\n return fetch(target.uploadUrl, {\n method: 'POST',\n headers: {\n 'x-goog-resumable': 'start',\n 'X-Goog-Content-Length-Range': `0,${target.fileSize}`,\n 'User-Agent': 'oxygen-cli',\n },\n })\n .then((res) => {\n return {\n sessionUri: res.headers.get('x-guploader-uploadid')!,\n location: res.headers.get('location')!,\n target,\n };\n })\n .catch((err) => {\n throw new Error(\n `Failed to initiate resumable upload for file ${target.filePath} (status code ${err.statusCode})`,\n );\n });\n}\n\nasync function performResumableUpload(\n localFilePath: string,\n initData: InitiateResumableResponse,\n startByte = 0,\n attemptNumber = 0,\n) {\n await uploadResumable(initData.location, localFilePath, startByte).catch(\n async (err) => {\n if (isErrorCode(err, 'ENOENT')) {\n throw new Error(`File not found: ${initData.target.filePath}`);\n }\n\n if (\n err &&\n attemptNumber >= Number(deployDefaults.maxResumabeUploadAttempts)\n ) {\n throw new Error(\n `Failed to upload file ${initData.target.filePath} after ${deployDefaults.maxResumabeUploadAttempts} attempts`,\n );\n }\n const status = await resumableUploadStatus(\n initData.location,\n initData.target.fileSize,\n );\n if (!status.complete) {\n const nextAttemptStartByte = status.lastReceivedByte;\n const attempt = attemptNumber + 1;\n await performResumableUpload(\n localFilePath,\n initData,\n nextAttemptStartByte,\n attempt,\n );\n }\n },\n );\n}\n\nasync function uploadResumable(\n location: string,\n filePath: string,\n lastReceivedByte: number,\n): Promise<number> {\n const file = createFileReadStream(filePath, {start: lastReceivedByte});\n return fetch(location, {\n method: 'PUT',\n body: file,\n }).then((res) => {\n return res.status;\n });\n}\n\nasync function resumableUploadStatus(\n location: string,\n fileSize: number,\n): Promise<ResumableUploadStatus> {\n const getLastByte = (range: string | null): number => {\n if (!range || range.split('-').length !== 2) return 0;\n const rangeParts = range.split('-');\n return parseInt(rangeParts[1]!, 10);\n };\n\n return fetch(location, {\n method: 'PUT',\n headers: {\n 'Content-Length': '0',\n 'Content-Range': `bytes */${fileSize}`,\n },\n })\n .then((res) => {\n return {\n complete: res.status === 200,\n lastReceivedByte: getLastByte(res.headers.get('range')),\n };\n })\n .catch((err) => {\n // eslint-disable-next-line no-console\n console.error(err);\n return {\n complete: false,\n lastReceivedByte: 0,\n };\n });\n}\n\nfunction isErrorCode(err: unknown, code: string): boolean {\n return err instanceof Error && 'code' in err && err.code === code;\n}\n"]}
@@ -48,3 +48,5 @@ async function verifyDeployment(options) {
48
48
  }
49
49
 
50
50
  export { verifyDeployment };
51
+ //# sourceMappingURL=out.js.map
52
+ //# sourceMappingURL=verify-deployment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/deploy/verify-deployment.ts"],"names":[],"mappings":"AAAA,SAAQ,aAAY;AACpB,SAAgB,kBAAiB;AAEjC,SAA2C,yBAAwB;AASnE,eAAsB,iBACpB,SACe;AACf,QAAM,EAAC,QAAQ,KAAK,QAAQ,MAAK,IAAI;AACrC,SAAO,sBAAsB;AAC7B,aAAW,qDAAqD,MAAM;AAEtE,MAAI,WAAW;AACf,MAAI,QAAQ;AACZ,MAAI,0BAA0B;AAC9B,QAAM,YAAY,KAAK,IAAI;AAE3B,QAAM,iBAAiB,YAAY;AACjC,QAAI,WAAW,IAAI;AACjB,cAAQ;AAAA,IACV,WAAW,WAAW,MAAM,GAAG;AAC7B,eAAS;AAAA,IACX;AACA,UAAM,eAAe,KAAK,IAAI,IAAI,aAAa;AAC/C,QAAI,cAAc,QAAQ,MAAO,OAAO,yBAAyB;AAC/D,YAAM,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AACA,UAAI,CAAC,yBAAyB;AAC5B,kCAA0B;AAC1B,eAAO,sBAAsB,KAAK;AAAA,MACpC;AACA,YAAM;AAAA,IACR;AACA;AACA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AACzD,UAAM,MAAM;AAAA,EACd;AAEA,QAAM,QAAQ,YAAY;AACxB,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,GAAG,qBAAqB;AACxD,UAAI,SAAS,WAAW,KAAK;AAC3B,mBAAW,wCAAwC,MAAM;AACzD,eAAO,yBAAyB;AAChC,eAAO,QAAQ,QAAQ;AAAA,MACzB;AACA,YAAM,eAAe;AAAA,IACvB,QAAQ;AACN,YAAM,eAAe;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,MAAM;AACd","sourcesContent":["import {fetch} from '@shopify/cli-kit/node/http';\nimport {Logger, outputInfo} from '@shopify/cli-kit/node/output';\n\nimport {DeploymentConfig, DeploymentHooks, VerificationError} from './types.js';\n\ninterface VerificationOptions {\n config: DeploymentConfig;\n hooks?: DeploymentHooks;\n logger: Logger;\n url: string;\n}\n\nexport async function verifyDeployment(\n options: VerificationOptions,\n): Promise<void> {\n const {config, url, logger, hooks} = options;\n hooks?.onVerificationStart?.();\n outputInfo('Verifying worker deployment has been completed...', logger);\n\n let attempts = 0;\n let delay = 0;\n let calledVerificationError = false;\n const startTime = Date.now();\n\n const handleInterval = async () => {\n if (attempts < 10) {\n delay = 500;\n } else if (attempts % 5 === 0) {\n delay += 5000;\n }\n const elapsedTime = (Date.now() - startTime) / 1000;\n if (elapsedTime + delay / 1000 > config.verificationMaxDuration) {\n const error = new VerificationError(\n 'Unable to verify worker deployment completion.',\n );\n if (!calledVerificationError) {\n calledVerificationError = true;\n hooks?.onVerificationError?.(error);\n }\n throw error;\n }\n attempts++;\n await new Promise((resolve) => setTimeout(resolve, delay));\n await check();\n };\n\n const check = async () => {\n try {\n const response = await fetch(`${url}/.oxygen/deployment`);\n if (response.status === 200) {\n outputInfo('Deployment verification check passed', logger);\n hooks?.onVerificationComplete?.();\n return Promise.resolve();\n }\n await handleInterval();\n } catch {\n await handleInterval();\n }\n };\n\n await check();\n}\n"]}
package/dist/index.js CHANGED
@@ -9,3 +9,5 @@ async function runOxygenCLI() {
9
9
  var src_default = runOxygenCLI;
10
10
 
11
11
  export { src_default as default };
12
+ //# sourceMappingURL=out.js.map
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAQ,cAAa;AAErB,eAAe,eAAe;AAC5B,QAAM,OAAO;AAAA,IACX,WAAW,YAAY;AAAA,IACvB,aAAa;AAAA,EACf,CAAC;AACH;AAEA,IAAO,cAAQ","sourcesContent":["import {runCLI} from '@shopify/cli-kit/node/cli';\n\nasync function runOxygenCLI() {\n await runCLI({\n moduleURL: import.meta.url,\n development: false,\n });\n}\n\nexport default runOxygenCLI;\n"]}
@@ -3,3 +3,5 @@ import runCLI from './index.js';
3
3
 
4
4
  process.removeAllListeners("warning");
5
5
  runCLI();
6
+ //# sourceMappingURL=out.js.map
7
+ //# sourceMappingURL=oxygen-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/oxygen-cli.ts"],"names":[],"mappings":";AAEA,OAAO,YAAY;AAEnB,QAAQ,mBAAmB,SAAS;AAEpC,OAAO","sourcesContent":["#!/usr/bin/env node\n\nimport runCLI from './index.js';\n\nprocess.removeAllListeners('warning');\n\nrunCLI();\n"]}
@@ -0,0 +1,6 @@
1
+ import Bugsnag from '@bugsnag/node';
2
+
3
+ declare function initializeBugsnag(disableBugsnag: boolean): void;
4
+ declare function getBugsnag(): Bugsnag.Client | undefined;
5
+
6
+ export { getBugsnag, initializeBugsnag };
@@ -0,0 +1,38 @@
1
+ import fs from 'fs';
2
+ import path, { dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import Bugsnag from '@bugsnag/node';
5
+
6
+ function loadPackageJson() {
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ const packageJsonPath = path.resolve(__dirname, "../../package.json");
10
+ const packageJsonData = fs.readFileSync(packageJsonPath, "utf8");
11
+ return JSON.parse(packageJsonData);
12
+ }
13
+ let BugsnagClient;
14
+ function setupBugsnag(disableBugsnag) {
15
+ if (disableBugsnag) {
16
+ return;
17
+ } else if (Bugsnag._client) {
18
+ return Bugsnag;
19
+ }
20
+ const packageJson = loadPackageJson();
21
+ const bugsnagServerOptions = {
22
+ apiKey: "21fd37fe87ead4b9c5a8eed90752b455",
23
+ autoDetectErrors: true,
24
+ appVersion: packageJson.version,
25
+ logger: null
26
+ };
27
+ return Bugsnag.start(bugsnagServerOptions);
28
+ }
29
+ function initializeBugsnag(disableBugsnag) {
30
+ BugsnagClient = setupBugsnag(disableBugsnag);
31
+ }
32
+ function getBugsnag() {
33
+ return BugsnagClient;
34
+ }
35
+
36
+ export { getBugsnag, initializeBugsnag };
37
+ //# sourceMappingURL=out.js.map
38
+ //# sourceMappingURL=bugsnag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/bugsnag.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ;AACf,OAAO,QAAO,eAAc;AAC5B,SAAQ,qBAAoB;AAE5B,OAAO,aAAa;AAGpB,SAAS,kBAAkB;AACzB,QAAM,aAAa,cAAc,YAAY,GAAG;AAChD,QAAM,YAAY,QAAQ,UAAU;AACpC,QAAM,kBAAkB,KAAK,QAAQ,WAAW,oBAAoB;AACpE,QAAM,kBAAkB,GAAG,aAAa,iBAAiB,MAAM;AAC/D,SAAO,KAAK,MAAM,eAAe;AACnC;AAEA,IAAI;AAEJ,SAAS,aAAa,gBAAyB;AAC7C,MAAI,gBAAgB;AAClB;AAAA,EACF,WAAY,QAAgB,SAAS;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,gBAAgB;AAEpC,QAAM,uBAA2C;AAAA,IAC/C,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,YAAY,YAAY;AAAA,IACxB,QAAQ;AAAA,EACV;AAEA,SAAQ,QAAgB,MAAM,oBAAoB;AACpD;AAEO,SAAS,kBAAkB,gBAAyB;AACzD,kBAAgB,aAAa,cAAc;AAC7C;AAEO,SAAS,aAAa;AAC3B,SAAO;AACT","sourcesContent":["import fs from 'fs';\nimport path, {dirname} from 'path';\nimport {fileURLToPath} from 'url';\n\nimport Bugsnag from '@bugsnag/node';\nimport * as BugsnagCore from '@bugsnag/core';\n\nfunction loadPackageJson() {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packageJsonPath = path.resolve(__dirname, '../../package.json');\n const packageJsonData = fs.readFileSync(packageJsonPath, 'utf8');\n return JSON.parse(packageJsonData);\n}\n\nlet BugsnagClient: BugsnagCore.Client | undefined;\n\nfunction setupBugsnag(disableBugsnag: boolean) {\n if (disableBugsnag) {\n return;\n } else if ((Bugsnag as any)._client) {\n return Bugsnag;\n }\n\n const packageJson = loadPackageJson();\n\n const bugsnagServerOptions: BugsnagCore.Config = {\n apiKey: '21fd37fe87ead4b9c5a8eed90752b455',\n autoDetectErrors: true,\n appVersion: packageJson.version,\n logger: null,\n };\n\n return (Bugsnag as any).start(bugsnagServerOptions);\n}\n\nexport function initializeBugsnag(disableBugsnag: boolean) {\n BugsnagClient = setupBugsnag(disableBugsnag);\n}\n\nexport function getBugsnag() {\n return BugsnagClient;\n}\n"]}
@@ -12,6 +12,7 @@ const testToken = {
12
12
  function createTestConfig(rootFolder) {
13
13
  return {
14
14
  assetsDir: "/assets/",
15
+ bugsnag: false,
15
16
  buildCommand: String(deployDefaults.buildCommandDefault),
16
17
  deploymentToken: testToken,
17
18
  environmentTag: "environment",
@@ -28,3 +29,5 @@ function createTestConfig(rootFolder) {
28
29
  }
29
30
 
30
31
  export { createTestConfig, testToken };
32
+ //# sourceMappingURL=out.js.map
33
+ //# sourceMappingURL=test-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/test-helper.ts"],"names":[],"mappings":"AAEA,SAAQ,sBAAqB;AAEtB,MAAM,YAAY;AAAA,EACvB,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,WAAW;AAAA,EACX,aAAa;AACf;AAEO,SAAS,iBAAiB,YAAsC;AACrE,SAAO;AAAA,IACL,WAAW;AAAA,IACX,SAAS;AAAA,IACT,cAAc,OAAO,eAAe,mBAAoB;AAAA,IACxD,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,yBAAyB;AAAA,IACzB,UAAU,CAAC;AAAA,IACX,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AACF","sourcesContent":["import type {DeploymentConfig} from '../deploy/types.js';\n\nimport {deployDefaults} from './utils.js';\n\nexport const testToken = {\n accessToken: 'some_token',\n allowedResource: 'gid://oxygen-hub/Namespace/1',\n appId: 'gid://oxygen-hub/App/1',\n client: 'gid://oxygen-hub/Client/1',\n expiresAt: '2023-04-08T09:38:50.368Z',\n namespace: 'fresh-namespace',\n namespaceId: 'gid://oxygen-hub/Namespace/1',\n};\n\nexport function createTestConfig(rootFolder: string): DeploymentConfig {\n return {\n assetsDir: '/assets/',\n bugsnag: false,\n buildCommand: String(deployDefaults.buildCommandDefault!),\n deploymentToken: testToken,\n environmentTag: 'environment',\n deploymentUrl: 'https://localhost:3000',\n verificationMaxDuration: 300,\n metadata: {},\n rootPath: rootFolder,\n publicDeployment: false,\n skipBuild: false,\n skipVerification: false,\n workerDir: '/worker/',\n workerOnly: false,\n };\n}\n"]}
@@ -134,3 +134,5 @@ function convertKeysToCamelCase(obj) {
134
134
  }
135
135
 
136
136
  export { Header, deployDefaults, errorHandler, getBuildCommandFromLockFile, isClientError, maxLabelLength, parseToken, stderrLogger, verifyConfig };
137
+ //# sourceMappingURL=out.js.map
138
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/utils.ts"],"names":["Header"],"mappings":"AAAA,SAAQ,YAAY,sBAAqB;AACzC,SAAQ,YAAY,kBAAiB;AACrC,SAAQ,gBAA8B;AACtC,SAAQ,kBAAiB;AAQlB,MAAM,iBAAmD;AAAA,EAC9D,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,6BAA6B;AAAA,EAC7B,mBAAmB;AAAA,EACnB,2BAA2B;AAAA,EAC3B,kBAAkB;AACpB;AAEO,SAAS,aAAa,OAAY;AACvC,MAAI,cAAc,KAAK,GAAG;AACxB,QAAI,MAAM,eAAe,KAAK;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,eAAe,KAAK;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,iBAAiB,cAAc,MAAM,QAAQ,SAAS,KAAK,GAAG;AAChE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,4BAA4B,QAAkC;AAC5E,QAAM,wBAAwB,oBAAI,IAAI;AAAA,IACpC,CAAC,qBAAqB,eAAe;AAAA,IACrC,CAAC,kBAAkB,gBAAgB;AAAA,IACnC,CAAC,aAAa,YAAY;AAAA,EAC5B,CAAC;AAED,QAAM,iBAAiB,CAAC;AAExB,aAAW,CAAC,cAAc,YAAY,KAAK,uBAAuB;AAChE,QAAI,eAAe,SAAS,OAAO,UAAW,YAAY,CAAC,GAAG;AAC5D,qBAAe,KAAK,EAAC,cAAc,aAAY,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,gBAAgB,eACnB,IAAI,CAAC,EAAC,aAAY,MAAM,YAAY,EACpC,KAAK,IAAI;AACZ;AAAA,MACE,wCAAwC,aAAa;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,EAAC,cAAc,aAAY,IAAI,eAAe,CAAC;AAKrD,UAAM,UAAU,eAAe,SAAS,IAAI,KAAK,UAAU,YAAY;AAEvE;AAAA,MACE,GAAG,OAAO,aAAa,YAAY;AAAA,MACnC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,eAAe,mBAAmB;AAClD;AAEO,IAAK,SAAL,kBAAKA,YAAL;AACL,EAAAA,QAAA,2BAAwB;AADd,SAAAA;AAAA,GAAA;AAIL,SAAS,cAAc,OAAsC;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,gBAAgB;AACxE;AAEO,SAAS,aAAa,KAAmB;AAC9C,UAAQ,OAAO,MAAM,GAAG,GAAG;AAAA,CAAI;AACjC;AAEO,MAAM,iBAAiB;AAEvB,SAAS,WAAW,YAAqC;AAC9D,MAAI;AACF,UAAM,eAAe,OAAO,KAAK,YAAY,QAAQ,EAAE,SAAS,OAAO;AACvE,UAAM,WAAW,KAAK,MAAM,YAAY;AACxC,WAAO,uBAAuB,QAAQ;AAAA,EACxC,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAOA,eAAsB,aAAa;AAAA,EACjC;AAAA,EACA,iBAAiB;AACnB,GAAuB;AACrB,QAAM,EAAC,UAAU,WAAW,WAAW,WAAW,WAAU,IAAI;AAChE,QAAM,aAA2C;AAAA,IAC/C,MAAM;AAAA,EACR;AAEA,MAAI,aAAa,gBAAgB;AAC/B,eAAW,SAAS,SAAS,UAAW,SAAU;AAClD,QAAI,CAAC,YAAY;AACf,iBAAW,SAAS,SAAS,UAAW,SAAU;AAAA,IACpD;AAAA,EACF;AAEA,aAAW,YAAY,OAAO,KAAK,UAAU,GAAG;AAC9C,UAAM,UAAU,WAAW,QAAQ,GAAI,QAAQ;AAAA,EACjD;AAEA,QAAM,eACJ;AACF,MAAI,CAAC,aAAa,KAAK,OAAO,aAAa,GAAG;AAC5C,UAAM,IAAI,MAAM,mCAAmC,OAAO,aAAa,EAAE;AAAA,EAC3E;AACF;AAEA,eAAe,UAAU,MAAc,UAAkB;AACvD,MAAI,CAAE,MAAM,WAAW,IAAI,GAAI;AAC7B,QAAI,aAAa,UAAU;AACzB;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,IAAI,MAAM,mBAAmB,IAAI,EAAE;AAAA,EAC3C;AACF;AAMA,SAAS,uBACP,KAC0B;AAC1B,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO,OAAO,KAAK,GAAG,EAAE,OAAO,CAAC,QAAa,QAAgB;AAC3D,YAAM,eAAe,IAAI;AAAA,QAAQ;AAAA,QAAiB,CAAC,OACjD,GAAG,YAAY,EAAE,QAAQ,KAAK,EAAE,EAAE,QAAQ,KAAK,EAAE;AAAA,MACnD;AACA,UAAI,IAAI,GAAG,MAAM,QAAW;AAC1B,cAAM,IAAI,MAAM,kBAAkB,GAAG,eAAe;AAAA,MACtD;AACA,aAAO,YAAY,IAAI,uBAAuB,IAAI,GAAG,CAAc;AACnE,aAAO;AAAA,IACT,GAAG,CAAC,CAAoB;AAAA,EAC1B;AACA,SAAO;AACT","sourcesContent":["import {fileExists, fileExistsSync} from '@shopify/cli-kit/node/fs';\nimport {outputInfo, outputWarn} from '@shopify/cli-kit/node/output';\nimport {joinPath, normalizePath} from '@shopify/cli-kit/node/path';\nimport {AbortError} from '@shopify/cli-kit/node/error';\n\nimport {\n ClientError,\n DeploymentConfig,\n DeploymentToken,\n} from '../deploy/types.js';\n\nexport const deployDefaults: {[key: string]: string | number} = {\n assetsDirDefault: 'dist/client/',\n buildCommandDefault: 'yarn build',\n verificationDurationDefault: 180,\n maxUploadAttempts: 3,\n maxResumabeUploadAttempts: 9,\n workerDirDefault: 'dist/worker/',\n};\n\nexport function errorHandler(error: any) {\n if (isClientError(error)) {\n if (error.statusCode === 401) {\n throw new AbortError(\n 'You are not authorized to perform this action. Please check your deployment token.',\n );\n }\n\n if (error.statusCode === 429) {\n throw new AbortError(\n \"You've made too many requests. Please try again later\",\n );\n }\n }\n\n if (error instanceof AbortError && error.message.includes('503')) {\n throw new AbortError(\n 'The server is currently unavailable. Please try again later.',\n );\n }\n}\n\nexport function getBuildCommandFromLockFile(config: DeploymentConfig): string {\n const lockFileBuildCommands = new Map([\n ['package-lock.json', 'npm run build'],\n ['pnpm-lock.yaml', 'pnpm run build'],\n ['yarn.lock', 'yarn build'],\n ]);\n\n const foundLockFiles = [];\n\n for (const [lockFileName, buildCommand] of lockFileBuildCommands) {\n if (fileExistsSync(joinPath(config.rootPath!, lockFileName))) {\n foundLockFiles.push({lockFileName, buildCommand});\n }\n }\n\n if (foundLockFiles.length > 1) {\n const lockFilesList = foundLockFiles\n .map(({lockFileName}) => lockFileName)\n .join(', ');\n outputWarn(\n `Warning: Multiple lock files found: (${lockFilesList}).`,\n stderrLogger,\n );\n }\n\n if (foundLockFiles.length > 0) {\n const {lockFileName, buildCommand} = foundLockFiles[0] as {\n lockFileName: string;\n buildCommand: string;\n };\n\n const infoMsg = foundLockFiles.length > 1 ? '' : `Found: ${lockFileName}. `;\n\n outputInfo(\n `${infoMsg}Assuming \"${buildCommand}\" as build command. Use the buildCommand flag to override.`,\n stderrLogger,\n );\n return buildCommand;\n }\n\n return String(deployDefaults.buildCommandDefault);\n}\n\nexport enum Header {\n OxygenNamespaceHandle = 'X-Oxygen-Namespace-Handle',\n}\n\nexport function isClientError(error: unknown): error is ClientError {\n return typeof error === 'object' && error !== null && 'statusCode' in error;\n}\n\nexport function stderrLogger(log: string): void {\n process.stderr.write(`${log}\\n`);\n}\n\nexport const maxLabelLength = 375;\n\nexport function parseToken(inputToken: string): DeploymentToken {\n try {\n const decodedToken = Buffer.from(inputToken, 'base64').toString('utf-8');\n const rawToken = JSON.parse(decodedToken);\n return convertKeysToCamelCase(rawToken) as DeploymentToken;\n } catch (error) {\n throw new Error(\n `Error processing deployment token. Please check your token and try again.`,\n );\n }\n}\n\ninterface VerifyConfigParams {\n config: DeploymentConfig;\n performedBuild?: boolean;\n}\n\nexport async function verifyConfig({\n config,\n performedBuild = false,\n}: VerifyConfigParams) {\n const {rootPath, workerDir, assetsDir, skipBuild, workerOnly} = config;\n const checkPaths: {[pathType: string]: string} = {\n root: rootPath!,\n };\n\n if (skipBuild || performedBuild) {\n checkPaths.worker = joinPath(rootPath!, workerDir!);\n if (!workerOnly) {\n checkPaths.assets = joinPath(rootPath!, assetsDir!);\n }\n }\n\n for (const pathType of Object.keys(checkPaths)) {\n await checkPath(checkPaths[pathType]!, pathType);\n }\n\n const addressRegex =\n /^https:\\/\\/(?:[\\w-]+\\.)*[\\w-]+|^https:\\/\\/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/;\n if (!addressRegex.test(config.deploymentUrl)) {\n throw new Error(`Invalid deployment service URL: ${config.deploymentUrl}`);\n }\n}\n\nasync function checkPath(path: string, pathType: string) {\n if (!(await fileExists(path))) {\n if (pathType === 'assets') {\n outputWarn(\n `Use the \"workerOnly\" flag to perform a worker-only deployment.`,\n stderrLogger,\n );\n }\n throw new Error(`Path not found: ${path}`);\n }\n}\n\ninterface TokenType {\n [x: string]: string | TokenType;\n}\n\nfunction convertKeysToCamelCase(\n obj: TokenType | string,\n): DeploymentToken | string {\n if (typeof obj === 'object') {\n return Object.keys(obj).reduce((result: any, key: string) => {\n const camelCaseKey = key.replace(/([-_][a-z])/gi, ($1) =>\n $1.toUpperCase().replace('-', '').replace('_', ''),\n );\n if (obj[key] === undefined) {\n throw new Error(`Invalid token: ${key} is undefined`);\n }\n result[camelCaseKey] = convertKeysToCamelCase(obj[key] as TokenType);\n return result;\n }, {} as DeploymentToken);\n }\n return obj;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.3-unstable.202310051444.0",
2
+ "version": "2.1.1-unstable.202310110934.0",
3
3
  "commands": {
4
4
  "oxygen:deploy": {
5
5
  "id": "oxygen:deploy",
@@ -29,6 +29,13 @@
29
29
  "multiple": false,
30
30
  "default": "yarn build"
31
31
  },
32
+ "disableBugsnag": {
33
+ "name": "disableBugsnag",
34
+ "type": "boolean",
35
+ "description": "Disable Bugsnag error reporting",
36
+ "required": false,
37
+ "allowNo": false
38
+ },
32
39
  "environmentTag": {
33
40
  "name": "environmentTag",
34
41
  "type": "option",
package/package.json CHANGED
@@ -5,20 +5,21 @@
5
5
  "@shopify:registry": "https://registry.npmjs.org"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "2.0.3-unstable.202310051444.0",
8
+ "version": "2.1.1-unstable.202310110934.0",
9
9
  "type": "module",
10
10
  "scripts": {
11
- "build": "tsup --clean --config ./tsup.config.ts && oclif manifest",
11
+ "build": "tsup --sourcemap --clean --config ./tsup.config.ts && oclif manifest",
12
12
  "changesets:check": "changeset status",
13
13
  "dev": "tsup --watch --config ./tsup.config.ts",
14
14
  "typecheck": "tsc --noEmit",
15
15
  "lint": "eslint --ext .js,.ts --max-warnings 0 src",
16
16
  "lint:format": "prettier --write \"**/*.*\" && npm run lint --fix",
17
17
  "generate:manifest": "oclif manifest",
18
- "prepublishOnly": "npm install && npm run build && rm -rf dist/**/*.test.*",
18
+ "prepublishOnly": "npm install && npm run build && rm -rf dist/**/*.test.* && npm run upload-sourcemaps",
19
19
  "release": "npm run prepublishOnly && npx changeset publish && git push --follow-tags",
20
20
  "test": "vitest run",
21
- "test:watch": "vitest"
21
+ "test:watch": "vitest",
22
+ "upload-sourcemaps": "node ./upload-sourcemaps.mjs"
22
23
  },
23
24
  "bin": {
24
25
  "oxygen-cli": "./dist/oxygen-cli.js"
@@ -34,11 +35,15 @@
34
35
  "/oclif.manifest.json"
35
36
  ],
36
37
  "dependencies": {
38
+ "@bugsnag/core": "^7.19.0",
39
+ "@bugsnag/js": "^7.21.0",
40
+ "@bugsnag/node": "^7.19.0",
37
41
  "@oclif/core": "2.15.0",
38
42
  "@shopify/cli-kit": "^3.49.6",
39
43
  "async": "^3.2.4"
40
44
  },
41
45
  "devDependencies": {
46
+ "@bugsnag/source-maps": "^2.3.1",
42
47
  "@changesets/cli": "^2.26.1",
43
48
  "@shopify/eslint-plugin": "^43.0.0",
44
49
  "@shopify/prettier-config": "^1.1.2",