@shopify/cli-hydrogen 4.0.8 → 4.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/README.md +9 -0
- package/dist/commands/hydrogen/build.d.ts +4 -1
- package/dist/commands/hydrogen/build.js +21 -17
- package/dist/commands/hydrogen/check.d.ts +3 -6
- package/dist/commands/hydrogen/check.js +10 -9
- package/dist/commands/hydrogen/dev.d.ts +3 -2
- package/dist/commands/hydrogen/dev.js +24 -22
- package/dist/commands/hydrogen/g.d.ts +10 -0
- package/dist/commands/hydrogen/g.js +17 -0
- package/dist/commands/hydrogen/generate/route.d.ts +7 -9
- package/dist/commands/hydrogen/generate/route.js +49 -47
- package/dist/commands/hydrogen/generate/route.test.js +48 -40
- package/dist/commands/hydrogen/generate/routes.d.ts +2 -2
- package/dist/commands/hydrogen/init.d.ts +3 -3
- package/dist/commands/hydrogen/init.js +76 -95
- package/dist/commands/hydrogen/init.test.js +126 -0
- package/dist/commands/hydrogen/preview.d.ts +2 -2
- package/dist/commands/hydrogen/preview.js +4 -4
- package/dist/commands/hydrogen/shortcut.d.ts +9 -0
- package/dist/commands/hydrogen/shortcut.js +74 -0
- package/dist/commands/hydrogen/shortcut.test.js +58 -0
- package/dist/generator-templates/routes/[robots.txt].tsx +35 -1
- package/dist/generator-templates/routes/[sitemap.xml].tsx +45 -10
- package/dist/generator-templates/routes/account/login.tsx +42 -13
- package/dist/generator-templates/routes/account/register.tsx +42 -13
- package/dist/generator-templates/routes/cart.tsx +42 -2
- package/dist/generator-templates/routes/collections/$collectionHandle.tsx +44 -5
- package/dist/generator-templates/routes/index.tsx +33 -0
- package/dist/generator-templates/routes/pages/$pageHandle.tsx +48 -10
- package/dist/generator-templates/routes/policies/$policyHandle.tsx +67 -14
- package/dist/generator-templates/routes/policies/index.tsx +54 -4
- package/dist/generator-templates/routes/products/$productHandle.tsx +44 -9
- package/dist/hooks/init.js +2 -2
- package/dist/{utils → lib}/check-lockfile.js +7 -4
- package/dist/{utils → lib}/check-lockfile.test.js +19 -28
- package/dist/{utils → lib}/check-version.test.js +3 -2
- package/dist/lib/colors.d.ts +8 -0
- package/dist/lib/colors.js +8 -0
- package/dist/{utils → lib}/config.js +10 -19
- package/dist/{utils → lib}/flags.d.ts +9 -3
- package/dist/{utils → lib}/flags.js +19 -4
- package/dist/lib/flags.test.d.ts +1 -0
- package/dist/{utils → lib}/mini-oxygen.js +14 -12
- package/dist/{utils → lib}/missing-routes.js +1 -1
- package/dist/lib/remix-version-interop.d.ts +11 -0
- package/dist/lib/remix-version-interop.js +54 -0
- package/dist/lib/remix-version-interop.test.d.ts +1 -0
- package/dist/lib/remix-version-interop.test.js +93 -0
- package/dist/lib/shell.d.ts +12 -0
- package/dist/lib/shell.js +73 -0
- package/dist/lib/template-downloader.d.ts +6 -0
- package/dist/{utils → lib}/template-downloader.js +21 -16
- package/dist/{utils → lib}/transpile-ts.js +5 -5
- package/dist/lib/virtual-routes.test.d.ts +1 -0
- package/dist/virtual-routes/routes/index.jsx +2 -15
- package/dist/virtual-routes/virtual-root.jsx +5 -6
- package/oclif.manifest.json +1 -1
- package/package.json +11 -10
- package/dist/utils/template-downloader.d.ts +0 -11
- /package/dist/{utils/check-lockfile.test.d.ts → commands/hydrogen/init.test.d.ts} +0 -0
- /package/dist/{utils/check-version.test.d.ts → commands/hydrogen/shortcut.test.d.ts} +0 -0
- /package/dist/{utils → lib}/check-lockfile.d.ts +0 -0
- /package/dist/{utils/flags.test.d.ts → lib/check-lockfile.test.d.ts} +0 -0
- /package/dist/{utils → lib}/check-version.d.ts +0 -0
- /package/dist/{utils → lib}/check-version.js +0 -0
- /package/dist/{utils/virtual-routes.test.d.ts → lib/check-version.test.d.ts} +0 -0
- /package/dist/{utils → lib}/config.d.ts +0 -0
- /package/dist/{utils → lib}/flags.test.js +0 -0
- /package/dist/{utils → lib}/log.d.ts +0 -0
- /package/dist/{utils → lib}/log.js +0 -0
- /package/dist/{utils → lib}/mini-oxygen.d.ts +0 -0
- /package/dist/{utils → lib}/missing-routes.d.ts +0 -0
- /package/dist/{utils → lib}/transpile-ts.d.ts +0 -0
- /package/dist/{utils → lib}/virtual-routes.d.ts +0 -0
- /package/dist/{utils → lib}/virtual-routes.js +0 -0
- /package/dist/{utils → lib}/virtual-routes.test.js +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import { getRemixConfig } from './config.js';
|
|
3
|
+
|
|
4
|
+
function isRemixV2() {
|
|
5
|
+
try {
|
|
6
|
+
const require2 = createRequire(import.meta.url);
|
|
7
|
+
const version = require2("@remix-run/server-runtime/package.json")?.version ?? "";
|
|
8
|
+
return version.startsWith("2.");
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async function getV2Flags(root) {
|
|
14
|
+
const isV2 = isRemixV2();
|
|
15
|
+
const futureFlags = {
|
|
16
|
+
...!isV2 && (await getRemixConfig(root)).future
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
isV2Meta: isV2 || !!futureFlags.v2_meta,
|
|
20
|
+
isV2ErrorBoundary: isV2 || !!futureFlags.v2_errorBoundary,
|
|
21
|
+
isV2RouteConvention: isV2 ? !isV1RouteConventionInstalled() : !!futureFlags.v2_routeConvention
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function convertRouteToV2(route) {
|
|
25
|
+
return route.replace(/\/index$/, "/_index").replace(/(?<!^)\//g, ".");
|
|
26
|
+
}
|
|
27
|
+
function convertTemplateToRemixVersion(template, { isV2Meta, isV2ErrorBoundary }) {
|
|
28
|
+
template = isV2Meta ? convertToMetaV2(template) : convertToMetaV1(template);
|
|
29
|
+
template = isV2ErrorBoundary ? convertToErrorBoundaryV2(template) : convertToErrorBoundaryV1(template);
|
|
30
|
+
return template;
|
|
31
|
+
}
|
|
32
|
+
function convertToMetaV2(template) {
|
|
33
|
+
return template.replace(/type MetaFunction\s*,?/, "").replace(/export (const|function) metaV1.+?\n};?\n/s, "").replace(/import \{\s*\} from '@shopify\/remix-oxygen';/, "");
|
|
34
|
+
}
|
|
35
|
+
function convertToMetaV1(template) {
|
|
36
|
+
return template.replace(/type V2_MetaFunction\s*,?/, "").replace(/export (const|function) meta[^V].+?\n};?\n/s, "").replace(/(const|function) metaV1/, "$1 meta").replace(/import \{\s*\} from '@remix-run\/react';/, "");
|
|
37
|
+
}
|
|
38
|
+
function convertToErrorBoundaryV2(template) {
|
|
39
|
+
return template.replace(/type ErrorBoundaryComponent\s*,?/s, "").replace(/useCatch\s*,?/s, "").replace(/export function CatchBoundary.+?\n}/s, "").replace(/export (const|function) ErrorBoundaryV1.+?\n};?/s, "").replace(/import \{\s*\} from '@shopify\/remix-oxygen';/, "").replace(/import \{\s*\} from '@remix-run\/react';/, "");
|
|
40
|
+
}
|
|
41
|
+
function convertToErrorBoundaryV1(template) {
|
|
42
|
+
return template.replace(/useRouteError\s*,?/s, "").replace(/isRouteErrorResponse\s*,?/s, "").replace(/export function ErrorBoundary[^V].+?\n}/s, "").replace(/(const|function) ErrorBoundaryV1/, "$1 ErrorBoundary").replace(/import \{\s*\} from '@remix-run\/react';/, "");
|
|
43
|
+
}
|
|
44
|
+
function isV1RouteConventionInstalled() {
|
|
45
|
+
try {
|
|
46
|
+
const require2 = createRequire(import.meta.url);
|
|
47
|
+
require2.resolve("@remix-run/v1-route-convention/package.json");
|
|
48
|
+
return true;
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { convertRouteToV2, convertTemplateToRemixVersion, getV2Flags, isRemixV2 };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { convertTemplateToRemixVersion } from './remix-version-interop.js';
|
|
3
|
+
|
|
4
|
+
describe("remix-version-interop", () => {
|
|
5
|
+
describe("v2_meta", () => {
|
|
6
|
+
const META_TEMPLATE = `
|
|
7
|
+
import {type MetaFunction} from '@shopify/remix-oxygen';
|
|
8
|
+
import {type V2_MetaFunction} from '@remix-run/react';
|
|
9
|
+
export const metaV1: MetaFunction = ({data}) => {
|
|
10
|
+
const title = 'title';
|
|
11
|
+
return {title};
|
|
12
|
+
};
|
|
13
|
+
export const meta: V2_MetaFunction = ({data}) => {
|
|
14
|
+
const title = 'title';
|
|
15
|
+
return [{title}];
|
|
16
|
+
};
|
|
17
|
+
`.replace(/^\s{4}/gm, "");
|
|
18
|
+
it("transforms meta exports to v2", async () => {
|
|
19
|
+
const result = convertTemplateToRemixVersion(META_TEMPLATE, {
|
|
20
|
+
isV2Meta: true
|
|
21
|
+
});
|
|
22
|
+
expect(result).toContain("type V2_MetaFunction");
|
|
23
|
+
expect(result).not.toContain("type MetaFunction");
|
|
24
|
+
expect(result).not.toContain("@shopify/remix-oxygen");
|
|
25
|
+
expect(result).toMatch(/return \[\{title\}\];/);
|
|
26
|
+
expect(result).not.toMatch(/return \{title\};/);
|
|
27
|
+
});
|
|
28
|
+
it("transforms meta exports to v1", async () => {
|
|
29
|
+
const result = convertTemplateToRemixVersion(META_TEMPLATE, {
|
|
30
|
+
isV2Meta: false
|
|
31
|
+
});
|
|
32
|
+
expect(result).toContain("type MetaFunction");
|
|
33
|
+
expect(result).not.toContain("type V2_MetaFunction");
|
|
34
|
+
expect(result).not.toContain("@remix-run/react");
|
|
35
|
+
expect(result).toMatch(/return \{title\};/);
|
|
36
|
+
expect(result).not.toMatch(/return \[\{title\}\];/);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe("v2_errorBoundary", () => {
|
|
40
|
+
const ERROR_BOUNDARY_TEMPLATE = `
|
|
41
|
+
import {useCatch, isRouteErrorResponse, useRouteError} from "@remix-run/react";
|
|
42
|
+
import {type ErrorBoundaryComponent} from '@shopify/remix-oxygen';
|
|
43
|
+
|
|
44
|
+
export function CatchBoundary() {
|
|
45
|
+
const caught = useCatch();
|
|
46
|
+
console.error(caught);
|
|
47
|
+
|
|
48
|
+
return <div>stuff</div>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const ErrorBoundaryV1: ErrorBoundaryComponent = ({error}) => {
|
|
52
|
+
console.error(error);
|
|
53
|
+
|
|
54
|
+
return <div>There was an error.</div>;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export function ErrorBoundary() {
|
|
58
|
+
const error = useRouteError();
|
|
59
|
+
|
|
60
|
+
if (isRouteErrorResponse(error)) {
|
|
61
|
+
return <div>RouteError</div>;
|
|
62
|
+
} else {
|
|
63
|
+
return <h1>Unknown Error</h1>;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
`.replace(/^\s{4}/gm, "");
|
|
67
|
+
it("transforms ErrorBoundary exports to v2", async () => {
|
|
68
|
+
const result = convertTemplateToRemixVersion(ERROR_BOUNDARY_TEMPLATE, {
|
|
69
|
+
isV2ErrorBoundary: true
|
|
70
|
+
});
|
|
71
|
+
expect(result).toContain("export function ErrorBoundary");
|
|
72
|
+
expect(result).not.toContain("export const ErrorBoundary");
|
|
73
|
+
expect(result).not.toMatch("export function CatchBoundary");
|
|
74
|
+
expect(result).not.toContain("type ErrorBoundaryComponent");
|
|
75
|
+
expect(result).not.toContain("@shopify/remix-oxygen");
|
|
76
|
+
expect(result).toContain("useRouteError");
|
|
77
|
+
expect(result).toContain("isRouteErrorResponse");
|
|
78
|
+
expect(result).not.toContain("useCatch");
|
|
79
|
+
});
|
|
80
|
+
it("transforms ErrorBoundary exports to v1", async () => {
|
|
81
|
+
const result = convertTemplateToRemixVersion(ERROR_BOUNDARY_TEMPLATE, {
|
|
82
|
+
isV2ErrorBoundary: false
|
|
83
|
+
});
|
|
84
|
+
expect(result).toContain("export const ErrorBoundary");
|
|
85
|
+
expect(result).not.toContain("export function ErrorBoundary");
|
|
86
|
+
expect(result).toMatch("export function CatchBoundary");
|
|
87
|
+
expect(result).toContain("type ErrorBoundaryComponent");
|
|
88
|
+
expect(result).toContain("useCatch");
|
|
89
|
+
expect(result).not.toContain("useRouteError");
|
|
90
|
+
expect(result).not.toContain("isRouteErrorResponse");
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type UnixShell = 'zsh' | 'bash' | 'fish';
|
|
2
|
+
type WindowsShell = 'PowerShell' | 'PowerShell 7+' | 'CMD';
|
|
3
|
+
type Shell = UnixShell | WindowsShell;
|
|
4
|
+
declare const isWindows: () => boolean;
|
|
5
|
+
declare const isGitBash: () => boolean;
|
|
6
|
+
declare function homeFileExists(filepath: string): false | Promise<boolean>;
|
|
7
|
+
declare function supportsShell(shell: UnixShell): boolean;
|
|
8
|
+
declare function hasAlias(aliasName: string, filepath: string): boolean;
|
|
9
|
+
declare function shellWriteFile(filepath: string, content: string, append?: boolean): boolean;
|
|
10
|
+
declare function shellRunScript(script: string, shellBin: string): boolean;
|
|
11
|
+
|
|
12
|
+
export { Shell, UnixShell, WindowsShell, hasAlias, homeFileExists, isGitBash, isWindows, shellRunScript, shellWriteFile, supportsShell };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { fileExists } from '@shopify/cli-kit/node/fs';
|
|
5
|
+
import { outputDebug } from '@shopify/cli-kit/node/output';
|
|
6
|
+
|
|
7
|
+
const isWindows = () => process.platform === "win32";
|
|
8
|
+
const isGitBash = () => !!process.env.MINGW_PREFIX;
|
|
9
|
+
function resolveFromHome(filepath) {
|
|
10
|
+
if (filepath[0] === "~") {
|
|
11
|
+
return path.join(os.homedir(), filepath.slice(1));
|
|
12
|
+
}
|
|
13
|
+
return filepath;
|
|
14
|
+
}
|
|
15
|
+
function homeFileExists(filepath) {
|
|
16
|
+
try {
|
|
17
|
+
return fileExists(resolveFromHome(filepath));
|
|
18
|
+
} catch (error) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function supportsShell(shell) {
|
|
23
|
+
try {
|
|
24
|
+
execSync(`which ${shell}`, { stdio: "ignore" });
|
|
25
|
+
return true;
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function hasAlias(aliasName, filepath) {
|
|
31
|
+
try {
|
|
32
|
+
const result = execSync(
|
|
33
|
+
`grep 'alias ${aliasName}' ${resolveFromHome(filepath)}`,
|
|
34
|
+
{ stdio: "pipe" }
|
|
35
|
+
).toString();
|
|
36
|
+
return !!result;
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function shellWriteFile(filepath, content, append = false) {
|
|
42
|
+
content = `"${content}"`;
|
|
43
|
+
content = content.replaceAll("\n", "\\n");
|
|
44
|
+
if (!isWindows()) {
|
|
45
|
+
content = content.replaceAll("$", "\\$");
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
execSync(
|
|
49
|
+
`printf ${content} ${append ? ">>" : ">"} ${resolveFromHome(filepath)}`
|
|
50
|
+
);
|
|
51
|
+
return true;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
outputDebug(
|
|
54
|
+
`Could not create or modify ${filepath}:
|
|
55
|
+
` + error.stack
|
|
56
|
+
);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function shellRunScript(script, shellBin) {
|
|
61
|
+
try {
|
|
62
|
+
execSync(script, { shell: shellBin, stdio: "ignore" });
|
|
63
|
+
return true;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
outputDebug(
|
|
66
|
+
`Could not run shell script for ${shellBin}:
|
|
67
|
+
` + error.stack
|
|
68
|
+
);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { hasAlias, homeFileExists, isGitBash, isWindows, shellRunScript, shellWriteFile, supportsShell };
|
|
@@ -2,17 +2,19 @@ import path from 'path';
|
|
|
2
2
|
import { pipeline } from 'stream/promises';
|
|
3
3
|
import gunzipMaybe from 'gunzip-maybe';
|
|
4
4
|
import { extract } from 'tar-fs';
|
|
5
|
-
import {
|
|
5
|
+
import { fetch } from '@shopify/cli-kit/node/http';
|
|
6
|
+
import { fileExists, mkdir } from '@shopify/cli-kit/node/fs';
|
|
7
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
6
8
|
import { fileURLToPath } from 'url';
|
|
7
9
|
|
|
8
10
|
const REPO_RELEASES_URL = `https://api.github.com/repos/shopify/hydrogen/releases/latest`;
|
|
11
|
+
const getTryMessage = (status) => status === 403 ? `If you are using a VPN, WARP, or similar service, consider disabling it momentarily.` : void 0;
|
|
9
12
|
async function getLatestReleaseDownloadUrl() {
|
|
10
|
-
const response = await
|
|
13
|
+
const response = await fetch(REPO_RELEASES_URL);
|
|
11
14
|
if (!response.ok || response.status >= 400) {
|
|
12
|
-
throw new
|
|
13
|
-
`Failed to fetch the latest release information. Status ${response.status} ${response.statusText.replace(/\.$/, "")}
|
|
14
|
-
|
|
15
|
-
If you are using a VPN, WARP, or similar service, consider disabling it momentarily.` : "")
|
|
15
|
+
throw new AbortError(
|
|
16
|
+
`Failed to fetch the latest release information. Status ${response.status} ${response.statusText.replace(/\.$/, "")}.`,
|
|
17
|
+
getTryMessage(response.status)
|
|
16
18
|
);
|
|
17
19
|
}
|
|
18
20
|
const release = await response.json();
|
|
@@ -22,10 +24,11 @@ If you are using a VPN, WARP, or similar service, consider disabling it momentar
|
|
|
22
24
|
};
|
|
23
25
|
}
|
|
24
26
|
async function downloadTarball(url, storageDir) {
|
|
25
|
-
const response = await
|
|
27
|
+
const response = await fetch(url);
|
|
26
28
|
if (!response.ok || response.status >= 400) {
|
|
27
|
-
throw new
|
|
28
|
-
`Failed to download the latest release files. Status ${response.status} ${response.statusText}}
|
|
29
|
+
throw new AbortError(
|
|
30
|
+
`Failed to download the latest release files. Status ${response.status} ${response.statusText}}`,
|
|
31
|
+
getTryMessage(response.status)
|
|
29
32
|
);
|
|
30
33
|
}
|
|
31
34
|
await pipeline(
|
|
@@ -46,11 +49,11 @@ async function getLatestTemplates() {
|
|
|
46
49
|
const templateStoragePath = fileURLToPath(
|
|
47
50
|
new URL("../starter-templates", import.meta.url)
|
|
48
51
|
);
|
|
49
|
-
if (!await
|
|
50
|
-
await
|
|
52
|
+
if (!await fileExists(templateStoragePath)) {
|
|
53
|
+
await mkdir(templateStoragePath);
|
|
51
54
|
}
|
|
52
55
|
const templateStorageVersionPath = path.join(templateStoragePath, version);
|
|
53
|
-
if (!await
|
|
56
|
+
if (!await fileExists(templateStorageVersionPath)) {
|
|
54
57
|
await downloadTarball(url, templateStorageVersionPath);
|
|
55
58
|
}
|
|
56
59
|
return {
|
|
@@ -59,12 +62,14 @@ async function getLatestTemplates() {
|
|
|
59
62
|
};
|
|
60
63
|
} catch (e) {
|
|
61
64
|
const error = e;
|
|
62
|
-
|
|
65
|
+
throw new AbortError(
|
|
66
|
+
`Could not download Hydrogen templates from GitHub.
|
|
63
67
|
Please check your internet connection and the following error:
|
|
64
68
|
|
|
65
|
-
` + error.message
|
|
66
|
-
|
|
69
|
+
` + error.message,
|
|
70
|
+
error.tryMessage
|
|
71
|
+
);
|
|
67
72
|
}
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
export {
|
|
75
|
+
export { getLatestTemplates };
|
|
@@ -3,7 +3,7 @@ import fs from 'fs/promises';
|
|
|
3
3
|
import prettier from 'prettier';
|
|
4
4
|
import ts from 'typescript';
|
|
5
5
|
import glob from 'fast-glob';
|
|
6
|
-
import {
|
|
6
|
+
import { outputDebug } from '@shopify/cli-kit/node/output';
|
|
7
7
|
|
|
8
8
|
const escapeNewLines = (code) => code.replace(/\n\n/g, "\n/* :newline: */");
|
|
9
9
|
const restoreNewLines = (code) => code.replace(/\/\* :newline: \*\//g, "\n");
|
|
@@ -112,7 +112,7 @@ async function transpileProject(projectDir) {
|
|
|
112
112
|
remixConfig = remixConfig.replace(/\/server\.ts/gim, "/server.js");
|
|
113
113
|
await fs.writeFile(remixConfigPath, remixConfig);
|
|
114
114
|
} catch (error) {
|
|
115
|
-
|
|
115
|
+
outputDebug(
|
|
116
116
|
"Could not change TS extensions in remix.config.js:\n" + error.stack
|
|
117
117
|
);
|
|
118
118
|
}
|
|
@@ -129,7 +129,7 @@ async function transpileProject(projectDir) {
|
|
|
129
129
|
"utf8"
|
|
130
130
|
);
|
|
131
131
|
} catch (error) {
|
|
132
|
-
|
|
132
|
+
outputDebug(
|
|
133
133
|
"Could not transpile tsconfig.json:\n" + error.stack
|
|
134
134
|
);
|
|
135
135
|
}
|
|
@@ -150,7 +150,7 @@ async function transpileProject(projectDir) {
|
|
|
150
150
|
JSON.stringify(pkgJson, null, 2)
|
|
151
151
|
);
|
|
152
152
|
} catch (error) {
|
|
153
|
-
|
|
153
|
+
outputDebug(
|
|
154
154
|
"Could not remove TS dependencies from package.json:\n" + error.stack
|
|
155
155
|
);
|
|
156
156
|
}
|
|
@@ -160,7 +160,7 @@ async function transpileProject(projectDir) {
|
|
|
160
160
|
eslintrc = eslintrc.replace(/\/\*\*[\s*]+@type.+\s+\*\/\s?/gim, "").replace(/\s*,?\s*['"`]plugin:hydrogen\/typescript['"`]/gim, "").replace(/\s+['"`]@typescript-eslint\/.+,/gim, "");
|
|
161
161
|
await fs.writeFile(eslintrcPath, eslintrc);
|
|
162
162
|
} catch (error) {
|
|
163
|
-
|
|
163
|
+
outputDebug(
|
|
164
164
|
"Could not remove TS rules from .eslintrc:\n" + error.stack
|
|
165
165
|
);
|
|
166
166
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -9,14 +9,6 @@ import { IconError } from "../components/IconError.jsx";
|
|
|
9
9
|
import favicon from "../assets/favicon.svg";
|
|
10
10
|
import interVariableFontWoff2 from "../assets/inter-variable-font.woff2";
|
|
11
11
|
import jetbrainsmonoVariableFontWoff2 from "../assets/jetbrainsmono-variable-font.woff2";
|
|
12
|
-
const meta = () => {
|
|
13
|
-
return {
|
|
14
|
-
title: "Hydrogen",
|
|
15
|
-
description: "A custom storefront powered by Hydrogen",
|
|
16
|
-
charset: "utf-8",
|
|
17
|
-
viewport: "width=device-width,initial-scale=1"
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
12
|
const links = () => [
|
|
21
13
|
{
|
|
22
14
|
rel: "icon",
|
|
@@ -43,9 +35,6 @@ async function loader({ context }) {
|
|
|
43
35
|
return { layout };
|
|
44
36
|
}
|
|
45
37
|
const HYDROGEN_SHOP_ID = "gid://shopify/Shop/55145660472";
|
|
46
|
-
function CatchBoundary() {
|
|
47
|
-
return <ErrorPage />;
|
|
48
|
-
}
|
|
49
38
|
function ErrorBoundary() {
|
|
50
39
|
return <ErrorPage />;
|
|
51
40
|
}
|
|
@@ -74,7 +63,7 @@ function Index() {
|
|
|
74
63
|
<code>.env</code>
|
|
75
64
|
{". Then, create your first route with the file"}
|
|
76
65
|
{` `}
|
|
77
|
-
<code>/app/routes/
|
|
66
|
+
<code>/app/routes/_index.jsx</code>
|
|
78
67
|
{". Learn more about"}
|
|
79
68
|
{` `}
|
|
80
69
|
<a target="_blank" rel="norefferer noopener" href="https://shopify.dev/docs/custom-storefronts/hydrogen/environment-variables">editing environment variables</a>
|
|
@@ -153,11 +142,9 @@ const LAYOUT_QUERY = `#graphql
|
|
|
153
142
|
}
|
|
154
143
|
`;
|
|
155
144
|
export {
|
|
156
|
-
CatchBoundary,
|
|
157
145
|
ErrorBoundary,
|
|
158
146
|
HYDROGEN_SHOP_ID,
|
|
159
147
|
Index as default,
|
|
160
148
|
links,
|
|
161
|
-
loader
|
|
162
|
-
meta
|
|
149
|
+
loader
|
|
163
150
|
};
|
|
@@ -14,13 +14,13 @@ const links = () => {
|
|
|
14
14
|
{ rel: "icon", type: "image/svg+xml", href: favicon }
|
|
15
15
|
];
|
|
16
16
|
};
|
|
17
|
-
const meta = () => ({
|
|
18
|
-
charset: "utf-8",
|
|
19
|
-
viewport: "width=device-width,initial-scale=1"
|
|
20
|
-
});
|
|
21
17
|
function App() {
|
|
22
18
|
return <html lang="en">
|
|
23
19
|
<head>
|
|
20
|
+
<meta charSet="utf-8" />
|
|
21
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
22
|
+
<title>Hydrogen</title>
|
|
23
|
+
<meta name="description" content="A custom storefront powered by Hydrogen" />
|
|
24
24
|
<Meta />
|
|
25
25
|
<Links />
|
|
26
26
|
</head>
|
|
@@ -33,6 +33,5 @@ function App() {
|
|
|
33
33
|
}
|
|
34
34
|
export {
|
|
35
35
|
App as default,
|
|
36
|
-
links
|
|
37
|
-
meta
|
|
36
|
+
links
|
|
38
37
|
};
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"4.0
|
|
1
|
+
{"version":"4.1.0","commands":{"hydrogen:build":{"id":"hydrogen:build","description":"Builds a Hydrogen storefront for production.","strict":true,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","aliases":[],"flags":{"path":{"name":"path","type":"option","description":"The path to the directory of the Hydrogen storefront. The default is the current directory.","multiple":false},"sourcemap":{"name":"sourcemap","type":"boolean","description":"Generate sourcemaps for the build.","allowNo":false},"disable-route-warning":{"name":"disable-route-warning","type":"boolean","description":"Disable warning about missing standard routes.","allowNo":false},"base":{"name":"base","type":"option","hidden":true,"multiple":false},"entry":{"name":"entry","type":"option","hidden":true,"multiple":false},"target":{"name":"target","type":"option","hidden":true,"multiple":false}},"args":[]},"hydrogen:check":{"id":"hydrogen:check","description":"Returns diagnostic information about a Hydrogen storefront.","strict":true,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","aliases":[],"flags":{"path":{"name":"path","type":"option","description":"The path to the directory of the Hydrogen storefront. The default is the current directory.","multiple":false}},"args":[{"name":"resource","description":"The resource to check. Currently only 'routes' is supported.","required":true,"options":["routes"]}]},"hydrogen:dev":{"id":"hydrogen:dev","description":"Runs Hydrogen storefront in an Oxygen worker for development.","strict":true,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","aliases":[],"flags":{"path":{"name":"path","type":"option","description":"The path to the directory of the Hydrogen storefront. The default is the current directory.","multiple":false},"port":{"name":"port","type":"option","description":"Port to run the server on.","multiple":false,"default":3000},"disable-virtual-routes":{"name":"disable-virtual-routes","type":"boolean","description":"Disable rendering fallback routes when a route file doesn't exist","allowNo":false},"host":{"name":"host","type":"option","hidden":true,"multiple":false}},"args":[]},"hydrogen:g":{"id":"hydrogen:g","description":"Shortcut for `hydrogen generate`. See `hydrogen generate --help` for more information.","strict":false,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","hidden":true,"aliases":[],"flags":{},"args":[]},"hydrogen:init":{"id":"hydrogen:init","description":"Creates a new Hydrogen storefront.","strict":true,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","aliases":[],"flags":{"force":{"name":"force","type":"boolean","char":"f","description":"Overwrite the destination directory and files if they already exist.","allowNo":false},"path":{"name":"path","type":"option","description":"The path to the directory of the new Hydrogen storefront.","multiple":false},"language":{"name":"language","type":"option","description":"Sets the template language to use. One of `js` or `ts`.","multiple":false},"template":{"name":"template","type":"option","description":"Sets the template to use. One of `demo-store` or `hello-world`.","multiple":false},"install-deps":{"name":"install-deps","type":"boolean","description":"Auto install dependencies using the active package manager","allowNo":true}},"args":[]},"hydrogen:preview":{"id":"hydrogen:preview","description":"Runs a Hydrogen storefront in an Oxygen worker for production.","strict":true,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","aliases":[],"flags":{"path":{"name":"path","type":"option","description":"The path to the directory of the Hydrogen storefront. The default is the current directory.","multiple":false},"port":{"name":"port","type":"option","description":"Port to run the server on.","multiple":false,"default":3000}},"args":[]},"hydrogen:shortcut":{"id":"hydrogen:shortcut","description":"Creates a global `h2` shortcut for the Hydrogen CLI","strict":true,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","aliases":[],"flags":{},"args":[]},"hydrogen:generate:route":{"id":"hydrogen:generate:route","description":"Generates a standard Shopify route.","strict":true,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","aliases":[],"flags":{"adapter":{"name":"adapter","type":"option","description":"Remix adapter used in the route. The default is `@shopify/remix-oxygen`.","multiple":false},"typescript":{"name":"typescript","type":"boolean","description":"Generate TypeScript files","allowNo":false},"force":{"name":"force","type":"boolean","char":"f","description":"Overwrite the destination directory and files if they already exist.","allowNo":false},"path":{"name":"path","type":"option","description":"The path to the directory of the Hydrogen storefront. The default is the current directory.","multiple":false}},"args":[{"name":"route","description":"The route to generate. One of home,page,cart,products,collections,policies,robots,sitemap,account,all.","required":true,"options":["home","page","cart","products","collections","policies","robots","sitemap","account","all"]}]},"hydrogen:generate:routes":{"id":"hydrogen:generate:routes","description":"Generates all supported standard shopify routes.","strict":true,"pluginName":"@shopify/cli-hydrogen","pluginAlias":"@shopify/cli-hydrogen","pluginType":"core","aliases":[],"flags":{"adapter":{"name":"adapter","type":"option","description":"Remix adapter used in the route. The default is `@shopify/remix-oxygen`.","multiple":false},"typescript":{"name":"typescript","type":"boolean","description":"Generate TypeScript files","allowNo":false},"force":{"name":"force","type":"boolean","char":"f","description":"Overwrite the destination directory and files if they already exist.","allowNo":false},"path":{"name":"path","type":"option","description":"The path to the directory of the Hydrogen storefront. The default is the current directory.","multiple":false}},"args":[]}}}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"@shopify:registry": "https://registry.npmjs.org"
|
|
6
6
|
},
|
|
7
|
-
"version": "4.0
|
|
7
|
+
"version": "4.1.0",
|
|
8
8
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
@@ -21,20 +21,21 @@
|
|
|
21
21
|
"@types/prettier": "^2.7.2",
|
|
22
22
|
"@types/recursive-readdir": "^2.2.1",
|
|
23
23
|
"@types/tar-fs": "^2.0.1",
|
|
24
|
-
"oclif": "
|
|
25
|
-
"
|
|
26
|
-
"
|
|
24
|
+
"oclif": "2.1.4",
|
|
25
|
+
"tempy": "^3.0.0",
|
|
26
|
+
"vitest": "^0.28.1"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"@remix-run/react": "^1.
|
|
30
|
-
"@shopify/hydrogen-react": "^2023.1.
|
|
31
|
-
"@shopify/remix-oxygen": "^1.0.
|
|
29
|
+
"@remix-run/react": "^1.15.0",
|
|
30
|
+
"@shopify/hydrogen-react": "^2023.1.8",
|
|
31
|
+
"@shopify/remix-oxygen": "^1.0.5"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@oclif/core": "
|
|
35
|
-
"@remix-run/dev": "
|
|
36
|
-
"@shopify/cli-kit": "3.
|
|
34
|
+
"@oclif/core": "2.1.4",
|
|
35
|
+
"@remix-run/dev": "1.15.0",
|
|
36
|
+
"@shopify/cli-kit": "3.45.0",
|
|
37
37
|
"@shopify/mini-oxygen": "^1.3.1",
|
|
38
|
+
"ansi-colors": "^4.1.3",
|
|
38
39
|
"fast-glob": "^3.2.12",
|
|
39
40
|
"fs-extra": "^10.1.0",
|
|
40
41
|
"gunzip-maybe": "^1.4.2",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
declare function getLatestReleaseDownloadUrl(): Promise<{
|
|
2
|
-
version: string;
|
|
3
|
-
url: string;
|
|
4
|
-
}>;
|
|
5
|
-
declare function downloadTarball(url: string, storageDir: string): Promise<void>;
|
|
6
|
-
declare function getLatestTemplates(): Promise<{
|
|
7
|
-
version: string;
|
|
8
|
-
templatesDir: string;
|
|
9
|
-
}>;
|
|
10
|
-
|
|
11
|
-
export { downloadTarball, getLatestReleaseDownloadUrl, getLatestTemplates };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|