@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.
Files changed (76) hide show
  1. package/README.md +9 -0
  2. package/dist/commands/hydrogen/build.d.ts +4 -1
  3. package/dist/commands/hydrogen/build.js +21 -17
  4. package/dist/commands/hydrogen/check.d.ts +3 -6
  5. package/dist/commands/hydrogen/check.js +10 -9
  6. package/dist/commands/hydrogen/dev.d.ts +3 -2
  7. package/dist/commands/hydrogen/dev.js +24 -22
  8. package/dist/commands/hydrogen/g.d.ts +10 -0
  9. package/dist/commands/hydrogen/g.js +17 -0
  10. package/dist/commands/hydrogen/generate/route.d.ts +7 -9
  11. package/dist/commands/hydrogen/generate/route.js +49 -47
  12. package/dist/commands/hydrogen/generate/route.test.js +48 -40
  13. package/dist/commands/hydrogen/generate/routes.d.ts +2 -2
  14. package/dist/commands/hydrogen/init.d.ts +3 -3
  15. package/dist/commands/hydrogen/init.js +76 -95
  16. package/dist/commands/hydrogen/init.test.js +126 -0
  17. package/dist/commands/hydrogen/preview.d.ts +2 -2
  18. package/dist/commands/hydrogen/preview.js +4 -4
  19. package/dist/commands/hydrogen/shortcut.d.ts +9 -0
  20. package/dist/commands/hydrogen/shortcut.js +74 -0
  21. package/dist/commands/hydrogen/shortcut.test.js +58 -0
  22. package/dist/generator-templates/routes/[robots.txt].tsx +35 -1
  23. package/dist/generator-templates/routes/[sitemap.xml].tsx +45 -10
  24. package/dist/generator-templates/routes/account/login.tsx +42 -13
  25. package/dist/generator-templates/routes/account/register.tsx +42 -13
  26. package/dist/generator-templates/routes/cart.tsx +42 -2
  27. package/dist/generator-templates/routes/collections/$collectionHandle.tsx +44 -5
  28. package/dist/generator-templates/routes/index.tsx +33 -0
  29. package/dist/generator-templates/routes/pages/$pageHandle.tsx +48 -10
  30. package/dist/generator-templates/routes/policies/$policyHandle.tsx +67 -14
  31. package/dist/generator-templates/routes/policies/index.tsx +54 -4
  32. package/dist/generator-templates/routes/products/$productHandle.tsx +44 -9
  33. package/dist/hooks/init.js +2 -2
  34. package/dist/{utils → lib}/check-lockfile.js +7 -4
  35. package/dist/{utils → lib}/check-lockfile.test.js +19 -28
  36. package/dist/{utils → lib}/check-version.test.js +3 -2
  37. package/dist/lib/colors.d.ts +8 -0
  38. package/dist/lib/colors.js +8 -0
  39. package/dist/{utils → lib}/config.js +10 -19
  40. package/dist/{utils → lib}/flags.d.ts +9 -3
  41. package/dist/{utils → lib}/flags.js +19 -4
  42. package/dist/lib/flags.test.d.ts +1 -0
  43. package/dist/{utils → lib}/mini-oxygen.js +14 -12
  44. package/dist/{utils → lib}/missing-routes.js +1 -1
  45. package/dist/lib/remix-version-interop.d.ts +11 -0
  46. package/dist/lib/remix-version-interop.js +54 -0
  47. package/dist/lib/remix-version-interop.test.d.ts +1 -0
  48. package/dist/lib/remix-version-interop.test.js +93 -0
  49. package/dist/lib/shell.d.ts +12 -0
  50. package/dist/lib/shell.js +73 -0
  51. package/dist/lib/template-downloader.d.ts +6 -0
  52. package/dist/{utils → lib}/template-downloader.js +21 -16
  53. package/dist/{utils → lib}/transpile-ts.js +5 -5
  54. package/dist/lib/virtual-routes.test.d.ts +1 -0
  55. package/dist/virtual-routes/routes/index.jsx +2 -15
  56. package/dist/virtual-routes/virtual-root.jsx +5 -6
  57. package/oclif.manifest.json +1 -1
  58. package/package.json +11 -10
  59. package/dist/utils/template-downloader.d.ts +0 -11
  60. /package/dist/{utils/check-lockfile.test.d.ts → commands/hydrogen/init.test.d.ts} +0 -0
  61. /package/dist/{utils/check-version.test.d.ts → commands/hydrogen/shortcut.test.d.ts} +0 -0
  62. /package/dist/{utils → lib}/check-lockfile.d.ts +0 -0
  63. /package/dist/{utils/flags.test.d.ts → lib/check-lockfile.test.d.ts} +0 -0
  64. /package/dist/{utils → lib}/check-version.d.ts +0 -0
  65. /package/dist/{utils → lib}/check-version.js +0 -0
  66. /package/dist/{utils/virtual-routes.test.d.ts → lib/check-version.test.d.ts} +0 -0
  67. /package/dist/{utils → lib}/config.d.ts +0 -0
  68. /package/dist/{utils → lib}/flags.test.js +0 -0
  69. /package/dist/{utils → lib}/log.d.ts +0 -0
  70. /package/dist/{utils → lib}/log.js +0 -0
  71. /package/dist/{utils → lib}/mini-oxygen.d.ts +0 -0
  72. /package/dist/{utils → lib}/missing-routes.d.ts +0 -0
  73. /package/dist/{utils → lib}/transpile-ts.d.ts +0 -0
  74. /package/dist/{utils → lib}/virtual-routes.d.ts +0 -0
  75. /package/dist/{utils → lib}/virtual-routes.js +0 -0
  76. /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,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 };
@@ -0,0 +1,6 @@
1
+ declare function getLatestTemplates(): Promise<{
2
+ version: string;
3
+ templatesDir: string;
4
+ }>;
5
+
6
+ export { getLatestTemplates };
@@ -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 { http, file } from '@shopify/cli-kit';
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 http.fetch(REPO_RELEASES_URL);
13
+ const response = await fetch(REPO_RELEASES_URL);
11
14
  if (!response.ok || response.status >= 400) {
12
- throw new Error(
13
- `Failed to fetch the latest release information. Status ${response.status} ${response.statusText.replace(/\.$/, "")}.` + (response.status === 403 ? `
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 http.fetch(url);
27
+ const response = await fetch(url);
26
28
  if (!response.ok || response.status >= 400) {
27
- throw new Error(
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 file.exists(templateStoragePath)) {
50
- await file.mkdir(templateStoragePath);
52
+ if (!await fileExists(templateStoragePath)) {
53
+ await mkdir(templateStoragePath);
51
54
  }
52
55
  const templateStorageVersionPath = path.join(templateStoragePath, version);
53
- if (!await file.exists(templateStorageVersionPath)) {
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
- error.message = `Could not download Hydrogen templates from GitHub.
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
- throw error;
69
+ ` + error.message,
70
+ error.tryMessage
71
+ );
67
72
  }
68
73
  }
69
74
 
70
- export { downloadTarball, getLatestReleaseDownloadUrl, getLatestTemplates };
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 { output } from '@shopify/cli-kit';
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
- output.debug(
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
- output.debug(
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
- output.debug(
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
- output.debug(
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/index.jsx</code>
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
  };
@@ -1 +1 @@
1
- {"version":"4.0.8","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}},"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}},"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: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":[]}}}
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.8",
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": "^3.4.2",
25
- "vitest": "^0.28.1",
26
- "tempy": "^3.0.0"
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.12.0",
30
- "@shopify/hydrogen-react": "^2023.1.5",
31
- "@shopify/remix-oxygen": "^1.0.3"
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": "^1.20.4",
35
- "@remix-run/dev": "^1.12.0",
36
- "@shopify/cli-kit": "3.29.0",
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