@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.
- package/dist/commands/hydrogen/build-vite.js +131 -0
- package/dist/commands/hydrogen/build.js +6 -15
- package/dist/commands/hydrogen/check.js +1 -1
- package/dist/commands/hydrogen/codegen.js +3 -3
- package/dist/commands/hydrogen/debug/cpu.js +1 -1
- package/dist/commands/hydrogen/deploy.js +46 -31
- package/dist/commands/hydrogen/deploy.test.js +35 -49
- package/dist/commands/hydrogen/dev-vite.js +159 -0
- package/dist/commands/hydrogen/dev.js +11 -14
- package/dist/commands/hydrogen/env/list.js +1 -1
- package/dist/commands/hydrogen/env/pull.js +3 -3
- package/dist/commands/hydrogen/env/pull.test.js +2 -0
- package/dist/commands/hydrogen/env/push__unstable.js +190 -0
- package/dist/commands/hydrogen/env/push__unstable.test.js +383 -0
- package/dist/commands/hydrogen/generate/route.js +2 -2
- package/dist/commands/hydrogen/init.d.ts +69 -0
- package/dist/commands/hydrogen/init.js +5 -5
- package/dist/commands/hydrogen/init.test.js +2 -2
- package/dist/commands/hydrogen/link.js +2 -2
- package/dist/commands/hydrogen/list.js +1 -1
- package/dist/commands/hydrogen/login.js +2 -9
- package/dist/commands/hydrogen/logout.js +1 -1
- package/dist/commands/hydrogen/preview.js +15 -7
- package/dist/commands/hydrogen/setup/css.js +3 -3
- package/dist/commands/hydrogen/setup/markets.js +4 -4
- package/dist/commands/hydrogen/setup/vite.js +209 -0
- package/dist/commands/hydrogen/setup.js +8 -6
- package/dist/commands/hydrogen/unlink.js +1 -1
- package/dist/commands/hydrogen/upgrade.js +5 -3
- package/dist/generator-templates/assets/vite/package.json +15 -0
- package/dist/generator-templates/assets/vite/vite.config.js +13 -0
- package/dist/generator-templates/starter/CHANGELOG.md +34 -0
- package/dist/generator-templates/starter/app/root.tsx +1 -2
- package/dist/generator-templates/starter/package.json +9 -8
- package/dist/generator-templates/starter/public/.gitkeep +0 -0
- package/dist/lib/build.js +2 -1
- package/dist/lib/codegen.js +8 -3
- package/dist/lib/environment-variables.test.js +4 -2
- package/dist/lib/flags.js +149 -95
- package/dist/lib/graphql/admin/pull-variables.js +1 -0
- package/dist/lib/graphql/admin/pull-variables.test.js +7 -1
- package/dist/lib/graphql/admin/push-variables.js +35 -0
- package/dist/lib/log.js +1 -0
- package/dist/lib/mini-oxygen/common.js +2 -1
- package/dist/lib/mini-oxygen/node.js +2 -2
- package/dist/lib/mini-oxygen/workerd-inspector.js +1 -1
- package/dist/lib/mini-oxygen/workerd.js +29 -17
- package/dist/lib/onboarding/common.js +0 -3
- package/dist/lib/onboarding/local.js +4 -1
- package/dist/lib/onboarding/remote.js +16 -11
- package/dist/lib/remix-config.js +1 -1
- package/dist/lib/request-events.js +3 -3
- package/dist/lib/setups/css/assets.js +7 -2
- package/dist/lib/template-diff.js +26 -11
- package/dist/lib/template-downloader.js +11 -2
- package/dist/lib/vite/hydrogen-middleware.js +82 -0
- package/dist/lib/vite/mini-oxygen.js +152 -0
- package/dist/lib/vite/plugins.d.ts +27 -0
- package/dist/lib/vite/plugins.js +139 -0
- package/dist/lib/vite/shared.js +10 -0
- package/dist/lib/vite/utils.js +55 -0
- package/dist/lib/vite/worker-entry.js +1518 -0
- package/dist/lib/vite-config.js +45 -0
- package/dist/virtual-routes/lib/useDebugNetworkServer.jsx +4 -2
- package/dist/virtual-routes/routes/index.jsx +5 -5
- package/dist/virtual-routes/routes/subrequest-profiler.jsx +1 -1
- package/dist/virtual-routes/virtual-root.jsx +1 -1
- package/oclif.manifest.json +1127 -494
- package/package.json +36 -11
- /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
|
-
|
|
24
|
-
sourcemap
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
|
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
|
|
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:
|
|
294
|
+
rootPath: root,
|
|
281
295
|
skipBuild: false,
|
|
282
296
|
workerOnly: false,
|
|
283
|
-
workerDir
|
|
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
|
-
|
|
342
|
-
|
|
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,
|
|
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 {
|
|
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/
|
|
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
|
|
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
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
isSecret: true
|
|
171
|
+
vi.mocked(readAndParseDotEnv).mockResolvedValue({
|
|
172
|
+
path: "fake-env-file",
|
|
173
|
+
variables: {
|
|
174
|
+
"fake-key": "fake-value"
|
|
176
175
|
}
|
|
177
|
-
|
|
178
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
541
|
+
await runDeploy({
|
|
556
542
|
...deployParams,
|
|
557
543
|
token: "fake-token",
|
|
558
544
|
jsonOutput: false
|