@shopify/cli-hydrogen 5.1.2 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/hydrogen/build.js +4 -1
- package/dist/commands/hydrogen/dev.js +26 -17
- package/dist/commands/hydrogen/init.js +3 -0
- package/dist/commands/hydrogen/init.test.js +2 -0
- package/dist/commands/hydrogen/preview.js +4 -3
- package/dist/commands/hydrogen/setup.js +3 -0
- package/dist/generator-templates/starter/app/components/Footer.tsx +1 -1
- package/dist/generator-templates/starter/app/components/Header.tsx +1 -1
- package/dist/generator-templates/starter/app/components/Search.tsx +3 -3
- package/dist/generator-templates/starter/app/root.tsx +24 -1
- package/dist/generator-templates/starter/app/routes/$.tsx +4 -0
- package/dist/generator-templates/starter/app/routes/_index.tsx +6 -2
- package/dist/generator-templates/starter/app/routes/account.$.tsx +1 -2
- package/dist/generator-templates/starter/app/routes/account.addresses.tsx +1 -1
- package/dist/generator-templates/starter/app/routes/account.orders._index.tsx +2 -7
- package/dist/generator-templates/starter/app/routes/account.profile.tsx +7 -2
- package/dist/generator-templates/starter/app/routes/account.tsx +4 -3
- package/dist/generator-templates/starter/app/routes/account_.activate.$id.$activationToken.tsx +6 -2
- package/dist/generator-templates/starter/app/routes/account_.login.tsx +6 -2
- package/dist/generator-templates/starter/app/routes/account_.logout.tsx +2 -6
- package/dist/generator-templates/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +1 -2
- package/dist/generator-templates/starter/app/routes/blogs.$blogHandle._index.tsx +1 -2
- package/dist/generator-templates/starter/app/routes/blogs._index.tsx +1 -2
- package/dist/generator-templates/starter/app/routes/cart.tsx +1 -2
- package/dist/generator-templates/starter/app/routes/collections.$handle.tsx +1 -2
- package/dist/generator-templates/starter/app/routes/pages.$handle.tsx +1 -2
- package/dist/generator-templates/starter/app/routes/policies.$handle.tsx +2 -3
- package/dist/generator-templates/starter/app/routes/products.$handle.tsx +23 -15
- package/dist/generator-templates/starter/app/routes/search.tsx +1 -2
- package/dist/generator-templates/starter/package.json +2 -2
- package/dist/generator-templates/starter/remix.config.js +1 -0
- package/dist/generator-templates/starter/storefrontapi.generated.d.ts +9 -9
- package/dist/lib/ast.js +9 -0
- package/dist/lib/check-version.test.js +1 -0
- package/dist/lib/codegen.js +17 -7
- package/dist/lib/environment-variables.js +15 -11
- package/dist/lib/find-port.js +9 -0
- package/dist/lib/flags.js +3 -2
- package/dist/lib/format-code.js +3 -0
- package/dist/lib/live-reload.js +62 -0
- package/dist/lib/log.js +6 -1
- package/dist/lib/mini-oxygen.js +28 -18
- package/dist/lib/missing-routes.js +17 -1
- package/dist/lib/onboarding/common.js +5 -0
- package/dist/lib/onboarding/local.js +21 -8
- package/dist/lib/remix-config.js +2 -0
- package/dist/lib/remix-version-check.test.js +1 -0
- package/dist/lib/setups/css/replacers.js +7 -4
- package/dist/lib/setups/i18n/replacers.js +7 -5
- package/dist/lib/setups/routes/generate.js +4 -1
- package/dist/lib/template-downloader.js +4 -0
- package/dist/lib/transpile-ts.js +1 -0
- package/dist/lib/virtual-routes.js +4 -1
- package/dist/virtual-routes/components/HydrogenLogoBaseBW.jsx +26 -4
- package/dist/virtual-routes/components/HydrogenLogoBaseColor.jsx +40 -10
- package/dist/virtual-routes/components/IconBanner.jsx +286 -44
- package/dist/virtual-routes/components/IconDiscord.jsx +17 -1
- package/dist/virtual-routes/components/IconError.jsx +55 -17
- package/dist/virtual-routes/components/IconGithub.jsx +19 -1
- package/dist/virtual-routes/components/IconTwitter.jsx +17 -1
- package/dist/virtual-routes/components/Layout.jsx +1 -1
- package/dist/virtual-routes/routes/index.jsx +110 -94
- package/dist/virtual-routes/virtual-root.jsx +7 -15
- package/oclif.manifest.json +1 -1
- package/package.json +7 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import Command from '@shopify/cli-kit/node/base-command';
|
|
3
3
|
import { outputInfo, outputContent, outputToken, outputWarn } from '@shopify/cli-kit/node/output';
|
|
4
|
-
import { rmdir, fileSize, glob, removeFile, copyFile } from '@shopify/cli-kit/node/fs';
|
|
4
|
+
import { rmdir, fileSize, glob, removeFile, fileExists, copyFile } from '@shopify/cli-kit/node/fs';
|
|
5
5
|
import { resolvePath, relativePath, joinPath } from '@shopify/cli-kit/node/path';
|
|
6
6
|
import { getPackageManager } from '@shopify/cli-kit/node/node-package-manager';
|
|
7
7
|
import colors from '@shopify/cli-kit/node/colors';
|
|
@@ -130,6 +130,9 @@ This build is missing ${missingRoutes.length} route${missingRoutes.length > 1 ?
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
async function copyPublicFiles(publicPath, buildPathClient) {
|
|
133
|
+
if (!await fileExists(publicPath)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
133
136
|
return copyFile(publicPath, buildPathClient);
|
|
134
137
|
}
|
|
135
138
|
|
|
@@ -6,8 +6,8 @@ import { renderFatalError } from '@shopify/cli-kit/node/ui';
|
|
|
6
6
|
import colors from '@shopify/cli-kit/node/colors';
|
|
7
7
|
import { copyPublicFiles } from './build.js';
|
|
8
8
|
import { getProjectPaths, assertOxygenChecks, getRemixConfig } from '../../lib/remix-config.js';
|
|
9
|
-
import { muteDevLogs,
|
|
10
|
-
import { commonFlags, deprecated, flagsToCamelObject } from '../../lib/flags.js';
|
|
9
|
+
import { muteDevLogs, createRemixLogger, enhanceH2Logs } from '../../lib/log.js';
|
|
10
|
+
import { commonFlags, deprecated, flagsToCamelObject, DEFAULT_PORT } from '../../lib/flags.js';
|
|
11
11
|
import Command from '@shopify/cli-kit/node/base-command';
|
|
12
12
|
import { Flags } from '@oclif/core';
|
|
13
13
|
import { startMiniOxygen } from '../../lib/mini-oxygen.js';
|
|
@@ -16,6 +16,8 @@ import { addVirtualRoutes } from '../../lib/virtual-routes.js';
|
|
|
16
16
|
import { spawnCodegenProcess } from '../../lib/codegen.js';
|
|
17
17
|
import { getAllEnvironmentVariables } from '../../lib/environment-variables.js';
|
|
18
18
|
import { getConfig } from '../../lib/shopify-config.js';
|
|
19
|
+
import { findPort } from '../../lib/find-port.js';
|
|
20
|
+
import { setupLiveReload } from '../../lib/live-reload.js';
|
|
19
21
|
import { checkRemixVersions } from '../../lib/remix-version-check.js';
|
|
20
22
|
|
|
21
23
|
const LOG_REBUILDING = "\u{1F9F1} Rebuilding...";
|
|
@@ -56,7 +58,7 @@ class Dev extends Command {
|
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
async function runDev({
|
|
59
|
-
port,
|
|
61
|
+
port: portFlag = DEFAULT_PORT,
|
|
60
62
|
path: appPath,
|
|
61
63
|
useCodegen = false,
|
|
62
64
|
codegenConfigPath,
|
|
@@ -68,7 +70,6 @@ async function runDev({
|
|
|
68
70
|
if (!process.env.NODE_ENV)
|
|
69
71
|
process.env.NODE_ENV = "development";
|
|
70
72
|
muteDevLogs();
|
|
71
|
-
await muteRemixLogs();
|
|
72
73
|
if (debug)
|
|
73
74
|
(await import('node:inspector')).open();
|
|
74
75
|
const { root, publicPath, buildPathClient, buildPathWorkerFile } = getProjectPaths(appPath);
|
|
@@ -102,14 +103,15 @@ async function runDev({
|
|
|
102
103
|
let isInitialBuild = true;
|
|
103
104
|
let initialBuildDurationMs = 0;
|
|
104
105
|
let initialBuildStartTimeMs = Date.now();
|
|
106
|
+
const liveReload = remixConfig.future.v2_dev ? await setupLiveReload(remixConfig.devServerPort) : void 0;
|
|
105
107
|
let miniOxygen;
|
|
106
108
|
async function safeStartMiniOxygen() {
|
|
107
109
|
if (miniOxygen)
|
|
108
110
|
return;
|
|
109
111
|
miniOxygen = await startMiniOxygen({
|
|
110
112
|
root,
|
|
111
|
-
port,
|
|
112
|
-
watch:
|
|
113
|
+
port: await findPort(portFlag),
|
|
114
|
+
watch: !liveReload,
|
|
113
115
|
buildPathWorkerFile,
|
|
114
116
|
buildPathClient,
|
|
115
117
|
env: await envPromise
|
|
@@ -145,13 +147,15 @@ View GraphiQL API browser: ${graphiqlUrl}`)]
|
|
|
145
147
|
},
|
|
146
148
|
{
|
|
147
149
|
reloadConfig,
|
|
148
|
-
onBuildStart() {
|
|
150
|
+
onBuildStart(ctx) {
|
|
149
151
|
if (!isInitialBuild && !skipRebuildLogs) {
|
|
150
152
|
outputInfo(LOG_REBUILDING);
|
|
151
153
|
console.time(LOG_REBUILT);
|
|
152
154
|
}
|
|
155
|
+
liveReload?.onBuildStart(ctx);
|
|
153
156
|
},
|
|
154
|
-
|
|
157
|
+
onBuildManifest: liveReload?.onBuildManifest,
|
|
158
|
+
async onBuildFinish(context, duration, succeeded) {
|
|
155
159
|
if (isInitialBuild) {
|
|
156
160
|
await copyingFiles;
|
|
157
161
|
initialBuildDurationMs = Date.now() - initialBuildStartTimeMs;
|
|
@@ -162,16 +166,21 @@ View GraphiQL API browser: ${graphiqlUrl}`)]
|
|
|
162
166
|
if (!miniOxygen)
|
|
163
167
|
console.log("");
|
|
164
168
|
}
|
|
165
|
-
if (!miniOxygen) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
if (!miniOxygen && !await serverBundleExists()) {
|
|
170
|
+
return renderFatalError({
|
|
171
|
+
name: "BuildError",
|
|
172
|
+
type: 0,
|
|
173
|
+
message: "MiniOxygen cannot start because the server bundle has not been generated.",
|
|
174
|
+
tryMessage: "This is likely due to an error in your app and Remix is unable to compile. Try fixing the app and MiniOxygen will start."
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
if (succeeded) {
|
|
178
|
+
if (!miniOxygen) {
|
|
179
|
+
await safeStartMiniOxygen();
|
|
180
|
+
} else if (liveReload) {
|
|
181
|
+
await miniOxygen.reload({ worker: true });
|
|
173
182
|
}
|
|
174
|
-
|
|
183
|
+
liveReload?.onAppReady(context);
|
|
175
184
|
}
|
|
176
185
|
},
|
|
177
186
|
async onFileCreated(file) {
|
|
@@ -70,6 +70,9 @@ async function runInit(options = parseProcessFlags(process.argv, FLAG_MAP)) {
|
|
|
70
70
|
supressNodeExperimentalWarnings();
|
|
71
71
|
options.git ??= true;
|
|
72
72
|
const showUpgrade = await checkHydrogenVersion(
|
|
73
|
+
// Resolving the CLI package from a local directory might fail because
|
|
74
|
+
// this code could be run from a global dependency (e.g. on `npm create`).
|
|
75
|
+
// Therefore, pass the known path to the package.json directly from here:
|
|
73
76
|
fileURLToPath(new URL("../../../package.json", import.meta.url)),
|
|
74
77
|
"cli"
|
|
75
78
|
);
|
|
@@ -145,6 +145,7 @@ describe("init", () => {
|
|
|
145
145
|
expect(output).toMatch("Help");
|
|
146
146
|
expect(output).toMatch("Next steps");
|
|
147
147
|
expect(output).toMatch(
|
|
148
|
+
// Output contains banner characters. USe [^\w]*? to match them.
|
|
148
149
|
/Run `cd .*? &&[^\w]*?npm[^\w]*?install[^\w]*?&&[^\w]*?npm[^\w]*?run[^\w]*?dev`/ims
|
|
149
150
|
);
|
|
150
151
|
});
|
|
@@ -220,6 +221,7 @@ describe("init", () => {
|
|
|
220
221
|
expect(output).toMatch("Help");
|
|
221
222
|
expect(output).toMatch("Next steps");
|
|
222
223
|
expect(output).toMatch(
|
|
224
|
+
// Output contains banner characters. USe [^\w]*? to match them.
|
|
223
225
|
/Run `cd .*? &&[^\w]*?npm[^\w]*?install[^\w]*?&&[^\w]*?npm[^\w]*?run[^\w]*?dev`/ims
|
|
224
226
|
);
|
|
225
227
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import Command from '@shopify/cli-kit/node/base-command';
|
|
2
2
|
import { muteDevLogs } from '../../lib/log.js';
|
|
3
3
|
import { getProjectPaths } from '../../lib/remix-config.js';
|
|
4
|
-
import { commonFlags } from '../../lib/flags.js';
|
|
4
|
+
import { commonFlags, DEFAULT_PORT } from '../../lib/flags.js';
|
|
5
5
|
import { startMiniOxygen } from '../../lib/mini-oxygen.js';
|
|
6
|
+
import { findPort } from '../../lib/find-port.js';
|
|
6
7
|
|
|
7
8
|
class Preview extends Command {
|
|
8
9
|
static description = "Runs a Hydrogen storefront in an Oxygen worker for production.";
|
|
@@ -16,7 +17,7 @@ class Preview extends Command {
|
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
async function runPreview({
|
|
19
|
-
port,
|
|
20
|
+
port = DEFAULT_PORT,
|
|
20
21
|
path: appPath
|
|
21
22
|
}) {
|
|
22
23
|
if (!process.env.NODE_ENV)
|
|
@@ -25,7 +26,7 @@ async function runPreview({
|
|
|
25
26
|
const { root, buildPathWorkerFile, buildPathClient } = getProjectPaths(appPath);
|
|
26
27
|
const miniOxygen = await startMiniOxygen({
|
|
27
28
|
root,
|
|
28
|
-
port,
|
|
29
|
+
port: await findPort(port),
|
|
29
30
|
buildPathClient,
|
|
30
31
|
buildPathWorkerFile
|
|
31
32
|
});
|
|
@@ -57,6 +57,8 @@ async function runSetup(options) {
|
|
|
57
57
|
const typescript = !!remixConfig.tsconfigPath;
|
|
58
58
|
backgroundWorkPromise = backgroundWorkPromise.then(
|
|
59
59
|
() => Promise.all([
|
|
60
|
+
// When starting from hello-world, the server entry point won't
|
|
61
|
+
// include all the cart logic from skeleton, so we need to copy it.
|
|
60
62
|
generateProjectFile("../server.ts", { ...remixConfig, typescript }),
|
|
61
63
|
...typescript ? [
|
|
62
64
|
copyFile(
|
|
@@ -71,6 +73,7 @@ async function runSetup(options) {
|
|
|
71
73
|
)
|
|
72
74
|
)
|
|
73
75
|
] : [],
|
|
76
|
+
// Copy app entries
|
|
74
77
|
generateProjectEntries({
|
|
75
78
|
rootDirectory: remixConfig.rootDirectory,
|
|
76
79
|
appDirectory: remixConfig.appDirectory,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
useParams,
|
|
3
|
-
useFetcher,
|
|
4
2
|
Link,
|
|
5
3
|
Form,
|
|
4
|
+
useParams,
|
|
5
|
+
useFetcher,
|
|
6
|
+
useFetchers,
|
|
6
7
|
type FormProps,
|
|
7
8
|
} from '@remix-run/react';
|
|
8
9
|
import {Image, Money, Pagination} from '@shopify/hydrogen';
|
|
9
10
|
import React, {useRef, useEffect} from 'react';
|
|
10
|
-
import {useFetchers} from '@remix-run/react';
|
|
11
11
|
|
|
12
12
|
import type {
|
|
13
13
|
PredictiveProductFragment,
|
|
@@ -5,19 +5,40 @@ import {
|
|
|
5
5
|
Outlet,
|
|
6
6
|
Scripts,
|
|
7
7
|
useCatch,
|
|
8
|
+
LiveReload,
|
|
8
9
|
useMatches,
|
|
9
10
|
useRouteError,
|
|
10
11
|
useLoaderData,
|
|
11
12
|
ScrollRestoration,
|
|
12
13
|
isRouteErrorResponse,
|
|
14
|
+
type ShouldRevalidateFunction,
|
|
13
15
|
} from '@remix-run/react';
|
|
14
|
-
import type {CustomerAccessToken} from '@shopify/hydrogen
|
|
16
|
+
import type {CustomerAccessToken} from '@shopify/hydrogen/storefront-api-types';
|
|
15
17
|
import type {HydrogenSession} from '../server';
|
|
16
18
|
import favicon from '../public/favicon.svg';
|
|
17
19
|
import resetStyles from './styles/reset.css';
|
|
18
20
|
import appStyles from './styles/app.css';
|
|
19
21
|
import {Layout} from '~/components/Layout';
|
|
20
22
|
|
|
23
|
+
// This is important to avoid re-fetching root queries on sub-navigations
|
|
24
|
+
export const shouldRevalidate: ShouldRevalidateFunction = ({
|
|
25
|
+
formMethod,
|
|
26
|
+
currentUrl,
|
|
27
|
+
nextUrl,
|
|
28
|
+
}) => {
|
|
29
|
+
// revalidate when a mutation is performed e.g add to cart, login...
|
|
30
|
+
if (formMethod && formMethod !== 'GET') {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// revalidate when manually revalidating via useRevalidator
|
|
35
|
+
if (currentUrl.toString() === nextUrl.toString()) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return false;
|
|
40
|
+
};
|
|
41
|
+
|
|
21
42
|
export function links() {
|
|
22
43
|
return [
|
|
23
44
|
{rel: 'stylesheet', href: resetStyles},
|
|
@@ -93,6 +114,7 @@ export default function App() {
|
|
|
93
114
|
</Layout>
|
|
94
115
|
<ScrollRestoration />
|
|
95
116
|
<Scripts />
|
|
117
|
+
<LiveReload />
|
|
96
118
|
</body>
|
|
97
119
|
</html>
|
|
98
120
|
);
|
|
@@ -133,6 +155,7 @@ export function ErrorBoundary() {
|
|
|
133
155
|
</Layout>
|
|
134
156
|
<ScrollRestoration />
|
|
135
157
|
<Scripts />
|
|
158
|
+
<LiveReload />
|
|
136
159
|
</body>
|
|
137
160
|
</html>
|
|
138
161
|
);
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
2
1
|
import {defer, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Await,
|
|
4
|
+
useLoaderData,
|
|
5
|
+
Link,
|
|
6
|
+
type V2_MetaFunction,
|
|
7
|
+
} from '@remix-run/react';
|
|
4
8
|
import {Suspense} from 'react';
|
|
5
9
|
import {Image, Money} from '@shopify/hydrogen';
|
|
6
10
|
import type {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {redirect} from '@shopify/remix-oxygen';
|
|
1
|
+
import {redirect, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
2
|
|
|
4
3
|
export async function loader({context}: LoaderArgs) {
|
|
5
4
|
if (await context.session.get('customerAccessToken')) {
|
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
redirect,
|
|
6
6
|
type ActionArgs,
|
|
7
7
|
type LoaderArgs,
|
|
8
|
-
type V2_MetaFunction,
|
|
9
8
|
} from '@shopify/remix-oxygen';
|
|
10
9
|
import {
|
|
11
10
|
Form,
|
|
12
11
|
useActionData,
|
|
13
12
|
useNavigation,
|
|
14
13
|
useOutletContext,
|
|
14
|
+
type V2_MetaFunction,
|
|
15
15
|
} from '@remix-run/react';
|
|
16
16
|
|
|
17
17
|
export type ActionResponse = {
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {Link, useLoaderData} from '@remix-run/react';
|
|
1
|
+
import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
|
|
2
2
|
import {Money, Pagination, getPaginationVariables} from '@shopify/hydrogen';
|
|
3
|
-
import {
|
|
4
|
-
json,
|
|
5
|
-
redirect,
|
|
6
|
-
type LoaderArgs,
|
|
7
|
-
type V2_MetaFunction,
|
|
8
|
-
} from '@shopify/remix-oxygen';
|
|
3
|
+
import {json, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
9
4
|
import type {
|
|
10
5
|
CustomerOrdersFragment,
|
|
11
6
|
OrderItemFragment,
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import type {CustomerFragment} from 'storefrontapi.generated';
|
|
2
2
|
import type {CustomerUpdateInput} from '@shopify/hydrogen/storefront-api-types';
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
json,
|
|
5
|
+
redirect,
|
|
6
|
+
type ActionArgs,
|
|
7
|
+
type LoaderArgs,
|
|
8
|
+
} from '@shopify/remix-oxygen';
|
|
5
9
|
import {
|
|
6
10
|
Form,
|
|
7
11
|
useActionData,
|
|
8
12
|
useNavigation,
|
|
9
13
|
useOutletContext,
|
|
14
|
+
type V2_MetaFunction,
|
|
10
15
|
} from '@remix-run/react';
|
|
11
16
|
|
|
12
17
|
export type ActionResponse = {
|
|
@@ -109,13 +109,13 @@ function AccountLayout({
|
|
|
109
109
|
<div className="account">
|
|
110
110
|
<h1>{heading}</h1>
|
|
111
111
|
<br />
|
|
112
|
-
<
|
|
112
|
+
<AccountMenu />
|
|
113
113
|
{children}
|
|
114
114
|
</div>
|
|
115
115
|
);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
function
|
|
118
|
+
function AccountMenu() {
|
|
119
119
|
function isActiveStyle({
|
|
120
120
|
isActive,
|
|
121
121
|
isPending,
|
|
@@ -124,10 +124,11 @@ function AcccountMenu() {
|
|
|
124
124
|
isPending: boolean;
|
|
125
125
|
}) {
|
|
126
126
|
return {
|
|
127
|
-
fontWeight: isActive ? 'bold' :
|
|
127
|
+
fontWeight: isActive ? 'bold' : undefined,
|
|
128
128
|
color: isPending ? 'grey' : 'black',
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
+
|
|
131
132
|
return (
|
|
132
133
|
<nav role="navigation">
|
|
133
134
|
<NavLink to="/account/orders" style={isActiveStyle}>
|
package/dist/generator-templates/starter/app/routes/account_.activate.$id.$activationToken.tsx
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
json,
|
|
3
|
+
redirect,
|
|
4
|
+
type ActionArgs,
|
|
5
|
+
type LoaderArgs,
|
|
6
|
+
} from '@shopify/remix-oxygen';
|
|
3
7
|
import {Form, useActionData, type V2_MetaFunction} from '@remix-run/react';
|
|
4
8
|
|
|
5
9
|
type ActionResponse = {
|
|
@@ -3,9 +3,13 @@ import {
|
|
|
3
3
|
redirect,
|
|
4
4
|
type ActionArgs,
|
|
5
5
|
type LoaderArgs,
|
|
6
|
-
type V2_MetaFunction,
|
|
7
6
|
} from '@shopify/remix-oxygen';
|
|
8
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Form,
|
|
9
|
+
Link,
|
|
10
|
+
useActionData,
|
|
11
|
+
type V2_MetaFunction,
|
|
12
|
+
} from '@remix-run/react';
|
|
9
13
|
|
|
10
14
|
type ActionResponse = {
|
|
11
15
|
error: string | null;
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
redirect,
|
|
4
|
-
type ActionArgs,
|
|
5
|
-
type V2_MetaFunction,
|
|
6
|
-
} from '@shopify/remix-oxygen';
|
|
1
|
+
import {json, redirect, type ActionArgs} from '@shopify/remix-oxygen';
|
|
2
|
+
import {type V2_MetaFunction} from '@remix-run/react';
|
|
7
3
|
|
|
8
4
|
export const meta: V2_MetaFunction = () => {
|
|
9
5
|
return [{title: 'Logout'}];
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
2
1
|
import {json, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {useLoaderData} from '@remix-run/react';
|
|
2
|
+
import {useLoaderData, type V2_MetaFunction} from '@remix-run/react';
|
|
4
3
|
import {Image} from '@shopify/hydrogen';
|
|
5
4
|
|
|
6
5
|
export const meta: V2_MetaFunction = ({data}) => {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
2
1
|
import {json, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {Link, useLoaderData} from '@remix-run/react';
|
|
2
|
+
import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
|
|
4
3
|
import {Image, Pagination, getPaginationVariables} from '@shopify/hydrogen';
|
|
5
4
|
import type {ArticleItemFragment} from 'storefrontapi.generated';
|
|
6
5
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
2
1
|
import {json, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {Link, useLoaderData} from '@remix-run/react';
|
|
2
|
+
import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
|
|
4
3
|
import {Pagination, getPaginationVariables} from '@shopify/hydrogen';
|
|
5
4
|
|
|
6
5
|
export const meta: V2_MetaFunction = () => {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {Await, useMatches} from '@remix-run/react';
|
|
1
|
+
import {Await, useMatches, type V2_MetaFunction} from '@remix-run/react';
|
|
2
2
|
import {Suspense} from 'react';
|
|
3
3
|
import type {CartQueryData} from '@shopify/hydrogen';
|
|
4
4
|
import {CartForm} from '@shopify/hydrogen';
|
|
5
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
6
5
|
import {type ActionArgs, json} from '@shopify/remix-oxygen';
|
|
7
6
|
import type {CartApiQueryFragment} from 'storefrontapi.generated';
|
|
8
7
|
import {CartMain} from '~/components/Cart';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
2
1
|
import {json, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {useLoaderData, Link} from '@remix-run/react';
|
|
2
|
+
import {useLoaderData, Link, type V2_MetaFunction} from '@remix-run/react';
|
|
4
3
|
import {
|
|
5
4
|
Pagination,
|
|
6
5
|
getPaginationVariables,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
2
1
|
import {json, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {useLoaderData} from '@remix-run/react';
|
|
2
|
+
import {useLoaderData, type V2_MetaFunction} from '@remix-run/react';
|
|
4
3
|
|
|
5
4
|
export const meta: V2_MetaFunction = ({data}) => {
|
|
6
5
|
return [{title: `Hydrogen | ${data.page.title}`}];
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
2
1
|
import {json, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {Link, useLoaderData} from '@remix-run/react';
|
|
4
|
-
import {type Shop} from '@shopify/hydrogen
|
|
2
|
+
import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
|
|
3
|
+
import {type Shop} from '@shopify/hydrogen/storefront-api-types';
|
|
5
4
|
|
|
6
5
|
type SelectedPolicies = keyof Pick<
|
|
7
6
|
Shop,
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import {Suspense} from 'react';
|
|
2
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
3
2
|
import {defer, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
4
|
-
import
|
|
5
|
-
|
|
3
|
+
import {
|
|
4
|
+
Await,
|
|
5
|
+
Link,
|
|
6
|
+
useLoaderData,
|
|
7
|
+
type V2_MetaFunction,
|
|
8
|
+
type FetcherWithComponents,
|
|
9
|
+
} from '@remix-run/react';
|
|
6
10
|
import type {
|
|
7
11
|
ProductFragment,
|
|
8
12
|
ProductVariantsQuery,
|
|
@@ -17,7 +21,10 @@ import {
|
|
|
17
21
|
getSelectedProductOptions,
|
|
18
22
|
CartForm,
|
|
19
23
|
} from '@shopify/hydrogen';
|
|
20
|
-
import type {
|
|
24
|
+
import type {
|
|
25
|
+
CartLineInput,
|
|
26
|
+
SelectedOption,
|
|
27
|
+
} from '@shopify/hydrogen/storefront-api-types';
|
|
21
28
|
import {getVariantUrl} from '~/utils';
|
|
22
29
|
|
|
23
30
|
export const meta: V2_MetaFunction = ({data}) => {
|
|
@@ -47,15 +54,6 @@ export async function loader({params, request, context}: LoaderArgs) {
|
|
|
47
54
|
variables: {handle, selectedOptions},
|
|
48
55
|
});
|
|
49
56
|
|
|
50
|
-
// In order to show which variants are available in the UI, we need to query
|
|
51
|
-
// all of them. But there might be a *lot*, so instead separate the variants
|
|
52
|
-
// into it's own separate query that is deferred. So there's a brief moment
|
|
53
|
-
// where variant options might show as available when they're not, but after
|
|
54
|
-
// this deffered query resolves, the UI will update.
|
|
55
|
-
const variants = storefront.query(VARIANTS_QUERY, {
|
|
56
|
-
variables: {handle},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
57
|
if (!product?.id) {
|
|
60
58
|
throw new Response(null, {status: 404});
|
|
61
59
|
}
|
|
@@ -63,7 +61,8 @@ export async function loader({params, request, context}: LoaderArgs) {
|
|
|
63
61
|
const firstVariant = product.variants.nodes[0];
|
|
64
62
|
const firstVariantIsDefault = Boolean(
|
|
65
63
|
firstVariant.selectedOptions.find(
|
|
66
|
-
(option) =>
|
|
64
|
+
(option: SelectedOption) =>
|
|
65
|
+
option.name === 'Title' && option.value === 'Default Title',
|
|
67
66
|
),
|
|
68
67
|
);
|
|
69
68
|
|
|
@@ -76,6 +75,16 @@ export async function loader({params, request, context}: LoaderArgs) {
|
|
|
76
75
|
return redirectToFirstVariant({product, request});
|
|
77
76
|
}
|
|
78
77
|
}
|
|
78
|
+
|
|
79
|
+
// In order to show which variants are available in the UI, we need to query
|
|
80
|
+
// all of them. But there might be a *lot*, so instead separate the variants
|
|
81
|
+
// into it's own separate query that is deferred. So there's a brief moment
|
|
82
|
+
// where variant options might show as available when they're not, but after
|
|
83
|
+
// this deffered query resolves, the UI will update.
|
|
84
|
+
const variants = storefront.query(VARIANTS_QUERY, {
|
|
85
|
+
variables: {handle},
|
|
86
|
+
});
|
|
87
|
+
|
|
79
88
|
return defer({product, variants});
|
|
80
89
|
}
|
|
81
90
|
|
|
@@ -337,7 +346,6 @@ const PRODUCT_VARIANT_FRAGMENT = `#graphql
|
|
|
337
346
|
title
|
|
338
347
|
handle
|
|
339
348
|
}
|
|
340
|
-
quantityAvailable
|
|
341
349
|
selectedOptions {
|
|
342
350
|
name
|
|
343
351
|
value
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {V2_MetaFunction} from '@shopify/remix-oxygen';
|
|
2
1
|
import {defer, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {useLoaderData} from '@remix-run/react';
|
|
2
|
+
import {useLoaderData, type V2_MetaFunction} from '@remix-run/react';
|
|
4
3
|
import {getPaginationVariables} from '@shopify/hydrogen';
|
|
5
4
|
|
|
6
5
|
import {SearchForm, SearchResults, NoSearchResults} from '~/components/Search';
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@remix-run/react": "1.19.1",
|
|
17
17
|
"@shopify/cli": "3.48.0",
|
|
18
|
-
"@shopify/cli-hydrogen": "^5.
|
|
19
|
-
"@shopify/hydrogen": "^2023.7.
|
|
18
|
+
"@shopify/cli-hydrogen": "^5.2.0",
|
|
19
|
+
"@shopify/hydrogen": "^2023.7.3",
|
|
20
20
|
"@shopify/remix-oxygen": "^1.1.3",
|
|
21
21
|
"graphql": "^16.6.0",
|
|
22
22
|
"graphql-tag": "^2.12.6",
|