@shopify/cli-hydrogen 7.0.1 → 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 (87) hide show
  1. package/dist/commands/hydrogen/build-vite.js +131 -0
  2. package/dist/commands/hydrogen/build.js +7 -21
  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 +113 -51
  7. package/dist/commands/hydrogen/deploy.test.js +162 -19
  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 +8 -3
  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 +3 -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 +69 -0
  33. package/dist/generator-templates/starter/README.md +25 -2
  34. package/dist/generator-templates/starter/app/components/Cart.tsx +2 -2
  35. package/dist/generator-templates/starter/app/components/Layout.tsx +9 -1
  36. package/dist/generator-templates/starter/app/components/Search.tsx +44 -15
  37. package/dist/generator-templates/starter/app/lib/search.ts +29 -0
  38. package/dist/generator-templates/starter/app/root.tsx +1 -4
  39. package/dist/generator-templates/starter/app/routes/account.orders._index.tsx +2 -2
  40. package/dist/generator-templates/starter/app/routes/api.predictive-search.tsx +1 -21
  41. package/dist/generator-templates/starter/app/routes/cart.tsx +1 -5
  42. package/dist/generator-templates/starter/app/routes/search.tsx +8 -2
  43. package/dist/generator-templates/starter/app/styles/app.css +10 -15
  44. package/dist/generator-templates/starter/package.json +9 -8
  45. package/dist/generator-templates/starter/public/.gitkeep +0 -0
  46. package/dist/generator-templates/starter/remix.config.js +1 -0
  47. package/dist/generator-templates/starter/server.ts +1 -0
  48. package/dist/hooks/init.js +3 -3
  49. package/dist/lib/build.js +2 -1
  50. package/dist/lib/codegen.js +8 -3
  51. package/dist/lib/environment-variables.test.js +4 -2
  52. package/dist/lib/flags.js +149 -89
  53. package/dist/lib/graphql/admin/pull-variables.js +1 -0
  54. package/dist/lib/graphql/admin/pull-variables.test.js +7 -1
  55. package/dist/lib/graphql/admin/push-variables.js +35 -0
  56. package/dist/lib/log.js +1 -0
  57. package/dist/lib/mini-oxygen/common.js +2 -1
  58. package/dist/lib/mini-oxygen/node.js +2 -2
  59. package/dist/lib/mini-oxygen/workerd-inspector.js +1 -1
  60. package/dist/lib/mini-oxygen/workerd.js +29 -17
  61. package/dist/lib/onboarding/common.js +0 -3
  62. package/dist/lib/onboarding/local.js +4 -1
  63. package/dist/lib/onboarding/remote.js +16 -11
  64. package/dist/lib/remix-config.js +1 -1
  65. package/dist/lib/request-events.js +3 -3
  66. package/dist/lib/setups/css/assets.js +7 -2
  67. package/dist/lib/setups/i18n/replacers.test.js +1 -0
  68. package/dist/lib/setups/routes/generate.js +58 -10
  69. package/dist/lib/setups/routes/templates/locale-check.js +9 -0
  70. package/dist/lib/setups/routes/templates/locale-check.ts +16 -0
  71. package/dist/lib/template-diff.js +26 -11
  72. package/dist/lib/template-downloader.js +11 -2
  73. package/dist/lib/vite/hydrogen-middleware.js +82 -0
  74. package/dist/lib/vite/mini-oxygen.js +152 -0
  75. package/dist/lib/vite/plugins.d.ts +27 -0
  76. package/dist/lib/vite/plugins.js +139 -0
  77. package/dist/lib/vite/shared.js +10 -0
  78. package/dist/lib/vite/utils.js +55 -0
  79. package/dist/lib/vite/worker-entry.js +1518 -0
  80. package/dist/lib/vite-config.js +45 -0
  81. package/dist/virtual-routes/lib/useDebugNetworkServer.jsx +4 -2
  82. package/dist/virtual-routes/routes/index.jsx +5 -5
  83. package/dist/virtual-routes/routes/subrequest-profiler.jsx +1 -1
  84. package/dist/virtual-routes/virtual-root.jsx +1 -1
  85. package/oclif.manifest.json +1146 -474
  86. package/package.json +36 -11
  87. /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,31 +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: "Generate sourcemaps for the build.",
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
- description: "Show a bundle size summary after building.",
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": Flags.boolean({
36
- description: "Checks that there is exactly 1 valid lockfile in the project.",
37
- env: "SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK",
38
- default: true,
39
- allowNo: true
40
- }),
41
- "disable-route-warning": Flags.boolean({
42
- description: "Disable warning about missing standard routes.",
43
- env: "SHOPIFY_HYDROGEN_FLAG_DISABLE_ROUTE_WARNING"
44
- }),
45
- codegen: commonFlags.codegen,
46
- "codegen-config-path": commonFlags.codegenConfigPath,
47
- diff: commonFlags.diff
30
+ ...commonFlags.lockfileCheck,
31
+ ...commonFlags.disableRouteWarning,
32
+ ...commonFlags.codegen,
33
+ ...commonFlags.diff
48
34
  };
49
35
  async run() {
50
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,22 @@ 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
13
  import { commonFlags, flagsToCamelObject } from '../../lib/flags.js';
13
14
  import { getOxygenDeploymentData } from '../../lib/get-oxygen-deployment-data.js';
14
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';
15
19
 
20
+ const DEPLOY_OUTPUT_FILE_HANDLE = "h2_deploy_log.json";
16
21
  const deploymentLogger = (message, level = "info") => {
17
22
  if (level === "error" || level === "warn") {
18
23
  outputWarn(message);
@@ -25,6 +30,10 @@ class Deploy extends Command {
25
30
  description: "Environment branch (tag) for environment to deploy to.",
26
31
  required: false
27
32
  }),
33
+ "env-file": Flags.string({
34
+ description: "Path to an environment file to override existing environment variables for the deployment.",
35
+ required: false
36
+ }),
28
37
  preview: Flags.boolean({
29
38
  description: "Deploys to the Preview environment. Overrides --env-branch and Git metadata.",
30
39
  required: false,
@@ -37,17 +46,28 @@ class Deploy extends Command {
37
46
  env: "SHOPIFY_HYDROGEN_FLAG_FORCE",
38
47
  required: false
39
48
  }),
49
+ "no-verify": Flags.boolean({
50
+ description: "Skip the routability verification step after deployment.",
51
+ default: false,
52
+ required: false
53
+ }),
40
54
  "auth-bypass-token": Flags.boolean({
41
55
  description: "Generate an authentication bypass token, which can be used to perform end-to-end tests against the deployment.",
42
56
  required: false,
43
57
  default: false
44
58
  }),
45
- path: commonFlags.path,
46
- shop: commonFlags.shop,
47
- "no-json-output": Flags.boolean({
48
- description: "Prevents the command from creating a JSON file containing the deployment URL in CI environments.",
59
+ "build-command": Flags.string({
60
+ description: "Specify a build command to run before deploying. If not specified, `shopify hydrogen build` will be used.",
61
+ required: false
62
+ }),
63
+ ...commonFlags.lockfileCheck,
64
+ ...commonFlags.path,
65
+ ...commonFlags.shop,
66
+ "json-output": Flags.boolean({
67
+ allowNo: true,
68
+ description: "Create a JSON file containing the deployment details in CI environments. Defaults to true, use `--no-json-output` to disable.",
49
69
  required: false,
50
- default: false
70
+ default: true
51
71
  }),
52
72
  token: Flags.string({
53
73
  char: "t",
@@ -74,17 +94,20 @@ class Deploy extends Command {
74
94
  required: false,
75
95
  env: "SHOPIFY_HYDROGEN_FLAG_METADATA_VERSION",
76
96
  hidden: true
77
- })
97
+ }),
98
+ ...commonFlags.diff
78
99
  };
79
100
  async run() {
80
101
  const { flags } = await this.parse(Deploy);
81
102
  const deploymentOptions = this.flagsToOxygenDeploymentOptions(flags);
82
- await oxygenDeploy(deploymentOptions).catch((error) => {
83
- renderFatalError(error);
84
- process.exit(1);
85
- }).finally(() => {
86
- process.exit(0);
87
- });
103
+ if (flags.diff) {
104
+ deploymentOptions.path = await prepareDiffDirectory(
105
+ deploymentOptions.path,
106
+ false
107
+ );
108
+ }
109
+ await runDeploy(deploymentOptions);
110
+ process.exit(0);
88
111
  }
89
112
  flagsToOxygenDeploymentOptions(flags) {
90
113
  const camelFlags = flagsToCamelObject(flags);
@@ -92,6 +115,7 @@ class Deploy extends Command {
92
115
  ...camelFlags,
93
116
  defaultEnvironment: flags.preview,
94
117
  environmentTag: flags["env-branch"],
118
+ environmentFile: flags["env-file"],
95
119
  path: flags.path ? resolvePath(flags.path) : process.cwd()
96
120
  };
97
121
  }
@@ -99,10 +123,10 @@ class Deploy extends Command {
99
123
  function createUnexpectedAbortError(message) {
100
124
  return new AbortError(
101
125
  message || "The deployment failed due to an unexpected error.",
102
- "Retrying the deployement may succeed.",
126
+ "Retrying the deployment may succeed.",
103
127
  [
104
128
  [
105
- "If the issue persits, please check the",
129
+ "If the issue persists, please check the",
106
130
  {
107
131
  link: {
108
132
  label: "Shopify status page",
@@ -114,14 +138,18 @@ function createUnexpectedAbortError(message) {
114
138
  ]
115
139
  );
116
140
  }
117
- async function oxygenDeploy(options) {
141
+ async function runDeploy(options) {
118
142
  const {
119
143
  authBypassToken: generateAuthBypassToken,
144
+ buildCommand,
120
145
  defaultEnvironment,
121
146
  environmentTag,
147
+ environmentFile,
122
148
  force: forceOnUncommitedChanges,
123
- noJsonOutput,
124
- path,
149
+ noVerify,
150
+ lockfileCheck,
151
+ jsonOutput,
152
+ path: root,
125
153
  shop,
126
154
  metadataUrl,
127
155
  metadataUser,
@@ -130,7 +158,7 @@ async function oxygenDeploy(options) {
130
158
  let { metadataDescription } = options;
131
159
  let isCleanGit = true;
132
160
  try {
133
- await ensureIsClean(path);
161
+ await ensureIsClean(root);
134
162
  } catch (error) {
135
163
  if (error instanceof GitDirectoryNotCleanError) {
136
164
  isCleanGit = false;
@@ -153,7 +181,7 @@ async function oxygenDeploy(options) {
153
181
  let deploymentEnvironmentTag = void 0;
154
182
  let gitCommit;
155
183
  try {
156
- gitCommit = await getLatestGitCommit(path);
184
+ gitCommit = await getLatestGitCommit(root);
157
185
  branch = (/HEAD -> ([^,]*)/.exec(gitCommit.refs) || [])[1];
158
186
  commitHash = gitCommit.hash;
159
187
  } catch (error) {
@@ -173,9 +201,20 @@ async function oxygenDeploy(options) {
173
201
  });
174
202
  metadataDescription = `${commitHash} with additional changes`;
175
203
  }
204
+ let overriddenEnvironmentVariables;
205
+ if (environmentFile) {
206
+ const { variables } = await readAndParseDotEnv(environmentFile);
207
+ overriddenEnvironmentVariables = Object.entries(variables).map(
208
+ ([key, value]) => ({
209
+ isSecret: true,
210
+ key,
211
+ value
212
+ })
213
+ );
214
+ }
176
215
  if (!isCI) {
177
216
  deploymentData = await getOxygenDeploymentData({
178
- root: path,
217
+ root,
179
218
  flagShop: shop
180
219
  });
181
220
  if (!deploymentData) {
@@ -229,8 +268,15 @@ async function oxygenDeploy(options) {
229
268
  deploymentEnvironmentTag = void 0;
230
269
  isPreview = true;
231
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
+ }
232
278
  const config = {
233
- assetsDir: "dist/client",
279
+ assetsDir,
234
280
  bugsnag: true,
235
281
  deploymentUrl,
236
282
  defaultEnvironment: defaultEnvironment || isPreview,
@@ -244,11 +290,12 @@ async function oxygenDeploy(options) {
244
290
  ...metadataUser ? { user: metadataUser } : {},
245
291
  ...metadataVersion ? { version: metadataVersion } : {}
246
292
  },
247
- skipVerification: false,
248
- rootPath: path,
293
+ skipVerification: noVerify,
294
+ rootPath: root,
249
295
  skipBuild: false,
250
296
  workerOnly: false,
251
- workerDir: "dist/worker"
297
+ workerDir,
298
+ overriddenEnvironmentVariables
252
299
  };
253
300
  let resolveUpload;
254
301
  const uploadPromise = new Promise((resolve) => {
@@ -272,17 +319,6 @@ async function oxygenDeploy(options) {
272
319
  rejectDeploy = reject;
273
320
  });
274
321
  const hooks = {
275
- buildFunction: async (assetPath) => {
276
- outputInfo(
277
- outputContent`${colors.whiteBright("Building project...")}`.value
278
- );
279
- await runBuild({
280
- directory: path,
281
- assetPath,
282
- sourcemap: true,
283
- useCodegen: false
284
- });
285
- },
286
322
  onDeploymentCompleted: () => resolveDeploymentCompletedVerification(),
287
323
  onVerificationComplete: () => resolveRoutableCheck(),
288
324
  onDeploymentCompletedVerificationError() {
@@ -309,6 +345,23 @@ async function oxygenDeploy(options) {
309
345
  );
310
346
  }
311
347
  };
348
+ if (buildCommand) {
349
+ config.buildCommand = buildCommand;
350
+ } else {
351
+ hooks.buildFunction = async (assetPath) => {
352
+ outputInfo(
353
+ outputContent`${colors.whiteBright("Building project...")}`.value
354
+ );
355
+ const build = maybeVite ? runViteBuild : runBuild;
356
+ await build({
357
+ directory: root,
358
+ assetPath,
359
+ lockfileCheck,
360
+ sourcemap: true,
361
+ useCodegen: false
362
+ });
363
+ };
364
+ }
312
365
  const uploadStart = async () => {
313
366
  outputInfo(
314
367
  outputContent`${colors.whiteBright("Deploying to Oxygen..\n")}`.value
@@ -324,7 +377,8 @@ async function oxygenDeploy(options) {
324
377
  },
325
378
  {
326
379
  title: "Verifying deployment is routable",
327
- task: async () => await routableCheckPromise
380
+ task: async () => await routableCheckPromise,
381
+ skip: () => noVerify
328
382
  }
329
383
  ]);
330
384
  };
@@ -333,27 +387,35 @@ async function oxygenDeploy(options) {
333
387
  rejectDeploy(createUnexpectedAbortError());
334
388
  return;
335
389
  }
336
- const nextSteps = [
337
- [
390
+ const nextSteps = [];
391
+ if (isCI) {
392
+ if (jsonOutput) {
393
+ nextSteps.push([
394
+ "View the deployment information in",
395
+ { subdued: DEPLOY_OUTPUT_FILE_HANDLE }
396
+ ]);
397
+ }
398
+ } else {
399
+ nextSteps.push([
338
400
  "Open",
339
401
  { link: { url: completedDeployment.url } },
340
- `in your browser to view your deployment.`
341
- ]
342
- ];
343
- if (completedDeployment?.authBypassToken) {
344
- nextSteps.push([
345
- "Use the",
346
- { subdued: completedDeployment.authBypassToken },
347
- "token to perform end-to-end tests against the deployment."
402
+ "in your browser to view your deployment."
348
403
  ]);
404
+ if (completedDeployment?.authBypassToken) {
405
+ nextSteps.push([
406
+ "Use the",
407
+ { subdued: completedDeployment.authBypassToken },
408
+ "token to perform end-to-end tests against the deployment."
409
+ ]);
410
+ }
349
411
  }
350
412
  renderSuccess({
351
413
  body: ["Successfully deployed to Oxygen"],
352
414
  nextSteps
353
415
  });
354
- if (isCI && !noJsonOutput) {
416
+ if (isCI && jsonOutput) {
355
417
  await writeFile(
356
- "h2_deploy_log.json",
418
+ DEPLOY_OUTPUT_FILE_HANDLE,
357
419
  JSON.stringify(completedDeployment)
358
420
  );
359
421
  }
@@ -364,4 +426,4 @@ async function oxygenDeploy(options) {
364
426
  return deployPromise;
365
427
  }
366
428
 
367
- export { Deploy as default, deploymentLogger, oxygenDeploy };
429
+ export { Deploy as default, deploymentLogger, runDeploy };