@shopify/oxygen-cli 5.0.1-unstable.202507092257.0 → 6.0.1-unstable.202507281554.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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @shopify/oxygen-cli
2
2
 
3
+ ## 6.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 56a2b48: Update eslint from 8.57.1 to 9.21.0
8
+ - be391b8: Update @shopify/eslint-plugin from 48.0.2 to 49.0.0
9
+
10
+ ### Minor Changes
11
+
12
+ - 5af26a7: Remove consoleError call, add missing test for deploy entrypoint
13
+
3
14
  ## 5.0.0
4
15
 
5
16
  ### Major Changes
@@ -15,6 +26,7 @@
15
26
 
16
27
  ### Patch Changes
17
28
 
29
+ - e4cd96d: returns AbortError instead of Error for build failures
18
30
  - 7977fc5: Update changesets/action from 1.5.0 to 1.5.3
19
31
  - 590b1b3: Update @types/node from 22.15.17 to 22.15.21
20
32
  - 18c232a: Update brace-expansion from 1.1.11 to 1.1.12
@@ -1,5 +1,5 @@
1
1
  import { Command, Flags } from '@oclif/core';
2
- import { consoleError } from '@shopify/cli-kit/node/output';
2
+ import { outputWarn } from '@shopify/cli-kit/node/output';
3
3
  import { normalizePath } from '@shopify/cli-kit/node/path';
4
4
  import { readAndParseDotEnv } from '@shopify/cli-kit/node/dot-env';
5
5
  import { initializeBugsnag, getBugsnag } from '../../utils/bugsnag.js';
@@ -172,9 +172,9 @@ class Deploy extends Command {
172
172
  Bugsnag.notify(error);
173
173
  }
174
174
  if (error instanceof Error) {
175
- consoleError(error.message);
175
+ outputWarn(error.message);
176
176
  } else {
177
- consoleError(error);
177
+ outputWarn(error);
178
178
  }
179
179
  this.exit(1);
180
180
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/oxygen/deploy.ts"],"names":[],"mappings":";;;;;;;;AAkBO,MAAM,eAAe,OAAQ,CAAA;AAAA,EAClC,OAAO,WAAc,GAAA,gCAAA;AAAA,EACrB,OAAO,MAAS,GAAA,KAAA;AAAA,EAChB,OAAO,KAAQ,GAAA;AAAA,IACb,YAAA,EAAc,MAAM,MAAO,CAAA;AAAA,MACzB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,eAAA;AAAA,MACb,OAAA,EAAS,MAAO,CAAA,cAAA,CAAe,gBAAgB,CAAA;AAAA,MAC/C,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,YAAA,EAAc,MAAM,MAAO,CAAA;AAAA,MACzB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,eAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,OAAA,EAAS,MAAO,CAAA,cAAA,CAAe,mBAAoB,CAAA;AAAA,MACnD,KAAA,EAAO,CAAC,KAA2B,KAAA;AACjC,QAAA,IAAA,CAAK,qBAAwB,GAAA,IAAA;AAC7B,QAAO,OAAA,OAAA,CAAQ,QAAQ,KAAK,CAAA;AAAA;AAC9B,KACD,CAAA;AAAA,IACD,cAAA,EAAgB,MAAM,OAAQ,CAAA;AAAA,MAC5B,WAAa,EAAA,iCAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA;AAAA,KACV,CAAA;AAAA,IACD,cAAA,EAAgB,MAAM,MAAO,CAAA;AAAA,MAC3B,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,qCAAA;AAAA,MACb,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,IAAA,EAAM,MAAM,MAAO,CAAA;AAAA,MACjB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,WAAA;AAAA,MACb,OAAS,EAAA,IAAA;AAAA,MACT,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,kBAAA,EAAoB,MAAM,OAAQ,CAAA;AAAA,MAChC,GAAK,EAAA,4BAAA;AAAA,MACL,WAAa,EAAA,+CAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA;AAAA,KACV,CAAA;AAAA,IACD,SAAA,EAAW,MAAM,OAAQ,CAAA;AAAA,MACvB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,4BAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA;AAAA,KACV,CAAA;AAAA,IACD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,MAClB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,yBAAA;AAAA,MACb,GAAK,EAAA,yBAAA;AAAA,MACL,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,YAAA,EAAc,MAAM,MAAO,CAAA;AAAA,MACzB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,eAAA;AAAA,MACb,OAAA,EAAS,MAAO,CAAA,cAAA,CAAe,gBAAgB,CAAA;AAAA,MAC/C,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,UAAA,EAAY,MAAM,OAAQ,CAAA;AAAA,MACxB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,wBAAA;AAAA,MACb,OAAS,EAAA,KAAA;AAAA,MACT,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,mBAAA,EAAqB,MAAM,MAAO,CAAA;AAAA,MAChC,WACE,EAAA,iFAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,uBAAA,EAAyB,MAAM,MAAO,CAAA;AAAA,MACpC,WAAa,EAAA,0DAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,WAAA,EAAa,MAAM,MAAO,CAAA;AAAA,MACxB,WACE,EAAA,oFAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,YAAA,EAAc,MAAM,MAAO,CAAA;AAAA,MACzB,WACE,EAAA,sFAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,MAC5B,WACE,EAAA,2FAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,uBAAA,EAAyB,MAAM,OAAQ,CAAA;AAAA,MACrC,WACE,EAAA,0FAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA;AAAA,KACV,CAAA;AAAA,IACD,uBAAA,EAAyB,MAAM,MAAO,CAAA;AAAA,MACpC,WACE,EAAA,sGAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,SAAA,EAAW,CAAC,yBAAyB;AAAA,KACtC,CAAA;AAAA,IACD,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,MAC5B,WACE,EAAA,4FAAA;AAAA,MACF,QAAU,EAAA;AAAA,KACX;AAAA,GACH;AAAA,EAEA,OAAO,qBAAwB,GAAA,KAAA;AAAA,EAE/B,MAAM,GAAM,GAAA;AACV,IAAI,IAAA;AACF,MAAA,MAAM,EAAC,KAAK,EAAA,GAAI,MAAM,IAAA,CAAK,MAAM,MAAM,CAAA;AACvC,MAAM,MAAA,QAAA,GAAW,aAAc,CAAA,KAAA,CAAM,IAAI,CAAA;AAEzC,MAAI,IAAA,8BAAA;AAEJ,MAAA,IAAI,MAAM,eAAiB,EAAA;AACzB,QAAA,MAAM,IAAO,GAAA,MAAM,kBAAmB,CAAA,KAAA,CAAM,eAAe,CAAA;AAE3D,QAAA,8BAAA,GAAiC,MAAO,CAAA,OAAA,CAAQ,IAAK,CAAA,SAAS,CAAE,CAAA,GAAA;AAAA,UAC9D,CAAC,CAAC,GAAK,EAAA,KAAK,CAAO,MAAA;AAAA,YACjB,QAAU,EAAA,IAAA;AAAA,YACV,GAAA;AAAA,YACA;AAAA,WACF;AAAA,SACF;AAAA;AAGF,MAAA,iBAAA,CAAkB,MAAM,cAAc,CAAA;AACtC,MAAA,MAAM,UAAU,UAAW,EAAA;AAE3B,MAAM,MAAA,aAAA;AAAA;AAAA,QAEJ,OAAA,CAAQ,IAAI,4BACZ,IAAA;AAAA,OAAA;AACF,MAAA,OAAA,EAAS,YAAY,OAAS,EAAA;AAAA,QAC5B,KAAO,EAAA,EAAC,GAAG,KAAA,EAAO,OAAO,KAAK,EAAA;AAAA,QAC9B;AAAA,OACD,CAAA;AAED,MAAA,MAAM,MAA2B,GAAA;AAAA,QAC/B,SAAA,EAAW,aAAc,CAAA,KAAA,CAAM,YAAY,CAAA;AAAA,QAC3C,OAAA,EAAS,CAAC,KAAM,CAAA,cAAA;AAAA,QAChB,cAAc,KAAM,CAAA,YAAA;AAAA,QACpB,eAAA,EAAiB,UAAW,CAAA,KAAA,CAAM,KAAM,CAAA;AAAA,QACxC,gBAAgB,KAAM,CAAA,cAAA;AAAA,QACtB,aAAA;AAAA,QACA,QAAU,EAAA;AAAA,UACR,aAAa,KAAM,CAAA,mBAAA;AAAA,UACnB,iBAAiB,KAAM,CAAA,uBAAA;AAAA,UACvB,KAAK,KAAM,CAAA,WAAA;AAAA,UACX,MAAM,KAAM,CAAA,YAAA;AAAA,UACZ,SAAS,KAAM,CAAA;AAAA,SACjB;AAAA,QACA,oBAAoB,KAAM,CAAA,kBAAA;AAAA,QAC1B,QAAA;AAAA,QACA,WAAW,KAAM,CAAA,SAAA;AAAA,QACjB,SAAA,EAAW,aAAc,CAAA,KAAA,CAAM,YAAY,CAAA;AAAA,QAC3C,YAAY,KAAM,CAAA,UAAA;AAAA,QAClB,yBAAyB,KAAM,CAAA,uBAAA;AAAA,QAC/B,yBAAyB,KAAM,CAAA,uBAAA;AAAA,QAC/B;AAAA,OACF;AAEA,MAAM,MAAA,YAAA,CAAa,EAAC,MAAA,EAAO,CAAA;AAC3B,MAAA,IAAI,CAAC,MAAA,CAAO,qBAAyB,IAAA,CAAC,OAAO,SAAW,EAAA;AACtD,QAAO,MAAA,CAAA,YAAA,GAAe,4BAA4B,MAAM,CAAA;AAAA;AAE1D,MAAM,MAAA,YAAA,CAAa,EAAC,MAAA,EAAO,CAAA;AAAA,aACpB,KAAO,EAAA;AACd,MAAA,MAAM,UAAU,UAAW,EAAA;AAC3B,MAAA,IAAI,OAAY,KAAA,KAAA,YAAiB,KAAS,IAAA,OAAO,UAAU,QAAW,CAAA,EAAA;AACpE,QAAA,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA;AAGtB,MAAA,IAAI,iBAAiB,KAAO,EAAA;AAC1B,QAAA,YAAA,CAAa,MAAM,OAAO,CAAA;AAAA,OACrB,MAAA;AACL,QAAA,YAAA,CAAa,KAAe,CAAA;AAAA;AAG9B,MAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA;AACb;AAEJ","file":"deploy.js","sourcesContent":["import {Command, Flags} from '@oclif/core';\nimport {consoleError} from '@shopify/cli-kit/node/output';\nimport {normalizePath} from '@shopify/cli-kit/node/path';\nimport {readAndParseDotEnv} from '@shopify/cli-kit/node/dot-env';\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 {\n DeploymentConfig,\n EnvironmentVariable,\n} 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 path: Flags.string({\n char: 'p',\n description: 'Root path',\n default: './',\n required: false,\n }),\n defaultEnvironment: Flags.boolean({\n env: 'OXYGEN_DEFAULT_ENVIRONMENT',\n description: 'Deploys to the default environment of the app',\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 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 metadataHydrogenVersion: Flags.string({\n description: 'The Hydrogen version of the deployment from package.json',\n required: false,\n env: 'OXYGEN_METADATA_HYDROGEN_VERSION',\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 generateAuthBypassToken: Flags.boolean({\n description:\n 'Generate an auth bypass token used to perform end-to-end testing against the deployment.',\n required: false,\n default: false,\n }),\n authBypassTokenDuration: Flags.string({\n description:\n 'Specify the duration (in hours) up to 12 hours for the authentication bypass token. Defaults to `2`.',\n required: false,\n dependsOn: ['generateAuthBypassToken'],\n }),\n environmentFile: Flags.string({\n description:\n 'Path to an environment file to override existing environment variables for the deployment.',\n required: false,\n }),\n };\n\n static hasCustomBuildCommand = false;\n\n async run() {\n try {\n const {flags} = await this.parse(Deploy);\n const rootPath = normalizePath(flags.path);\n\n let overriddenEnvironmentVariables: EnvironmentVariable[] | undefined;\n\n if (flags.environmentFile) {\n const file = await readAndParseDotEnv(flags.environmentFile);\n\n overriddenEnvironmentVariables = Object.entries(file.variables).map(\n ([key, value]) => ({\n isSecret: true,\n key,\n value,\n }),\n );\n }\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', {\n flags: {...flags, token: '***'},\n deploymentUrl,\n });\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 metadata: {\n description: flags.metadataDescription,\n hydrogenVersion: flags.metadataHydrogenVersion,\n url: flags.metadataUrl,\n user: flags.metadataUser,\n version: flags.metadataVersion,\n },\n defaultEnvironment: flags.defaultEnvironment,\n rootPath,\n skipBuild: flags.skipBuild,\n workerDir: normalizePath(flags.workerFolder),\n workerOnly: flags.workerOnly,\n generateAuthBypassToken: flags.generateAuthBypassToken,\n authBypassTokenDuration: flags.authBypassTokenDuration,\n overriddenEnvironmentVariables,\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.message);\n } else {\n consoleError(error as string);\n }\n\n this.exit(1);\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../../src/commands/oxygen/deploy.ts"],"names":[],"mappings":";;;;;;;;AAkBO,MAAM,eAAe,OAAQ,CAAA;AAAA,EAClC,OAAO,WAAc,GAAA,gCAAA;AAAA,EACrB,OAAO,MAAS,GAAA,KAAA;AAAA,EAChB,OAAO,KAAQ,GAAA;AAAA,IACb,YAAA,EAAc,MAAM,MAAO,CAAA;AAAA,MACzB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,eAAA;AAAA,MACb,OAAA,EAAS,MAAO,CAAA,cAAA,CAAe,gBAAgB,CAAA;AAAA,MAC/C,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,YAAA,EAAc,MAAM,MAAO,CAAA;AAAA,MACzB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,eAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,OAAA,EAAS,MAAO,CAAA,cAAA,CAAe,mBAAoB,CAAA;AAAA,MACnD,KAAA,EAAO,CAAC,KAA2B,KAAA;AACjC,QAAA,IAAA,CAAK,qBAAwB,GAAA,IAAA;AAC7B,QAAO,OAAA,OAAA,CAAQ,QAAQ,KAAK,CAAA;AAAA;AAC9B,KACD,CAAA;AAAA,IACD,cAAA,EAAgB,MAAM,OAAQ,CAAA;AAAA,MAC5B,WAAa,EAAA,iCAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA;AAAA,KACV,CAAA;AAAA,IACD,cAAA,EAAgB,MAAM,MAAO,CAAA;AAAA,MAC3B,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,qCAAA;AAAA,MACb,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,IAAA,EAAM,MAAM,MAAO,CAAA;AAAA,MACjB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,WAAA;AAAA,MACb,OAAS,EAAA,IAAA;AAAA,MACT,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,kBAAA,EAAoB,MAAM,OAAQ,CAAA;AAAA,MAChC,GAAK,EAAA,4BAAA;AAAA,MACL,WAAa,EAAA,+CAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA;AAAA,KACV,CAAA;AAAA,IACD,SAAA,EAAW,MAAM,OAAQ,CAAA;AAAA,MACvB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,4BAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA;AAAA,KACV,CAAA;AAAA,IACD,KAAA,EAAO,MAAM,MAAO,CAAA;AAAA,MAClB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,yBAAA;AAAA,MACb,GAAK,EAAA,yBAAA;AAAA,MACL,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,YAAA,EAAc,MAAM,MAAO,CAAA;AAAA,MACzB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,eAAA;AAAA,MACb,OAAA,EAAS,MAAO,CAAA,cAAA,CAAe,gBAAgB,CAAA;AAAA,MAC/C,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,UAAA,EAAY,MAAM,OAAQ,CAAA;AAAA,MACxB,IAAM,EAAA,GAAA;AAAA,MACN,WAAa,EAAA,wBAAA;AAAA,MACb,OAAS,EAAA,KAAA;AAAA,MACT,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,IACD,mBAAA,EAAqB,MAAM,MAAO,CAAA;AAAA,MAChC,WACE,EAAA,iFAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,uBAAA,EAAyB,MAAM,MAAO,CAAA;AAAA,MACpC,WAAa,EAAA,0DAAA;AAAA,MACb,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,WAAA,EAAa,MAAM,MAAO,CAAA;AAAA,MACxB,WACE,EAAA,oFAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,YAAA,EAAc,MAAM,MAAO,CAAA;AAAA,MACzB,WACE,EAAA,sFAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,MAC5B,WACE,EAAA,2FAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,KACN,CAAA;AAAA,IACD,uBAAA,EAAyB,MAAM,OAAQ,CAAA;AAAA,MACrC,WACE,EAAA,0FAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA;AAAA,KACV,CAAA;AAAA,IACD,uBAAA,EAAyB,MAAM,MAAO,CAAA;AAAA,MACpC,WACE,EAAA,sGAAA;AAAA,MACF,QAAU,EAAA,KAAA;AAAA,MACV,SAAA,EAAW,CAAC,yBAAyB;AAAA,KACtC,CAAA;AAAA,IACD,eAAA,EAAiB,MAAM,MAAO,CAAA;AAAA,MAC5B,WACE,EAAA,4FAAA;AAAA,MACF,QAAU,EAAA;AAAA,KACX;AAAA,GACH;AAAA,EAEA,OAAO,qBAAwB,GAAA,KAAA;AAAA,EAE/B,MAAM,GAAM,GAAA;AACV,IAAI,IAAA;AACF,MAAA,MAAM,EAAC,KAAK,EAAA,GAAI,MAAM,IAAA,CAAK,MAAM,MAAM,CAAA;AACvC,MAAM,MAAA,QAAA,GAAW,aAAc,CAAA,KAAA,CAAM,IAAI,CAAA;AAEzC,MAAI,IAAA,8BAAA;AAEJ,MAAA,IAAI,MAAM,eAAiB,EAAA;AACzB,QAAA,MAAM,IAAO,GAAA,MAAM,kBAAmB,CAAA,KAAA,CAAM,eAAe,CAAA;AAE3D,QAAA,8BAAA,GAAiC,MAAO,CAAA,OAAA,CAAQ,IAAK,CAAA,SAAS,CAAE,CAAA,GAAA;AAAA,UAC9D,CAAC,CAAC,GAAK,EAAA,KAAK,CAAO,MAAA;AAAA,YACjB,QAAU,EAAA,IAAA;AAAA,YACV,GAAA;AAAA,YACA;AAAA,WACF;AAAA,SACF;AAAA;AAGF,MAAA,iBAAA,CAAkB,MAAM,cAAc,CAAA;AACtC,MAAA,MAAM,UAAU,UAAW,EAAA;AAE3B,MAAM,MAAA,aAAA;AAAA;AAAA,QAEJ,OAAA,CAAQ,IAAI,4BACZ,IAAA;AAAA,OAAA;AACF,MAAA,OAAA,EAAS,YAAY,OAAS,EAAA;AAAA,QAC5B,KAAO,EAAA,EAAC,GAAG,KAAA,EAAO,OAAO,KAAK,EAAA;AAAA,QAC9B;AAAA,OACD,CAAA;AAED,MAAA,MAAM,MAA2B,GAAA;AAAA,QAC/B,SAAA,EAAW,aAAc,CAAA,KAAA,CAAM,YAAY,CAAA;AAAA,QAC3C,OAAA,EAAS,CAAC,KAAM,CAAA,cAAA;AAAA,QAChB,cAAc,KAAM,CAAA,YAAA;AAAA,QACpB,eAAA,EAAiB,UAAW,CAAA,KAAA,CAAM,KAAM,CAAA;AAAA,QACxC,gBAAgB,KAAM,CAAA,cAAA;AAAA,QACtB,aAAA;AAAA,QACA,QAAU,EAAA;AAAA,UACR,aAAa,KAAM,CAAA,mBAAA;AAAA,UACnB,iBAAiB,KAAM,CAAA,uBAAA;AAAA,UACvB,KAAK,KAAM,CAAA,WAAA;AAAA,UACX,MAAM,KAAM,CAAA,YAAA;AAAA,UACZ,SAAS,KAAM,CAAA;AAAA,SACjB;AAAA,QACA,oBAAoB,KAAM,CAAA,kBAAA;AAAA,QAC1B,QAAA;AAAA,QACA,WAAW,KAAM,CAAA,SAAA;AAAA,QACjB,SAAA,EAAW,aAAc,CAAA,KAAA,CAAM,YAAY,CAAA;AAAA,QAC3C,YAAY,KAAM,CAAA,UAAA;AAAA,QAClB,yBAAyB,KAAM,CAAA,uBAAA;AAAA,QAC/B,yBAAyB,KAAM,CAAA,uBAAA;AAAA,QAC/B;AAAA,OACF;AAEA,MAAM,MAAA,YAAA,CAAa,EAAC,MAAA,EAAO,CAAA;AAC3B,MAAA,IAAI,CAAC,MAAA,CAAO,qBAAyB,IAAA,CAAC,OAAO,SAAW,EAAA;AACtD,QAAO,MAAA,CAAA,YAAA,GAAe,4BAA4B,MAAM,CAAA;AAAA;AAE1D,MAAM,MAAA,YAAA,CAAa,EAAC,MAAA,EAAO,CAAA;AAAA,aACpB,KAAO,EAAA;AACd,MAAA,MAAM,UAAU,UAAW,EAAA;AAC3B,MAAA,IAAI,OAAY,KAAA,KAAA,YAAiB,KAAS,IAAA,OAAO,UAAU,QAAW,CAAA,EAAA;AACpE,QAAA,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA;AAGtB,MAAA,IAAI,iBAAiB,KAAO,EAAA;AAC1B,QAAA,UAAA,CAAW,MAAM,OAAO,CAAA;AAAA,OACnB,MAAA;AACL,QAAA,UAAA,CAAW,KAAe,CAAA;AAAA;AAG5B,MAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA;AACb;AAEJ","file":"deploy.js","sourcesContent":["import {Command, Flags} from '@oclif/core';\nimport {outputWarn} from '@shopify/cli-kit/node/output';\nimport {normalizePath} from '@shopify/cli-kit/node/path';\nimport {readAndParseDotEnv} from '@shopify/cli-kit/node/dot-env';\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 {\n DeploymentConfig,\n EnvironmentVariable,\n} 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 path: Flags.string({\n char: 'p',\n description: 'Root path',\n default: './',\n required: false,\n }),\n defaultEnvironment: Flags.boolean({\n env: 'OXYGEN_DEFAULT_ENVIRONMENT',\n description: 'Deploys to the default environment of the app',\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 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 metadataHydrogenVersion: Flags.string({\n description: 'The Hydrogen version of the deployment from package.json',\n required: false,\n env: 'OXYGEN_METADATA_HYDROGEN_VERSION',\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 generateAuthBypassToken: Flags.boolean({\n description:\n 'Generate an auth bypass token used to perform end-to-end testing against the deployment.',\n required: false,\n default: false,\n }),\n authBypassTokenDuration: Flags.string({\n description:\n 'Specify the duration (in hours) up to 12 hours for the authentication bypass token. Defaults to `2`.',\n required: false,\n dependsOn: ['generateAuthBypassToken'],\n }),\n environmentFile: Flags.string({\n description:\n 'Path to an environment file to override existing environment variables for the deployment.',\n required: false,\n }),\n };\n\n static hasCustomBuildCommand = false;\n\n async run() {\n try {\n const {flags} = await this.parse(Deploy);\n const rootPath = normalizePath(flags.path);\n\n let overriddenEnvironmentVariables: EnvironmentVariable[] | undefined;\n\n if (flags.environmentFile) {\n const file = await readAndParseDotEnv(flags.environmentFile);\n\n overriddenEnvironmentVariables = Object.entries(file.variables).map(\n ([key, value]) => ({\n isSecret: true,\n key,\n value,\n }),\n );\n }\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', {\n flags: {...flags, token: '***'},\n deploymentUrl,\n });\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 metadata: {\n description: flags.metadataDescription,\n hydrogenVersion: flags.metadataHydrogenVersion,\n url: flags.metadataUrl,\n user: flags.metadataUser,\n version: flags.metadataVersion,\n },\n defaultEnvironment: flags.defaultEnvironment,\n rootPath,\n skipBuild: flags.skipBuild,\n workerDir: normalizePath(flags.workerFolder),\n workerOnly: flags.workerOnly,\n generateAuthBypassToken: flags.generateAuthBypassToken,\n authBypassTokenDuration: flags.authBypassTokenDuration,\n overriddenEnvironmentVariables,\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 outputWarn(error.message);\n } else {\n outputWarn(error as string);\n }\n\n this.exit(1);\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,104 @@
1
+ import { vi, describe, beforeEach, test, expect } from 'vitest';
2
+ import { outputWarn } from '@shopify/cli-kit/node/output';
3
+ import { createDeploy } from '../../deploy/index.js';
4
+ import { verifyConfig } from '../../utils/utils.js';
5
+ import { getBugsnag } from '../../utils/bugsnag.js';
6
+ import { Deploy } from './deploy.js';
7
+
8
+ vi.mock("@shopify/cli-kit/node/output");
9
+ vi.mock("../../deploy/index.js");
10
+ vi.mock("../../utils/utils.js");
11
+ const mockBugsnag = {
12
+ notify: vi.fn(),
13
+ addMetadata: vi.fn()
14
+ };
15
+ vi.mock("../../utils/bugsnag.js", () => ({
16
+ getBugsnag: vi.fn().mockReturnValue(void 0),
17
+ initializeBugsnag: vi.fn()
18
+ }));
19
+ vi.mock("@shopify/cli-kit/node/path", () => ({
20
+ normalizePath: vi.fn((path) => path)
21
+ }));
22
+ vi.mock("@shopify/cli-kit/node/dot-env", () => ({
23
+ readAndParseDotEnv: vi.fn()
24
+ }));
25
+ describe("Deploy command", () => {
26
+ let deploy;
27
+ beforeEach(() => {
28
+ deploy = new Deploy([], {
29
+ runHook: vi.fn()
30
+ });
31
+ vi.clearAllMocks();
32
+ mockBugsnag.notify.mockClear();
33
+ mockBugsnag.addMetadata.mockClear();
34
+ vi.mocked(getBugsnag).mockReturnValue(void 0);
35
+ });
36
+ test("should handle errors and call outputWarn", async () => {
37
+ const errorMessage = "Test deployment error";
38
+ const error = new Error(errorMessage);
39
+ vi.spyOn(deploy, "parse").mockResolvedValue({
40
+ flags: { token: "test-token", path: "./" }
41
+ });
42
+ vi.mocked(verifyConfig).mockRejectedValueOnce(error);
43
+ const exitSpy = vi.spyOn(deploy, "exit").mockImplementation(() => {
44
+ throw new Error("Process exit called");
45
+ });
46
+ await expect(deploy.run()).rejects.toThrow("Process exit called");
47
+ expect(outputWarn).toHaveBeenCalledWith(errorMessage);
48
+ expect(exitSpy).toHaveBeenCalledWith(1);
49
+ });
50
+ test("should handle string errors and call outputWarn", async () => {
51
+ const errorMessage = "String error message";
52
+ vi.spyOn(deploy, "parse").mockResolvedValue({
53
+ flags: { token: "test-token", path: "./" }
54
+ });
55
+ vi.mocked(verifyConfig).mockRejectedValueOnce(errorMessage);
56
+ const exitSpy = vi.spyOn(deploy, "exit").mockImplementation(() => {
57
+ throw new Error("Process exit called");
58
+ });
59
+ await expect(deploy.run()).rejects.toThrow("Process exit called");
60
+ expect(outputWarn).toHaveBeenCalledWith(errorMessage);
61
+ expect(exitSpy).toHaveBeenCalledWith(1);
62
+ });
63
+ test("should succeed when deployment completes without errors", async () => {
64
+ vi.spyOn(deploy, "parse").mockResolvedValue({
65
+ flags: { token: "test-token", path: "./" }
66
+ });
67
+ vi.mocked(verifyConfig).mockResolvedValueOnce(void 0);
68
+ vi.mocked(createDeploy).mockResolvedValueOnce(void 0);
69
+ await deploy.run();
70
+ expect(outputWarn).not.toHaveBeenCalled();
71
+ });
72
+ test("should notify Observe when enabled and error occurs", async () => {
73
+ const errorMessage = "Bugsnag test error";
74
+ const error = new Error(errorMessage);
75
+ vi.spyOn(deploy, "parse").mockResolvedValue({
76
+ flags: { token: "test-token", path: "./", disableBugsnag: false }
77
+ });
78
+ vi.mocked(getBugsnag).mockReturnValue(mockBugsnag);
79
+ vi.mocked(verifyConfig).mockRejectedValueOnce(error);
80
+ vi.spyOn(deploy, "exit").mockImplementation(() => {
81
+ throw new Error("Process exit called");
82
+ });
83
+ await expect(deploy.run()).rejects.toThrow("Process exit called");
84
+ expect(mockBugsnag.notify).toHaveBeenCalledWith(error);
85
+ expect(outputWarn).toHaveBeenCalledWith(errorMessage);
86
+ });
87
+ test("should not notify Observe when disabled", async () => {
88
+ const errorMessage = "No Bugsnag test error";
89
+ const error = new Error(errorMessage);
90
+ vi.spyOn(deploy, "parse").mockResolvedValue({
91
+ flags: { token: "test-token", path: "./", disableBugsnag: true }
92
+ });
93
+ vi.mocked(getBugsnag).mockReturnValue(void 0);
94
+ vi.mocked(verifyConfig).mockRejectedValueOnce(error);
95
+ vi.spyOn(deploy, "exit").mockImplementation(() => {
96
+ throw new Error("Process exit called");
97
+ });
98
+ await expect(deploy.run()).rejects.toThrow("Process exit called");
99
+ expect(mockBugsnag.notify).not.toHaveBeenCalled();
100
+ expect(outputWarn).toHaveBeenCalledWith(errorMessage);
101
+ });
102
+ });
103
+ //# sourceMappingURL=deploy.test.js.map
104
+ //# sourceMappingURL=deploy.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/oxygen/deploy.test.ts"],"names":[],"mappings":"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","file":"deploy.test.js","sourcesContent":["import {expect, describe, test, vi, beforeEach} from 'vitest';\nimport {outputWarn} from '@shopify/cli-kit/node/output';\n\nimport {createDeploy} from '../../deploy/index.js';\nimport {verifyConfig} from '../../utils/utils.js';\nimport {getBugsnag} from '../../utils/bugsnag.js';\n\nimport {Deploy} from './deploy.js';\n\nvi.mock('@shopify/cli-kit/node/output');\nvi.mock('../../deploy/index.js');\nvi.mock('../../utils/utils.js');\nconst mockBugsnag = {\n notify: vi.fn(),\n addMetadata: vi.fn(),\n};\n\nvi.mock('../../utils/bugsnag.js', () => ({\n getBugsnag: vi.fn().mockReturnValue(undefined),\n initializeBugsnag: vi.fn(),\n}));\nvi.mock('@shopify/cli-kit/node/path', () => ({\n normalizePath: vi.fn((path: string) => path),\n}));\nvi.mock('@shopify/cli-kit/node/dot-env', () => ({\n readAndParseDotEnv: vi.fn(),\n}));\n\ndescribe('Deploy command', () => {\n let deploy: Deploy;\n\n beforeEach(() => {\n deploy = new Deploy([], {\n runHook: vi.fn(),\n } as any);\n vi.clearAllMocks();\n mockBugsnag.notify.mockClear();\n mockBugsnag.addMetadata.mockClear();\n\n vi.mocked(getBugsnag).mockReturnValue(undefined);\n });\n\n test('should handle errors and call outputWarn', async () => {\n const errorMessage = 'Test deployment error';\n const error = new Error(errorMessage);\n\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './'},\n } as any);\n\n vi.mocked(verifyConfig).mockRejectedValueOnce(error);\n\n const exitSpy = vi.spyOn(deploy, 'exit').mockImplementation(() => {\n throw new Error('Process exit called');\n });\n\n await expect(deploy.run()).rejects.toThrow('Process exit called');\n\n expect(outputWarn).toHaveBeenCalledWith(errorMessage);\n expect(exitSpy).toHaveBeenCalledWith(1);\n });\n\n test('should handle string errors and call outputWarn', async () => {\n const errorMessage = 'String error message';\n\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './'},\n } as any);\n\n vi.mocked(verifyConfig).mockRejectedValueOnce(errorMessage);\n\n const exitSpy = vi.spyOn(deploy, 'exit').mockImplementation(() => {\n throw new Error('Process exit called');\n });\n\n await expect(deploy.run()).rejects.toThrow('Process exit called');\n\n expect(outputWarn).toHaveBeenCalledWith(errorMessage);\n expect(exitSpy).toHaveBeenCalledWith(1);\n });\n\n test('should succeed when deployment completes without errors', async () => {\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './'},\n } as any);\n\n vi.mocked(verifyConfig).mockResolvedValueOnce(undefined);\n vi.mocked(createDeploy).mockResolvedValueOnce(undefined);\n\n await deploy.run();\n\n expect(outputWarn).not.toHaveBeenCalled();\n });\n\n test('should notify Observe when enabled and error occurs', async () => {\n const errorMessage = 'Bugsnag test error';\n const error = new Error(errorMessage);\n\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './', disableBugsnag: false},\n } as any);\n\n vi.mocked(getBugsnag).mockReturnValue(mockBugsnag as any);\n vi.mocked(verifyConfig).mockRejectedValueOnce(error);\n\n vi.spyOn(deploy, 'exit').mockImplementation(() => {\n throw new Error('Process exit called');\n });\n\n await expect(deploy.run()).rejects.toThrow('Process exit called');\n\n expect(mockBugsnag.notify).toHaveBeenCalledWith(error);\n expect(outputWarn).toHaveBeenCalledWith(errorMessage);\n });\n\n test('should not notify Observe when disabled', async () => {\n const errorMessage = 'No Bugsnag test error';\n const error = new Error(errorMessage);\n\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './', disableBugsnag: true},\n } as any);\n\n vi.mocked(getBugsnag).mockReturnValue(undefined);\n vi.mocked(verifyConfig).mockRejectedValueOnce(error);\n\n vi.spyOn(deploy, 'exit').mockImplementation(() => {\n throw new Error('Process exit called');\n });\n\n await expect(deploy.run()).rejects.toThrow('Process exit called');\n\n expect(mockBugsnag.notify).not.toHaveBeenCalled();\n expect(outputWarn).toHaveBeenCalledWith(errorMessage);\n });\n});\n"]}
@@ -1,5 +1,6 @@
1
1
  import { spawn } from 'child_process';
2
2
  import { PassThrough } from 'stream';
3
+ import { AbortError } from '@shopify/cli-kit/node/error';
3
4
  import { getBugsnag } from '../utils/bugsnag.js';
4
5
  import { MetricName } from '../utils/metrics-exporter.js';
5
6
 
@@ -14,7 +15,7 @@ async function buildProject(options) {
14
15
  performance.now() - startTime
15
16
  );
16
17
  }).catch((error) => {
17
- throw new Error(`Build function failed with error: ${error}`);
18
+ throw new AbortError(`Build function failed with error: ${error}`);
18
19
  });
19
20
  }
20
21
  const assetPathEnvironment = assetPath ? { HYDROGEN_ASSET_BASE_URL: assetPath } : {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/deploy/build-project.ts"],"names":[],"mappings":";;;;;AAeA,eAAsB,aAAa,OAA8B,EAAA;AAC/D,EAAA,MAAM,EAAC,MAAA,EAAQ,SAAW,EAAA,KAAA,EAAS,GAAA,OAAA;AACnC,EAAA,MAAM,UAAU,UAAW,EAAA;AAE3B,EAAA,IAAI,OAAO,aAAe,EAAA;AACxB,IAAM,MAAA,SAAA,GAAY,YAAY,GAAI,EAAA;AAClC,IAAA,OAAO,KACJ,CAAA,aAAA,CAAc,SAAS,CAAA,CACvB,KAAK,MAAM;AACV,MAAA,OAAA,CAAQ,eAAiB,EAAA,GAAA;AAAA,QACvB,UAAW,CAAA,SAAA;AAAA,QACX,WAAA,CAAY,KAAQ,GAAA;AAAA,OACtB;AAAA,KACD,CAAA,CACA,KAAM,CAAA,CAAC,KAAU,KAAA;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAqC,kCAAA,EAAA,KAAK,CAAE,CAAA,CAAA;AAAA,KAC7D,CAAA;AAAA;AAGL,EAAA,MAAM,uBAAuB,SACzB,GAAA,EAAC,uBAAyB,EAAA,SAAA,KAC1B,EAAC;AACL,EAAI,IAAA;AACF,IAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACrC,MAAA,IAAI,MAAS,GAAA,EAAA;AACb,MAAM,MAAA,YAAA,GAAe,IAAI,WAAY,EAAA;AAErC,MAAa,YAAA,CAAA,EAAA,CAAG,MAAQ,EAAA,CAAC,KAAU,KAAA;AACjC,QAAU,MAAA,IAAA,KAAA;AACV,QAAQ,OAAA,CAAA,MAAA,CAAO,MAAM,KAAK,CAAA;AAAA,OAC3B,CAAA;AAED,MAAM,MAAA,SAAA,GAAY,YAAY,GAAI,EAAA;AAClC,MAAA,MAAM,YAAe,GAAA,KAAA,CAAM,MAAO,CAAA,YAAA,EAAe,EAAI,EAAA;AAAA,QACnD,KAAO,EAAA,CAAC,SAAW,EAAA,MAAA,EAAQ,MAAM,CAAA;AAAA,QACjC,GAAK,EAAA;AAAA;AAAA,UAEH,GAAG,OAAQ,CAAA,GAAA;AAAA,UACX,GAAG;AAAA,SACL;AAAA,QACA,KAAK,MAAO,CAAA,QAAA;AAAA,QACZ,KAAO,EAAA;AAAA,OACR,CAAA;AAED,MAAC,YAAA,CAAa,MAA4B,EAAA,IAAA,CAAK,YAAY,CAAA;AAC3D,MAAC,YAAA,CAAa,MAA4B,EAAA,IAAA,CAAK,YAAY,CAAA;AAE3D,MAAa,YAAA,CAAA,EAAA,CAAG,OAAS,EAAA,CAAC,IAAS,KAAA;AACjC,QAAA,IAAI,SAAS,CAAG,EAAA;AACd,UAAA,OAAA,CAAQ,eAAiB,EAAA,GAAA;AAAA,YACvB,UAAW,CAAA,SAAA;AAAA,YACX,WAAA,CAAY,KAAQ,GAAA;AAAA,WACtB;AAAA;AAEF,QAAA,OAAA,EAAS,YAAY,cAAgB,EAAA;AAAA,UACnC,SAAS,MAAO,CAAA,YAAA;AAAA,UAChB,MAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,IAAI,SAAS,CAAG,EAAA;AACd,UAAA,MAAA,CAAO,IAAI,CAAA;AACX,UAAA;AAAA;AAEF,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,OACb,CAAA;AAAA,KACF,CAAA;AAAA,WACM,KAAO,EAAA;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,CAAiC,8BAAA,EAAA,KAAK,CAAE,CAAA,CAAA;AAAA;AAE5D","file":"build-project.js","sourcesContent":["import {spawn} from 'child_process';\nimport {PassThrough, Readable} from 'stream';\n\nimport {getBugsnag} from '../utils/bugsnag.js';\nimport {MetricsExporter, MetricName} from '../utils/metrics-exporter.js';\n\nimport {DeploymentConfig, DeploymentHooks} from './types.js';\n\ninterface BuildProjectOptions {\n config: DeploymentConfig;\n assetPath?: string;\n hooks?: DeploymentHooks;\n metricsExporter?: MetricsExporter;\n}\n\nexport async function buildProject(options: BuildProjectOptions) {\n const {config, assetPath, hooks} = options;\n const Bugsnag = getBugsnag();\n\n if (hooks?.buildFunction) {\n const startTime = performance.now();\n return hooks\n .buildFunction(assetPath)\n .then(() => {\n options.metricsExporter?.add(\n MetricName.BuildTime,\n performance.now() - startTime,\n );\n })\n .catch((error) => {\n throw new Error(`Build function failed with error: ${error}`);\n });\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 startTime = performance.now();\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 if (code === 0) {\n options.metricsExporter?.add(\n MetricName.BuildTime,\n performance.now() - startTime,\n );\n }\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"]}
1
+ {"version":3,"sources":["../../src/deploy/build-project.ts"],"names":[],"mappings":";;;;;;AAiBA,eAAsB,aAAa,OAA8B,EAAA;AAC/D,EAAA,MAAM,EAAC,MAAA,EAAQ,SAAW,EAAA,KAAA,EAAS,GAAA,OAAA;AACnC,EAAA,MAAM,UAAU,UAAW,EAAA;AAE3B,EAAA,IAAI,OAAO,aAAe,EAAA;AACxB,IAAM,MAAA,SAAA,GAAY,YAAY,GAAI,EAAA;AAClC,IAAA,OAAO,KACJ,CAAA,aAAA,CAAc,SAAS,CAAA,CACvB,KAAK,MAAM;AACV,MAAA,OAAA,CAAQ,eAAiB,EAAA,GAAA;AAAA,QACvB,UAAW,CAAA,SAAA;AAAA,QACX,WAAA,CAAY,KAAQ,GAAA;AAAA,OACtB;AAAA,KACD,CAAA,CACA,KAAM,CAAA,CAAC,KAAU,KAAA;AAChB,MAAA,MAAM,IAAI,UAAA,CAAW,CAAqC,kCAAA,EAAA,KAAK,CAAE,CAAA,CAAA;AAAA,KAClE,CAAA;AAAA;AAGL,EAAA,MAAM,uBAAuB,SACzB,GAAA,EAAC,uBAAyB,EAAA,SAAA,KAC1B,EAAC;AACL,EAAI,IAAA;AACF,IAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACrC,MAAA,IAAI,MAAS,GAAA,EAAA;AACb,MAAM,MAAA,YAAA,GAAe,IAAI,WAAY,EAAA;AAErC,MAAa,YAAA,CAAA,EAAA,CAAG,MAAQ,EAAA,CAAC,KAAU,KAAA;AACjC,QAAU,MAAA,IAAA,KAAA;AACV,QAAQ,OAAA,CAAA,MAAA,CAAO,MAAM,KAAK,CAAA;AAAA,OAC3B,CAAA;AAED,MAAM,MAAA,SAAA,GAAY,YAAY,GAAI,EAAA;AAClC,MAAA,MAAM,YAAe,GAAA,KAAA,CAAM,MAAO,CAAA,YAAA,EAAe,EAAI,EAAA;AAAA,QACnD,KAAO,EAAA,CAAC,SAAW,EAAA,MAAA,EAAQ,MAAM,CAAA;AAAA,QACjC,GAAK,EAAA;AAAA;AAAA,UAEH,GAAG,OAAQ,CAAA,GAAA;AAAA,UACX,GAAG;AAAA,SACL;AAAA,QACA,KAAK,MAAO,CAAA,QAAA;AAAA,QACZ,KAAO,EAAA;AAAA,OACR,CAAA;AAED,MAAC,YAAA,CAAa,MAA4B,EAAA,IAAA,CAAK,YAAY,CAAA;AAC3D,MAAC,YAAA,CAAa,MAA4B,EAAA,IAAA,CAAK,YAAY,CAAA;AAE3D,MAAa,YAAA,CAAA,EAAA,CAAG,OAAS,EAAA,CAAC,IAAS,KAAA;AACjC,QAAA,IAAI,SAAS,CAAG,EAAA;AACd,UAAA,OAAA,CAAQ,eAAiB,EAAA,GAAA;AAAA,YACvB,UAAW,CAAA,SAAA;AAAA,YACX,WAAA,CAAY,KAAQ,GAAA;AAAA,WACtB;AAAA;AAEF,QAAA,OAAA,EAAS,YAAY,cAAgB,EAAA;AAAA,UACnC,SAAS,MAAO,CAAA,YAAA;AAAA,UAChB,MAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,IAAI,SAAS,CAAG,EAAA;AACd,UAAA,MAAA,CAAO,IAAI,CAAA;AACX,UAAA;AAAA;AAEF,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,OACb,CAAA;AAAA,KACF,CAAA;AAAA,WACM,KAAO,EAAA;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,CAAiC,8BAAA,EAAA,KAAK,CAAE,CAAA,CAAA;AAAA;AAE5D","file":"build-project.js","sourcesContent":["import {spawn} from 'child_process';\nimport {PassThrough, Readable} from 'stream';\n\nimport {AbortError} from '@shopify/cli-kit/node/error';\n\nimport {getBugsnag} from '../utils/bugsnag.js';\nimport {MetricsExporter, MetricName} from '../utils/metrics-exporter.js';\n\nimport {DeploymentConfig, DeploymentHooks} from './types.js';\n\ninterface BuildProjectOptions {\n config: DeploymentConfig;\n assetPath?: string;\n hooks?: DeploymentHooks;\n metricsExporter?: MetricsExporter;\n}\n\nexport async function buildProject(options: BuildProjectOptions) {\n const {config, assetPath, hooks} = options;\n const Bugsnag = getBugsnag();\n\n if (hooks?.buildFunction) {\n const startTime = performance.now();\n return hooks\n .buildFunction(assetPath)\n .then(() => {\n options.metricsExporter?.add(\n MetricName.BuildTime,\n performance.now() - startTime,\n );\n })\n .catch((error) => {\n throw new AbortError(`Build function failed with error: ${error}`);\n });\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 startTime = performance.now();\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 if (code === 0) {\n options.metricsExporter?.add(\n MetricName.BuildTime,\n performance.now() - startTime,\n );\n }\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"]}
@@ -186,5 +186,5 @@
186
186
  ]
187
187
  }
188
188
  },
189
- "version": "5.0.1-unstable.202507092257.0"
189
+ "version": "6.0.1-unstable.202507281554.0"
190
190
  }
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "@shopify:registry": "https://registry.npmjs.org"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "5.0.1-unstable.202507092257.0",
8
+ "version": "6.0.1-unstable.202507281554.0",
9
9
  "type": "module",
10
10
  "scripts": {
11
11
  "build": "tsup --sourcemap --clean --config ./tsup.config.ts && oclif manifest",
@@ -49,11 +49,11 @@
49
49
  "devDependencies": {
50
50
  "@bugsnag/source-maps": "^2.3.3",
51
51
  "@changesets/cli": "^2.29.5",
52
- "@shopify/eslint-plugin": "^48.0.2",
52
+ "@shopify/eslint-plugin": "^50.0.0",
53
53
  "@shopify/prettier-config": "^1.1.4",
54
54
  "@types/async": "^3.2.24",
55
55
  "@types/node": "^22.15.21",
56
- "eslint": "^8.57.1",
56
+ "eslint": "^9.30.1",
57
57
  "eslint-plugin-node": "^11.1.0",
58
58
  "eslint-plugin-prettier": "^5.5.1",
59
59
  "node-fetch": "^3.3.2",