@shopify/cli-hydrogen 5.0.2 → 5.1.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.js +16 -2
- package/dist/commands/hydrogen/codegen-unstable.js +13 -24
- package/dist/commands/hydrogen/dev.js +45 -39
- package/dist/commands/hydrogen/env/list.js +25 -24
- package/dist/commands/hydrogen/env/list.test.js +46 -43
- package/dist/commands/hydrogen/env/pull.js +53 -25
- package/dist/commands/hydrogen/env/pull.test.js +123 -42
- package/dist/commands/hydrogen/generate/route.js +31 -132
- package/dist/commands/hydrogen/generate/route.test.js +34 -126
- package/dist/commands/hydrogen/init.js +46 -127
- package/dist/commands/hydrogen/init.test.js +352 -100
- package/dist/commands/hydrogen/link.js +70 -69
- package/dist/commands/hydrogen/link.test.js +72 -107
- package/dist/commands/hydrogen/list.js +22 -12
- package/dist/commands/hydrogen/list.test.js +51 -48
- package/dist/commands/hydrogen/login.js +31 -0
- package/dist/commands/hydrogen/logout.js +21 -0
- package/dist/commands/hydrogen/setup/css.js +79 -0
- package/dist/commands/hydrogen/setup/markets.js +53 -0
- package/dist/commands/hydrogen/setup.js +133 -0
- package/dist/commands/hydrogen/shortcut.js +2 -45
- package/dist/commands/hydrogen/shortcut.test.js +10 -37
- package/dist/generator-templates/assets/css-modules/package.json +6 -0
- package/dist/generator-templates/assets/postcss/package.json +10 -0
- package/dist/generator-templates/assets/postcss/postcss.config.js +8 -0
- package/dist/generator-templates/assets/tailwind/package.json +13 -0
- package/dist/generator-templates/assets/tailwind/postcss.config.js +10 -0
- package/dist/generator-templates/assets/tailwind/tailwind.config.js +8 -0
- package/dist/generator-templates/assets/tailwind/tailwind.css +3 -0
- package/dist/generator-templates/assets/vanilla-extract/package.json +9 -0
- package/dist/generator-templates/starter/.eslintignore +5 -0
- package/dist/generator-templates/starter/.eslintrc.js +18 -0
- package/dist/generator-templates/starter/.graphqlrc.yml +1 -0
- package/dist/generator-templates/starter/README.md +40 -0
- package/dist/generator-templates/starter/app/components/Aside.tsx +47 -0
- package/dist/generator-templates/starter/app/components/Cart.tsx +340 -0
- package/dist/generator-templates/starter/app/components/Footer.tsx +99 -0
- package/dist/generator-templates/starter/app/components/Header.tsx +178 -0
- package/dist/generator-templates/starter/app/components/Layout.tsx +95 -0
- package/dist/generator-templates/starter/app/components/Search.tsx +480 -0
- package/dist/generator-templates/starter/app/entry.client.tsx +12 -0
- package/dist/generator-templates/starter/app/entry.server.tsx +33 -0
- package/dist/generator-templates/starter/app/root.tsx +270 -0
- package/dist/generator-templates/starter/app/routes/$.tsx +7 -0
- package/dist/generator-templates/{routes → starter/app/routes}/[robots.txt].tsx +47 -69
- package/dist/generator-templates/starter/app/routes/[sitemap.xml].tsx +174 -0
- package/dist/generator-templates/starter/app/routes/_index.tsx +145 -0
- package/dist/generator-templates/starter/app/routes/account.$.tsx +9 -0
- package/dist/generator-templates/starter/app/routes/account.addresses.tsx +563 -0
- package/dist/generator-templates/starter/app/routes/account.orders.$id.tsx +309 -0
- package/dist/generator-templates/starter/app/routes/account.orders._index.tsx +196 -0
- package/dist/generator-templates/starter/app/routes/account.profile.tsx +289 -0
- package/dist/generator-templates/starter/app/routes/account.tsx +203 -0
- package/dist/generator-templates/starter/app/routes/account_.activate.$id.$activationToken.tsx +157 -0
- package/dist/generator-templates/starter/app/routes/account_.login.tsx +143 -0
- package/dist/generator-templates/starter/app/routes/account_.logout.tsx +33 -0
- package/dist/generator-templates/starter/app/routes/account_.recover.tsx +124 -0
- package/dist/generator-templates/starter/app/routes/account_.register.tsx +207 -0
- package/dist/generator-templates/starter/app/routes/account_.reset.$id.$resetToken.tsx +136 -0
- package/dist/generator-templates/starter/app/routes/api.predictive-search.tsx +342 -0
- package/dist/generator-templates/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +88 -0
- package/dist/generator-templates/starter/app/routes/blogs.$blogHandle._index.tsx +162 -0
- package/dist/generator-templates/starter/app/routes/blogs._index.tsx +94 -0
- package/dist/generator-templates/starter/app/routes/cart.tsx +104 -0
- package/dist/generator-templates/starter/app/routes/collections.$handle.tsx +184 -0
- package/dist/generator-templates/starter/app/routes/collections._index.tsx +120 -0
- package/dist/generator-templates/starter/app/routes/pages.$handle.tsx +57 -0
- package/dist/generator-templates/starter/app/routes/policies.$handle.tsx +94 -0
- package/dist/generator-templates/starter/app/routes/policies._index.tsx +63 -0
- package/dist/generator-templates/starter/app/routes/products.$handle.tsx +418 -0
- package/dist/generator-templates/starter/app/routes/search.tsx +168 -0
- package/dist/generator-templates/starter/app/styles/app.css +473 -0
- package/dist/generator-templates/starter/app/styles/reset.css +129 -0
- package/dist/generator-templates/starter/app/utils.ts +46 -0
- package/dist/generator-templates/starter/package.json +43 -0
- package/dist/generator-templates/starter/public/favicon.svg +28 -0
- package/dist/generator-templates/starter/remix.config.js +26 -0
- package/dist/generator-templates/starter/remix.env.d.ts +39 -0
- package/dist/generator-templates/starter/server.ts +253 -0
- package/dist/generator-templates/starter/storefrontapi.generated.d.ts +1906 -0
- package/dist/generator-templates/starter/tsconfig.json +22 -0
- package/dist/lib/auth.js +123 -0
- package/dist/lib/auth.test.js +157 -0
- package/dist/lib/build.js +51 -0
- package/dist/lib/check-version.js +3 -3
- package/dist/lib/check-version.test.js +24 -0
- package/dist/lib/codegen.js +26 -17
- package/dist/lib/environment-variables.js +68 -0
- package/dist/lib/environment-variables.test.js +147 -0
- package/dist/lib/file.js +41 -0
- package/dist/lib/file.test.js +69 -0
- package/dist/lib/flags.js +39 -2
- package/dist/lib/format-code.js +26 -0
- package/dist/lib/gid.js +12 -0
- package/dist/lib/{graphql.test.js → gid.test.js} +1 -1
- package/dist/lib/graphql/admin/client.js +27 -0
- package/dist/lib/graphql/admin/client.test.js +51 -0
- package/dist/lib/graphql/admin/create-storefront.js +13 -15
- package/dist/lib/graphql/admin/create-storefront.test.js +64 -0
- package/dist/lib/graphql/admin/fetch-job.js +6 -15
- package/dist/lib/graphql/admin/link-storefront.js +7 -11
- package/dist/lib/graphql/admin/link-storefront.test.js +38 -0
- package/dist/lib/graphql/admin/list-environments.js +2 -2
- package/dist/lib/graphql/admin/list-environments.test.js +44 -0
- package/dist/lib/graphql/admin/list-storefronts.js +7 -11
- package/dist/lib/graphql/admin/list-storefronts.test.js +44 -0
- package/dist/lib/graphql/admin/pull-variables.js +3 -3
- package/dist/lib/graphql/admin/pull-variables.test.js +37 -0
- package/dist/lib/graphql/business-platform/user-account.js +83 -0
- package/dist/lib/graphql/business-platform/user-account.test.js +80 -0
- package/dist/lib/log.js +185 -9
- package/dist/lib/log.test.js +92 -0
- package/dist/lib/mini-oxygen.js +19 -9
- package/dist/lib/missing-routes.js +0 -2
- package/dist/lib/onboarding/common.js +456 -0
- package/dist/lib/onboarding/index.js +2 -0
- package/dist/lib/onboarding/local.js +229 -0
- package/dist/lib/onboarding/remote.js +89 -0
- package/dist/lib/remix-version-interop.js +5 -5
- package/dist/lib/remix-version-interop.test.js +11 -1
- package/dist/lib/render-errors.js +13 -11
- package/dist/lib/setups/css/assets.js +89 -0
- package/dist/lib/setups/css/css-modules.js +22 -0
- package/dist/lib/setups/css/index.js +44 -0
- package/dist/lib/setups/css/postcss.js +34 -0
- package/dist/lib/setups/css/replacers.js +137 -0
- package/dist/lib/setups/css/tailwind.js +54 -0
- package/dist/lib/setups/css/vanilla-extract.js +22 -0
- package/dist/lib/setups/i18n/domains.test.js +25 -0
- package/dist/lib/setups/i18n/index.js +46 -0
- package/dist/lib/setups/i18n/replacers.js +227 -0
- package/dist/lib/setups/i18n/subdomains.test.js +25 -0
- package/dist/lib/setups/i18n/subfolders.test.js +25 -0
- package/dist/lib/setups/i18n/templates/domains.js +14 -0
- package/dist/lib/setups/i18n/templates/domains.ts +25 -0
- package/dist/lib/setups/i18n/templates/subdomains.js +14 -0
- package/dist/lib/setups/i18n/templates/subdomains.ts +24 -0
- package/dist/lib/setups/i18n/templates/subfolders.js +14 -0
- package/dist/lib/setups/i18n/templates/subfolders.ts +28 -0
- package/dist/lib/setups/routes/generate.js +244 -0
- package/dist/lib/setups/routes/generate.test.js +313 -0
- package/dist/lib/shell.js +52 -5
- package/dist/lib/shell.test.js +42 -16
- package/dist/lib/shopify-config.js +23 -18
- package/dist/lib/shopify-config.test.js +63 -73
- package/dist/lib/template-downloader.js +9 -7
- package/dist/lib/transpile-ts.js +9 -29
- package/dist/virtual-routes/routes/index.jsx +40 -19
- package/oclif.manifest.json +710 -1
- package/package.json +16 -16
- package/dist/commands/hydrogen/build.d.ts +0 -23
- package/dist/commands/hydrogen/check.d.ts +0 -15
- package/dist/commands/hydrogen/codegen-unstable.d.ts +0 -15
- package/dist/commands/hydrogen/dev.d.ts +0 -21
- package/dist/commands/hydrogen/env/list.d.ts +0 -18
- package/dist/commands/hydrogen/env/pull.d.ts +0 -22
- package/dist/commands/hydrogen/g.d.ts +0 -10
- package/dist/commands/hydrogen/generate/route.d.ts +0 -32
- package/dist/commands/hydrogen/generate/route.test.d.ts +0 -1
- package/dist/commands/hydrogen/generate/routes.d.ts +0 -16
- package/dist/commands/hydrogen/init.d.ts +0 -24
- package/dist/commands/hydrogen/init.test.d.ts +0 -1
- package/dist/commands/hydrogen/link.d.ts +0 -23
- package/dist/commands/hydrogen/link.test.d.ts +0 -1
- package/dist/commands/hydrogen/list.d.ts +0 -21
- package/dist/commands/hydrogen/list.test.d.ts +0 -1
- package/dist/commands/hydrogen/preview.d.ts +0 -17
- package/dist/commands/hydrogen/shortcut.d.ts +0 -9
- package/dist/commands/hydrogen/shortcut.test.d.ts +0 -1
- package/dist/commands/hydrogen/unlink.d.ts +0 -16
- package/dist/commands/hydrogen/unlink.test.d.ts +0 -1
- package/dist/create-app.d.ts +0 -1
- package/dist/generator-templates/routes/[sitemap.xml].tsx +0 -235
- package/dist/generator-templates/routes/account/login.tsx +0 -103
- package/dist/generator-templates/routes/account/register.tsx +0 -103
- package/dist/generator-templates/routes/cart.tsx +0 -81
- package/dist/generator-templates/routes/collections/$collectionHandle.tsx +0 -104
- package/dist/generator-templates/routes/collections/index.tsx +0 -102
- package/dist/generator-templates/routes/graphiql.tsx +0 -10
- package/dist/generator-templates/routes/index.tsx +0 -40
- package/dist/generator-templates/routes/pages/$pageHandle.tsx +0 -112
- package/dist/generator-templates/routes/policies/$policyHandle.tsx +0 -140
- package/dist/generator-templates/routes/policies/index.tsx +0 -117
- package/dist/generator-templates/routes/products/$productHandle.tsx +0 -92
- package/dist/hooks/init.d.ts +0 -5
- package/dist/lib/admin-session.d.ts +0 -6
- package/dist/lib/admin-session.js +0 -16
- package/dist/lib/admin-session.test.d.ts +0 -1
- package/dist/lib/admin-session.test.js +0 -27
- package/dist/lib/admin-urls.d.ts +0 -8
- package/dist/lib/check-lockfile.d.ts +0 -3
- package/dist/lib/check-lockfile.test.d.ts +0 -1
- package/dist/lib/check-version.d.ts +0 -16
- package/dist/lib/check-version.test.d.ts +0 -1
- package/dist/lib/codegen.d.ts +0 -26
- package/dist/lib/combined-environment-variables.d.ts +0 -8
- package/dist/lib/combined-environment-variables.js +0 -57
- package/dist/lib/combined-environment-variables.test.d.ts +0 -1
- package/dist/lib/combined-environment-variables.test.js +0 -111
- package/dist/lib/config.d.ts +0 -20
- package/dist/lib/flags.d.ts +0 -27
- package/dist/lib/flags.test.d.ts +0 -1
- package/dist/lib/graphql/admin/create-storefront.d.ts +0 -17
- package/dist/lib/graphql/admin/fetch-job.d.ts +0 -23
- package/dist/lib/graphql/admin/link-storefront.d.ts +0 -14
- package/dist/lib/graphql/admin/list-environments.d.ts +0 -21
- package/dist/lib/graphql/admin/list-storefronts.d.ts +0 -25
- package/dist/lib/graphql/admin/pull-variables.d.ts +0 -21
- package/dist/lib/graphql.d.ts +0 -21
- package/dist/lib/graphql.js +0 -18
- package/dist/lib/graphql.test.d.ts +0 -1
- package/dist/lib/log.d.ts +0 -6
- package/dist/lib/mini-oxygen.d.ts +0 -22
- package/dist/lib/missing-routes.d.ts +0 -8
- package/dist/lib/missing-routes.test.d.ts +0 -1
- package/dist/lib/missing-storefronts.d.ts +0 -5
- package/dist/lib/missing-storefronts.js +0 -18
- package/dist/lib/process.d.ts +0 -6
- package/dist/lib/pull-environment-variables.d.ts +0 -20
- package/dist/lib/pull-environment-variables.js +0 -57
- package/dist/lib/pull-environment-variables.test.d.ts +0 -1
- package/dist/lib/pull-environment-variables.test.js +0 -174
- package/dist/lib/remix-version-interop.d.ts +0 -11
- package/dist/lib/remix-version-interop.test.d.ts +0 -1
- package/dist/lib/render-errors.d.ts +0 -16
- package/dist/lib/shell.d.ts +0 -11
- package/dist/lib/shell.test.d.ts +0 -1
- package/dist/lib/shop.d.ts +0 -7
- package/dist/lib/shop.js +0 -32
- package/dist/lib/shop.test.d.ts +0 -1
- package/dist/lib/shop.test.js +0 -78
- package/dist/lib/shopify-config.d.ts +0 -35
- package/dist/lib/shopify-config.test.d.ts +0 -1
- package/dist/lib/string.d.ts +0 -3
- package/dist/lib/string.test.d.ts +0 -1
- package/dist/lib/template-downloader.d.ts +0 -6
- package/dist/lib/transpile-ts.d.ts +0 -16
- package/dist/lib/user-errors.d.ts +0 -9
- package/dist/lib/user-errors.js +0 -11
- package/dist/lib/virtual-routes.d.ts +0 -7
- package/dist/lib/virtual-routes.test.d.ts +0 -1
- /package/dist/{commands/hydrogen/env/list.test.d.ts → lib/setups/css/common.js} +0 -0
- /package/dist/{commands/hydrogen/env/pull.test.d.ts → lib/setups/i18n/mock-i18n-types.js} +0 -0
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import Command from '@shopify/cli-kit/node/base-command';
|
|
3
3
|
import { basename } from '@shopify/cli-kit/node/path';
|
|
4
|
-
import { renderConfirmationPrompt, renderWarning, renderSelectPrompt, renderTextPrompt, renderTasks
|
|
4
|
+
import { renderSuccess, renderConfirmationPrompt, renderWarning, renderSelectPrompt, renderTextPrompt, renderTasks } from '@shopify/cli-kit/node/ui';
|
|
5
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
5
6
|
import { commonFlags } from '../../lib/flags.js';
|
|
6
|
-
import { getHydrogenShop } from '../../lib/shop.js';
|
|
7
7
|
import { getStorefronts } from '../../lib/graphql/admin/link-storefront.js';
|
|
8
|
+
import { setStorefront } from '../../lib/shopify-config.js';
|
|
8
9
|
import { createStorefront } from '../../lib/graphql/admin/create-storefront.js';
|
|
9
10
|
import { waitForJob } from '../../lib/graphql/admin/fetch-job.js';
|
|
10
|
-
import { getConfig, setStorefront } from '../../lib/shopify-config.js';
|
|
11
|
-
import { logMissingStorefronts } from '../../lib/missing-storefronts.js';
|
|
12
11
|
import { titleize } from '../../lib/string.js';
|
|
13
12
|
import { getCliCommand } from '../../lib/shell.js';
|
|
14
|
-
import {
|
|
13
|
+
import { login } from '../../lib/auth.js';
|
|
15
14
|
|
|
16
15
|
class Link extends Command {
|
|
17
16
|
static description = "Link a local project to one of your shop's Hydrogen storefronts.";
|
|
18
17
|
static flags = {
|
|
19
18
|
force: commonFlags.force,
|
|
20
19
|
path: commonFlags.path,
|
|
21
|
-
shop: commonFlags.shop,
|
|
22
20
|
storefront: Flags.string({
|
|
23
21
|
description: `The name of a Hydrogen Storefront (e.g. "Jane's Apparel")`,
|
|
24
22
|
env: "SHOPIFY_HYDROGEN_STOREFRONT"
|
|
@@ -26,35 +24,54 @@ class Link extends Command {
|
|
|
26
24
|
};
|
|
27
25
|
async run() {
|
|
28
26
|
const { flags } = await this.parse(Link);
|
|
29
|
-
await
|
|
27
|
+
await runLink(flags);
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
|
-
|
|
33
|
-
async function linkStorefront({
|
|
30
|
+
async function runLink({
|
|
34
31
|
force,
|
|
35
|
-
path,
|
|
36
|
-
|
|
37
|
-
storefront: flagStorefront,
|
|
38
|
-
silent = false
|
|
32
|
+
path: root = process.cwd(),
|
|
33
|
+
storefront: flagStorefront
|
|
39
34
|
}) {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
const [{ session, config }, cliCommand] = await Promise.all([
|
|
36
|
+
login(root),
|
|
37
|
+
getCliCommand()
|
|
38
|
+
]);
|
|
39
|
+
const linkedStore = await linkStorefront(root, session, config, {
|
|
40
|
+
force,
|
|
41
|
+
flagStorefront,
|
|
42
|
+
cliCommand
|
|
43
|
+
});
|
|
44
|
+
if (!linkedStore)
|
|
45
|
+
return;
|
|
46
|
+
renderSuccess({
|
|
47
|
+
body: [{ userInput: linkedStore.title }, "is now linked"],
|
|
48
|
+
nextSteps: [
|
|
49
|
+
[
|
|
50
|
+
"Run",
|
|
51
|
+
{ command: `${cliCommand} dev` },
|
|
52
|
+
"to start your local development server and start building"
|
|
53
|
+
]
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function linkStorefront(root, session, config, {
|
|
58
|
+
force = false,
|
|
59
|
+
flagStorefront,
|
|
60
|
+
cliCommand
|
|
61
|
+
}) {
|
|
62
|
+
if (!config.shop) {
|
|
63
|
+
throw new AbortError("No shop found in local config, login first.");
|
|
64
|
+
}
|
|
65
|
+
if (config.storefront?.id && !force) {
|
|
43
66
|
const overwriteLink = await renderConfirmationPrompt({
|
|
44
|
-
message: `Your project is currently linked to ${
|
|
67
|
+
message: `Your project is currently linked to ${config.storefront.title}. Do you want to link to a different Hydrogen storefront on Shopify?`
|
|
45
68
|
});
|
|
46
69
|
if (!overwriteLink) {
|
|
47
70
|
return;
|
|
48
71
|
}
|
|
49
72
|
}
|
|
50
|
-
const
|
|
51
|
-
if (storefronts.length === 0) {
|
|
52
|
-
logMissingStorefronts(adminSession);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
73
|
+
const storefronts = await getStorefronts(session);
|
|
55
74
|
let selectedStorefront;
|
|
56
|
-
let selectCreateNewStorefront = false;
|
|
57
|
-
const cliCommand = await getCliCommand();
|
|
58
75
|
if (flagStorefront) {
|
|
59
76
|
selectedStorefront = storefronts.find(
|
|
60
77
|
({ title }) => title === flagStorefront
|
|
@@ -66,7 +83,7 @@ async function linkStorefront({
|
|
|
66
83
|
"There's no storefront matching",
|
|
67
84
|
{ userInput: flagStorefront },
|
|
68
85
|
"on your",
|
|
69
|
-
{ userInput: shop },
|
|
86
|
+
{ userInput: config.shop },
|
|
70
87
|
"shop. To see all available Hydrogen storefronts, run",
|
|
71
88
|
{
|
|
72
89
|
command: `${cliCommand} list`
|
|
@@ -76,36 +93,36 @@ async function linkStorefront({
|
|
|
76
93
|
return;
|
|
77
94
|
}
|
|
78
95
|
} else {
|
|
79
|
-
const choices =
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
96
|
+
const choices = [
|
|
97
|
+
{
|
|
98
|
+
label: "Create a new storefront",
|
|
99
|
+
value: null
|
|
100
|
+
},
|
|
101
|
+
...storefronts.map(({ id, title, productionUrl }) => ({
|
|
102
|
+
label: `${title} (${productionUrl})`,
|
|
103
|
+
value: id
|
|
104
|
+
}))
|
|
105
|
+
];
|
|
83
106
|
const storefrontId = await renderSelectPrompt({
|
|
84
|
-
message: "
|
|
107
|
+
message: "Select a Hydrogen storefront to link",
|
|
85
108
|
choices
|
|
86
109
|
});
|
|
87
|
-
if (storefrontId
|
|
88
|
-
selectCreateNewStorefront = true;
|
|
89
|
-
} else {
|
|
110
|
+
if (storefrontId) {
|
|
90
111
|
selectedStorefront = storefronts.find(({ id }) => id === storefrontId);
|
|
112
|
+
} else {
|
|
113
|
+
selectedStorefront = await createNewStorefront(root, session);
|
|
91
114
|
}
|
|
92
115
|
}
|
|
93
|
-
if (selectCreateNewStorefront) {
|
|
94
|
-
const storefront = await createNewStorefront(path, shop);
|
|
95
|
-
if (!storefront) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
selectedStorefront = storefront;
|
|
99
|
-
}
|
|
100
116
|
if (selectedStorefront) {
|
|
101
|
-
await
|
|
117
|
+
await setStorefront(root, selectedStorefront);
|
|
102
118
|
}
|
|
119
|
+
return selectedStorefront;
|
|
103
120
|
}
|
|
104
|
-
async function createNewStorefront(
|
|
105
|
-
const projectDirectory =
|
|
121
|
+
async function createNewStorefront(root, session) {
|
|
122
|
+
const projectDirectory = basename(root);
|
|
106
123
|
const projectName = await renderTextPrompt({
|
|
107
|
-
message: "
|
|
108
|
-
defaultValue: titleize(projectDirectory)
|
|
124
|
+
message: "New storefront name",
|
|
125
|
+
defaultValue: titleize(projectDirectory)
|
|
109
126
|
});
|
|
110
127
|
let storefront;
|
|
111
128
|
let jobId;
|
|
@@ -113,45 +130,29 @@ async function createNewStorefront(path, shop) {
|
|
|
113
130
|
{
|
|
114
131
|
title: "Creating storefront",
|
|
115
132
|
task: async () => {
|
|
116
|
-
const result = await createStorefront(
|
|
133
|
+
const result = await createStorefront(session, projectName);
|
|
117
134
|
storefront = result.storefront;
|
|
118
135
|
jobId = result.jobId;
|
|
119
|
-
if (result.userErrors.length > 0) {
|
|
120
|
-
renderUserErrors(result.userErrors);
|
|
121
|
-
}
|
|
122
136
|
}
|
|
123
137
|
},
|
|
124
138
|
{
|
|
125
139
|
title: "Creating API tokens",
|
|
126
140
|
task: async () => {
|
|
127
141
|
try {
|
|
128
|
-
await waitForJob(
|
|
142
|
+
await waitForJob(session, jobId);
|
|
129
143
|
} catch (_err) {
|
|
130
144
|
storefront = void 0;
|
|
131
|
-
renderError(
|
|
132
|
-
"Please try again or contact support if the error persists."
|
|
133
|
-
);
|
|
134
145
|
}
|
|
135
146
|
},
|
|
136
147
|
skip: () => !jobId
|
|
137
148
|
}
|
|
138
149
|
]);
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (!silent) {
|
|
144
|
-
renderSuccess({
|
|
145
|
-
body: [{ userInput: selectedStorefront.title }, "is now linked"],
|
|
146
|
-
nextSteps: [
|
|
147
|
-
[
|
|
148
|
-
"Run",
|
|
149
|
-
{ command: `${cliCommand} dev` },
|
|
150
|
-
"to start your local development server and start building"
|
|
151
|
-
]
|
|
152
|
-
]
|
|
153
|
-
});
|
|
150
|
+
if (!storefront) {
|
|
151
|
+
throw new AbortError(
|
|
152
|
+
"Unknown error ocurred. Please try again or contact support if the error persists."
|
|
153
|
+
);
|
|
154
154
|
}
|
|
155
|
+
return storefront;
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
export { Link as default, linkStorefront };
|
|
158
|
+
export { Link as default, linkStorefront, runLink };
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { vi, describe, beforeEach, afterEach, it, expect } from 'vitest';
|
|
2
2
|
import { mockAndCaptureOutput } from '@shopify/cli-kit/node/testing/output';
|
|
3
3
|
import { renderSelectPrompt, renderTextPrompt, renderConfirmationPrompt } from '@shopify/cli-kit/node/ui';
|
|
4
|
-
import {
|
|
4
|
+
import { login } from '../../lib/auth.js';
|
|
5
5
|
import { getStorefronts } from '../../lib/graphql/admin/link-storefront.js';
|
|
6
|
+
import { runLink } from './link.js';
|
|
6
7
|
import { createStorefront } from '../../lib/graphql/admin/create-storefront.js';
|
|
7
8
|
import { waitForJob } from '../../lib/graphql/admin/fetch-job.js';
|
|
8
|
-
import {
|
|
9
|
-
import { renderUserErrors, renderError } from '../../lib/user-errors.js';
|
|
10
|
-
import { linkStorefront } from './link.js';
|
|
9
|
+
import { setStorefront } from '../../lib/shopify-config.js';
|
|
11
10
|
|
|
12
|
-
const SHOP = "my-shop";
|
|
13
|
-
const ADMIN_SESSION = {
|
|
14
|
-
token: "abc123",
|
|
15
|
-
storeFqdn: SHOP
|
|
16
|
-
};
|
|
17
11
|
vi.mock("@shopify/cli-kit/node/ui", async () => {
|
|
18
12
|
const original = await vi.importActual("@shopify/cli-kit/node/ui");
|
|
19
13
|
return {
|
|
@@ -23,41 +17,62 @@ vi.mock("@shopify/cli-kit/node/ui", async () => {
|
|
|
23
17
|
renderTextPrompt: vi.fn()
|
|
24
18
|
};
|
|
25
19
|
});
|
|
26
|
-
vi.mock("../../lib/
|
|
20
|
+
vi.mock("../../lib/auth.js");
|
|
27
21
|
vi.mock("../../lib/shopify-config.js");
|
|
28
22
|
vi.mock("../../lib/graphql/admin/link-storefront.js");
|
|
29
23
|
vi.mock("../../lib/graphql/admin/create-storefront.js");
|
|
30
24
|
vi.mock("../../lib/graphql/admin/fetch-job.js");
|
|
31
|
-
vi.mock("../../lib/
|
|
32
|
-
vi.mock("../../lib/shop.js", () => ({
|
|
33
|
-
getHydrogenShop: () => SHOP
|
|
34
|
-
}));
|
|
35
|
-
vi.mock("../../lib/shell.js", () => ({
|
|
36
|
-
getCliCommand: () => "h2"
|
|
37
|
-
}));
|
|
25
|
+
vi.mock("../../lib/shell.js", () => ({ getCliCommand: () => "h2" }));
|
|
38
26
|
describe("link", () => {
|
|
39
27
|
const outputMock = mockAndCaptureOutput();
|
|
28
|
+
const ADMIN_SESSION = {
|
|
29
|
+
token: "abc123",
|
|
30
|
+
storeFqdn: "my-shop.myshopify.com"
|
|
31
|
+
};
|
|
32
|
+
const FULL_SHOPIFY_CONFIG = {
|
|
33
|
+
shop: "my-shop.myshopify.com",
|
|
34
|
+
shopName: "My Shop",
|
|
35
|
+
email: "email",
|
|
36
|
+
storefront: {
|
|
37
|
+
id: "gid://shopify/HydrogenStorefront/1",
|
|
38
|
+
title: "Hydrogen"
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const UNLINKED_SHOPIFY_CONFIG = {
|
|
42
|
+
...FULL_SHOPIFY_CONFIG,
|
|
43
|
+
storefront: void 0
|
|
44
|
+
};
|
|
40
45
|
beforeEach(async () => {
|
|
41
|
-
vi.mocked(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
vi.mocked(
|
|
46
|
+
vi.mocked(login).mockResolvedValue({
|
|
47
|
+
session: ADMIN_SESSION,
|
|
48
|
+
config: UNLINKED_SHOPIFY_CONFIG
|
|
49
|
+
});
|
|
50
|
+
vi.mocked(getStorefronts).mockResolvedValue([
|
|
51
|
+
{
|
|
52
|
+
...FULL_SHOPIFY_CONFIG.storefront,
|
|
53
|
+
parsedId: "1",
|
|
54
|
+
productionUrl: "https://example.com"
|
|
55
|
+
}
|
|
56
|
+
]);
|
|
57
|
+
vi.mocked(renderSelectPrompt).mockResolvedValue(FULL_SHOPIFY_CONFIG.shop);
|
|
53
58
|
});
|
|
54
59
|
afterEach(() => {
|
|
55
60
|
vi.resetAllMocks();
|
|
56
61
|
outputMock.clear();
|
|
57
62
|
});
|
|
58
|
-
it("
|
|
59
|
-
await
|
|
60
|
-
expect(getStorefronts).toHaveBeenCalledWith(
|
|
63
|
+
it("fetches the storefronts", async () => {
|
|
64
|
+
await runLink({});
|
|
65
|
+
expect(getStorefronts).toHaveBeenCalledWith(ADMIN_SESSION);
|
|
66
|
+
});
|
|
67
|
+
it("renders a list of choices and forwards the selection to setStorefront", async () => {
|
|
68
|
+
vi.mocked(renderSelectPrompt).mockResolvedValue(
|
|
69
|
+
FULL_SHOPIFY_CONFIG.storefront.id
|
|
70
|
+
);
|
|
71
|
+
await runLink({ path: "my-path" });
|
|
72
|
+
expect(setStorefront).toHaveBeenCalledWith(
|
|
73
|
+
"my-path",
|
|
74
|
+
expect.objectContaining(FULL_SHOPIFY_CONFIG.storefront)
|
|
75
|
+
);
|
|
61
76
|
});
|
|
62
77
|
describe("when you want to link an existing Hydrogen storefront", () => {
|
|
63
78
|
beforeEach(async () => {
|
|
@@ -66,141 +81,91 @@ describe("link", () => {
|
|
|
66
81
|
);
|
|
67
82
|
});
|
|
68
83
|
it("renders a list of choices and forwards the selection to setStorefront", async () => {
|
|
69
|
-
|
|
84
|
+
vi.mocked(renderSelectPrompt).mockResolvedValue(
|
|
85
|
+
FULL_SHOPIFY_CONFIG.storefront.id
|
|
86
|
+
);
|
|
87
|
+
await runLink({ path: "my-path" });
|
|
70
88
|
expect(setStorefront).toHaveBeenCalledWith(
|
|
71
89
|
"my-path",
|
|
72
|
-
expect.objectContaining(
|
|
73
|
-
id: "gid://shopify/HydrogenStorefront/1",
|
|
74
|
-
title: "Hydrogen"
|
|
75
|
-
})
|
|
90
|
+
expect.objectContaining(FULL_SHOPIFY_CONFIG.storefront)
|
|
76
91
|
);
|
|
77
92
|
});
|
|
78
93
|
it("renders a success message", async () => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
expect(outputMock.info()).toMatch(
|
|
82
|
-
/Run `h2 dev` to start your local development server and start building/g
|
|
94
|
+
vi.mocked(renderSelectPrompt).mockResolvedValue(
|
|
95
|
+
FULL_SHOPIFY_CONFIG.storefront.id
|
|
83
96
|
);
|
|
97
|
+
await runLink({ path: "my-path" });
|
|
98
|
+
expect(outputMock.info()).toMatch(/is now linked/i);
|
|
99
|
+
expect(outputMock.info()).toMatch(/Run `h2 dev`/i);
|
|
84
100
|
});
|
|
85
101
|
});
|
|
86
102
|
describe("when you want to link a new Hydrogen storefront", () => {
|
|
87
103
|
const expectedStorefrontName = "New Storefront";
|
|
88
104
|
const expectedJobId = "gid://shopify/Job/1";
|
|
89
105
|
beforeEach(async () => {
|
|
90
|
-
vi.mocked(renderSelectPrompt).mockResolvedValue(
|
|
106
|
+
vi.mocked(renderSelectPrompt).mockResolvedValue(null);
|
|
91
107
|
vi.mocked(createStorefront).mockResolvedValue({
|
|
92
|
-
adminSession: ADMIN_SESSION,
|
|
93
108
|
storefront: {
|
|
94
109
|
id: "gid://shopify/HydrogenStorefront/1",
|
|
95
110
|
title: expectedStorefrontName,
|
|
96
111
|
productionUrl: "https://example.com"
|
|
97
112
|
},
|
|
98
|
-
userErrors: [],
|
|
99
113
|
jobId: expectedJobId
|
|
100
114
|
});
|
|
101
115
|
});
|
|
102
116
|
it("chooses to create a new storefront given the directory path", async () => {
|
|
103
|
-
await
|
|
117
|
+
await runLink({ path: "my-path" });
|
|
104
118
|
expect(renderTextPrompt).toHaveBeenCalledWith({
|
|
105
119
|
message: expect.stringMatching(/name/i),
|
|
106
120
|
defaultValue: "My Path"
|
|
107
121
|
});
|
|
108
122
|
});
|
|
109
|
-
it("chooses to create a new storefront without directory path", async () => {
|
|
110
|
-
await linkStorefront({});
|
|
111
|
-
expect(renderTextPrompt).toHaveBeenCalledWith({
|
|
112
|
-
message: expect.stringMatching(/name/i),
|
|
113
|
-
defaultValue: "Hydrogen Storefront"
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
123
|
it("handles the successful creation of the storefront on Admin", async () => {
|
|
117
|
-
await
|
|
118
|
-
expect(waitForJob).toHaveBeenCalledWith(
|
|
124
|
+
await runLink({});
|
|
125
|
+
expect(waitForJob).toHaveBeenCalledWith(ADMIN_SESSION, expectedJobId);
|
|
119
126
|
expect(outputMock.info()).toContain(
|
|
120
127
|
`${expectedStorefrontName} is now linked`
|
|
121
128
|
);
|
|
122
129
|
});
|
|
123
|
-
it("handles the user-errors when creating the storefront on Admin", async () => {
|
|
124
|
-
const expectedUserErrors = [
|
|
125
|
-
{
|
|
126
|
-
code: "INVALID",
|
|
127
|
-
field: [],
|
|
128
|
-
message: "Bad thing happend."
|
|
129
|
-
}
|
|
130
|
-
];
|
|
131
|
-
vi.mocked(createStorefront).mockResolvedValue({
|
|
132
|
-
adminSession: ADMIN_SESSION,
|
|
133
|
-
storefront: void 0,
|
|
134
|
-
userErrors: expectedUserErrors,
|
|
135
|
-
jobId: void 0
|
|
136
|
-
});
|
|
137
|
-
await linkStorefront({});
|
|
138
|
-
expect(waitForJob).not.toHaveBeenCalled();
|
|
139
|
-
expect(renderUserErrors).toHaveBeenCalledWith(expectedUserErrors);
|
|
140
|
-
});
|
|
141
130
|
it("handles the job errors when creating the storefront on Admin", async () => {
|
|
142
131
|
vi.mocked(waitForJob).mockRejectedValue(void 0);
|
|
143
|
-
await
|
|
144
|
-
expect(renderError).toHaveBeenCalled();
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
describe("when there are no Hydrogen storefronts", () => {
|
|
148
|
-
it("renders a message and returns early", async () => {
|
|
149
|
-
vi.mocked(getStorefronts).mockResolvedValue({
|
|
150
|
-
adminSession: ADMIN_SESSION,
|
|
151
|
-
storefronts: []
|
|
152
|
-
});
|
|
153
|
-
await linkStorefront({});
|
|
154
|
-
expect(outputMock.info()).toMatch(
|
|
155
|
-
/There are no Hydrogen storefronts on your Shop/g
|
|
156
|
-
);
|
|
157
|
-
expect(renderSelectPrompt).not.toHaveBeenCalled();
|
|
158
|
-
expect(setStorefront).not.toHaveBeenCalled();
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
describe("when no storefront gets selected", () => {
|
|
162
|
-
it("does not call setStorefront", async () => {
|
|
163
|
-
vi.mocked(renderSelectPrompt).mockResolvedValue("");
|
|
164
|
-
await linkStorefront({});
|
|
165
|
-
expect(setStorefront).not.toHaveBeenCalled();
|
|
132
|
+
await expect(runLink({})).rejects.toThrow(Error);
|
|
166
133
|
});
|
|
167
134
|
});
|
|
168
135
|
describe("when a linked storefront already exists", () => {
|
|
169
136
|
beforeEach(() => {
|
|
170
|
-
vi.mocked(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
title: "Existing Link"
|
|
174
|
-
}
|
|
137
|
+
vi.mocked(login).mockResolvedValue({
|
|
138
|
+
session: ADMIN_SESSION,
|
|
139
|
+
config: FULL_SHOPIFY_CONFIG
|
|
175
140
|
});
|
|
176
141
|
});
|
|
177
142
|
it("prompts the user to confirm", async () => {
|
|
178
143
|
vi.mocked(renderConfirmationPrompt).mockResolvedValue(true);
|
|
179
|
-
await
|
|
144
|
+
await runLink({});
|
|
180
145
|
expect(renderConfirmationPrompt).toHaveBeenCalledWith({
|
|
181
146
|
message: expect.stringMatching(
|
|
182
|
-
/
|
|
147
|
+
/link to a different Hydrogen storefront/i
|
|
183
148
|
)
|
|
184
149
|
});
|
|
185
150
|
});
|
|
186
151
|
describe("and the user cancels", () => {
|
|
187
152
|
it("returns early", async () => {
|
|
188
153
|
vi.mocked(renderConfirmationPrompt).mockResolvedValue(false);
|
|
189
|
-
await
|
|
190
|
-
expect(
|
|
154
|
+
await runLink({});
|
|
155
|
+
expect(getStorefronts).not.toHaveBeenCalled();
|
|
191
156
|
expect(setStorefront).not.toHaveBeenCalled();
|
|
192
157
|
});
|
|
193
158
|
});
|
|
194
159
|
describe("and the --force flag is provided", () => {
|
|
195
160
|
it("does not prompt the user to confirm", async () => {
|
|
196
|
-
await
|
|
161
|
+
await runLink({ force: true });
|
|
197
162
|
expect(renderConfirmationPrompt).not.toHaveBeenCalled();
|
|
198
163
|
});
|
|
199
164
|
});
|
|
200
165
|
});
|
|
201
166
|
describe("when the --storefront flag is provided", () => {
|
|
202
167
|
it("does not prompt the user to make a selection", async () => {
|
|
203
|
-
await
|
|
168
|
+
await runLink({ path: "my-path", storefront: "Hydrogen" });
|
|
204
169
|
expect(renderSelectPrompt).not.toHaveBeenCalled();
|
|
205
170
|
expect(setStorefront).toHaveBeenCalledWith(
|
|
206
171
|
"my-path",
|
|
@@ -213,7 +178,7 @@ describe("link", () => {
|
|
|
213
178
|
describe("and there is no matching storefront", () => {
|
|
214
179
|
it("renders a warning message and returns early", async () => {
|
|
215
180
|
const outputMock2 = mockAndCaptureOutput();
|
|
216
|
-
await
|
|
181
|
+
await runLink({ storefront: "Does not exist" });
|
|
217
182
|
expect(setStorefront).not.toHaveBeenCalled();
|
|
218
183
|
expect(outputMock2.warn()).toMatch(/Couldn\'t find Does not exist/g);
|
|
219
184
|
});
|
|
@@ -2,32 +2,33 @@ import Command from '@shopify/cli-kit/node/base-command';
|
|
|
2
2
|
import { pluralize } from '@shopify/cli-kit/common/string';
|
|
3
3
|
import colors from '@shopify/cli-kit/node/colors';
|
|
4
4
|
import { outputNewline, outputInfo, outputContent } from '@shopify/cli-kit/node/output';
|
|
5
|
+
import { renderInfo } from '@shopify/cli-kit/node/ui';
|
|
5
6
|
import { commonFlags } from '../../lib/flags.js';
|
|
6
|
-
import {
|
|
7
|
-
import { parseGid } from '../../lib/graphql.js';
|
|
7
|
+
import { parseGid } from '../../lib/gid.js';
|
|
8
8
|
import { getStorefrontsWithDeployment } from '../../lib/graphql/admin/list-storefronts.js';
|
|
9
|
-
import {
|
|
9
|
+
import { newHydrogenStorefrontUrl } from '../../lib/admin-urls.js';
|
|
10
|
+
import { login } from '../../lib/auth.js';
|
|
11
|
+
import { getCliCommand } from '../../lib/shell.js';
|
|
10
12
|
|
|
11
13
|
class List extends Command {
|
|
12
14
|
static description = "Returns a list of Hydrogen storefronts available on a given shop.";
|
|
13
15
|
static flags = {
|
|
14
|
-
path: commonFlags.path
|
|
15
|
-
shop: commonFlags.shop
|
|
16
|
+
path: commonFlags.path
|
|
16
17
|
};
|
|
17
18
|
async run() {
|
|
18
19
|
const { flags } = await this.parse(List);
|
|
19
|
-
await
|
|
20
|
+
await runList(flags);
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
|
-
async function
|
|
23
|
-
const
|
|
24
|
-
const
|
|
23
|
+
async function runList({ path: root = process.cwd() }) {
|
|
24
|
+
const { session } = await login(root);
|
|
25
|
+
const storefronts = await getStorefrontsWithDeployment(session);
|
|
25
26
|
if (storefronts.length > 0) {
|
|
26
27
|
outputNewline();
|
|
27
28
|
outputInfo(
|
|
28
29
|
pluralizedStorefronts({
|
|
29
30
|
storefronts,
|
|
30
|
-
shop
|
|
31
|
+
shop: session.storeFqdn
|
|
31
32
|
}).toString()
|
|
32
33
|
);
|
|
33
34
|
storefronts.forEach(
|
|
@@ -53,7 +54,16 @@ async function listStorefronts({ path, shop: flagShop }) {
|
|
|
53
54
|
}
|
|
54
55
|
);
|
|
55
56
|
} else {
|
|
56
|
-
|
|
57
|
+
renderInfo({
|
|
58
|
+
headline: "Hydrogen storefronts",
|
|
59
|
+
body: "There are no Hydrogen storefronts on your Shop.",
|
|
60
|
+
nextSteps: [
|
|
61
|
+
`Ensure you are logged in to the correct shop (currently: ${session.storeFqdn})`,
|
|
62
|
+
`Create a new Hydrogen storefront: Run \`${await getCliCommand(
|
|
63
|
+
root
|
|
64
|
+
)} link\` or visit ${newHydrogenStorefrontUrl(session)}`
|
|
65
|
+
]
|
|
66
|
+
});
|
|
57
67
|
}
|
|
58
68
|
}
|
|
59
69
|
const dateFormat = new Intl.DateTimeFormat("default", {
|
|
@@ -84,4 +94,4 @@ const pluralizedStorefronts = ({
|
|
|
84
94
|
);
|
|
85
95
|
};
|
|
86
96
|
|
|
87
|
-
export { List as default, formatDeployment,
|
|
97
|
+
export { List as default, formatDeployment, runList };
|