@shopify/cli-hydrogen 5.1.0 → 5.1.2

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.
@@ -1,21 +1,15 @@
1
- import {
2
- isRouteErrorResponse,
3
- useCatch,
4
- useMatches,
5
- useRouteError,
6
- } from '@remix-run/react';
7
- import {
8
- defer,
9
- type LoaderArgs,
10
- type ErrorBoundaryComponent,
11
- } from '@shopify/remix-oxygen';
1
+ import {defer, type LoaderArgs} from '@shopify/remix-oxygen';
12
2
  import {
13
3
  Links,
14
4
  Meta,
15
5
  Outlet,
16
6
  Scripts,
17
- ScrollRestoration,
7
+ useCatch,
8
+ useMatches,
9
+ useRouteError,
18
10
  useLoaderData,
11
+ ScrollRestoration,
12
+ isRouteErrorResponse,
19
13
  } from '@remix-run/react';
20
14
  import type {CustomerAccessToken} from '@shopify/hydrogen-react/storefront-api-types';
21
15
  import type {HydrogenSession} from '../server';
@@ -144,7 +138,7 @@ export function ErrorBoundary() {
144
138
  );
145
139
  }
146
140
 
147
- export const ErrorBoundaryV1: ErrorBoundaryComponent = ({error}) => {
141
+ export const ErrorBoundaryV1 = ({error}: {error: Error}) => {
148
142
  // eslint-disable-next-line no-console
149
143
  console.error(error);
150
144
 
@@ -79,7 +79,7 @@ aside li {
79
79
  left: 0;
80
80
  opacity: 0;
81
81
  pointer-events: none;
82
- position: absolute;
82
+ position: fixed;
83
83
  right: 0;
84
84
  top: 0;
85
85
  transition: opacity 400ms ease-in-out;
@@ -13,11 +13,11 @@
13
13
  },
14
14
  "prettier": "@shopify/prettier-config",
15
15
  "dependencies": {
16
- "@remix-run/react": "1.17.1",
17
- "@shopify/cli": "3.47.5",
18
- "@shopify/cli-hydrogen": "^5.1.0",
19
- "@shopify/hydrogen": "^2023.7.0",
20
- "@shopify/remix-oxygen": "^1.1.1",
16
+ "@remix-run/react": "1.19.1",
17
+ "@shopify/cli": "3.48.0",
18
+ "@shopify/cli-hydrogen": "^5.1.2",
19
+ "@shopify/hydrogen": "^2023.7.2",
20
+ "@shopify/remix-oxygen": "^1.1.3",
21
21
  "graphql": "^16.6.0",
22
22
  "graphql-tag": "^2.12.6",
23
23
  "isbot": "^3.6.6",
@@ -25,8 +25,8 @@
25
25
  "react-dom": "^18.2.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@remix-run/dev": "1.17.1",
29
- "@shopify/oxygen-workers-types": "^3.17.2",
28
+ "@remix-run/dev": "1.19.1",
29
+ "@shopify/oxygen-workers-types": "^3.17.3",
30
30
  "@shopify/prettier-config": "^1.1.2",
31
31
  "@total-typescript/ts-reset": "^0.4.2",
32
32
  "@types/eslint": "^8.4.10",
@@ -1,13 +1,12 @@
1
- import { temporaryDirectoryTask } from 'tempy';
2
1
  import { describe, it, expect } from 'vitest';
3
2
  import { replaceFileContent, findFileWithExtension } from './file.js';
4
3
  import { resolvePath } from '@shopify/cli-kit/node/path';
5
- import { writeFile, readFile, mkdir } from '@shopify/cli-kit/node/fs';
4
+ import { inTemporaryDirectory, writeFile, readFile, mkdir } from '@shopify/cli-kit/node/fs';
6
5
 
7
6
  describe("File utils", () => {
8
7
  describe("replaceFileContent", () => {
9
8
  it("replaces the content of a file and formats it", async () => {
10
- await temporaryDirectoryTask(async (tmpDir) => {
9
+ await inTemporaryDirectory(async (tmpDir) => {
11
10
  const filepath = resolvePath(tmpDir, "index.js");
12
11
  await writeFile(
13
12
  filepath,
@@ -24,7 +23,7 @@ describe("File utils", () => {
24
23
  });
25
24
  describe("findFileWithExtension", () => {
26
25
  it("ignores missing files", async () => {
27
- await temporaryDirectoryTask(async (tmpDir) => {
26
+ await inTemporaryDirectory(async (tmpDir) => {
28
27
  expect(findFileWithExtension(tmpDir, "nope")).resolves.toEqual({
29
28
  filepath: void 0,
30
29
  extension: void 0,
@@ -33,7 +32,7 @@ describe("File utils", () => {
33
32
  });
34
33
  });
35
34
  it("finds the file with its corresponding extension and astType", async () => {
36
- await temporaryDirectoryTask(async (tmpDir) => {
35
+ await inTemporaryDirectory(async (tmpDir) => {
37
36
  await writeFile(resolvePath(tmpDir, "first.js"), "content");
38
37
  await writeFile(resolvePath(tmpDir, "second.tsx"), "content");
39
38
  await writeFile(resolvePath(tmpDir, "third.mjs"), "content");
package/dist/lib/log.js CHANGED
@@ -199,5 +199,36 @@ const warnOnce = (string) => {
199
199
  warnings.add(string);
200
200
  }
201
201
  };
202
+ function createRemixLogger() {
203
+ const noop = () => {
204
+ };
205
+ const buildMessageBody = (message, details) => `In Remix:
206
+
207
+ ` + colors.bold(message) + (details ? "\n\n" + details.join("\n") : "");
208
+ return {
209
+ dev: noop,
210
+ info: noop,
211
+ debug: noop,
212
+ warn: (message, options) => {
213
+ renderWarning({ body: buildMessageBody(message, options?.details) });
214
+ },
215
+ error: (message, options) => {
216
+ renderFatalError({
217
+ name: "error",
218
+ type: 0,
219
+ message: buildMessageBody(message, options?.details),
220
+ tryMessage: ""
221
+ });
222
+ }
223
+ };
224
+ }
225
+ async function muteRemixLogs() {
226
+ try {
227
+ const { logger } = await import('@remix-run/dev/dist/tux/logger.js');
228
+ logger.warn = logger.debug = logger.info = () => {
229
+ };
230
+ } catch {
231
+ }
232
+ }
202
233
 
203
- export { addMessageReplacers, enhanceH2Logs, muteAuthLogs, muteDevLogs, resetAllLogs, warnOnce };
234
+ export { addMessageReplacers, createRemixLogger, enhanceH2Logs, muteAuthLogs, muteDevLogs, muteRemixLogs, resetAllLogs, warnOnce };
@@ -3,7 +3,7 @@ import { copyFile } from '@shopify/cli-kit/node/fs';
3
3
  import { joinPath } from '@shopify/cli-kit/node/path';
4
4
  import { renderTasks, renderInfo } from '@shopify/cli-kit/node/ui';
5
5
  import { getLatestTemplates } from '../template-downloader.js';
6
- import { handleProjectLocation, createAbortHandler, handleLanguage, createInitialCommit, handleDependencies, renderProjectReady } from './common.js';
6
+ import { handleProjectLocation, createAbortHandler, handleLanguage, createInitialCommit, handleDependencies, commitAll, renderProjectReady } from './common.js';
7
7
 
8
8
  async function setupRemoteTemplate(options, controller) {
9
9
  const isOfficialTemplate = options.template === "demo-store" || options.template === "hello-world";
@@ -33,7 +33,9 @@ async function setupRemoteTemplate(options, controller) {
33
33
  controller,
34
34
  options.language
35
35
  );
36
- backgroundWorkPromise = backgroundWorkPromise.then(() => transpileProject().catch(abort)).then(() => createInitialCommit(project.directory));
36
+ backgroundWorkPromise = backgroundWorkPromise.then(() => transpileProject().catch(abort)).then(
37
+ () => options.git ? createInitialCommit(project.directory) : void 0
38
+ );
37
39
  const { packageManager, shouldInstallDeps, installDeps } = await handleDependencies(
38
40
  project.directory,
39
41
  controller,
@@ -73,10 +75,13 @@ async function setupRemoteTemplate(options, controller) {
73
75
  });
74
76
  }
75
77
  await renderTasks(tasks);
78
+ if (options.git) {
79
+ await commitAll(project.directory, "Lockfile");
80
+ }
76
81
  await renderProjectReady(project, setupSummary);
77
82
  if (isOfficialTemplate) {
78
83
  renderInfo({
79
- headline: `Your project will display inventory from the Hydrogen Demo Store.`,
84
+ headline: `Your project will display inventory from ${options.template === "demo-store" ? "the Hydrogen Demo Store" : "Mock.shop"}.`,
80
85
  body: `To connect this project to your Shopify store\u2019s inventory, update \`${project.name}/.env\` with your store ID and Storefront API key.`
81
86
  });
82
87
  }
@@ -0,0 +1,135 @@
1
+ import { createRequire } from 'node:module';
2
+ import { fileURLToPath } from 'node:url';
3
+ import path from 'node:path';
4
+ import { readdir } from 'node:fs/promises';
5
+ import { AbortError } from '@shopify/cli-kit/node/error';
6
+ import { outputWarn } from '@shopify/cli-kit/node/output';
7
+ import { fileExists } from '@shopify/cli-kit/node/fs';
8
+
9
+ const BUILD_DIR = "dist";
10
+ const CLIENT_SUBDIR = "client";
11
+ const WORKER_SUBDIR = "worker";
12
+ const oxygenServerMainFields = ["browser", "module", "main"];
13
+ function getProjectPaths(appPath, entry) {
14
+ const root = appPath ?? process.cwd();
15
+ const publicPath = path.join(root, "public");
16
+ const buildPath = path.join(root, BUILD_DIR);
17
+ const buildPathClient = path.join(buildPath, CLIENT_SUBDIR);
18
+ const buildPathWorkerFile = path.join(buildPath, WORKER_SUBDIR, "index.js");
19
+ return {
20
+ root,
21
+ buildPath,
22
+ buildPathClient,
23
+ buildPathWorkerFile,
24
+ publicPath
25
+ };
26
+ }
27
+ async function getRemixConfig(root, mode = process.env.NODE_ENV) {
28
+ const { readConfig } = await import('@remix-run/dev/dist/config.js');
29
+ const config = await readConfig(root, mode);
30
+ if (process.env.LOCAL_DEV) {
31
+ const packagesPath = fileURLToPath(new URL("../../..", import.meta.url));
32
+ config.watchPaths ??= [];
33
+ config.watchPaths.push(
34
+ ...(await readdir(packagesPath)).map(
35
+ (pkg) => pkg === "hydrogen-react" ? path.resolve(packagesPath, pkg, "dist", "browser-dev", "index.mjs") : path.resolve(packagesPath, pkg, "dist", "development", "index.js")
36
+ )
37
+ );
38
+ config.watchPaths.push(
39
+ path.join(packagesPath, "cli", "dist", "virtual-routes", "**", "*")
40
+ );
41
+ }
42
+ return config;
43
+ }
44
+ function assertOxygenChecks(config) {
45
+ try {
46
+ createRequire(import.meta.url).resolve("@shopify/remix-oxygen");
47
+ } catch {
48
+ return;
49
+ }
50
+ if (!config.serverEntryPoint) {
51
+ throw new AbortError(
52
+ "Could not find a server entry point.",
53
+ "Please add a server option to your remix.config.js pointing to an Oxygen worker entry file."
54
+ );
55
+ } else {
56
+ assertEntryFileExists(config.rootDirectory, config.serverEntryPoint);
57
+ }
58
+ if (config.serverPlatform !== "neutral") {
59
+ throw new AbortError(
60
+ 'The serverPlatform in remix.config.js must be "neutral".'
61
+ );
62
+ }
63
+ if (config.serverModuleFormat !== "esm") {
64
+ throw new AbortError(
65
+ 'The serverModuleFormat in remix.config.js must be "esm".'
66
+ );
67
+ }
68
+ if (config.serverDependenciesToBundle !== "all") {
69
+ throw new AbortError(
70
+ 'The serverDependenciesToBundle in remix.config.js must be "all".'
71
+ );
72
+ }
73
+ if (!config.serverConditions?.includes("worker")) {
74
+ throw new AbortError(
75
+ 'The serverConditions in remix.config.js must include "worker".'
76
+ );
77
+ }
78
+ if (process.env.NODE_ENV === "development" && !config.serverConditions?.includes("development")) {
79
+ outputWarn(
80
+ "Add `process.env.NODE_ENV` value to serverConditions in remix.config.js to enable debugging features in development."
81
+ );
82
+ }
83
+ if (!config.serverMainFields || !oxygenServerMainFields.every((v, i) => config.serverMainFields?.[i] === v)) {
84
+ throw new AbortError(
85
+ `The serverMainFields in remix.config.js must be ${JSON.stringify(
86
+ oxygenServerMainFields
87
+ )}.`
88
+ );
89
+ }
90
+ const cdnUrl = process.env.HYDROGEN_ASSET_BASE_URL;
91
+ if (cdnUrl && !config.publicPath.startsWith(cdnUrl)) {
92
+ throw new AbortError(
93
+ "The publicPath in remix.config.js must be prepended with the value of `process.env.HYDROGEN_ASSET_BASE_URL`."
94
+ );
95
+ }
96
+ const expectedServerBuildPath = path.join(
97
+ BUILD_DIR,
98
+ WORKER_SUBDIR,
99
+ "index.js"
100
+ );
101
+ if (config.serverBuildPath !== path.resolve(config.rootDirectory, expectedServerBuildPath)) {
102
+ throw new AbortError(
103
+ `The serverBuildPath in remix.config.js must be "${expectedServerBuildPath}".`
104
+ );
105
+ }
106
+ const expectedAssetsBuildDirectory = path.join(BUILD_DIR, CLIENT_SUBDIR);
107
+ if (!config.assetsBuildDirectory.startsWith(
108
+ path.resolve(config.rootDirectory, expectedAssetsBuildDirectory)
109
+ )) {
110
+ throw new AbortError(
111
+ `The assetsBuildDirectory in remix.config.js must be in "${expectedAssetsBuildDirectory}".`
112
+ );
113
+ }
114
+ }
115
+ async function assertEntryFileExists(root, fileRelative) {
116
+ const fileAbsolute = path.resolve(root, fileRelative);
117
+ const exists = await fileExists(fileAbsolute);
118
+ if (!exists) {
119
+ if (!path.extname(fileAbsolute)) {
120
+ const files = await readdir(path.dirname(fileAbsolute));
121
+ const exists2 = files.some((file) => {
122
+ const { name, ext } = path.parse(file);
123
+ return name === path.basename(fileAbsolute) && /^\.[jt]s$/.test(ext);
124
+ });
125
+ if (exists2)
126
+ return;
127
+ }
128
+ throw new AbortError(
129
+ `Entry file "${fileRelative}" not found.`,
130
+ "Please ensure the file exists and that the path is correctly added to the `server` property in remix.config.js."
131
+ );
132
+ }
133
+ }
134
+
135
+ export { assertOxygenChecks, getProjectPaths, getRemixConfig };
@@ -0,0 +1,51 @@
1
+ import { createRequire } from 'node:module';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { renderWarning } from '@shopify/cli-kit/node/ui';
4
+
5
+ function checkRemixVersions() {
6
+ const require2 = createRequire(import.meta.url);
7
+ const hydrogenPkgJson = require2(fileURLToPath(
8
+ new URL("../../package.json", import.meta.url)
9
+ ));
10
+ const requiredVersionInHydrogen = hydrogenPkgJson.dependencies["@remix-run/dev"];
11
+ const pkgs = [
12
+ "dev",
13
+ "react",
14
+ "server-runtime",
15
+ "css-bundle",
16
+ "node",
17
+ "express",
18
+ "eslint-config"
19
+ ].map((name) => getRemixPackageVersion(require2, name));
20
+ const outOfSyncPkgs = pkgs.filter(
21
+ (pkg) => pkg.version && pkg.version !== requiredVersionInHydrogen
22
+ );
23
+ if (outOfSyncPkgs.length === 0)
24
+ return;
25
+ const items = outOfSyncPkgs.reduce((acc, item) => {
26
+ if (item.version) {
27
+ acc.push(`${item.name}@${item.version}`);
28
+ }
29
+ return acc;
30
+ }, []);
31
+ renderWarning({
32
+ headline: `The current version of Hydrogen requires Remix @${requiredVersionInHydrogen}. The following packages are out of sync:`,
33
+ body: [
34
+ { list: { items } },
35
+ "\nPlease ensure your Remix packages have the same version and are in sync with Hydrogen."
36
+ ]
37
+ });
38
+ }
39
+ function getRemixPackageVersion(require2, name) {
40
+ const pkgName = "@remix-run/" + name;
41
+ const result = { name: pkgName, version: "" };
42
+ try {
43
+ const pkgJsonPath = require2.resolve(`${pkgName}/package.json`);
44
+ const pkgJson = require2(pkgJsonPath);
45
+ result.version = pkgJson.version;
46
+ } catch {
47
+ }
48
+ return result;
49
+ }
50
+
51
+ export { checkRemixVersions };
@@ -0,0 +1,38 @@
1
+ import { vi, describe, it, expect } from 'vitest';
2
+ import { mockAndCaptureOutput } from '@shopify/cli-kit/node/testing/output';
3
+ import { checkRemixVersions } from './remix-version-check.js';
4
+
5
+ const requireMock = vi.fn();
6
+ vi.mock("node:module", async () => {
7
+ const { createRequire } = await vi.importActual(
8
+ "node:module"
9
+ );
10
+ return {
11
+ createRequire: (url) => {
12
+ const actualRequire = createRequire(url);
13
+ requireMock.mockImplementation((mod) => actualRequire(mod));
14
+ const require2 = requireMock;
15
+ require2.resolve = actualRequire.resolve.bind(actualRequire);
16
+ return require2;
17
+ }
18
+ };
19
+ });
20
+ describe("remix-version-check", () => {
21
+ it("does nothing when versions are in sync", () => {
22
+ const outputMock = mockAndCaptureOutput();
23
+ checkRemixVersions();
24
+ expect(outputMock.warn()).toBe("");
25
+ });
26
+ it("warns when versions are out of sync", () => {
27
+ const expectedVersion = "42.0.0-test";
28
+ vi.mocked(requireMock).mockReturnValueOnce({
29
+ dependencies: { "@remix-run/dev": expectedVersion }
30
+ });
31
+ const outputMock = mockAndCaptureOutput();
32
+ checkRemixVersions();
33
+ const output = outputMock.warn();
34
+ expect(output).toMatch(`Hydrogen requires Remix @${expectedVersion}`);
35
+ expect(output).toMatch(`@remix-run/dev@`);
36
+ expect(output).toMatch(`@remix-run/react@`);
37
+ });
38
+ });
@@ -1,5 +1,5 @@
1
1
  import { createRequire } from 'module';
2
- import { getRemixConfig } from './config.js';
2
+ import { getRemixConfig } from './remix-config.js';
3
3
 
4
4
  function isRemixV2() {
5
5
  try {
@@ -13,7 +13,7 @@ function isRemixV2() {
13
13
  async function getV2Flags(root, remixConfigFuture) {
14
14
  const isV2 = isRemixV2();
15
15
  const futureFlags = {
16
- ...!isV2 && (remixConfigFuture ?? (await getRemixConfig(root, true)).future)
16
+ ...!isV2 && (remixConfigFuture ?? (await getRemixConfig(root)).future)
17
17
  };
18
18
  return {
19
19
  isV2Meta: isV2 || !!futureFlags.v2_meta,
@@ -58,7 +58,7 @@ describe("remix-version-interop", () => {
58
58
  return <div>stuff</div>;
59
59
  }
60
60
 
61
- export const ErrorBoundaryV1: ErrorBoundaryComponent = ({error}) => {
61
+ export const ErrorBoundaryV1 = ({error}: {error: Error}) => {
62
62
  console.error(error);
63
63
 
64
64
  return <div>There was an error.</div>;
@@ -7,7 +7,7 @@ import { transpileFile } from '../../../lib/transpile-ts.js';
7
7
  import { getCodeFormatOptions, formatCode } from '../../../lib/format-code.js';
8
8
  import { getTemplateAppFile, GENERATOR_ROUTE_DIR, getStarterDir } from '../../../lib/build.js';
9
9
  import { getV2Flags, convertTemplateToRemixVersion, convertRouteToV1 } from '../../../lib/remix-version-interop.js';
10
- import { getRemixConfig } from '../../../lib/config.js';
10
+ import { getRemixConfig } from '../../remix-config.js';
11
11
  import { findFileWithExtension } from '../../file.js';
12
12
 
13
13
  const NO_LOCALE_PATTERNS = [/robots\.txt/];
@@ -1,11 +1,10 @@
1
1
  import { describe, beforeEach, vi, it, expect } from 'vitest';
2
- import { temporaryDirectoryTask } from 'tempy';
3
2
  import { getResolvedRoutes, generateRoutes, generateProjectFile } from './generate.js';
4
3
  import { renderConfirmationPrompt } from '@shopify/cli-kit/node/ui';
5
- import { fileExists, readFile, mkdir, writeFile } from '@shopify/cli-kit/node/fs';
4
+ import { inTemporaryDirectory, fileExists, readFile, mkdir, writeFile } from '@shopify/cli-kit/node/fs';
6
5
  import { joinPath, dirname } from '@shopify/cli-kit/node/path';
7
6
  import { getTemplateAppFile } from '../../../lib/build.js';
8
- import { getRemixConfig } from '../../../lib/config.js';
7
+ import { getRemixConfig } from '../../remix-config.js';
9
8
 
10
9
  const readProjectFile = (dirs, fileBasename, ext = "tsx") => readFile(joinPath(dirs.appDirectory, `${fileBasename}.${ext}`));
11
10
  describe("generate/route", () => {
@@ -13,7 +12,7 @@ describe("generate/route", () => {
13
12
  vi.resetAllMocks();
14
13
  vi.mock("@shopify/cli-kit/node/output");
15
14
  vi.mock("@shopify/cli-kit/node/ui");
16
- vi.mock("../../config.js", async () => ({ getRemixConfig: vi.fn() }));
15
+ vi.mock("../../remix-config.js", async () => ({ getRemixConfig: vi.fn() }));
17
16
  });
18
17
  describe("generateRoutes", () => {
19
18
  it("generates all routes with correct configuration", async () => {
@@ -21,7 +20,7 @@ describe("generate/route", () => {
21
20
  expect(
22
21
  resolvedRouteFiles.find((item) => /account_?\.login/.test(item))
23
22
  ).toBeTruthy();
24
- await temporaryDirectoryTask(async (tmpDir) => {
23
+ await inTemporaryDirectory(async (tmpDir) => {
25
24
  const directories = await createHydrogenFixture(tmpDir, {
26
25
  files: [
27
26
  ["jsconfig.json", JSON.stringify({ compilerOptions: { test: "js" } })],
@@ -51,7 +50,7 @@ describe("generate/route", () => {
51
50
  });
52
51
  });
53
52
  it("figures out the locale if a home route already exists", async () => {
54
- await temporaryDirectoryTask(async (tmpDir) => {
53
+ await inTemporaryDirectory(async (tmpDir) => {
55
54
  const route = "routes/pages.$handle";
56
55
  const directories = await createHydrogenFixture(tmpDir, {
57
56
  files: [
@@ -89,7 +88,7 @@ describe("generate/route", () => {
89
88
  });
90
89
  describe("generateProjectFile", () => {
91
90
  it("generates a route file for Remix v1", async () => {
92
- await temporaryDirectoryTask(async (tmpDir) => {
91
+ await inTemporaryDirectory(async (tmpDir) => {
93
92
  const route = "routes/pages.$handle";
94
93
  const directories = await createHydrogenFixture(tmpDir, {
95
94
  files: [],
@@ -107,7 +106,7 @@ describe("generate/route", () => {
107
106
  });
108
107
  });
109
108
  it("generates a route file for Remix v2", async () => {
110
- await temporaryDirectoryTask(async (tmpDir) => {
109
+ await inTemporaryDirectory(async (tmpDir) => {
111
110
  const route = "routes/custom.path.$handle._index";
112
111
  const directories = await createHydrogenFixture(tmpDir, {
113
112
  files: [],
@@ -123,7 +122,7 @@ describe("generate/route", () => {
123
122
  });
124
123
  });
125
124
  it("generates route files with locale prefix", async () => {
126
- await temporaryDirectoryTask(async (tmpDir) => {
125
+ await inTemporaryDirectory(async (tmpDir) => {
127
126
  const routeCode = `const str = 'hello world'`;
128
127
  const directories = await createHydrogenFixture(tmpDir, {
129
128
  files: [],
@@ -174,7 +173,7 @@ describe("generate/route", () => {
174
173
  });
175
174
  });
176
175
  it("produces a typescript file when typescript argument is true", async () => {
177
- await temporaryDirectoryTask(async (tmpDir) => {
176
+ await inTemporaryDirectory(async (tmpDir) => {
178
177
  const route = "routes/pages.$handle";
179
178
  const directories = await createHydrogenFixture(tmpDir, {
180
179
  files: [],
@@ -191,7 +190,7 @@ describe("generate/route", () => {
191
190
  });
192
191
  });
193
192
  it("prompts the user if there the file already exists", async () => {
194
- await temporaryDirectoryTask(async (tmpDir) => {
193
+ await inTemporaryDirectory(async (tmpDir) => {
195
194
  vi.mocked(renderConfirmationPrompt).mockImplementationOnce(
196
195
  async () => true
197
196
  );
@@ -212,7 +211,7 @@ describe("generate/route", () => {
212
211
  });
213
212
  });
214
213
  it("does not prompt the user if the force property is true", async () => {
215
- await temporaryDirectoryTask(async (tmpDir) => {
214
+ await inTemporaryDirectory(async (tmpDir) => {
216
215
  vi.mocked(renderConfirmationPrompt).mockImplementationOnce(
217
216
  async () => true
218
217
  );
@@ -229,7 +228,7 @@ describe("generate/route", () => {
229
228
  });
230
229
  });
231
230
  it("generates all the route dependencies", async () => {
232
- await temporaryDirectoryTask(async (tmpDir) => {
231
+ await inTemporaryDirectory(async (tmpDir) => {
233
232
  const templates = [
234
233
  [
235
234
  "routes/pages.$pageHandle.tsx",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.1.0",
2
+ "version": "5.1.2",
3
3
  "commands": {
4
4
  "hydrogen:build": {
5
5
  "id": "hydrogen:build",
package/package.json CHANGED
@@ -4,14 +4,14 @@
4
4
  "access": "public",
5
5
  "@shopify:registry": "https://registry.npmjs.org"
6
6
  },
7
- "version": "5.1.0",
7
+ "version": "5.1.2",
8
8
  "license": "MIT",
9
9
  "type": "module",
10
10
  "scripts": {
11
- "build": "tsup --config ./tsup.config.ts && node scripts/build-check.mjs",
11
+ "build": "rm -rf dist && tsup --config ./tsup.config.ts && node scripts/build-check.mjs",
12
12
  "dev": "tsup --watch --config ./tsup.config.ts",
13
13
  "typecheck": "tsc --noEmit",
14
- "generate:manifest": "oclif manifest",
14
+ "generate:manifest": "node scripts/generate-manifest.mjs",
15
15
  "test": "cross-env SHOPIFY_UNIT_TEST=1 vitest run --test-timeout=15000",
16
16
  "test:watch": "cross-env SHOPIFY_UNIT_TEST=1 vitest --test-timeout=15000"
17
17
  },
@@ -22,22 +22,21 @@
22
22
  "@types/prettier": "^2.7.2",
23
23
  "@types/recursive-readdir": "^2.2.1",
24
24
  "@types/tar-fs": "^2.0.1",
25
- "oclif": "3.9.1",
26
- "tempy": "^3.0.0",
25
+ "@vitest/coverage-v8": "^0.33.0",
27
26
  "type-fest": "^3.6.0",
28
27
  "vitest": "^0.33.0"
29
28
  },
30
29
  "peerDependencies": {
31
- "@remix-run/react": "^1.17.1",
32
- "@shopify/hydrogen-react": "^2023.7.0",
33
- "@shopify/remix-oxygen": "^1.1.1"
30
+ "@remix-run/react": "1.19.1",
31
+ "@shopify/hydrogen-react": "^2023.7.1",
32
+ "@shopify/remix-oxygen": "^1.1.3"
34
33
  },
35
34
  "dependencies": {
36
35
  "@ast-grep/napi": "^0.5.3",
37
36
  "@graphql-codegen/cli": "3.3.1",
38
- "@oclif/core": "2.8.5",
39
- "@remix-run/dev": "1.17.1",
40
- "@shopify/cli-kit": "3.47.5",
37
+ "@oclif/core": "2.8.11",
38
+ "@remix-run/dev": "1.19.1",
39
+ "@shopify/cli-kit": "3.48.0",
41
40
  "@shopify/hydrogen-codegen": "^0.0.2",
42
41
  "@shopify/mini-oxygen": "^1.7.0",
43
42
  "ansi-escapes": "^6.2.0",