@shopify/cli-hydrogen 6.0.2 → 7.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.js +40 -78
- package/dist/commands/hydrogen/codegen.js +8 -3
- package/dist/commands/hydrogen/deploy.js +173 -37
- package/dist/commands/hydrogen/deploy.test.js +192 -20
- package/dist/commands/hydrogen/dev.js +56 -31
- package/dist/commands/hydrogen/init.js +1 -1
- package/dist/commands/hydrogen/init.test.js +155 -53
- package/dist/commands/hydrogen/link.js +5 -21
- package/dist/commands/hydrogen/link.test.js +10 -10
- package/dist/commands/hydrogen/preview.js +22 -11
- package/dist/commands/hydrogen/setup.js +0 -4
- package/dist/commands/hydrogen/setup.test.js +0 -1
- package/dist/commands/hydrogen/shortcut.js +1 -0
- package/dist/commands/hydrogen/upgrade.js +720 -0
- package/dist/commands/hydrogen/upgrade.test.js +786 -0
- package/dist/generator-templates/starter/.graphqlrc.yml +12 -1
- package/dist/generator-templates/starter/CHANGELOG.md +126 -0
- package/dist/generator-templates/starter/README.md +23 -0
- package/dist/generator-templates/starter/app/components/Cart.tsx +1 -1
- package/dist/generator-templates/starter/app/components/Footer.tsx +3 -1
- package/dist/generator-templates/starter/app/components/Header.tsx +5 -1
- package/dist/generator-templates/starter/app/components/Layout.tsx +14 -11
- package/dist/generator-templates/starter/app/components/Search.tsx +1 -1
- package/dist/generator-templates/starter/app/graphql/customer-account/CustomerAddressMutations.ts +61 -0
- package/dist/generator-templates/starter/app/graphql/customer-account/CustomerDetailsQuery.ts +39 -0
- package/dist/generator-templates/starter/app/graphql/customer-account/CustomerOrderQuery.ts +87 -0
- package/dist/generator-templates/starter/app/graphql/customer-account/CustomerOrdersQuery.ts +58 -0
- package/dist/generator-templates/starter/app/graphql/customer-account/CustomerUpdateMutation.ts +24 -0
- package/dist/generator-templates/starter/app/lib/fragments.ts +102 -0
- package/dist/generator-templates/starter/app/lib/session.ts +67 -0
- package/dist/generator-templates/starter/app/root.tsx +11 -45
- package/dist/generator-templates/starter/app/routes/[robots.txt].tsx +0 -27
- package/dist/generator-templates/starter/app/routes/account.$.tsx +8 -4
- package/dist/generator-templates/starter/app/routes/account._index.tsx +5 -0
- package/dist/generator-templates/starter/app/routes/account.addresses.tsx +215 -206
- package/dist/generator-templates/starter/app/routes/account.orders.$id.tsx +56 -163
- package/dist/generator-templates/starter/app/routes/account.orders._index.tsx +32 -109
- package/dist/generator-templates/starter/app/routes/account.profile.tsx +40 -180
- package/dist/generator-templates/starter/app/routes/account.tsx +20 -135
- package/dist/generator-templates/starter/app/routes/account_.authorize.tsx +5 -0
- package/dist/generator-templates/starter/app/routes/account_.login.tsx +3 -140
- package/dist/generator-templates/starter/app/routes/account_.logout.tsx +5 -24
- package/dist/generator-templates/starter/app/routes/cart.tsx +7 -5
- package/dist/generator-templates/starter/app/routes/collections.$handle.tsx +1 -1
- package/dist/generator-templates/starter/app/routes/products.$handle.tsx +2 -2
- package/dist/generator-templates/starter/app/routes/search.tsx +1 -1
- package/dist/generator-templates/starter/customer-accountapi.generated.d.ts +506 -0
- package/dist/generator-templates/starter/package.json +11 -10
- package/dist/generator-templates/starter/remix.config.js +4 -0
- package/dist/generator-templates/starter/remix.env.d.ts +6 -11
- package/dist/generator-templates/starter/server.ts +24 -167
- package/dist/generator-templates/starter/storefrontapi.generated.d.ts +104 -881
- package/dist/hooks/init.js +4 -4
- package/dist/lib/auth.js +5 -10
- package/dist/lib/build.js +6 -1
- package/dist/lib/bundle/analyzer.js +36 -26
- package/dist/lib/check-lockfile.js +1 -0
- package/dist/lib/codegen.js +59 -18
- package/dist/lib/defer.js +12 -0
- package/dist/lib/file.js +52 -3
- package/dist/lib/flags.js +27 -9
- package/dist/lib/get-oxygen-deployment-data.test.js +4 -2
- package/dist/lib/graphql/admin/client.test.js +2 -2
- package/dist/lib/graphql/admin/get-oxygen-data.js +1 -0
- package/dist/lib/log.js +32 -14
- package/dist/lib/mini-oxygen/assets.js +118 -0
- package/dist/lib/mini-oxygen/common.js +2 -1
- package/dist/lib/mini-oxygen/index.js +7 -5
- package/dist/lib/mini-oxygen/mini-oxygen.test.js +214 -0
- package/dist/lib/mini-oxygen/node.js +19 -5
- package/dist/lib/mini-oxygen/workerd-inspector-logs.js +227 -0
- package/dist/lib/mini-oxygen/workerd-inspector-proxy.js +200 -0
- package/dist/lib/mini-oxygen/workerd-inspector.js +62 -235
- package/dist/lib/mini-oxygen/workerd.js +74 -50
- package/dist/lib/missing-routes.js +6 -3
- package/dist/lib/onboarding/common.js +40 -9
- package/dist/lib/onboarding/local.js +19 -11
- package/dist/lib/onboarding/remote.js +48 -28
- package/dist/lib/render-errors.js +2 -0
- package/dist/lib/request-events.js +65 -31
- package/dist/lib/setups/css/assets.js +1 -46
- package/dist/lib/setups/css/css-modules.js +3 -2
- package/dist/lib/setups/css/postcss.js +4 -2
- package/dist/lib/setups/css/tailwind.js +4 -2
- package/dist/lib/setups/css/vanilla-extract.js +3 -2
- package/dist/lib/setups/i18n/replacers.test.js +56 -38
- package/dist/lib/shell.js +1 -1
- package/dist/lib/template-diff.js +89 -0
- package/dist/lib/template-downloader.js +3 -2
- package/dist/lib/transpile/project.js +1 -1
- package/dist/virtual-routes/assets/debug-network.css +592 -0
- package/dist/virtual-routes/assets/favicon-dark.svg +20 -0
- package/dist/virtual-routes/components/FlameChartWrapper.jsx +8 -10
- package/dist/virtual-routes/components/IconClose.jsx +38 -0
- package/dist/virtual-routes/components/IconDiscard.jsx +44 -0
- package/dist/virtual-routes/components/RequestDetails.jsx +179 -0
- package/dist/virtual-routes/components/RequestTable.jsx +92 -0
- package/dist/virtual-routes/components/RequestWaterfall.jsx +151 -0
- package/dist/virtual-routes/lib/useDebugNetworkServer.jsx +176 -0
- package/dist/virtual-routes/routes/subrequest-profiler.jsx +243 -0
- package/oclif.manifest.json +134 -59
- package/package.json +18 -26
- package/dist/generator-templates/starter/app/routes/account_.activate.$id.$activationToken.tsx +0 -161
- package/dist/generator-templates/starter/app/routes/account_.recover.tsx +0 -129
- package/dist/generator-templates/starter/app/routes/account_.register.tsx +0 -207
- package/dist/generator-templates/starter/app/routes/account_.reset.$id.$resetToken.tsx +0 -136
- package/dist/virtual-routes/routes/debug-network.jsx +0 -289
- /package/dist/generator-templates/starter/app/{utils.ts → lib/variants.ts} +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { readFile, writeFile, fileExists } from '@shopify/cli-kit/node/fs';
|
|
2
2
|
import { joinPath } from '@shopify/cli-kit/node/path';
|
|
3
3
|
import { renderConfirmationPrompt } from '@shopify/cli-kit/node/ui';
|
|
4
|
-
import { readAndParsePackageJson, writePackageJSON } from '@shopify/cli-kit/node/node-package-manager';
|
|
5
4
|
import { GENERATOR_SETUP_ASSETS_SUB_DIRS, getAssetDir } from '../../build.js';
|
|
6
5
|
|
|
7
6
|
const SETUP_CSS_STRATEGIES = GENERATOR_SETUP_ASSETS_SUB_DIRS;
|
|
@@ -41,49 +40,5 @@ async function canWriteFiles(assetMap, directory, force) {
|
|
|
41
40
|
}
|
|
42
41
|
return true;
|
|
43
42
|
}
|
|
44
|
-
const MANAGED_PACKAGE_JSON_KEYS = Object.freeze([
|
|
45
|
-
"dependencies",
|
|
46
|
-
"devDependencies",
|
|
47
|
-
"peerDependencies"
|
|
48
|
-
]);
|
|
49
|
-
async function mergePackageJson(feature, projectDir) {
|
|
50
|
-
const targetPkgJson = await readAndParsePackageJson(
|
|
51
|
-
joinPath(projectDir, "package.json")
|
|
52
|
-
);
|
|
53
|
-
const sourcePkgJson = await readAndParsePackageJson(
|
|
54
|
-
joinPath(getAssetDir(feature), "package.json")
|
|
55
|
-
);
|
|
56
|
-
delete sourcePkgJson.comment;
|
|
57
|
-
const unmanagedKeys = Object.keys(sourcePkgJson).filter(
|
|
58
|
-
(key) => !MANAGED_PACKAGE_JSON_KEYS.includes(key)
|
|
59
|
-
);
|
|
60
|
-
for (const key of unmanagedKeys) {
|
|
61
|
-
const sourceValue = sourcePkgJson[key];
|
|
62
|
-
const targetValue = targetPkgJson[key];
|
|
63
|
-
const newValue = Array.isArray(sourceValue) && Array.isArray(targetValue) ? [...targetValue, ...sourceValue] : typeof sourceValue === "object" && typeof targetValue === "object" ? { ...targetValue, ...sourceValue } : sourceValue;
|
|
64
|
-
targetPkgJson[key] = newValue;
|
|
65
|
-
}
|
|
66
|
-
const remixVersion = Object.entries(targetPkgJson.dependencies || {}).find(
|
|
67
|
-
([dep]) => dep.startsWith("@remix-run/")
|
|
68
|
-
)?.[1];
|
|
69
|
-
for (const key of MANAGED_PACKAGE_JSON_KEYS) {
|
|
70
|
-
if (sourcePkgJson[key]) {
|
|
71
|
-
targetPkgJson[key] = [
|
|
72
|
-
.../* @__PURE__ */ new Set([
|
|
73
|
-
...Object.keys(targetPkgJson[key] ?? {}),
|
|
74
|
-
...Object.keys(sourcePkgJson[key] ?? {})
|
|
75
|
-
])
|
|
76
|
-
].sort().reduce((acc, dep) => {
|
|
77
|
-
let version = sourcePkgJson[key]?.[dep] ?? targetPkgJson[key]?.[dep];
|
|
78
|
-
if (dep.startsWith("@remix-run/") && remixVersion) {
|
|
79
|
-
version = remixVersion;
|
|
80
|
-
}
|
|
81
|
-
acc[dep] = version;
|
|
82
|
-
return acc;
|
|
83
|
-
}, {});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
await writePackageJSON(projectDir, targetPkgJson);
|
|
87
|
-
}
|
|
88
43
|
|
|
89
|
-
export { SETUP_CSS_STRATEGIES, canWriteFiles, copyAssets
|
|
44
|
+
export { SETUP_CSS_STRATEGIES, canWriteFiles, copyAssets };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { mergePackageJson } from '
|
|
1
|
+
import { mergePackageJson } from '../../file.js';
|
|
2
2
|
import { getCodeFormatOptions } from '../../format-code.js';
|
|
3
3
|
import { injectCssBundlingLink } from './replacers.js';
|
|
4
|
+
import { getAssetDir } from '../../build.js';
|
|
4
5
|
|
|
5
6
|
async function setupCssModules({
|
|
6
7
|
rootDirectory,
|
|
7
8
|
appDirectory
|
|
8
9
|
}) {
|
|
9
10
|
const workPromise = Promise.all([
|
|
10
|
-
mergePackageJson("css-modules", rootDirectory),
|
|
11
|
+
mergePackageJson(getAssetDir("css-modules"), rootDirectory),
|
|
11
12
|
getCodeFormatOptions(rootDirectory).then(
|
|
12
13
|
(formatConfig) => injectCssBundlingLink(appDirectory, formatConfig)
|
|
13
14
|
)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { outputInfo } from '@shopify/cli-kit/node/output';
|
|
2
|
-
import {
|
|
2
|
+
import { mergePackageJson } from '../../file.js';
|
|
3
|
+
import { canWriteFiles, copyAssets } from './assets.js';
|
|
4
|
+
import { getAssetDir } from '../../build.js';
|
|
3
5
|
|
|
4
6
|
async function setupPostCss({ rootDirectory, appDirectory, ...futureOptions }, force = false) {
|
|
5
7
|
const assetMap = {
|
|
@@ -16,7 +18,7 @@ async function setupPostCss({ rootDirectory, appDirectory, ...futureOptions }, f
|
|
|
16
18
|
return;
|
|
17
19
|
}
|
|
18
20
|
const workPromise = Promise.all([
|
|
19
|
-
mergePackageJson("postcss", rootDirectory),
|
|
21
|
+
mergePackageJson(getAssetDir("postcss"), rootDirectory),
|
|
20
22
|
copyAssets("postcss", assetMap, rootDirectory)
|
|
21
23
|
]);
|
|
22
24
|
return {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { outputInfo } from '@shopify/cli-kit/node/output';
|
|
2
2
|
import { relativePath, joinPath } from '@shopify/cli-kit/node/path';
|
|
3
|
-
import {
|
|
3
|
+
import { mergePackageJson } from '../../file.js';
|
|
4
|
+
import { canWriteFiles, copyAssets } from './assets.js';
|
|
4
5
|
import { getCodeFormatOptions } from '../../format-code.js';
|
|
5
6
|
import { replaceRootLinks } from './replacers.js';
|
|
7
|
+
import { getAssetDir } from '../../build.js';
|
|
6
8
|
|
|
7
9
|
const tailwindCssPath = "styles/tailwind.css";
|
|
8
10
|
async function setupTailwind({ rootDirectory, appDirectory, ...futureOptions }, force = false) {
|
|
@@ -23,7 +25,7 @@ async function setupTailwind({ rootDirectory, appDirectory, ...futureOptions },
|
|
|
23
25
|
return;
|
|
24
26
|
}
|
|
25
27
|
const workPromise = Promise.all([
|
|
26
|
-
mergePackageJson("tailwind", rootDirectory),
|
|
28
|
+
mergePackageJson(getAssetDir("tailwind"), rootDirectory),
|
|
27
29
|
copyAssets(
|
|
28
30
|
"tailwind",
|
|
29
31
|
assetMap,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { mergePackageJson } from '
|
|
1
|
+
import { mergePackageJson } from '../../file.js';
|
|
2
2
|
import { getCodeFormatOptions } from '../../format-code.js';
|
|
3
3
|
import { injectCssBundlingLink } from './replacers.js';
|
|
4
|
+
import { getAssetDir } from '../../build.js';
|
|
4
5
|
|
|
5
6
|
async function setupVanillaExtract({
|
|
6
7
|
rootDirectory,
|
|
7
8
|
appDirectory
|
|
8
9
|
}) {
|
|
9
10
|
const workPromise = Promise.all([
|
|
10
|
-
mergePackageJson("vanilla-extract", rootDirectory),
|
|
11
|
+
mergePackageJson(getAssetDir("vanilla-extract"), rootDirectory),
|
|
11
12
|
getCodeFormatOptions(rootDirectory).then(
|
|
12
13
|
(formatConfig) => injectCssBundlingLink(appDirectory, formatConfig)
|
|
13
14
|
)
|
|
@@ -41,26 +41,29 @@ describe("i18n replacers", () => {
|
|
|
41
41
|
const newContent = await readFile(joinPath(tmpDir, remixDts));
|
|
42
42
|
expect(() => checkTypes(newContent)).not.toThrow();
|
|
43
43
|
expect(newContent).toMatchInlineSnapshot(`
|
|
44
|
-
"/// <reference types
|
|
45
|
-
/// <reference types
|
|
46
|
-
/// <reference types
|
|
44
|
+
"/// <reference types="@remix-run/dev" />
|
|
45
|
+
/// <reference types="@shopify/remix-oxygen" />
|
|
46
|
+
/// <reference types="@shopify/oxygen-workers-types" />
|
|
47
47
|
|
|
48
48
|
// Enhance TypeScript's built-in typings.
|
|
49
|
-
import
|
|
49
|
+
import "@total-typescript/ts-reset";
|
|
50
50
|
|
|
51
|
-
import type {
|
|
51
|
+
import type {
|
|
52
|
+
Storefront,
|
|
53
|
+
CustomerClient,
|
|
54
|
+
HydrogenCart,
|
|
55
|
+
} from "@shopify/hydrogen";
|
|
52
56
|
import type {
|
|
53
57
|
LanguageCode,
|
|
54
58
|
CountryCode,
|
|
55
|
-
} from
|
|
56
|
-
import type {
|
|
57
|
-
import type { HydrogenSession } from \\"./server\\";
|
|
59
|
+
} from "@shopify/hydrogen/storefront-api-types";
|
|
60
|
+
import type { AppSession } from "~/lib/session";
|
|
58
61
|
|
|
59
62
|
declare global {
|
|
60
63
|
/**
|
|
61
64
|
* A global \`process\` object is only available during build to access NODE_ENV.
|
|
62
65
|
*/
|
|
63
|
-
const process: { env: { NODE_ENV:
|
|
66
|
+
const process: { env: { NODE_ENV: "production" | "development" } };
|
|
64
67
|
|
|
65
68
|
/**
|
|
66
69
|
* Declare expected Env parameter in fetch handler.
|
|
@@ -71,6 +74,8 @@ describe("i18n replacers", () => {
|
|
|
71
74
|
PRIVATE_STOREFRONT_API_TOKEN: string;
|
|
72
75
|
PUBLIC_STORE_DOMAIN: string;
|
|
73
76
|
PUBLIC_STOREFRONT_ID: string;
|
|
77
|
+
PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID: string;
|
|
78
|
+
PUBLIC_CUSTOMER_ACCOUNT_API_URL: string;
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
/**
|
|
@@ -79,7 +84,7 @@ describe("i18n replacers", () => {
|
|
|
79
84
|
type I18nLocale = { language: LanguageCode; country: CountryCode };
|
|
80
85
|
}
|
|
81
86
|
|
|
82
|
-
declare module
|
|
87
|
+
declare module "@shopify/remix-oxygen" {
|
|
83
88
|
/**
|
|
84
89
|
* Declare local additions to the Remix loader context.
|
|
85
90
|
*/
|
|
@@ -87,15 +92,9 @@ describe("i18n replacers", () => {
|
|
|
87
92
|
env: Env;
|
|
88
93
|
cart: HydrogenCart;
|
|
89
94
|
storefront: Storefront<I18nLocale>;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Declare the data we expect to access via \`context.session\`.
|
|
96
|
-
*/
|
|
97
|
-
export interface SessionData {
|
|
98
|
-
customerAccessToken: CustomerAccessToken;
|
|
95
|
+
customerAccount: CustomerClient;
|
|
96
|
+
session: AppSession;
|
|
97
|
+
waitUntil: ExecutionContext["waitUntil"];
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
100
|
"
|
|
@@ -107,7 +106,7 @@ describe("i18n replacers", () => {
|
|
|
107
106
|
const skeletonDir = getSkeletonSourceDir();
|
|
108
107
|
await writeFile(
|
|
109
108
|
joinPath(tmpDir, serverTs),
|
|
110
|
-
// Remove the part that is not needed for this test (
|
|
109
|
+
// Remove the part that is not needed for this test (AppSession, Cart query, etc);
|
|
111
110
|
(await readFile(joinPath(skeletonDir, serverTs))).replace(/^};$.*/ms, "};")
|
|
112
111
|
);
|
|
113
112
|
await replaceServerI18n(
|
|
@@ -122,21 +121,22 @@ describe("i18n replacers", () => {
|
|
|
122
121
|
expect(() => checkTypes(newContent)).not.toThrow();
|
|
123
122
|
expect(newContent).toMatchInlineSnapshot(`
|
|
124
123
|
"// Virtual entry point for the app
|
|
125
|
-
import * as remixBuild from
|
|
124
|
+
import * as remixBuild from "@remix-run/dev/server-build";
|
|
126
125
|
import {
|
|
127
126
|
cartGetIdDefault,
|
|
128
127
|
cartSetIdDefault,
|
|
129
128
|
createCartHandler,
|
|
130
129
|
createStorefrontClient,
|
|
131
130
|
storefrontRedirect,
|
|
132
|
-
|
|
131
|
+
createCustomerAccountClient,
|
|
132
|
+
} from "@shopify/hydrogen";
|
|
133
133
|
import {
|
|
134
134
|
createRequestHandler,
|
|
135
135
|
getStorefrontHeaders,
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
} from
|
|
136
|
+
type AppLoadContext,
|
|
137
|
+
} from "@shopify/remix-oxygen";
|
|
138
|
+
import { AppSession } from "~/lib/session";
|
|
139
|
+
import { CART_QUERY_FRAGMENT } from "~/lib/fragments";
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
142
|
* Export a fetch handler in module format.
|
|
@@ -152,13 +152,13 @@ describe("i18n replacers", () => {
|
|
|
152
152
|
* Open a cache instance in the worker and a custom session instance.
|
|
153
153
|
*/
|
|
154
154
|
if (!env?.SESSION_SECRET) {
|
|
155
|
-
throw new Error(
|
|
155
|
+
throw new Error("SESSION_SECRET environment variable is not set");
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
const waitUntil = executionContext.waitUntil.bind(executionContext);
|
|
159
159
|
const [cache, session] = await Promise.all([
|
|
160
|
-
caches.open(
|
|
161
|
-
|
|
160
|
+
caches.open("hydrogen"),
|
|
161
|
+
AppSession.init(request, [env.SESSION_SECRET]),
|
|
162
162
|
]);
|
|
163
163
|
|
|
164
164
|
/**
|
|
@@ -175,6 +175,17 @@ describe("i18n replacers", () => {
|
|
|
175
175
|
storefrontHeaders: getStorefrontHeaders(request),
|
|
176
176
|
});
|
|
177
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Create a client for Customer Account API.
|
|
180
|
+
*/
|
|
181
|
+
const customerAccount = createCustomerAccountClient({
|
|
182
|
+
waitUntil,
|
|
183
|
+
request,
|
|
184
|
+
session,
|
|
185
|
+
customerAccountId: env.PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID,
|
|
186
|
+
customerAccountUrl: env.PUBLIC_CUSTOMER_ACCOUNT_API_URL,
|
|
187
|
+
});
|
|
188
|
+
|
|
178
189
|
/*
|
|
179
190
|
* Create a cart handler that will be used to
|
|
180
191
|
* create and update the cart in the session.
|
|
@@ -193,7 +204,14 @@ describe("i18n replacers", () => {
|
|
|
193
204
|
const handleRequest = createRequestHandler({
|
|
194
205
|
build: remixBuild,
|
|
195
206
|
mode: process.env.NODE_ENV,
|
|
196
|
-
getLoadContext: () => ({
|
|
207
|
+
getLoadContext: (): AppLoadContext => ({
|
|
208
|
+
session,
|
|
209
|
+
storefront,
|
|
210
|
+
customerAccount,
|
|
211
|
+
cart,
|
|
212
|
+
env,
|
|
213
|
+
waitUntil,
|
|
214
|
+
}),
|
|
197
215
|
});
|
|
198
216
|
|
|
199
217
|
const response = await handleRequest(request);
|
|
@@ -211,23 +229,23 @@ describe("i18n replacers", () => {
|
|
|
211
229
|
} catch (error) {
|
|
212
230
|
// eslint-disable-next-line no-console
|
|
213
231
|
console.error(error);
|
|
214
|
-
return new Response(
|
|
232
|
+
return new Response("An unexpected error occurred", { status: 500 });
|
|
215
233
|
}
|
|
216
234
|
},
|
|
217
235
|
};
|
|
218
236
|
|
|
219
237
|
function getLocaleFromRequest(request: Request): I18nLocale {
|
|
220
|
-
const defaultLocale: I18nLocale = { language:
|
|
238
|
+
const defaultLocale: I18nLocale = { language: "EN", country: "US" };
|
|
221
239
|
const supportedLocales = {
|
|
222
|
-
ES:
|
|
223
|
-
FR:
|
|
224
|
-
DE:
|
|
225
|
-
JP:
|
|
226
|
-
} as Record<I18nLocale[
|
|
240
|
+
ES: "ES",
|
|
241
|
+
FR: "FR",
|
|
242
|
+
DE: "DE",
|
|
243
|
+
JP: "JA",
|
|
244
|
+
} as Record<I18nLocale["country"], I18nLocale["language"]>;
|
|
227
245
|
|
|
228
246
|
const url = new URL(request.url);
|
|
229
247
|
const domain = url.hostname
|
|
230
|
-
.split(
|
|
248
|
+
.split(".")
|
|
231
249
|
.pop()
|
|
232
250
|
?.toUpperCase() as keyof typeof supportedLocales;
|
|
233
251
|
|
package/dist/lib/shell.js
CHANGED
|
@@ -160,7 +160,7 @@ async function getCliCommand(directory = process.cwd(), forcePkgManager) {
|
|
|
160
160
|
}
|
|
161
161
|
let cli = "npx";
|
|
162
162
|
const pkgManager = forcePkgManager ?? await getPackageManager(directory).catch(() => null);
|
|
163
|
-
if (pkgManager === "pnpm" || pkgManager === "yarn")
|
|
163
|
+
if (pkgManager === "bun" || pkgManager === "pnpm" || pkgManager === "yarn")
|
|
164
164
|
cli = pkgManager;
|
|
165
165
|
return `${cli} shopify hydrogen`;
|
|
166
166
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { rmdirSync } from 'node:fs';
|
|
2
|
+
import { temporaryDirectory } from 'tempy';
|
|
3
|
+
import { createSymlink, copy, remove } from 'fs-extra/esm';
|
|
4
|
+
import { copyFile, removeFile } from '@shopify/cli-kit/node/fs';
|
|
5
|
+
import { joinPath, relativePath } from '@shopify/cli-kit/node/path';
|
|
6
|
+
import colors from '@shopify/cli-kit/node/colors';
|
|
7
|
+
import { getRepoNodeModules, getStarterDir } from './build.js';
|
|
8
|
+
import { mergePackageJson } from './file.js';
|
|
9
|
+
|
|
10
|
+
async function prepareDiffDirectory(diffDirectory, watch) {
|
|
11
|
+
const targetDirectory = temporaryDirectory({ prefix: "tmp-hydrogen-diff-" });
|
|
12
|
+
process.on("exit", () => rmdirSync(targetDirectory, { recursive: true }));
|
|
13
|
+
console.info(
|
|
14
|
+
`
|
|
15
|
+
-- Applying diff to starter template in
|
|
16
|
+
${colors.dim(
|
|
17
|
+
targetDirectory
|
|
18
|
+
)}
|
|
19
|
+
`
|
|
20
|
+
);
|
|
21
|
+
await applyTemplateDiff(targetDirectory, diffDirectory);
|
|
22
|
+
await createSymlink(
|
|
23
|
+
await getRepoNodeModules(),
|
|
24
|
+
joinPath(targetDirectory, "node_modules")
|
|
25
|
+
);
|
|
26
|
+
if (watch) {
|
|
27
|
+
const pw = await import('@parcel/watcher').catch((error) => {
|
|
28
|
+
console.log("Could not watch for file changes.", error);
|
|
29
|
+
});
|
|
30
|
+
pw?.subscribe(
|
|
31
|
+
targetDirectory,
|
|
32
|
+
(error, events) => {
|
|
33
|
+
if (error) {
|
|
34
|
+
console.error(error);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
events.map((event) => {
|
|
38
|
+
return copyFile(
|
|
39
|
+
event.path,
|
|
40
|
+
joinPath(diffDirectory, relativePath(targetDirectory, event.path))
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
{ ignore: ["!*.generated.d.ts"] }
|
|
45
|
+
);
|
|
46
|
+
pw?.subscribe(
|
|
47
|
+
diffDirectory,
|
|
48
|
+
async (error, events) => {
|
|
49
|
+
if (error) {
|
|
50
|
+
console.error(error);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
await events.map((event) => {
|
|
54
|
+
const targetFile = joinPath(
|
|
55
|
+
targetDirectory,
|
|
56
|
+
relativePath(diffDirectory, event.path)
|
|
57
|
+
);
|
|
58
|
+
return event.type === "delete" ? removeFile(targetFile).catch(() => {
|
|
59
|
+
}) : copyFile(event.path, targetFile);
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
{ ignore: ["*.generated.d.ts", "package.json", "tsconfig.json"] }
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
return targetDirectory;
|
|
66
|
+
}
|
|
67
|
+
async function applyTemplateDiff(targetDirectory, diffDirectory, templateDir = getStarterDir()) {
|
|
68
|
+
const createFilter = (re) => (filepath) => !re.test(relativePath(templateDir, filepath));
|
|
69
|
+
await copy(templateDir, targetDirectory, {
|
|
70
|
+
filter: createFilter(/[\/\\](dist|node_modules|\.cache)(\/|\\|$)/i)
|
|
71
|
+
});
|
|
72
|
+
await copy(diffDirectory, targetDirectory, {
|
|
73
|
+
filter: createFilter(
|
|
74
|
+
/[\/\\](dist|node_modules|\.cache|package\.json|tsconfig\.json)(\/|\\|$)/i
|
|
75
|
+
)
|
|
76
|
+
});
|
|
77
|
+
await mergePackageJson(diffDirectory, targetDirectory, {
|
|
78
|
+
ignoredKeys: ["scripts"]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
async function copyDiffBuild(targetDirectory, diffDirectory) {
|
|
82
|
+
const targetDist = joinPath(diffDirectory, "dist");
|
|
83
|
+
await remove(targetDist);
|
|
84
|
+
await copy(joinPath(targetDirectory, "dist"), targetDist, {
|
|
85
|
+
overwrite: true
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { applyTemplateDiff, copyDiffBuild, prepareDiffDirectory };
|
|
@@ -42,7 +42,7 @@ async function downloadTarball(url, storageDir, signal) {
|
|
|
42
42
|
strip: 1,
|
|
43
43
|
filter: (name) => {
|
|
44
44
|
name = name.replace(storageDir, "");
|
|
45
|
-
return !name.startsWith(path.normalize("/templates/"))
|
|
45
|
+
return !name.startsWith(path.normalize("/templates/")) && !name.startsWith(path.normalize("/examples/"));
|
|
46
46
|
}
|
|
47
47
|
})
|
|
48
48
|
);
|
|
@@ -64,7 +64,8 @@ async function getLatestTemplates({
|
|
|
64
64
|
}
|
|
65
65
|
return {
|
|
66
66
|
version,
|
|
67
|
-
templatesDir: path.join(templateStorageVersionPath, "templates")
|
|
67
|
+
templatesDir: path.join(templateStorageVersionPath, "templates"),
|
|
68
|
+
examplesDir: path.join(templateStorageVersionPath, "examples")
|
|
68
69
|
};
|
|
69
70
|
} catch (e) {
|
|
70
71
|
const error = e;
|
|
@@ -102,7 +102,7 @@ async function transpileProject(projectDir, keepTypes = true) {
|
|
|
102
102
|
delete pkgJson.devDependencies[key];
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
-
const codegenFlag = /\s*--codegen
|
|
105
|
+
const codegenFlag = /\s*--codegen/;
|
|
106
106
|
if (pkgJson.scripts?.dev) {
|
|
107
107
|
pkgJson.scripts.dev = pkgJson.scripts.dev.replace(codegenFlag, "");
|
|
108
108
|
}
|