@shopify/cli-hydrogen 11.1.3 → 11.1.5
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/assets/hydrogen/bundle/analyzer.html +155 -148
- package/dist/assets/hydrogen/starter/CHANGELOG.md +125 -49
- package/dist/assets/hydrogen/starter/app/components/AddToCartButton.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/CartLineItem.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/CartSummary.tsx +62 -29
- package/dist/assets/hydrogen/starter/app/components/Header.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/PageLayout.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/ProductForm.tsx +2 -2
- package/dist/assets/hydrogen/starter/app/components/SearchForm.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/SearchFormPredictive.tsx +8 -3
- package/dist/assets/hydrogen/starter/app/components/SearchResults.tsx +3 -11
- package/dist/assets/hydrogen/starter/app/components/SearchResultsPredictive.tsx +2 -6
- package/dist/assets/hydrogen/starter/app/entry.client.tsx +10 -2
- package/dist/assets/hydrogen/starter/app/entry.server.tsx +5 -3
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerAddressMutations.ts +7 -4
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerDetailsQuery.ts +1 -1
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrderQuery.ts +4 -1
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrdersQuery.ts +10 -5
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerUpdateMutation.ts +3 -2
- package/dist/assets/hydrogen/starter/app/lib/context.ts +34 -17
- package/dist/assets/hydrogen/starter/app/lib/fragments.ts +1 -0
- package/dist/assets/hydrogen/starter/app/lib/orderFilters.ts +90 -0
- package/dist/assets/hydrogen/starter/app/lib/redirect.ts +1 -1
- package/dist/assets/hydrogen/starter/app/lib/session.ts +1 -1
- package/dist/assets/hydrogen/starter/app/lib/variants.ts +1 -1
- package/dist/assets/hydrogen/starter/app/root.tsx +23 -18
- package/dist/assets/hydrogen/starter/app/routes/$.tsx +2 -2
- package/dist/assets/hydrogen/starter/app/routes/[robots.txt].tsx +2 -2
- package/dist/assets/hydrogen/starter/app/routes/[sitemap.xml].tsx +2 -3
- package/dist/assets/hydrogen/starter/app/routes/_index.tsx +12 -8
- package/dist/assets/hydrogen/starter/app/routes/account.$.tsx +4 -3
- package/dist/assets/hydrogen/starter/app/routes/account._index.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +15 -11
- package/dist/assets/hydrogen/starter/app/routes/account.orders.$id.tsx +47 -22
- package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +152 -23
- package/dist/assets/hydrogen/starter/app/routes/account.profile.tsx +11 -8
- package/dist/assets/hydrogen/starter/app/routes/account.tsx +16 -4
- package/dist/assets/hydrogen/starter/app/routes/account_.authorize.tsx +2 -2
- package/dist/assets/hydrogen/starter/app/routes/account_.login.tsx +5 -3
- package/dist/assets/hydrogen/starter/app/routes/account_.logout.tsx +3 -2
- package/dist/assets/hydrogen/starter/app/routes/api.$version.[graphql.json].tsx +2 -2
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +6 -10
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +10 -7
- package/dist/assets/hydrogen/starter/app/routes/blogs._index.tsx +13 -7
- package/dist/assets/hydrogen/starter/app/routes/cart.$lines.tsx +3 -2
- package/dist/assets/hydrogen/starter/app/routes/cart.tsx +13 -9
- package/dist/assets/hydrogen/starter/app/routes/collections.$handle.tsx +8 -11
- package/dist/assets/hydrogen/starter/app/routes/collections._index.tsx +6 -6
- package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +10 -7
- package/dist/assets/hydrogen/starter/app/routes/discount.$code.tsx +3 -2
- package/dist/assets/hydrogen/starter/app/routes/pages.$handle.tsx +8 -6
- package/dist/assets/hydrogen/starter/app/routes/policies.$handle.tsx +7 -4
- package/dist/assets/hydrogen/starter/app/routes/policies._index.tsx +19 -13
- package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +9 -6
- package/dist/assets/hydrogen/starter/app/routes/search.tsx +14 -14
- package/dist/assets/hydrogen/starter/app/routes/sitemap.$type.$page[.xml].tsx +2 -3
- package/dist/assets/hydrogen/starter/app/routes.ts +1 -1
- package/dist/assets/hydrogen/starter/app/styles/app.css +53 -1
- package/dist/assets/hydrogen/starter/customer-accountapi.generated.d.ts +47 -13
- package/dist/assets/hydrogen/starter/env.d.ts +1 -39
- package/dist/assets/hydrogen/starter/eslint.config.js +35 -52
- package/dist/assets/hydrogen/starter/package.json +14 -15
- package/dist/assets/hydrogen/starter/react-router.config.ts +9 -3
- package/dist/assets/hydrogen/starter/server.ts +7 -7
- package/dist/assets/hydrogen/starter/storefrontapi.generated.d.ts +1 -1
- package/dist/assets/hydrogen/starter/tsconfig.json +17 -13
- package/dist/assets/hydrogen/starter/vite.config.ts +3 -0
- package/dist/assets/hydrogen/virtual-routes/components/RequestDetails.jsx +13 -20
- package/dist/assets/hydrogen/virtual-routes/routes/[.]well-known.appspecific.com[.]chrome[.]devtools[.]json.jsx +37 -0
- package/dist/commands/hydrogen/build.js +2 -16
- package/dist/commands/hydrogen/codegen.js +2 -10
- package/dist/commands/hydrogen/debug/cpu.js +3 -7
- package/dist/commands/hydrogen/deploy.js +14 -9
- package/dist/commands/hydrogen/dev.js +6 -10
- package/dist/commands/hydrogen/env/pull.js +9 -1
- package/dist/commands/hydrogen/init.d.ts +1 -1
- package/dist/commands/hydrogen/preview.js +1 -16
- package/dist/commands/hydrogen/upgrade.js +145 -20
- package/dist/index.d.ts +1 -6
- package/dist/lib/build.js +17 -4
- package/dist/lib/flags.js +2 -10
- package/dist/lib/import-utils.js +4 -1
- package/dist/lib/live-reload.js +4 -4
- package/dist/lib/log.js +1 -1
- package/dist/lib/mini-oxygen/common.js +4 -1
- package/dist/lib/onboarding/local.js +25 -1
- package/dist/lib/onboarding/remote.js +4 -13
- package/dist/lib/onboarding/setup-template.mocks.js +4 -6
- package/dist/lib/react-router-version-check.js +82 -0
- package/dist/lib/setups/routes/generate.js +3 -0
- package/dist/lib/transpile/project.js +15 -7
- package/oclif.manifest.json +8 -53
- package/package.json +5 -5
- package/dist/lib/template-diff.js +0 -202
package/dist/lib/build.js
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
2
3
|
import { findPathUp } from '@shopify/cli-kit/node/fs';
|
|
3
4
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
4
5
|
import { joinPath, dirname } from '@shopify/cli-kit/node/path';
|
|
5
6
|
import { execAsync } from './process.js';
|
|
6
7
|
|
|
7
8
|
const monorepoPackagesPath = new URL("../../..", import.meta.url).pathname;
|
|
8
|
-
const isHydrogenMonorepo =
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const isHydrogenMonorepo = (() => {
|
|
10
|
+
try {
|
|
11
|
+
const skeletonPath = joinPath(
|
|
12
|
+
dirname(monorepoPackagesPath),
|
|
13
|
+
"templates",
|
|
14
|
+
"skeleton"
|
|
15
|
+
);
|
|
16
|
+
return existsSync(skeletonPath);
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
11
21
|
const hydrogenPackagesPath = isHydrogenMonorepo ? monorepoPackagesPath : void 0;
|
|
12
22
|
const ASSETS_DIR_PREFIX = "assets/hydrogen";
|
|
13
23
|
const ASSETS_STARTER_DIR = "starter";
|
|
@@ -55,6 +65,9 @@ function getSkeletonSourceDir() {
|
|
|
55
65
|
}
|
|
56
66
|
return joinPath(dirname(monorepoPackagesPath), "templates", "skeleton");
|
|
57
67
|
}
|
|
68
|
+
function getSkeletonNodeModules() {
|
|
69
|
+
return joinPath(getSkeletonSourceDir(), "node_modules");
|
|
70
|
+
}
|
|
58
71
|
async function getRepoNodeModules() {
|
|
59
72
|
const { stdout } = await execAsync("npm root");
|
|
60
73
|
let nodeModulesPath = stdout.trim();
|
|
@@ -64,4 +77,4 @@ async function getRepoNodeModules() {
|
|
|
64
77
|
return nodeModulesPath;
|
|
65
78
|
}
|
|
66
79
|
|
|
67
|
-
export { ASSETS_DIR_PREFIX, ASSETS_STARTER_DIR, ASSETS_STARTER_DIR_ROUTES, getAssetsDir, getPkgJsonPath, getRepoNodeModules, getSkeletonSourceDir, getStarterDir, getTemplateAppFile, hydrogenPackagesPath, isHydrogenMonorepo };
|
|
80
|
+
export { ASSETS_DIR_PREFIX, ASSETS_STARTER_DIR, ASSETS_STARTER_DIR_ROUTES, getAssetsDir, getPkgJsonPath, getRepoNodeModules, getSkeletonNodeModules, getSkeletonSourceDir, getStarterDir, getTemplateAppFile, hydrogenPackagesPath, isHydrogenMonorepo };
|
package/dist/lib/flags.js
CHANGED
|
@@ -125,13 +125,6 @@ const commonFlags = {
|
|
|
125
125
|
env: "SHOPIFY_HYDROGEN_FLAG_INSPECTOR_PORT"
|
|
126
126
|
})
|
|
127
127
|
},
|
|
128
|
-
diff: {
|
|
129
|
-
diff: Flags.boolean({
|
|
130
|
-
description: "Applies the current files on top of Hydrogen's starter template in a temporary directory.",
|
|
131
|
-
required: false,
|
|
132
|
-
hidden: true
|
|
133
|
-
})
|
|
134
|
-
},
|
|
135
128
|
entry: {
|
|
136
129
|
entry: Flags.string({
|
|
137
130
|
description: "Entry file for the worker. Defaults to `./server`.",
|
|
@@ -153,9 +146,8 @@ const commonFlags = {
|
|
|
153
146
|
})
|
|
154
147
|
},
|
|
155
148
|
customerAccountPush: {
|
|
156
|
-
"customer-account-
|
|
157
|
-
|
|
158
|
-
description: "Use tunneling for local development and push the tunneling domain to admin. Required to use Customer Account API's Oauth flow",
|
|
149
|
+
"customer-account-push": Flags.boolean({
|
|
150
|
+
description: "Use tunneling for local development and push the tunneling domain to admin. Required to use Customer Account API's OAuth flow",
|
|
159
151
|
required: false,
|
|
160
152
|
env: "SHOPIFY_HYDROGEN_FLAG_CUSTOMER_ACCOUNT_PUSH"
|
|
161
153
|
})
|
package/dist/lib/import-utils.js
CHANGED
|
@@ -10,7 +10,10 @@ async function importVite(root) {
|
|
|
10
10
|
process.env.SHOPIFY_UNIT_TEST ? void 0 : { paths: [root] }
|
|
11
11
|
);
|
|
12
12
|
const vitePackageJson = await findUpAndReadPackageJson(vitePath);
|
|
13
|
-
let viteNodeIndexFile = vitePackageJson.content.exports?.["."]
|
|
13
|
+
let viteNodeIndexFile = vitePackageJson.content.exports?.["."];
|
|
14
|
+
if (typeof viteNodeIndexFile !== "string") {
|
|
15
|
+
viteNodeIndexFile = viteNodeIndexFile?.import;
|
|
16
|
+
}
|
|
14
17
|
if (typeof viteNodeIndexFile !== "string") {
|
|
15
18
|
viteNodeIndexFile = viteNodeIndexFile.default;
|
|
16
19
|
}
|
package/dist/lib/live-reload.js
CHANGED
|
@@ -6,18 +6,18 @@ async function setupLiveReload(devServerPort, root) {
|
|
|
6
6
|
try {
|
|
7
7
|
const [{ updates: hmrUpdates }, { serve }, { detectLoaderChanges }, { ok, err }] = await Promise.all([
|
|
8
8
|
importLocal(
|
|
9
|
-
"@
|
|
9
|
+
"@react-router/dev/dist/devServer_unstable/hmr.js",
|
|
10
10
|
root
|
|
11
11
|
),
|
|
12
12
|
importLocal(
|
|
13
|
-
"@
|
|
13
|
+
"@react-router/dev/dist/devServer_unstable/socket.js",
|
|
14
14
|
root
|
|
15
15
|
),
|
|
16
16
|
importLocal(
|
|
17
|
-
"@
|
|
17
|
+
"@react-router/dev/dist/devServer_unstable/hdr.js",
|
|
18
18
|
root
|
|
19
19
|
),
|
|
20
|
-
importLocal("@
|
|
20
|
+
importLocal("@react-router/dev/dist/result.js", root)
|
|
21
21
|
]).catch(handleRemixImportFail);
|
|
22
22
|
const state = {};
|
|
23
23
|
const server = http.createServer(function(req, res) {
|
package/dist/lib/log.js
CHANGED
|
@@ -333,7 +333,7 @@ function createRemixLogger() {
|
|
|
333
333
|
async function muteRemixLogs(root) {
|
|
334
334
|
try {
|
|
335
335
|
const { logger } = await importLocal(
|
|
336
|
-
"@
|
|
336
|
+
"@react-router/dev/dist/tux/logger.js",
|
|
337
337
|
root
|
|
338
338
|
);
|
|
339
339
|
logger.warn = logger.debug = logger.info = () => {
|
|
@@ -18,6 +18,9 @@ function logRequestLine({
|
|
|
18
18
|
}) {
|
|
19
19
|
try {
|
|
20
20
|
const url = new URL(request.url);
|
|
21
|
+
if (!meta.durationMs && meta.startTimeMs && meta.endTimeMs) {
|
|
22
|
+
meta.durationMs = meta.endTimeMs - meta.startTimeMs;
|
|
23
|
+
}
|
|
21
24
|
if (DEV_ROUTES.has(url.pathname) || url.pathname === "/favicon.ico") return;
|
|
22
25
|
const isDataRequest = url.searchParams.has("_data");
|
|
23
26
|
let route = request.url.replace(url.origin, "");
|
|
@@ -33,7 +36,7 @@ function logRequestLine({
|
|
|
33
36
|
outputInfo(
|
|
34
37
|
outputContent`${request.method.padStart(6)} ${colorizeStatus(
|
|
35
38
|
String(response.status)
|
|
36
|
-
)} ${outputToken.italic(type.padEnd(7, " "))} ${route} ${meta.durationMs > 0 ? colors.dim(` ${meta.durationMs}ms`) : ""}${info ? " " + colors.dim(info) : ""}${request.headers
|
|
39
|
+
)} ${outputToken.italic(type.padEnd(7, " "))} ${route} ${meta.durationMs && meta.durationMs > 0 ? colors.dim(` ${meta.durationMs}ms`) : ""}${info ? " " + colors.dim(info) : ""}${request.headers.purpose === "prefetch" ? colors.italic(colors.dim(" prefetch")) : ""}`
|
|
37
40
|
);
|
|
38
41
|
} catch {
|
|
39
42
|
if (request && response?.status) {
|
|
@@ -12,6 +12,8 @@ import { replaceFileContent } from '../file.js';
|
|
|
12
12
|
import { setUserAccount, setStorefront } from '../shopify-config.js';
|
|
13
13
|
import { getCliCommand, ALIAS_NAME } from '../shell.js';
|
|
14
14
|
import { CSS_STRATEGY_NAME_MAP } from '../setups/css/index.js';
|
|
15
|
+
import { execAsync } from '../process.js';
|
|
16
|
+
import { outputWarn } from '@shopify/cli-kit/node/output';
|
|
15
17
|
|
|
16
18
|
async function setupLocalStarterTemplate(options, controller) {
|
|
17
19
|
const templateAction = options.mockShop ? "mock" : await renderSelectPrompt({
|
|
@@ -170,6 +172,17 @@ async function setupLocalStarterTemplate(options, controller) {
|
|
|
170
172
|
try {
|
|
171
173
|
await installDeps();
|
|
172
174
|
setupSummary.depsInstalled = true;
|
|
175
|
+
if (language === "ts") {
|
|
176
|
+
try {
|
|
177
|
+
await execAsync("npx react-router typegen", {
|
|
178
|
+
cwd: project.directory
|
|
179
|
+
});
|
|
180
|
+
} catch (error) {
|
|
181
|
+
outputWarn(
|
|
182
|
+
"Failed to generate React Router types. You may need to run `npx react-router typegen` manually."
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
173
186
|
} catch (error) {
|
|
174
187
|
setupSummary.depsError = error;
|
|
175
188
|
}
|
|
@@ -239,8 +252,19 @@ async function setupLocalStarterTemplate(options, controller) {
|
|
|
239
252
|
// The init process might have added and modified files. Do not overwrite them.
|
|
240
253
|
// E.g. CSS imports might have been added to the root.
|
|
241
254
|
overwriteFileDeps: false
|
|
242
|
-
}).then((routes) => {
|
|
255
|
+
}).then(async (routes) => {
|
|
243
256
|
setupSummary.routes = routes;
|
|
257
|
+
if (language === "ts" && setupSummary.depsInstalled) {
|
|
258
|
+
try {
|
|
259
|
+
await execAsync("npx react-router typegen", {
|
|
260
|
+
cwd: project.directory
|
|
261
|
+
});
|
|
262
|
+
} catch (error) {
|
|
263
|
+
outputWarn(
|
|
264
|
+
"Failed to generate React Router types after route generation. You may need to run `npx react-router typegen` manually."
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
244
268
|
if (options.git && routes) {
|
|
245
269
|
return commitAll(
|
|
246
270
|
project.directory,
|
|
@@ -1,33 +1,24 @@
|
|
|
1
1
|
import { readdir } from 'node:fs/promises';
|
|
2
2
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
3
3
|
import { copyFile, fileExists } from '@shopify/cli-kit/node/fs';
|
|
4
|
-
import { readAndParsePackageJson } from '@shopify/cli-kit/node/node-package-manager';
|
|
5
4
|
import { joinPath } from '@shopify/cli-kit/node/path';
|
|
6
5
|
import { renderTasks, renderInfo } from '@shopify/cli-kit/node/ui';
|
|
7
6
|
import { downloadExternalRepo, downloadMonorepoTemplates } from '../template-downloader.js';
|
|
8
|
-
import { applyTemplateDiff } from '../template-diff.js';
|
|
9
7
|
import { getCliCommand } from '../shell.js';
|
|
10
|
-
import {
|
|
8
|
+
import { handleProjectLocation, createAbortHandler, handleLanguage, createInitialCommit, handleDependencies, commitAll, renderProjectReady } from './common.js';
|
|
11
9
|
|
|
12
10
|
const DEMO_STORE_REPO = "shopify/hydrogen-demo-store";
|
|
13
11
|
async function setupRemoteTemplate(options, controller) {
|
|
14
12
|
const appTemplate = options.template === "demo-store" ? DEMO_STORE_REPO : options.template;
|
|
15
|
-
let abort = createAbortHandler(controller);
|
|
16
|
-
const backgroundDownloadPromise = appTemplate.includes("/") ? getExternalTemplate(appTemplate, controller.signal).catch(abort) : getMonorepoTemplate(appTemplate, controller.signal).catch(abort);
|
|
17
13
|
const project = await handleProjectLocation({ ...options, controller });
|
|
18
14
|
if (!project) return;
|
|
19
|
-
abort = createAbortHandler(controller, project);
|
|
15
|
+
const abort = createAbortHandler(controller, project);
|
|
16
|
+
const backgroundDownloadPromise = appTemplate.includes("/") ? getExternalTemplate(appTemplate, controller.signal).catch(abort) : getMonorepoTemplate(appTemplate, controller.signal).catch(abort);
|
|
20
17
|
const downloaded = await backgroundDownloadPromise;
|
|
21
18
|
if (controller.signal.aborted) return;
|
|
22
19
|
let backgroundWorkPromise = Promise.resolve().then(async () => {
|
|
23
20
|
if (controller.signal.aborted) return;
|
|
24
|
-
const { sourcePath
|
|
25
|
-
const pkgJson = await readAndParsePackageJson(
|
|
26
|
-
joinPath(sourcePath, "package.json")
|
|
27
|
-
);
|
|
28
|
-
if (pkgJson.scripts?.dev?.includes("--diff")) {
|
|
29
|
-
return applyTemplateDiff(project.directory, sourcePath, skeletonPath);
|
|
30
|
-
}
|
|
21
|
+
const { sourcePath } = downloaded;
|
|
31
22
|
await copyFile(sourcePath, project.directory);
|
|
32
23
|
}).catch(abort);
|
|
33
24
|
const supportsTranspilation = await fileExists(
|
|
@@ -2,7 +2,7 @@ import { rm, symlink } from 'node:fs/promises';
|
|
|
2
2
|
import { vi } from 'vitest';
|
|
3
3
|
import { writeFile } from '@shopify/cli-kit/node/fs';
|
|
4
4
|
import { dirname, joinPath } from '@shopify/cli-kit/node/path';
|
|
5
|
-
import { getSkeletonSourceDir,
|
|
5
|
+
import { getSkeletonSourceDir, getSkeletonNodeModules } from '../build.js';
|
|
6
6
|
|
|
7
7
|
const { renderTasksHook } = vi.hoisted(() => ({ renderTasksHook: vi.fn() }));
|
|
8
8
|
vi.mock("../template-downloader.js", async () => ({
|
|
@@ -43,15 +43,13 @@ vi.mock(
|
|
|
43
43
|
renderTasksHook.mockImplementationOnce(async () => {
|
|
44
44
|
await writeFile(`${directory}/package-lock.json`, "{}");
|
|
45
45
|
});
|
|
46
|
-
|
|
46
|
+
const targetNodeModules = joinPath(directory, "node_modules");
|
|
47
|
+
await rm(targetNodeModules, {
|
|
47
48
|
force: true,
|
|
48
49
|
recursive: true
|
|
49
50
|
}).catch(() => {
|
|
50
51
|
});
|
|
51
|
-
await symlink(
|
|
52
|
-
await getRepoNodeModules(),
|
|
53
|
-
joinPath(directory, "node_modules")
|
|
54
|
-
);
|
|
52
|
+
await symlink(await getSkeletonNodeModules(), targetNodeModules);
|
|
55
53
|
})
|
|
56
54
|
};
|
|
57
55
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { readFile } from '@shopify/cli-kit/node/fs';
|
|
2
|
+
import { joinPath } from '@shopify/cli-kit/node/path';
|
|
3
|
+
import { renderWarning } from '@shopify/cli-kit/node/ui';
|
|
4
|
+
import { outputDebug } from '@shopify/cli-kit/node/output';
|
|
5
|
+
import semver from 'semver';
|
|
6
|
+
|
|
7
|
+
const REACT_ROUTER_PACKAGES = [
|
|
8
|
+
"react-router",
|
|
9
|
+
"react-router-dom",
|
|
10
|
+
"@react-router/dev",
|
|
11
|
+
"@react-router/fs-routes"
|
|
12
|
+
];
|
|
13
|
+
const EXPECTED_VERSION = "7.9.2";
|
|
14
|
+
async function checkReactRouterVersions(appPath) {
|
|
15
|
+
const mismatches = [];
|
|
16
|
+
const packageJsonPath = joinPath(appPath, "package.json");
|
|
17
|
+
let packageJson;
|
|
18
|
+
try {
|
|
19
|
+
packageJson = JSON.parse(await readFile(packageJsonPath));
|
|
20
|
+
} catch (error) {
|
|
21
|
+
outputDebug(
|
|
22
|
+
`Unable to read package.json for React Router version check: ${error}`
|
|
23
|
+
);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const allDeps = {
|
|
27
|
+
...packageJson.dependencies,
|
|
28
|
+
...packageJson.devDependencies,
|
|
29
|
+
...packageJson.peerDependencies
|
|
30
|
+
};
|
|
31
|
+
for (const pkg of REACT_ROUTER_PACKAGES) {
|
|
32
|
+
const installedVersion = allDeps[pkg];
|
|
33
|
+
if (!installedVersion) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
installedVersion.replace(/^[\^~]/, "");
|
|
37
|
+
if (!semver.satisfies(EXPECTED_VERSION, installedVersion)) {
|
|
38
|
+
mismatches.push({
|
|
39
|
+
package: pkg,
|
|
40
|
+
installed: installedVersion,
|
|
41
|
+
expected: EXPECTED_VERSION
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (mismatches.length > 0) {
|
|
46
|
+
const mismatchList = mismatches.map(
|
|
47
|
+
(m) => ` \u2022 ${m.package}: installed ${m.installed}, expected ${m.expected}`
|
|
48
|
+
).join("\n");
|
|
49
|
+
const devPackages = ["@react-router/dev", "@react-router/fs-routes"];
|
|
50
|
+
const regularMismatches = mismatches.filter(
|
|
51
|
+
(m) => !devPackages.includes(m.package)
|
|
52
|
+
);
|
|
53
|
+
const devMismatches = mismatches.filter(
|
|
54
|
+
(m) => devPackages.includes(m.package)
|
|
55
|
+
);
|
|
56
|
+
const commands = [];
|
|
57
|
+
if (regularMismatches.length > 0) {
|
|
58
|
+
const regularList = regularMismatches.map((m) => `${m.package}@${EXPECTED_VERSION}`).join(" ");
|
|
59
|
+
commands.push(`npm install ${regularList}`);
|
|
60
|
+
}
|
|
61
|
+
if (devMismatches.length > 0) {
|
|
62
|
+
const devList = devMismatches.map((m) => `${m.package}@${EXPECTED_VERSION}`).join(" ");
|
|
63
|
+
commands.push(`npm install -D ${devList}`);
|
|
64
|
+
}
|
|
65
|
+
renderWarning({
|
|
66
|
+
headline: "React Router version mismatch detected",
|
|
67
|
+
body: [
|
|
68
|
+
"Hydrogen requires React Router 7.9.x for proper functionality.",
|
|
69
|
+
"",
|
|
70
|
+
"Version mismatches found:",
|
|
71
|
+
mismatchList,
|
|
72
|
+
"",
|
|
73
|
+
"To fix this issue, run:",
|
|
74
|
+
...commands.map((cmd) => ` ${cmd}`),
|
|
75
|
+
"",
|
|
76
|
+
"This may cause issues with routing, code splitting, and other features."
|
|
77
|
+
].join("\n")
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { checkReactRouterVersions };
|
|
@@ -209,6 +209,9 @@ async function findRouteDependencies(routeFilePath, appDirectory) {
|
|
|
209
209
|
// import from '~/components/...'
|
|
210
210
|
relativePath(dirname(filePath), appDirectory) || "."
|
|
211
211
|
);
|
|
212
|
+
if (match.includes("/+types/")) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
212
215
|
const resolvedMatchPath = resolvePath(dirname(filePath), match);
|
|
213
216
|
const absoluteFilepath = (await findFileWithExtension(
|
|
214
217
|
dirname(resolvedMatchPath),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFile, writeFile, glob, removeFile } from '@shopify/cli-kit/node/fs';
|
|
1
|
+
import { fileExists, readFile, writeFile, glob, removeFile } from '@shopify/cli-kit/node/fs';
|
|
2
2
|
import { outputDebug } from '@shopify/cli-kit/node/output';
|
|
3
3
|
import { joinPath } from '@shopify/cli-kit/node/path';
|
|
4
4
|
import { getCodeFormatOptions, formatCode } from '../format-code.js';
|
|
@@ -45,12 +45,14 @@ function convertConfigToJS(tsConfig, keepTypes = false) {
|
|
|
45
45
|
}
|
|
46
46
|
async function transpileProject(projectDir, keepTypes = true) {
|
|
47
47
|
const routesPath = joinPath(projectDir, "app/routes.ts");
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
if (await fileExists(routesPath)) {
|
|
49
|
+
const routesFileContent = await readFile(routesPath);
|
|
50
|
+
const replacedRoutesFileContent = routesFileContent.replace(
|
|
51
|
+
"./layout.tsx",
|
|
52
|
+
"./layout.jsx"
|
|
53
|
+
);
|
|
54
|
+
await writeFile(routesPath, replacedRoutesFileContent);
|
|
55
|
+
}
|
|
54
56
|
const entries = await glob("**/*.+(ts|tsx)", {
|
|
55
57
|
absolute: true,
|
|
56
58
|
cwd: projectDir,
|
|
@@ -103,6 +105,12 @@ async function transpileProject(projectDir, keepTypes = true) {
|
|
|
103
105
|
await readFile(joinPath(projectDir, "package.json"))
|
|
104
106
|
);
|
|
105
107
|
delete pkgJson.scripts["typecheck"];
|
|
108
|
+
const typegenPattern = /react-router typegen\s*&&\s*/g;
|
|
109
|
+
for (const [key, value] of Object.entries(pkgJson.scripts || {})) {
|
|
110
|
+
if (typeof value === "string" && value.includes("react-router typegen")) {
|
|
111
|
+
pkgJson.scripts[key] = value.replace(typegenPattern, "");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
106
114
|
if (!keepTypes) {
|
|
107
115
|
delete pkgJson.devDependencies["typescript"];
|
|
108
116
|
delete pkgJson.devDependencies["@shopify/oxygen-workers-types"];
|
package/oclif.manifest.json
CHANGED
|
@@ -60,14 +60,6 @@
|
|
|
60
60
|
"multiple": false,
|
|
61
61
|
"type": "option"
|
|
62
62
|
},
|
|
63
|
-
"diff": {
|
|
64
|
-
"description": "Applies the current files on top of Hydrogen's starter template in a temporary directory.",
|
|
65
|
-
"hidden": true,
|
|
66
|
-
"name": "diff",
|
|
67
|
-
"required": false,
|
|
68
|
-
"allowNo": false,
|
|
69
|
-
"type": "boolean"
|
|
70
|
-
},
|
|
71
63
|
"watch": {
|
|
72
64
|
"description": "Watches for changes and rebuilds the project writing output to disk.",
|
|
73
65
|
"env": "SHOPIFY_HYDROGEN_FLAG_WATCH",
|
|
@@ -181,14 +173,6 @@
|
|
|
181
173
|
"required": false,
|
|
182
174
|
"allowNo": false,
|
|
183
175
|
"type": "boolean"
|
|
184
|
-
},
|
|
185
|
-
"diff": {
|
|
186
|
-
"description": "Applies the current files on top of Hydrogen's starter template in a temporary directory.",
|
|
187
|
-
"hidden": true,
|
|
188
|
-
"name": "diff",
|
|
189
|
-
"required": false,
|
|
190
|
-
"allowNo": false,
|
|
191
|
-
"type": "boolean"
|
|
192
176
|
}
|
|
193
177
|
},
|
|
194
178
|
"hasDynamicHelp": false,
|
|
@@ -281,14 +265,6 @@
|
|
|
281
265
|
"multiple": false,
|
|
282
266
|
"type": "option"
|
|
283
267
|
},
|
|
284
|
-
"diff": {
|
|
285
|
-
"description": "Applies the current files on top of Hydrogen's starter template in a temporary directory.",
|
|
286
|
-
"hidden": true,
|
|
287
|
-
"name": "diff",
|
|
288
|
-
"required": false,
|
|
289
|
-
"allowNo": false,
|
|
290
|
-
"type": "boolean"
|
|
291
|
-
},
|
|
292
268
|
"entry": {
|
|
293
269
|
"description": "Entry file for the worker. Defaults to `./server`.",
|
|
294
270
|
"env": "SHOPIFY_HYDROGEN_FLAG_ENTRY",
|
|
@@ -496,11 +472,10 @@
|
|
|
496
472
|
"multiple": false,
|
|
497
473
|
"type": "option"
|
|
498
474
|
},
|
|
499
|
-
"
|
|
500
|
-
"description": "
|
|
501
|
-
"
|
|
502
|
-
"name": "
|
|
503
|
-
"required": false,
|
|
475
|
+
"force-client-sourcemap": {
|
|
476
|
+
"description": "Client sourcemapping is avoided by default because it makes backend code visible in the browser. Use this flag to force enabling it.",
|
|
477
|
+
"env": "SHOPIFY_HYDROGEN_FLAG_FORCE_CLIENT_SOURCEMAP",
|
|
478
|
+
"name": "force-client-sourcemap",
|
|
504
479
|
"allowNo": false,
|
|
505
480
|
"type": "boolean"
|
|
506
481
|
}
|
|
@@ -630,19 +605,10 @@
|
|
|
630
605
|
"allowNo": false,
|
|
631
606
|
"type": "boolean"
|
|
632
607
|
},
|
|
633
|
-
"
|
|
634
|
-
"description": "
|
|
635
|
-
"hidden": true,
|
|
636
|
-
"name": "diff",
|
|
637
|
-
"required": false,
|
|
638
|
-
"allowNo": false,
|
|
639
|
-
"type": "boolean"
|
|
640
|
-
},
|
|
641
|
-
"customer-account-push__unstable": {
|
|
642
|
-
"description": "Use tunneling for local development and push the tunneling domain to admin. Required to use Customer Account API's Oauth flow",
|
|
608
|
+
"customer-account-push": {
|
|
609
|
+
"description": "Use tunneling for local development and push the tunneling domain to admin. Required to use Customer Account API's OAuth flow",
|
|
643
610
|
"env": "SHOPIFY_HYDROGEN_FLAG_CUSTOMER_ACCOUNT_PUSH",
|
|
644
|
-
"
|
|
645
|
-
"name": "customer-account-push__unstable",
|
|
611
|
+
"name": "customer-account-push",
|
|
646
612
|
"required": false,
|
|
647
613
|
"allowNo": false,
|
|
648
614
|
"type": "boolean"
|
|
@@ -1405,17 +1371,6 @@
|
|
|
1405
1371
|
"hasDynamicHelp": false,
|
|
1406
1372
|
"multiple": false,
|
|
1407
1373
|
"type": "option"
|
|
1408
|
-
},
|
|
1409
|
-
"diff": {
|
|
1410
|
-
"dependsOn": [
|
|
1411
|
-
"build"
|
|
1412
|
-
],
|
|
1413
|
-
"description": "Applies the current files on top of Hydrogen's starter template in a temporary directory.",
|
|
1414
|
-
"hidden": true,
|
|
1415
|
-
"name": "diff",
|
|
1416
|
-
"required": false,
|
|
1417
|
-
"allowNo": false,
|
|
1418
|
-
"type": "boolean"
|
|
1419
1374
|
}
|
|
1420
1375
|
},
|
|
1421
1376
|
"hasDynamicHelp": false,
|
|
@@ -1728,5 +1683,5 @@
|
|
|
1728
1683
|
]
|
|
1729
1684
|
}
|
|
1730
1685
|
},
|
|
1731
|
-
"version": "11.1.
|
|
1686
|
+
"version": "11.1.5"
|
|
1732
1687
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"@shopify:registry": "https://registry.npmjs.org"
|
|
6
6
|
},
|
|
7
|
-
"version": "11.1.
|
|
7
|
+
"version": "11.1.5",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"repository": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"test:watch": "cross-env SHOPIFY_UNIT_TEST=1 LANG=en-US.UTF-8 vitest --test-timeout=60000"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@react-router/dev": "7.
|
|
24
|
+
"@react-router/dev": "7.9.2",
|
|
25
25
|
"@types/diff": "^5.0.2",
|
|
26
26
|
"@types/gunzip-maybe": "^1.4.0",
|
|
27
27
|
"@types/prettier": "^2.7.2",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"vitest": "^1.0.4"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@ast-grep/napi": "0.
|
|
40
|
+
"@ast-grep/napi": "0.34.1",
|
|
41
41
|
"@oclif/core": "3.26.5",
|
|
42
42
|
"@shopify/cli-kit": "^3.80.4",
|
|
43
43
|
"@shopify/oxygen-cli": "4.6.18",
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"@graphql-codegen/cli": "^5.0.2",
|
|
63
|
-
"@react-router/dev": "7.
|
|
63
|
+
"@react-router/dev": "7.9.2",
|
|
64
64
|
"@shopify/hydrogen-codegen": "^0.3.3",
|
|
65
|
-
"@shopify/mini-oxygen": "^
|
|
65
|
+
"@shopify/mini-oxygen": "^4.0.0",
|
|
66
66
|
"graphql-config": "^5.0.3",
|
|
67
67
|
"vite": "^5.1.0 || ^6.2.0"
|
|
68
68
|
},
|