@shopify/cli-hydrogen 7.1.2 → 8.0.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/dist/commands/hydrogen/build-vite.js +19 -10
- package/dist/commands/hydrogen/build.js +10 -2
- package/dist/commands/hydrogen/check.js +1 -0
- package/dist/commands/hydrogen/codegen.js +1 -0
- package/dist/commands/hydrogen/customer-account/push.js +170 -0
- package/dist/commands/hydrogen/debug/cpu.js +3 -0
- package/dist/commands/hydrogen/deploy.js +121 -36
- package/dist/commands/hydrogen/dev-vite.js +128 -59
- package/dist/commands/hydrogen/dev.js +108 -51
- package/dist/commands/hydrogen/env/list.js +7 -8
- package/dist/commands/hydrogen/env/pull.js +17 -1
- package/dist/commands/hydrogen/env/{push__unstable.js → push.js} +23 -50
- package/dist/commands/hydrogen/generate/route.js +1 -0
- package/dist/commands/hydrogen/init.js +45 -17
- package/dist/commands/hydrogen/link.js +20 -4
- package/dist/commands/hydrogen/list.js +1 -0
- package/dist/commands/hydrogen/login.js +1 -0
- package/dist/commands/hydrogen/logout.js +1 -0
- package/dist/commands/hydrogen/preview.js +31 -16
- package/dist/commands/hydrogen/setup/css.js +8 -1
- package/dist/commands/hydrogen/setup/markets.js +1 -0
- package/dist/commands/hydrogen/setup/vite.js +244 -138
- package/dist/commands/hydrogen/setup.js +21 -22
- package/dist/commands/hydrogen/shortcut.js +10 -0
- package/dist/commands/hydrogen/unlink.js +1 -0
- package/dist/commands/hydrogen/upgrade.js +2 -1
- package/dist/generator-templates/assets/vite/package.json +3 -4
- package/dist/generator-templates/assets/vite/vite.config.js +10 -2
- package/dist/generator-templates/starter/CHANGELOG.md +89 -0
- package/dist/generator-templates/starter/README.md +3 -44
- package/dist/generator-templates/starter/app/graphql/customer-account/CustomerDetailsQuery.ts +1 -0
- package/dist/generator-templates/starter/app/lib/fragments.ts +2 -0
- package/dist/generator-templates/starter/app/root.tsx +2 -5
- package/dist/generator-templates/starter/app/routes/account.orders._index.tsx +1 -1
- package/dist/generator-templates/starter/app/routes/account.tsx +1 -1
- package/dist/generator-templates/starter/app/routes/collections.all.tsx +160 -0
- package/dist/generator-templates/starter/app/routes/products.$handle.tsx +1 -2
- package/dist/generator-templates/starter/customer-accountapi.generated.d.ts +6 -3
- package/dist/generator-templates/starter/{remix.env.d.ts → env.d.ts} +8 -2
- package/dist/generator-templates/starter/package.json +14 -9
- package/dist/generator-templates/starter/server.ts +2 -1
- package/dist/generator-templates/starter/storefrontapi.generated.d.ts +59 -3
- package/dist/generator-templates/starter/vite.config.ts +21 -0
- package/dist/{commands/hydrogen/init.d.ts → init.d.ts} +11 -3
- package/dist/lib/check-lockfile.js +12 -18
- package/dist/lib/codegen.js +37 -13
- package/dist/lib/common.js +50 -0
- package/dist/lib/cpu-profiler.js +4 -1
- package/dist/lib/dev-shared.js +97 -0
- package/dist/lib/environment-variables.js +51 -30
- package/dist/lib/file.js +8 -1
- package/dist/lib/flags.js +37 -16
- package/dist/lib/graphql/admin/customer-application-update.js +29 -0
- package/dist/lib/graphql/admin/get-oxygen-data.js +1 -0
- package/dist/lib/graphql/admin/list-environments.js +1 -0
- package/dist/lib/graphql/admin/pull-variables.js +4 -4
- package/dist/lib/graphql/admin/test-helper.js +37 -0
- package/dist/lib/log.js +86 -13
- package/dist/lib/mini-oxygen/common.js +19 -33
- package/dist/lib/mini-oxygen/index.js +6 -2
- package/dist/lib/mini-oxygen/node.js +43 -31
- package/dist/lib/mini-oxygen/workerd.js +72 -165
- package/dist/lib/missing-routes.js +1 -1
- package/dist/lib/onboarding/common.js +82 -70
- package/dist/lib/onboarding/local.js +19 -9
- package/dist/lib/onboarding/remote.js +35 -30
- package/dist/lib/package-managers.js +24 -0
- package/dist/lib/remix-config.js +17 -1
- package/dist/lib/request-events.js +6 -1
- package/dist/lib/setups/i18n/replacers.js +9 -6
- package/dist/lib/setups/routes/generate.js +1 -0
- package/dist/lib/shell.js +2 -1
- package/dist/lib/shopify-config.js +19 -1
- package/dist/lib/template-diff.js +36 -15
- package/dist/lib/template-downloader.js +35 -5
- package/dist/lib/transpile/morph/typedefs.js +5 -2
- package/dist/lib/transpile/project.js +8 -4
- package/dist/lib/tunneling.js +44 -0
- package/dist/lib/virtual-routes.js +1 -1
- package/dist/lib/vite-config.js +39 -9
- package/oclif.manifest.json +711 -498
- package/package.json +32 -24
- package/dist/commands/hydrogen/deploy.test.js +0 -553
- package/dist/commands/hydrogen/env/list.test.js +0 -148
- package/dist/commands/hydrogen/env/pull.test.js +0 -207
- package/dist/commands/hydrogen/env/push__unstable.test.js +0 -383
- package/dist/commands/hydrogen/generate/route.test.js +0 -43
- package/dist/commands/hydrogen/init.test.js +0 -641
- package/dist/commands/hydrogen/link.test.js +0 -187
- package/dist/commands/hydrogen/list.test.js +0 -111
- package/dist/commands/hydrogen/setup.test.js +0 -61
- package/dist/commands/hydrogen/shortcut.test.js +0 -30
- package/dist/commands/hydrogen/unlink.test.js +0 -36
- package/dist/commands/hydrogen/upgrade.test.js +0 -786
- package/dist/generator-templates/starter/remix.config.js +0 -24
- package/dist/lib/auth.test.js +0 -157
- package/dist/lib/check-lockfile.test.js +0 -81
- package/dist/lib/check-version.test.js +0 -86
- package/dist/lib/environment-variables.test.js +0 -149
- package/dist/lib/file.test.js +0 -68
- package/dist/lib/flags.test.js +0 -43
- package/dist/lib/get-oxygen-deployment-data.test.js +0 -120
- package/dist/lib/gid.test.js +0 -15
- package/dist/lib/graphql/admin/client.test.js +0 -76
- package/dist/lib/graphql/admin/create-storefront.test.js +0 -64
- package/dist/lib/graphql/admin/link-storefront.test.js +0 -38
- package/dist/lib/graphql/admin/list-environments.test.js +0 -44
- package/dist/lib/graphql/admin/list-storefronts.test.js +0 -44
- package/dist/lib/graphql/admin/pull-variables.test.js +0 -43
- package/dist/lib/graphql/business-platform/user-account.test.js +0 -80
- package/dist/lib/log.test.js +0 -92
- package/dist/lib/mini-oxygen/assets.js +0 -134
- package/dist/lib/mini-oxygen/mini-oxygen.test.js +0 -214
- package/dist/lib/mini-oxygen/workerd-inspector-logs.js +0 -227
- package/dist/lib/mini-oxygen/workerd-inspector-proxy.js +0 -200
- package/dist/lib/mini-oxygen/workerd-inspector.js +0 -219
- package/dist/lib/missing-routes.test.js +0 -45
- package/dist/lib/remix-version-check.test.js +0 -39
- package/dist/lib/remix-version-interop.test.js +0 -13
- package/dist/lib/setups/i18n/domains.test.js +0 -39
- package/dist/lib/setups/i18n/replacers.test.js +0 -261
- package/dist/lib/setups/i18n/subdomains.test.js +0 -39
- package/dist/lib/setups/i18n/subfolders.test.js +0 -39
- package/dist/lib/setups/routes/generate.test.js +0 -296
- package/dist/lib/shell.test.js +0 -111
- package/dist/lib/shopify-config.test.js +0 -199
- package/dist/lib/string.test.js +0 -16
- package/dist/lib/virtual-routes.test.js +0 -49
- package/dist/lib/vite/hydrogen-middleware.js +0 -82
- package/dist/lib/vite/mini-oxygen.js +0 -152
- package/dist/lib/vite/plugins.d.ts +0 -27
- package/dist/lib/vite/plugins.js +0 -139
- package/dist/lib/vite/shared.js +0 -10
- package/dist/lib/vite/utils.js +0 -55
- package/dist/lib/vite/worker-entry.js +0 -1518
- /package/dist/generator-templates/starter/{.eslintrc.js → .eslintrc.cjs} +0 -0
|
@@ -7,22 +7,21 @@ import { getCliCommand } from '../../../lib/shell.js';
|
|
|
7
7
|
import { resolvePath } from '@shopify/cli-kit/node/path';
|
|
8
8
|
import { renderConfirmationPrompt, renderSelectPrompt, renderInfo, renderSuccess } from '@shopify/cli-kit/node/ui';
|
|
9
9
|
import { outputContent, outputToken, outputWarn } from '@shopify/cli-kit/node/output';
|
|
10
|
+
import { orderEnvironmentsBySafety, findEnvironmentOrThrow, createEnvironmentCliChoiceLabel } from '../../../lib/common.js';
|
|
10
11
|
import { renderMissingLink } from '../../../lib/render-errors.js';
|
|
11
12
|
import { getStorefrontEnvironments } from '../../../lib/graphql/admin/list-environments.js';
|
|
12
13
|
import { linkStorefront } from '../link.js';
|
|
13
14
|
import { getStorefrontEnvVariables } from '../../../lib/graphql/admin/pull-variables.js';
|
|
14
15
|
import { pushStorefrontEnvVariables } from '../../../lib/graphql/admin/push-variables.js';
|
|
15
16
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
16
|
-
import { readAndParseDotEnv } from '@shopify/cli-kit/node/dot-env';
|
|
17
|
+
import { readAndParseDotEnv, createDotEnvFileLine } from '@shopify/cli-kit/node/dot-env';
|
|
17
18
|
|
|
18
19
|
class EnvPush extends Command {
|
|
19
20
|
static description = "Push environment variables from the local .env file to your linked Hydrogen storefront.";
|
|
20
|
-
static hidden = true;
|
|
21
21
|
static flags = {
|
|
22
22
|
...commonFlags.env,
|
|
23
23
|
"env-file": Flags.string({
|
|
24
|
-
description: "
|
|
25
|
-
env: "SHOPIFY_HYDROGEN_ENVIRONMENT_FILENAME"
|
|
24
|
+
description: "Path to an environment file to override existing environment variables for the selected environment. Defaults to the '.env' located in your project path `--path`."
|
|
26
25
|
}),
|
|
27
26
|
...commonFlags.path
|
|
28
27
|
};
|
|
@@ -32,12 +31,12 @@ class EnvPush extends Command {
|
|
|
32
31
|
}
|
|
33
32
|
}
|
|
34
33
|
async function runEnvPush({
|
|
35
|
-
env:
|
|
36
|
-
envFile
|
|
34
|
+
env: envHandle,
|
|
35
|
+
envFile,
|
|
37
36
|
path = process.cwd()
|
|
38
37
|
}) {
|
|
39
|
-
let validatedEnvironment
|
|
40
|
-
const dotEnvPath = resolvePath(path,
|
|
38
|
+
let validatedEnvironment;
|
|
39
|
+
const dotEnvPath = envFile || resolvePath(path, ".env");
|
|
41
40
|
const { variables: localVariables } = await readAndParseDotEnv(dotEnvPath);
|
|
42
41
|
const [{ session, config }, cliCommand] = await Promise.all([
|
|
43
42
|
login(path),
|
|
@@ -62,69 +61,43 @@ async function runEnvPush({
|
|
|
62
61
|
if (!environmentsData) {
|
|
63
62
|
throw new AbortError("Failed to fetch environments");
|
|
64
63
|
}
|
|
65
|
-
const environments =
|
|
66
|
-
...environmentsData.filter((environment) => environment.type === "PREVIEW"),
|
|
67
|
-
...environmentsData.filter((environment) => environment.type === "CUSTOM"),
|
|
68
|
-
...environmentsData.filter(
|
|
69
|
-
(environment) => environment.type === "PRODUCTION"
|
|
70
|
-
)
|
|
71
|
-
];
|
|
64
|
+
const environments = orderEnvironmentsBySafety(environmentsData);
|
|
72
65
|
if (environments.length === 0) {
|
|
73
66
|
throw new AbortError("No environments found");
|
|
74
67
|
}
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
({ name }) => name === environmentName
|
|
78
|
-
);
|
|
79
|
-
if (matchedEnvironments.length === 0) {
|
|
80
|
-
throw new AbortError(
|
|
81
|
-
"Environment not found",
|
|
82
|
-
`We could not find an environment matching the name '${environmentName}'.`
|
|
83
|
-
);
|
|
84
|
-
} else if (matchedEnvironments.length === 1) {
|
|
85
|
-
const { id, name, branch, type } = matchedEnvironments[0] ?? {};
|
|
86
|
-
validatedEnvironment = { id, name, branch, type };
|
|
87
|
-
} else {
|
|
88
|
-
const selection = await renderSelectPrompt({
|
|
89
|
-
message: `There were multiple environments found with the name ${environmentName}:`,
|
|
90
|
-
choices: [
|
|
91
|
-
...matchedEnvironments.map(({ id: id2, name: name2, branch: branch2, type: type2, url }) => ({
|
|
92
|
-
label: `${name2} (${branch2}) ${type2} ${url}`,
|
|
93
|
-
value: id2
|
|
94
|
-
}))
|
|
95
|
-
]
|
|
96
|
-
});
|
|
97
|
-
const { id, name, branch, type } = matchedEnvironments.find(({ id: id2 }) => id2 === selection) ?? {};
|
|
98
|
-
validatedEnvironment = { id, name, branch, type };
|
|
99
|
-
}
|
|
68
|
+
if (envHandle) {
|
|
69
|
+
validatedEnvironment = findEnvironmentOrThrow(environments, envHandle);
|
|
100
70
|
} else {
|
|
101
71
|
const choices = [
|
|
102
|
-
...environments.map(({ id
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
72
|
+
...environments.map(({ id, name, branch, handle }) => {
|
|
73
|
+
return {
|
|
74
|
+
label: createEnvironmentCliChoiceLabel(name, handle, branch),
|
|
75
|
+
value: id
|
|
76
|
+
};
|
|
77
|
+
})
|
|
106
78
|
];
|
|
107
79
|
const pushToBranchSelection = await renderSelectPrompt({
|
|
108
|
-
message: "Select
|
|
80
|
+
message: "Select an environment to overwrite its environment variables:",
|
|
109
81
|
choices
|
|
110
82
|
});
|
|
111
|
-
|
|
112
|
-
|
|
83
|
+
validatedEnvironment = environments.find(
|
|
84
|
+
({ id }) => id === pushToBranchSelection
|
|
85
|
+
);
|
|
113
86
|
}
|
|
114
87
|
const { environmentVariables = [] } = await getStorefrontEnvVariables(
|
|
115
88
|
session,
|
|
116
89
|
config.storefront.id,
|
|
117
|
-
validatedEnvironment.
|
|
90
|
+
validatedEnvironment.handle
|
|
118
91
|
) ?? {};
|
|
119
92
|
const remoteVars = environmentVariables.filter(
|
|
120
93
|
({ isSecret, readOnly }) => !isSecret && !readOnly
|
|
121
94
|
);
|
|
122
|
-
const comparableRemoteVars = remoteVars.sort((a, b) => a.key.localeCompare(b.key)).map(({ key, value }) =>
|
|
95
|
+
const comparableRemoteVars = remoteVars.sort((a, b) => a.key.localeCompare(b.key)).map(({ key, value }) => createDotEnvFileLine(key, value)).join("\n") + "\n";
|
|
123
96
|
const compareableLocalVars = Object.keys(localVariables).sort((a, b) => a.localeCompare(b)).reduce((acc, key) => {
|
|
124
97
|
const { isSecret, readOnly } = environmentVariables.find((variable) => variable.key === key) ?? {};
|
|
125
98
|
if (isSecret || readOnly)
|
|
126
99
|
return acc;
|
|
127
|
-
return [...acc,
|
|
100
|
+
return [...acc, createDotEnvFileLine(key, localVariables[key])];
|
|
128
101
|
}, []).join("\n") + "\n";
|
|
129
102
|
if (!validatedEnvironment.name)
|
|
130
103
|
throw new AbortError("Missing environment name");
|
|
@@ -8,6 +8,7 @@ import { ALL_ROUTE_CHOICES, generateRoutes } from '../../../lib/setups/routes/ge
|
|
|
8
8
|
import { isV1RouteConventionInstalled } from '../../../lib/remix-version-interop.js';
|
|
9
9
|
|
|
10
10
|
class GenerateRoute extends Command {
|
|
11
|
+
static descriptionWithMarkdown = `Generates a set of default routes from the starter template.`;
|
|
11
12
|
static description = "Generates a standard Shopify route.";
|
|
12
13
|
static flags = {
|
|
13
14
|
adapter: Flags.string({
|
|
@@ -14,6 +14,7 @@ import { LANGUAGES } from '../../lib/onboarding/common.js';
|
|
|
14
14
|
|
|
15
15
|
const FLAG_MAP = { f: "force" };
|
|
16
16
|
class Init extends Command {
|
|
17
|
+
static descriptionWithMarkdown = "Creates a new Hydrogen storefront.";
|
|
17
18
|
static description = "Creates a new Hydrogen storefront.";
|
|
18
19
|
static flags = {
|
|
19
20
|
...commonFlags.force,
|
|
@@ -50,29 +51,55 @@ class Init extends Command {
|
|
|
50
51
|
env: "SHOPIFY_HYDROGEN_FLAG_GIT",
|
|
51
52
|
default: true,
|
|
52
53
|
allowNo: true
|
|
54
|
+
}),
|
|
55
|
+
quickstart: Flags.boolean({
|
|
56
|
+
description: "Scaffolds a new Hydrogen project with a set of sensible defaults.",
|
|
57
|
+
env: "SHOPIFY_HYDROGEN_FLAG_QUICKSTART",
|
|
58
|
+
default: false
|
|
59
|
+
}),
|
|
60
|
+
"package-manager": Flags.string({
|
|
61
|
+
env: "SHOPIFY_HYDROGEN_FLAG_PACKAGE_MANAGER",
|
|
62
|
+
hidden: true,
|
|
63
|
+
options: ["npm", "yarn", "pnpm", "unknown"]
|
|
53
64
|
})
|
|
54
65
|
};
|
|
55
66
|
async run() {
|
|
56
|
-
const {
|
|
57
|
-
flags: { markets, ..._flags }
|
|
58
|
-
} = await this.parse(Init);
|
|
59
|
-
const flags = { ..._flags, i18n: markets };
|
|
60
|
-
if (flags.i18n && !I18N_CHOICES.includes(flags.i18n)) {
|
|
61
|
-
throw new AbortError(
|
|
62
|
-
`Invalid URL structure strategy: ${flags.i18n}. Must be one of ${I18N_CHOICES.join(", ")}`
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
if (flags.styling && !STYLING_CHOICES.includes(flags.styling)) {
|
|
66
|
-
throw new AbortError(
|
|
67
|
-
`Invalid styling strategy: ${flags.styling}. Must be one of ${STYLING_CHOICES.join(", ")}`
|
|
68
|
-
);
|
|
69
|
-
}
|
|
67
|
+
const { flags } = await this.parse(Init);
|
|
70
68
|
await runInit(flagsToCamelObject(flags));
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
|
-
async function runInit(
|
|
71
|
+
async function runInit({
|
|
72
|
+
markets,
|
|
73
|
+
...options
|
|
74
|
+
} = parseProcessFlags(
|
|
75
|
+
process.argv,
|
|
76
|
+
FLAG_MAP
|
|
77
|
+
)) {
|
|
74
78
|
supressNodeExperimentalWarnings();
|
|
79
|
+
if (!options.i18n && markets) {
|
|
80
|
+
options.i18n = markets;
|
|
81
|
+
}
|
|
82
|
+
if (options.i18n && !I18N_CHOICES.includes(options.i18n)) {
|
|
83
|
+
throw new AbortError(
|
|
84
|
+
`Invalid URL structure strategy: ${options.i18n}. Must be one of ${I18N_CHOICES.join(", ")}`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
if (options.styling && !STYLING_CHOICES.includes(options.styling)) {
|
|
88
|
+
throw new AbortError(
|
|
89
|
+
`Invalid styling strategy: ${options.styling}. Must be one of ${STYLING_CHOICES.join(", ")}`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
75
92
|
options.git ??= true;
|
|
93
|
+
if (options.quickstart) {
|
|
94
|
+
options.i18n ||= "none";
|
|
95
|
+
options.installDeps ||= true;
|
|
96
|
+
options.language ||= "js";
|
|
97
|
+
options.mockShop ||= true;
|
|
98
|
+
options.path ||= "./hydrogen-quickstart";
|
|
99
|
+
options.routes ||= true;
|
|
100
|
+
options.shortcut ||= true;
|
|
101
|
+
options.styling ||= "tailwind";
|
|
102
|
+
}
|
|
76
103
|
const showUpgrade = await checkHydrogenVersion(
|
|
77
104
|
// Resolving the CLI package from a local directory might fail because
|
|
78
105
|
// this code could be run from a global dependency (e.g. on `npm create`).
|
|
@@ -81,14 +108,15 @@ async function runInit(options = parseProcessFlags(process.argv, FLAG_MAP)) {
|
|
|
81
108
|
"cli"
|
|
82
109
|
);
|
|
83
110
|
if (showUpgrade) {
|
|
84
|
-
const packageManager = packageManagerFromUserAgent();
|
|
111
|
+
const packageManager = options.packageManager ?? packageManagerFromUserAgent();
|
|
85
112
|
showUpgrade(
|
|
86
113
|
packageManager === "unknown" ? "" : `Please use the latest version with \`${packageManager} create @shopify/hydrogen@latest\``
|
|
87
114
|
);
|
|
88
115
|
}
|
|
89
116
|
const controller = new AbortController();
|
|
90
117
|
try {
|
|
91
|
-
|
|
118
|
+
const template = options.template;
|
|
119
|
+
return template ? await setupRemoteTemplate({ ...options, template }, controller) : await setupLocalStarterTemplate(options, controller);
|
|
92
120
|
} catch (error) {
|
|
93
121
|
controller.abort();
|
|
94
122
|
throw error;
|
|
@@ -11,9 +11,14 @@ import { waitForJob } from '../../lib/graphql/admin/fetch-job.js';
|
|
|
11
11
|
import { titleize } from '../../lib/string.js';
|
|
12
12
|
import { getCliCommand } from '../../lib/shell.js';
|
|
13
13
|
import { login } from '../../lib/auth.js';
|
|
14
|
-
import { handleStorefrontSelection } from '../../lib/onboarding/common.js';
|
|
14
|
+
import { handleStorefrontSelection, generateRandomName } from '../../lib/onboarding/common.js';
|
|
15
15
|
|
|
16
16
|
class Link extends Command {
|
|
17
|
+
static descriptionWithMarkdown = `Links your local development environment to a remote Hydrogen storefront. You can link an unlimited number of development environments to a single Hydrogen storefront.
|
|
18
|
+
|
|
19
|
+
Linking to a Hydrogen storefront enables you to run [dev](https://shopify.dev/docs/api/shopify-cli/hydrogen/hydrogen-dev) and automatically inject your linked Hydrogen storefront's environment variables directly into the server runtime.
|
|
20
|
+
|
|
21
|
+
After you run the \`link\` command, you can access the [env list](https://shopify.dev/docs/api/shopify-cli/hydrogen/hydrogen-env-list), [env pull](https://shopify.dev/docs/api/shopify-cli/hydrogen/hydrogen-env-pull), and [unlink](https://shopify.dev/docs/api/shopify-cli/hydrogen/hydrogen-unlink) commands.`;
|
|
17
22
|
static description = "Link a local project to one of your shop's Hydrogen storefronts.";
|
|
18
23
|
static flags = {
|
|
19
24
|
...commonFlags.force,
|
|
@@ -96,17 +101,28 @@ async function linkStorefront(root, session, config, {
|
|
|
96
101
|
} else {
|
|
97
102
|
selectedStorefront = await handleStorefrontSelection(storefronts);
|
|
98
103
|
if (!selectedStorefront) {
|
|
99
|
-
selectedStorefront = await createNewStorefront(
|
|
104
|
+
selectedStorefront = await createNewStorefront(
|
|
105
|
+
root,
|
|
106
|
+
session,
|
|
107
|
+
storefronts
|
|
108
|
+
);
|
|
100
109
|
}
|
|
101
110
|
}
|
|
102
111
|
await setStorefront(root, selectedStorefront);
|
|
103
112
|
return selectedStorefront;
|
|
104
113
|
}
|
|
105
|
-
async function createNewStorefront(root, session) {
|
|
114
|
+
async function createNewStorefront(root, session, storefronts) {
|
|
106
115
|
const projectDirectory = basename(root);
|
|
116
|
+
let defaultProjectName = titleize(projectDirectory);
|
|
117
|
+
const nameAlreadyUsed = storefronts.some(
|
|
118
|
+
({ title }) => title === defaultProjectName
|
|
119
|
+
);
|
|
120
|
+
if (nameAlreadyUsed) {
|
|
121
|
+
defaultProjectName = generateRandomName();
|
|
122
|
+
}
|
|
107
123
|
const projectName = await renderTextPrompt({
|
|
108
124
|
message: "New storefront name",
|
|
109
|
-
defaultValue:
|
|
125
|
+
defaultValue: defaultProjectName
|
|
110
126
|
});
|
|
111
127
|
let storefront;
|
|
112
128
|
let jobId;
|
|
@@ -11,6 +11,7 @@ import { login } from '../../lib/auth.js';
|
|
|
11
11
|
import { getCliCommand } from '../../lib/shell.js';
|
|
12
12
|
|
|
13
13
|
class List extends Command {
|
|
14
|
+
static descriptionWithMarkdown = "Lists all remote Hydrogen storefronts available to link to your local development environment.";
|
|
14
15
|
static description = "Returns a list of Hydrogen storefronts available on a given shop.";
|
|
15
16
|
static flags = {
|
|
16
17
|
...commonFlags.path
|
|
@@ -3,6 +3,7 @@ import { commonFlags } from '../../lib/flags.js';
|
|
|
3
3
|
import { login, renderLoginSuccess } from '../../lib/auth.js';
|
|
4
4
|
|
|
5
5
|
class Login extends Command {
|
|
6
|
+
static descriptionWithMarkdown = "Logs in to the specified shop and saves the shop domain to the project.";
|
|
6
7
|
static description = "Login to your Shopify account.";
|
|
7
8
|
static flags = {
|
|
8
9
|
...commonFlags.path,
|
|
@@ -4,6 +4,7 @@ import { commonFlags } from '../../lib/flags.js';
|
|
|
4
4
|
import { logout } from '../../lib/auth.js';
|
|
5
5
|
|
|
6
6
|
class Logout extends Command {
|
|
7
|
+
static descriptionWithMarkdown = "Log out from the current shop.";
|
|
7
8
|
static description = "Logout of your local session.";
|
|
8
9
|
static flags = {
|
|
9
10
|
...commonFlags.path
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import Command from '@shopify/cli-kit/node/base-command';
|
|
2
|
-
import { muteDevLogs } from '../../lib/log.js';
|
|
3
|
-
import { getProjectPaths } from '../../lib/remix-config.js';
|
|
4
|
-
import { commonFlags, deprecated, flagsToCamelObject } from '../../lib/flags.js';
|
|
2
|
+
import { setH2OVerbose, isH2Verbose, muteDevLogs } from '../../lib/log.js';
|
|
3
|
+
import { getProjectPaths, hasRemixConfigFile } from '../../lib/remix-config.js';
|
|
4
|
+
import { commonFlags, deprecated, flagsToCamelObject, DEFAULT_APP_PORT } from '../../lib/flags.js';
|
|
5
5
|
import { startMiniOxygen } from '../../lib/mini-oxygen/index.js';
|
|
6
6
|
import { getAllEnvironmentVariables } from '../../lib/environment-variables.js';
|
|
7
7
|
import { getConfig } from '../../lib/shopify-config.js';
|
|
8
8
|
import { findPort } from '../../lib/find-port.js';
|
|
9
|
-
import { fileExists } from '@shopify/cli-kit/node/fs';
|
|
10
9
|
import { joinPath } from '@shopify/cli-kit/node/path';
|
|
11
10
|
import { getViteConfig } from '../../lib/vite-config.js';
|
|
12
11
|
|
|
13
12
|
class Preview extends Command {
|
|
13
|
+
static descriptionWithMarkdown = "Runs a server in your local development environment that serves your Hydrogen app's production build. Requires running the [build](https://shopify.dev/docs/api/shopify-cli/hydrogen/hydrogen-build) command first.";
|
|
14
14
|
static description = "Runs a Hydrogen storefront in an Oxygen worker for production.";
|
|
15
15
|
static flags = {
|
|
16
16
|
...commonFlags.path,
|
|
17
17
|
...commonFlags.port,
|
|
18
18
|
worker: deprecated("--worker", { isBoolean: true }),
|
|
19
19
|
...commonFlags.legacyRuntime,
|
|
20
|
+
...commonFlags.env,
|
|
20
21
|
...commonFlags.envBranch,
|
|
21
22
|
...commonFlags.inspectorPort,
|
|
22
|
-
...commonFlags.debug
|
|
23
|
+
...commonFlags.debug,
|
|
24
|
+
...commonFlags.verbose
|
|
23
25
|
};
|
|
24
26
|
async run() {
|
|
25
27
|
const { flags } = await this.parse(Preview);
|
|
@@ -32,31 +34,44 @@ async function runPreview({
|
|
|
32
34
|
port: appPort,
|
|
33
35
|
path: appPath,
|
|
34
36
|
legacyRuntime = false,
|
|
37
|
+
env: envHandle,
|
|
35
38
|
envBranch,
|
|
36
39
|
inspectorPort,
|
|
37
|
-
debug
|
|
40
|
+
debug,
|
|
41
|
+
verbose
|
|
38
42
|
}) {
|
|
39
43
|
if (!process.env.NODE_ENV)
|
|
40
44
|
process.env.NODE_ENV = "production";
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!
|
|
45
|
+
if (verbose)
|
|
46
|
+
setH2OVerbose();
|
|
47
|
+
if (!isH2Verbose())
|
|
48
|
+
muteDevLogs();
|
|
49
|
+
let { root, buildPath, buildPathWorkerFile, buildPathClient } = getProjectPaths(appPath);
|
|
50
|
+
if (!await hasRemixConfigFile(root)) {
|
|
44
51
|
const maybeResult = await getViteConfig(root).catch(() => null);
|
|
45
|
-
|
|
46
|
-
buildPathWorkerFile = maybeResult.serverOutFile;
|
|
52
|
+
buildPathWorkerFile = maybeResult?.serverOutFile ?? joinPath(buildPath, "server", "index.js");
|
|
47
53
|
}
|
|
48
54
|
const { shop, storefront } = await getConfig(root);
|
|
49
55
|
const fetchRemote = !!shop && !!storefront?.id;
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
const { allVariables, logInjectedVariables } = await getAllEnvironmentVariables(
|
|
57
|
+
{
|
|
58
|
+
root,
|
|
59
|
+
fetchRemote,
|
|
60
|
+
envBranch,
|
|
61
|
+
envHandle
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
if (!appPort) {
|
|
65
|
+
appPort = await findPort(DEFAULT_APP_PORT);
|
|
66
|
+
}
|
|
53
67
|
const assetsPort = legacyRuntime ? 0 : await findPort(appPort + 100);
|
|
68
|
+
logInjectedVariables();
|
|
54
69
|
const miniOxygen = await startMiniOxygen(
|
|
55
70
|
{
|
|
56
71
|
root,
|
|
57
|
-
|
|
72
|
+
appPort,
|
|
58
73
|
assetsPort,
|
|
59
|
-
env,
|
|
74
|
+
env: allVariables,
|
|
60
75
|
buildPathClient,
|
|
61
76
|
buildPathWorkerFile,
|
|
62
77
|
inspectorPort,
|
|
@@ -4,10 +4,12 @@ import Command from '@shopify/cli-kit/node/base-command';
|
|
|
4
4
|
import { renderTasks, renderSuccess } from '@shopify/cli-kit/node/ui';
|
|
5
5
|
import { getPackageManager, installNodeModules } from '@shopify/cli-kit/node/node-package-manager';
|
|
6
6
|
import { Args } from '@oclif/core';
|
|
7
|
-
import { getRemixConfig } from '../../../lib/remix-config.js';
|
|
7
|
+
import { hasRemixConfigFile, getRemixConfig } from '../../../lib/remix-config.js';
|
|
8
8
|
import { SETUP_CSS_STRATEGIES, renderCssPrompt, setupCssStrategy, CSS_STRATEGY_NAME_MAP } from '../../../lib/setups/css/index.js';
|
|
9
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
9
10
|
|
|
10
11
|
class SetupCSS extends Command {
|
|
12
|
+
static descriptionWithMarkdown = "Adds support for certain CSS strategies to your project.";
|
|
11
13
|
static description = "Setup CSS strategies for your project.";
|
|
12
14
|
static flags = {
|
|
13
15
|
...commonFlags.path,
|
|
@@ -37,6 +39,11 @@ async function runSetupCSS({
|
|
|
37
39
|
force = false,
|
|
38
40
|
installDeps = true
|
|
39
41
|
}) {
|
|
42
|
+
if (!await hasRemixConfigFile(directory)) {
|
|
43
|
+
throw new AbortError(
|
|
44
|
+
"No remix.config.js file found. This command is not supported in Vite projects."
|
|
45
|
+
);
|
|
46
|
+
}
|
|
40
47
|
const remixConfigPromise = getRemixConfig(directory);
|
|
41
48
|
const strategy = flagStrategy ? flagStrategy : await renderCssPrompt();
|
|
42
49
|
const remixConfig = await remixConfigPromise;
|
|
@@ -7,6 +7,7 @@ import { getRemixConfig } from '../../../lib/remix-config.js';
|
|
|
7
7
|
import { SETUP_I18N_STRATEGIES, renderI18nPrompt, setupI18nStrategy, I18N_STRATEGY_NAME_MAP } from '../../../lib/setups/i18n/index.js';
|
|
8
8
|
|
|
9
9
|
class SetupMarkets extends Command {
|
|
10
|
+
static descriptionWithMarkdown = "Adds support for multiple [markets](https://shopify.dev/docs/custom-storefronts/hydrogen/markets) to your project by using the URL structure.";
|
|
10
11
|
static description = "Setup support for multiple markets in your project.";
|
|
11
12
|
static flags = {
|
|
12
13
|
...commonFlags.path
|