@shopify/cli-hydrogen 7.1.0 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/commands/hydrogen/build-vite.js +131 -0
  2. package/dist/commands/hydrogen/build.js +6 -15
  3. package/dist/commands/hydrogen/check.js +1 -1
  4. package/dist/commands/hydrogen/codegen.js +3 -3
  5. package/dist/commands/hydrogen/debug/cpu.js +1 -1
  6. package/dist/commands/hydrogen/deploy.js +46 -31
  7. package/dist/commands/hydrogen/deploy.test.js +35 -49
  8. package/dist/commands/hydrogen/dev-vite.js +159 -0
  9. package/dist/commands/hydrogen/dev.js +11 -14
  10. package/dist/commands/hydrogen/env/list.js +1 -1
  11. package/dist/commands/hydrogen/env/pull.js +3 -3
  12. package/dist/commands/hydrogen/env/pull.test.js +2 -0
  13. package/dist/commands/hydrogen/env/push__unstable.js +190 -0
  14. package/dist/commands/hydrogen/env/push__unstable.test.js +383 -0
  15. package/dist/commands/hydrogen/generate/route.js +2 -2
  16. package/dist/commands/hydrogen/init.d.ts +69 -0
  17. package/dist/commands/hydrogen/init.js +5 -5
  18. package/dist/commands/hydrogen/init.test.js +2 -2
  19. package/dist/commands/hydrogen/link.js +2 -2
  20. package/dist/commands/hydrogen/list.js +1 -1
  21. package/dist/commands/hydrogen/login.js +2 -9
  22. package/dist/commands/hydrogen/logout.js +1 -1
  23. package/dist/commands/hydrogen/preview.js +15 -7
  24. package/dist/commands/hydrogen/setup/css.js +3 -3
  25. package/dist/commands/hydrogen/setup/markets.js +4 -4
  26. package/dist/commands/hydrogen/setup/vite.js +209 -0
  27. package/dist/commands/hydrogen/setup.js +8 -6
  28. package/dist/commands/hydrogen/unlink.js +1 -1
  29. package/dist/commands/hydrogen/upgrade.js +5 -3
  30. package/dist/generator-templates/assets/vite/package.json +15 -0
  31. package/dist/generator-templates/assets/vite/vite.config.js +13 -0
  32. package/dist/generator-templates/starter/CHANGELOG.md +34 -0
  33. package/dist/generator-templates/starter/app/root.tsx +1 -2
  34. package/dist/generator-templates/starter/package.json +9 -8
  35. package/dist/generator-templates/starter/public/.gitkeep +0 -0
  36. package/dist/lib/build.js +2 -1
  37. package/dist/lib/codegen.js +8 -3
  38. package/dist/lib/environment-variables.test.js +4 -2
  39. package/dist/lib/flags.js +149 -95
  40. package/dist/lib/graphql/admin/pull-variables.js +1 -0
  41. package/dist/lib/graphql/admin/pull-variables.test.js +7 -1
  42. package/dist/lib/graphql/admin/push-variables.js +35 -0
  43. package/dist/lib/log.js +1 -0
  44. package/dist/lib/mini-oxygen/common.js +2 -1
  45. package/dist/lib/mini-oxygen/node.js +2 -2
  46. package/dist/lib/mini-oxygen/workerd-inspector.js +1 -1
  47. package/dist/lib/mini-oxygen/workerd.js +29 -17
  48. package/dist/lib/onboarding/common.js +0 -3
  49. package/dist/lib/onboarding/local.js +4 -1
  50. package/dist/lib/onboarding/remote.js +16 -11
  51. package/dist/lib/remix-config.js +1 -1
  52. package/dist/lib/request-events.js +3 -3
  53. package/dist/lib/setups/css/assets.js +7 -2
  54. package/dist/lib/template-diff.js +26 -11
  55. package/dist/lib/template-downloader.js +11 -2
  56. package/dist/lib/vite/hydrogen-middleware.js +82 -0
  57. package/dist/lib/vite/mini-oxygen.js +152 -0
  58. package/dist/lib/vite/plugins.d.ts +27 -0
  59. package/dist/lib/vite/plugins.js +139 -0
  60. package/dist/lib/vite/shared.js +10 -0
  61. package/dist/lib/vite/utils.js +55 -0
  62. package/dist/lib/vite/worker-entry.js +1518 -0
  63. package/dist/lib/vite-config.js +45 -0
  64. package/dist/virtual-routes/lib/useDebugNetworkServer.jsx +4 -2
  65. package/dist/virtual-routes/routes/index.jsx +5 -5
  66. package/dist/virtual-routes/routes/subrequest-profiler.jsx +1 -1
  67. package/dist/virtual-routes/virtual-root.jsx +1 -1
  68. package/oclif.manifest.json +1127 -494
  69. package/package.json +36 -11
  70. /package/dist/generator-templates/starter/{public → app/assets}/favicon.svg +0 -0
@@ -0,0 +1,131 @@
1
+ import Command from '@shopify/cli-kit/node/base-command';
2
+ import { outputWarn } from '@shopify/cli-kit/node/output';
3
+ import { removeFile, fileSize } from '@shopify/cli-kit/node/fs';
4
+ import { resolvePath, joinPath } from '@shopify/cli-kit/node/path';
5
+ import { getPackageManager } from '@shopify/cli-kit/node/node-package-manager';
6
+ import { commonFlags, flagsToCamelObject } from '../../lib/flags.js';
7
+ import { checkLockfileStatus } from '../../lib/check-lockfile.js';
8
+ import { findMissingRoutes } from '../../lib/missing-routes.js';
9
+ import { codegen } from '../../lib/codegen.js';
10
+ import { isCI } from '../../lib/is-ci.js';
11
+ import { prepareDiffDirectory, copyDiffBuild } from '../../lib/template-diff.js';
12
+ import { getViteConfig } from '../../lib/vite-config.js';
13
+
14
+ const WORKER_BUILD_SIZE_LIMIT = 5;
15
+ class Build extends Command {
16
+ static description = "Builds a Hydrogen storefront for production.";
17
+ static flags = {
18
+ ...commonFlags.path,
19
+ ...commonFlags.entry,
20
+ ...commonFlags.sourcemap,
21
+ ...commonFlags.lockfileCheck,
22
+ ...commonFlags.disableRouteWarning,
23
+ ...commonFlags.codegen,
24
+ ...commonFlags.diff
25
+ };
26
+ async run() {
27
+ const { flags } = await this.parse(Build);
28
+ const originalDirectory = flags.path ? resolvePath(flags.path) : process.cwd();
29
+ let directory = originalDirectory;
30
+ if (flags.diff) {
31
+ directory = await prepareDiffDirectory(originalDirectory, false);
32
+ }
33
+ await runViteBuild({
34
+ ...flagsToCamelObject(flags),
35
+ useCodegen: flags.codegen,
36
+ directory
37
+ });
38
+ if (flags.diff) {
39
+ await copyDiffBuild(directory, originalDirectory);
40
+ }
41
+ }
42
+ }
43
+ async function runViteBuild({
44
+ entry: ssrEntry,
45
+ directory,
46
+ useCodegen = false,
47
+ codegenConfigPath,
48
+ sourcemap = false,
49
+ disableRouteWarning = false,
50
+ lockfileCheck = true,
51
+ assetPath = "/"
52
+ }) {
53
+ if (!process.env.NODE_ENV) {
54
+ process.env.NODE_ENV = "production";
55
+ }
56
+ const root = directory ?? process.cwd();
57
+ if (lockfileCheck) {
58
+ await checkLockfileStatus(root, isCI());
59
+ }
60
+ const {
61
+ userViteConfig,
62
+ remixConfig,
63
+ clientOutDir,
64
+ serverOutDir,
65
+ serverOutFile
66
+ } = await getViteConfig(root);
67
+ const serverMinify = userViteConfig.build?.minify ?? true;
68
+ const commonConfig = {
69
+ root,
70
+ mode: process.env.NODE_ENV,
71
+ base: assetPath
72
+ };
73
+ const vite = await import('vite');
74
+ await vite.build({
75
+ ...commonConfig,
76
+ build: {
77
+ emptyOutDir: true,
78
+ copyPublicDir: true,
79
+ // Disable client sourcemaps in production
80
+ sourcemap: process.env.NODE_ENV !== "production" && sourcemap
81
+ }
82
+ });
83
+ console.log("");
84
+ await vite.build({
85
+ ...commonConfig,
86
+ build: {
87
+ sourcemap,
88
+ ssr: ssrEntry ?? true,
89
+ emptyOutDir: false,
90
+ copyPublicDir: false,
91
+ minify: serverMinify
92
+ }
93
+ });
94
+ await Promise.all([
95
+ removeFile(joinPath(clientOutDir, ".vite")),
96
+ removeFile(joinPath(serverOutDir, ".vite")),
97
+ removeFile(joinPath(serverOutDir, "assets"))
98
+ ]);
99
+ if (useCodegen) {
100
+ await codegen({
101
+ rootDirectory: root,
102
+ appDirectory: remixConfig.appDirectory,
103
+ configFilePath: codegenConfigPath
104
+ });
105
+ }
106
+ if (process.env.NODE_ENV !== "development") {
107
+ const sizeMB = await fileSize(serverOutFile) / (1024 * 1024);
108
+ if (sizeMB >= WORKER_BUILD_SIZE_LIMIT) {
109
+ outputWarn(
110
+ `\u{1F6A8} Smaller worker bundles are faster to deploy and run.${serverMinify ? "" : "\n Minify your bundle by adding `build.minify: true` to vite.config.js."}
111
+ Learn more about optimizing your worker bundle file: https://h2o.fyi/debugging/bundle-size
112
+ `
113
+ );
114
+ }
115
+ }
116
+ if (!disableRouteWarning) {
117
+ const missingRoutes = findMissingRoutes(remixConfig);
118
+ if (missingRoutes.length) {
119
+ const packageManager = await getPackageManager(root);
120
+ const exec = packageManager === "npm" ? "npx" : packageManager;
121
+ outputWarn(
122
+ `Heads up: Shopify stores have a number of standard routes that aren\u2019t set up yet.
123
+ Some functionality and backlinks might not work as expected until these are created or redirects are set up.
124
+ This build is missing ${missingRoutes.length} route${missingRoutes.length > 1 ? "s" : ""}. For more details, run \`${exec} shopify hydrogen check routes\`.
125
+ `
126
+ );
127
+ }
128
+ }
129
+ }
130
+
131
+ export { Build as default, runViteBuild };
@@ -20,26 +20,17 @@ const WORKER_BUILD_SIZE_LIMIT = 5;
20
20
  class Build extends Command {
21
21
  static description = "Builds a Hydrogen storefront for production.";
22
22
  static flags = {
23
- path: commonFlags.path,
24
- sourcemap: Flags.boolean({
25
- description: "Controls whether sourcemaps are generated. Default to true, use `--no-sourcemaps` to disable.",
26
- env: "SHOPIFY_HYDROGEN_FLAG_SOURCEMAP",
27
- allowNo: true,
28
- default: true
29
- }),
23
+ ...commonFlags.path,
24
+ ...commonFlags.sourcemap,
30
25
  "bundle-stats": Flags.boolean({
31
26
  description: "Show a bundle size summary after building. Defaults to true, use `--no-bundle-stats` to disable.",
32
27
  default: true,
33
28
  allowNo: true
34
29
  }),
35
- "lockfile-check": commonFlags.lockfileCheck,
36
- "disable-route-warning": Flags.boolean({
37
- description: "Disable warning about missing standard routes.",
38
- env: "SHOPIFY_HYDROGEN_FLAG_DISABLE_ROUTE_WARNING"
39
- }),
40
- codegen: commonFlags.codegen,
41
- "codegen-config-path": commonFlags.codegenConfigPath,
42
- diff: commonFlags.diff
30
+ ...commonFlags.lockfileCheck,
31
+ ...commonFlags.disableRouteWarning,
32
+ ...commonFlags.codegen,
33
+ ...commonFlags.diff
43
34
  };
44
35
  async run() {
45
36
  const { flags } = await this.parse(Build);
@@ -8,7 +8,7 @@ import { Args } from '@oclif/core';
8
8
  class GenerateRoute extends Command {
9
9
  static description = "Returns diagnostic information about a Hydrogen storefront.";
10
10
  static flags = {
11
- path: commonFlags.path
11
+ ...commonFlags.path
12
12
  };
13
13
  static args = {
14
14
  resource: Args.string({
@@ -10,12 +10,12 @@ import { codegen } from '../../lib/codegen.js';
10
10
  class Codegen extends Command {
11
11
  static description = "Generate types for the Storefront API queries found in your project.";
12
12
  static flags = {
13
- path: commonFlags.path,
14
- ["codegen-config-path"]: Flags.string({
13
+ ...commonFlags.path,
14
+ "codegen-config-path": Flags.string({
15
15
  description: "Specify a path to a codegen configuration file. Defaults to `<root>/codegen.ts` if it exists.",
16
16
  required: false
17
17
  }),
18
- ["force-sfapi-version"]: Flags.string({
18
+ "force-sfapi-version": Flags.string({
19
19
  description: "Force generating Storefront API types for a specific version instead of using the one provided in Hydrogen. A token can also be provided with this format: `<version>:<token>`.",
20
20
  hidden: true
21
21
  }),
@@ -14,7 +14,7 @@ const DEFAULT_OUTPUT_PATH = "startup.cpuprofile";
14
14
  class DebugCpu extends Command {
15
15
  static description = "Builds and profiles the server startup time the app.";
16
16
  static flags = {
17
- path: commonFlags.path,
17
+ ...commonFlags.path,
18
18
  output: Flags.string({
19
19
  description: `Specify a path to generate the profile file. Defaults to "${DEFAULT_OUTPUT_PATH}".`,
20
20
  default: DEFAULT_OUTPUT_PATH,
@@ -2,17 +2,20 @@ import { Flags } from '@oclif/core';
2
2
  import Command from '@shopify/cli-kit/node/base-command';
3
3
  import colors from '@shopify/cli-kit/node/colors';
4
4
  import { outputWarn, outputInfo, outputContent } from '@shopify/cli-kit/node/output';
5
+ import { readAndParseDotEnv } from '@shopify/cli-kit/node/dot-env';
5
6
  import { AbortError } from '@shopify/cli-kit/node/error';
6
7
  import { writeFile } from '@shopify/cli-kit/node/fs';
7
8
  import { ensureIsClean, getLatestGitCommit, GitDirectoryNotCleanError } from '@shopify/cli-kit/node/git';
8
- import { resolvePath } from '@shopify/cli-kit/node/path';
9
- import { renderFatalError, renderWarning, renderSelectPrompt, renderSuccess, renderTasks } from '@shopify/cli-kit/node/ui';
9
+ import { resolvePath, relativePath } from '@shopify/cli-kit/node/path';
10
+ import { renderWarning, renderSelectPrompt, renderSuccess, renderTasks } from '@shopify/cli-kit/node/ui';
10
11
  import { ciPlatform } from '@shopify/cli-kit/node/context/local';
11
12
  import { parseToken, createDeploy } from '@shopify/oxygen-cli/deploy';
12
- import { loadEnvironmentVariableFile } from '@shopify/oxygen-cli/utils';
13
13
  import { commonFlags, flagsToCamelObject } from '../../lib/flags.js';
14
14
  import { getOxygenDeploymentData } from '../../lib/get-oxygen-deployment-data.js';
15
15
  import { runBuild } from './build.js';
16
+ import { runViteBuild } from './build-vite.js';
17
+ import { getViteConfig } from '../../lib/vite-config.js';
18
+ import { prepareDiffDirectory } from '../../lib/template-diff.js';
16
19
 
17
20
  const DEPLOY_OUTPUT_FILE_HANDLE = "h2_deploy_log.json";
18
21
  const deploymentLogger = (message, level = "info") => {
@@ -57,9 +60,9 @@ class Deploy extends Command {
57
60
  description: "Specify a build command to run before deploying. If not specified, `shopify hydrogen build` will be used.",
58
61
  required: false
59
62
  }),
60
- "lockfile-check": commonFlags.lockfileCheck,
61
- path: commonFlags.path,
62
- shop: commonFlags.shop,
63
+ ...commonFlags.lockfileCheck,
64
+ ...commonFlags.path,
65
+ ...commonFlags.shop,
63
66
  "json-output": Flags.boolean({
64
67
  allowNo: true,
65
68
  description: "Create a JSON file containing the deployment details in CI environments. Defaults to true, use `--no-json-output` to disable.",
@@ -91,17 +94,20 @@ class Deploy extends Command {
91
94
  required: false,
92
95
  env: "SHOPIFY_HYDROGEN_FLAG_METADATA_VERSION",
93
96
  hidden: true
94
- })
97
+ }),
98
+ ...commonFlags.diff
95
99
  };
96
100
  async run() {
97
101
  const { flags } = await this.parse(Deploy);
98
102
  const deploymentOptions = this.flagsToOxygenDeploymentOptions(flags);
99
- await oxygenDeploy(deploymentOptions).catch((error) => {
100
- renderFatalError(error);
101
- process.exit(1);
102
- }).finally(() => {
103
- process.exit(0);
104
- });
103
+ if (flags.diff) {
104
+ deploymentOptions.path = await prepareDiffDirectory(
105
+ deploymentOptions.path,
106
+ false
107
+ );
108
+ }
109
+ await runDeploy(deploymentOptions);
110
+ process.exit(0);
105
111
  }
106
112
  flagsToOxygenDeploymentOptions(flags) {
107
113
  const camelFlags = flagsToCamelObject(flags);
@@ -132,7 +138,7 @@ function createUnexpectedAbortError(message) {
132
138
  ]
133
139
  );
134
140
  }
135
- async function oxygenDeploy(options) {
141
+ async function runDeploy(options) {
136
142
  const {
137
143
  authBypassToken: generateAuthBypassToken,
138
144
  buildCommand,
@@ -143,7 +149,7 @@ async function oxygenDeploy(options) {
143
149
  noVerify,
144
150
  lockfileCheck,
145
151
  jsonOutput,
146
- path,
152
+ path: root,
147
153
  shop,
148
154
  metadataUrl,
149
155
  metadataUser,
@@ -152,7 +158,7 @@ async function oxygenDeploy(options) {
152
158
  let { metadataDescription } = options;
153
159
  let isCleanGit = true;
154
160
  try {
155
- await ensureIsClean(path);
161
+ await ensureIsClean(root);
156
162
  } catch (error) {
157
163
  if (error instanceof GitDirectoryNotCleanError) {
158
164
  isCleanGit = false;
@@ -175,7 +181,7 @@ async function oxygenDeploy(options) {
175
181
  let deploymentEnvironmentTag = void 0;
176
182
  let gitCommit;
177
183
  try {
178
- gitCommit = await getLatestGitCommit(path);
184
+ gitCommit = await getLatestGitCommit(root);
179
185
  branch = (/HEAD -> ([^,]*)/.exec(gitCommit.refs) || [])[1];
180
186
  commitHash = gitCommit.hash;
181
187
  } catch (error) {
@@ -197,17 +203,18 @@ async function oxygenDeploy(options) {
197
203
  }
198
204
  let overriddenEnvironmentVariables;
199
205
  if (environmentFile) {
200
- try {
201
- overriddenEnvironmentVariables = loadEnvironmentVariableFile(environmentFile);
202
- } catch (error) {
203
- throw new AbortError(
204
- `Could not load environment file at ${environmentFile}`
205
- );
206
- }
206
+ const { variables } = await readAndParseDotEnv(environmentFile);
207
+ overriddenEnvironmentVariables = Object.entries(variables).map(
208
+ ([key, value]) => ({
209
+ isSecret: true,
210
+ key,
211
+ value
212
+ })
213
+ );
207
214
  }
208
215
  if (!isCI) {
209
216
  deploymentData = await getOxygenDeploymentData({
210
- root: path,
217
+ root,
211
218
  flagShop: shop
212
219
  });
213
220
  if (!deploymentData) {
@@ -261,8 +268,15 @@ async function oxygenDeploy(options) {
261
268
  deploymentEnvironmentTag = void 0;
262
269
  isPreview = true;
263
270
  }
271
+ let assetsDir = "dist/client";
272
+ let workerDir = "dist/worker";
273
+ const maybeVite = await getViteConfig(root).catch(() => null);
274
+ if (maybeVite) {
275
+ assetsDir = relativePath(root, maybeVite.clientOutDir);
276
+ workerDir = relativePath(root, maybeVite.serverOutDir);
277
+ }
264
278
  const config = {
265
- assetsDir: "dist/client",
279
+ assetsDir,
266
280
  bugsnag: true,
267
281
  deploymentUrl,
268
282
  defaultEnvironment: defaultEnvironment || isPreview,
@@ -277,10 +291,10 @@ async function oxygenDeploy(options) {
277
291
  ...metadataVersion ? { version: metadataVersion } : {}
278
292
  },
279
293
  skipVerification: noVerify,
280
- rootPath: path,
294
+ rootPath: root,
281
295
  skipBuild: false,
282
296
  workerOnly: false,
283
- workerDir: "dist/worker",
297
+ workerDir,
284
298
  overriddenEnvironmentVariables
285
299
  };
286
300
  let resolveUpload;
@@ -338,8 +352,9 @@ async function oxygenDeploy(options) {
338
352
  outputInfo(
339
353
  outputContent`${colors.whiteBright("Building project...")}`.value
340
354
  );
341
- await runBuild({
342
- directory: path,
355
+ const build = maybeVite ? runViteBuild : runBuild;
356
+ await build({
357
+ directory: root,
343
358
  assetPath,
344
359
  lockfileCheck,
345
360
  sourcemap: true,
@@ -411,4 +426,4 @@ async function oxygenDeploy(options) {
411
426
  return deployPromise;
412
427
  }
413
428
 
414
- export { Deploy as default, deploymentLogger, oxygenDeploy };
429
+ export { Deploy as default, deploymentLogger, runDeploy };
@@ -1,19 +1,19 @@
1
1
  import { vi, describe, expect, beforeEach, afterEach, it } from 'vitest';
2
2
  import { login } from '../../lib/auth.js';
3
3
  import { getStorefronts } from '../../lib/graphql/admin/link-storefront.js';
4
+ import { readAndParseDotEnv } from '@shopify/cli-kit/node/dot-env';
4
5
  import { AbortError } from '@shopify/cli-kit/node/error';
5
6
  import { writeFile } from '@shopify/cli-kit/node/fs';
6
7
  import { renderSelectPrompt, renderSuccess, renderWarning, renderFatalError } from '@shopify/cli-kit/node/ui';
7
8
  import { ensureIsClean, GitDirectoryNotCleanError, getLatestGitCommit } from '@shopify/cli-kit/node/git';
8
- import { oxygenDeploy, deploymentLogger } from './deploy.js';
9
+ import { runDeploy, deploymentLogger } from './deploy.js';
9
10
  import { getOxygenDeploymentData } from '../../lib/get-oxygen-deployment-data.js';
10
11
  import { createDeploy, parseToken } from '@shopify/oxygen-cli/deploy';
11
- import { loadEnvironmentVariableFile } from '@shopify/oxygen-cli/utils';
12
12
  import { ciPlatform } from '@shopify/cli-kit/node/context/local';
13
13
  import { runBuild } from './build.js';
14
14
 
15
15
  vi.mock("@shopify/oxygen-cli/deploy");
16
- vi.mock("@shopify/oxygen-cli/utils");
16
+ vi.mock("@shopify/cli-kit/node/dot-env");
17
17
  vi.mock("@shopify/cli-kit/node/fs");
18
18
  vi.mock("@shopify/cli-kit/node/context/local");
19
19
  vi.mock("../../lib/get-oxygen-deployment-data.js");
@@ -151,7 +151,7 @@ describe("deploy", () => {
151
151
  process.exit = originalExit;
152
152
  });
153
153
  it("calls getOxygenDeploymentData with the correct parameters", async () => {
154
- await oxygenDeploy(deployParams);
154
+ await runDeploy(deployParams);
155
155
  expect(getOxygenDeploymentData).toHaveBeenCalledWith({
156
156
  root: "./",
157
157
  flagShop: "snowdevil.myshopify.com"
@@ -159,7 +159,7 @@ describe("deploy", () => {
159
159
  expect(getOxygenDeploymentData).toHaveBeenCalledTimes(1);
160
160
  });
161
161
  it("calls createDeploy with the correct parameters", async () => {
162
- await oxygenDeploy(deployParams);
162
+ await runDeploy(deployParams);
163
163
  expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
164
164
  config: expectedConfig,
165
165
  hooks: expectedHooks,
@@ -168,50 +168,36 @@ describe("deploy", () => {
168
168
  expect(vi.mocked(renderSuccess)).toHaveBeenCalled;
169
169
  });
170
170
  it("calls createDeploy with overridden variables in environment file", async () => {
171
- const overriddenEnvironmentVariables = [
172
- {
173
- key: "fake-key",
174
- value: "fake-value",
175
- isSecret: true
171
+ vi.mocked(readAndParseDotEnv).mockResolvedValue({
172
+ path: "fake-env-file",
173
+ variables: {
174
+ "fake-key": "fake-value"
176
175
  }
177
- ];
178
- vi.mocked(loadEnvironmentVariableFile).mockReturnValue(
179
- overriddenEnvironmentVariables
180
- );
181
- await oxygenDeploy({
176
+ });
177
+ await runDeploy({
182
178
  ...deployParams,
183
179
  environmentFile: "fake-env-file"
184
180
  });
185
181
  expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
186
182
  config: {
187
183
  ...expectedConfig,
188
- overriddenEnvironmentVariables
184
+ overriddenEnvironmentVariables: [
185
+ {
186
+ key: "fake-key",
187
+ value: "fake-value",
188
+ isSecret: true
189
+ }
190
+ ]
189
191
  },
190
192
  hooks: expectedHooks,
191
193
  logger: deploymentLogger
192
194
  });
193
195
  });
194
- it("errors when supplied environment file does not exist", async () => {
195
- vi.mocked(loadEnvironmentVariableFile).mockImplementation(
196
- (_path) => {
197
- throw new AbortError("File not found");
198
- }
199
- );
200
- try {
201
- await oxygenDeploy({
202
- ...deployParams,
203
- environmentFile: "fake-env-file"
204
- });
205
- expect(true).toBe(false);
206
- } catch (err) {
207
- expect(err).toBeInstanceOf(AbortError);
208
- }
209
- });
210
196
  it("errors when there are uncommited changes", async () => {
211
197
  vi.mocked(ensureIsClean).mockRejectedValue(
212
198
  new GitDirectoryNotCleanError("Uncommitted changes")
213
199
  );
214
- await expect(oxygenDeploy(deployParams)).rejects.toThrowError(
200
+ await expect(runDeploy(deployParams)).rejects.toThrowError(
215
201
  "Uncommitted changes detected"
216
202
  );
217
203
  expect(vi.mocked(createDeploy)).not.toHaveBeenCalled;
@@ -229,7 +215,7 @@ describe("deploy", () => {
229
215
  body: "test body",
230
216
  refs: "HEAD -> main"
231
217
  });
232
- await oxygenDeploy({
218
+ await runDeploy({
233
219
  ...deployParams,
234
220
  force: true
235
221
  });
@@ -263,7 +249,7 @@ describe("deploy", () => {
263
249
  body: "test body",
264
250
  refs: "HEAD -> main"
265
251
  });
266
- await oxygenDeploy({
252
+ await runDeploy({
267
253
  ...deployParams,
268
254
  force: true,
269
255
  metadataDescription: "cool new stuff"
@@ -292,7 +278,7 @@ describe("deploy", () => {
292
278
  body: "test body",
293
279
  refs: "HEAD -> main"
294
280
  });
295
- await oxygenDeploy(deployParams);
281
+ await runDeploy(deployParams);
296
282
  expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
297
283
  config: { ...expectedConfig, environmentTag: "main" },
298
284
  hooks: expectedHooks,
@@ -308,7 +294,7 @@ describe("deploy", () => {
308
294
  { name: "Preview", branch: null, type: "PREVIEW" }
309
295
  ]
310
296
  });
311
- await oxygenDeploy(deployParams);
297
+ await runDeploy(deployParams);
312
298
  expect(vi.mocked(renderSelectPrompt)).toHaveBeenCalledWith({
313
299
  message: "Select an environment to deploy to",
314
300
  choices: [
@@ -338,7 +324,7 @@ describe("deploy", () => {
338
324
  vi.mocked(renderSelectPrompt).mockResolvedValue(
339
325
  "shopify-preview-environment."
340
326
  );
341
- await oxygenDeploy(deployParams);
327
+ await runDeploy(deployParams);
342
328
  expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
343
329
  config: {
344
330
  ...expectedConfig,
@@ -361,7 +347,7 @@ describe("deploy", () => {
361
347
  resolve({ url: "https://a-lovely-deployment.com" });
362
348
  });
363
349
  });
364
- await oxygenDeploy(params);
350
+ await runDeploy(params);
365
351
  expect(vi.mocked(runBuild)).toHaveBeenCalledWith({
366
352
  assetPath: "some-cool-asset-path",
367
353
  directory: params.path,
@@ -376,7 +362,7 @@ describe("deploy", () => {
376
362
  buildCommand: "hocus pocus"
377
363
  };
378
364
  const { buildFunction: _, ...hooks } = expectedHooks;
379
- await oxygenDeploy(params);
365
+ await runDeploy(params);
380
366
  expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
381
367
  config: {
382
368
  ...expectedConfig,
@@ -398,7 +384,7 @@ describe("deploy", () => {
398
384
  metadataDescription: "cool new stuff",
399
385
  generateAuthBypassToken: true
400
386
  };
401
- await oxygenDeploy(ciDeployParams);
387
+ await runDeploy(ciDeployParams);
402
388
  expect(vi.mocked(writeFile)).toHaveBeenCalledWith(
403
389
  "h2_deploy_log.json",
404
390
  JSON.stringify({
@@ -408,7 +394,7 @@ describe("deploy", () => {
408
394
  );
409
395
  vi.mocked(writeFile).mockClear();
410
396
  ciDeployParams.jsonOutput = false;
411
- await oxygenDeploy(ciDeployParams);
397
+ await runDeploy(ciDeployParams);
412
398
  expect(vi.mocked(writeFile)).not.toHaveBeenCalled();
413
399
  });
414
400
  it("handles error during uploadFiles", async () => {
@@ -423,7 +409,7 @@ describe("deploy", () => {
423
409
  });
424
410
  });
425
411
  try {
426
- await oxygenDeploy(deployParams);
412
+ await runDeploy(deployParams);
427
413
  expect(true).toBe(false);
428
414
  } catch (err) {
429
415
  if (err instanceof AbortError) {
@@ -449,7 +435,7 @@ describe("deploy", () => {
449
435
  });
450
436
  });
451
437
  try {
452
- await oxygenDeploy(deployParams);
438
+ await runDeploy(deployParams);
453
439
  expect(true).toBe(false);
454
440
  } catch (err) {
455
441
  if (err instanceof AbortError) {
@@ -478,7 +464,7 @@ describe("deploy", () => {
478
464
  });
479
465
  });
480
466
  try {
481
- await oxygenDeploy(deployParams);
467
+ await runDeploy(deployParams);
482
468
  expect(true).toBe(false);
483
469
  } catch (err) {
484
470
  if (err instanceof AbortError) {
@@ -494,7 +480,7 @@ describe("deploy", () => {
494
480
  vi.mocked(createDeploy).mockResolvedValue({
495
481
  url: "https://a-lovely-deployment.com"
496
482
  });
497
- await oxygenDeploy(deployParams);
483
+ await runDeploy(deployParams);
498
484
  expect(vi.mocked(renderSuccess)).toHaveBeenCalledWith({
499
485
  body: ["Successfully deployed to Oxygen"],
500
486
  nextSteps: [
@@ -511,7 +497,7 @@ describe("deploy", () => {
511
497
  url: "https://a-lovely-deployment.com",
512
498
  authBypassToken: "some-token"
513
499
  });
514
- await oxygenDeploy(deployParams);
500
+ await runDeploy(deployParams);
515
501
  expect(vi.mocked(renderSuccess)).toHaveBeenCalledWith({
516
502
  body: ["Successfully deployed to Oxygen"],
517
503
  nextSteps: [
@@ -535,7 +521,7 @@ describe("deploy", () => {
535
521
  name: "github",
536
522
  metadata: {}
537
523
  });
538
- await oxygenDeploy({ ...deployParams, token: "fake-token" });
524
+ await runDeploy({ ...deployParams, token: "fake-token" });
539
525
  expect(vi.mocked(renderSuccess)).toHaveBeenCalledWith({
540
526
  body: ["Successfully deployed to Oxygen"],
541
527
  nextSteps: [
@@ -552,7 +538,7 @@ describe("deploy", () => {
552
538
  name: "github",
553
539
  metadata: {}
554
540
  });
555
- await oxygenDeploy({
541
+ await runDeploy({
556
542
  ...deployParams,
557
543
  token: "fake-token",
558
544
  jsonOutput: false