@shopify/cli-hydrogen 5.1.2 → 5.2.1
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 +25 -17
- package/dist/commands/hydrogen/generate/route.test.js +0 -1
- package/dist/commands/hydrogen/init.js +6 -3
- package/dist/commands/hydrogen/init.test.js +2 -0
- package/dist/commands/hydrogen/preview.js +2 -2
- 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/entry.server.tsx +9 -1
- package/dist/generator-templates/starter/app/root.tsx +31 -5
- 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 +2 -3
- 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 +5 -5
- package/dist/generator-templates/starter/remix.config.js +1 -0
- package/dist/generator-templates/starter/storefrontapi.generated.d.ts +9 -9
- package/dist/generator-templates/starter/tsconfig.json +1 -0
- 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/file.js +1 -1
- package/dist/lib/find-port.js +9 -0
- package/dist/lib/flags.js +6 -5
- package/dist/lib/format-code.js +7 -4
- package/dist/lib/graphql/admin/client.js +18 -0
- package/dist/lib/graphql/admin/client.test.js +28 -3
- 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/index.js +4 -2
- 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 +15 -29
- package/dist/lib/setups/routes/generate.test.js +1 -3
- package/dist/lib/template-downloader.js +4 -0
- package/dist/lib/transpile-ts.js +5 -3
- package/dist/lib/virtual-routes.js +4 -1
- package/dist/virtual-routes/components/HydrogenLogoBaseBW.jsx +29 -4
- package/dist/virtual-routes/components/HydrogenLogoBaseColor.jsx +44 -10
- package/dist/virtual-routes/components/IconBanner.jsx +289 -44
- package/dist/virtual-routes/components/IconDiscord.jsx +18 -1
- package/dist/virtual-routes/components/IconError.jsx +58 -17
- package/dist/virtual-routes/components/IconGithub.jsx +20 -1
- package/dist/virtual-routes/components/IconTwitter.jsx +18 -1
- package/dist/virtual-routes/components/Layout.jsx +2 -1
- package/dist/virtual-routes/routes/index.jsx +199 -94
- package/dist/virtual-routes/virtual-root.jsx +62 -16
- package/oclif.manifest.json +3 -3
- package/package.json +8 -7
|
@@ -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,7 @@ 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 { setupLiveReload } from '../../lib/live-reload.js';
|
|
19
20
|
import { checkRemixVersions } from '../../lib/remix-version-check.js';
|
|
20
21
|
|
|
21
22
|
const LOG_REBUILDING = "\u{1F9F1} Rebuilding...";
|
|
@@ -56,7 +57,7 @@ class Dev extends Command {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
async function runDev({
|
|
59
|
-
port,
|
|
60
|
+
port: portFlag = DEFAULT_PORT,
|
|
60
61
|
path: appPath,
|
|
61
62
|
useCodegen = false,
|
|
62
63
|
codegenConfigPath,
|
|
@@ -68,7 +69,6 @@ async function runDev({
|
|
|
68
69
|
if (!process.env.NODE_ENV)
|
|
69
70
|
process.env.NODE_ENV = "development";
|
|
70
71
|
muteDevLogs();
|
|
71
|
-
await muteRemixLogs();
|
|
72
72
|
if (debug)
|
|
73
73
|
(await import('node:inspector')).open();
|
|
74
74
|
const { root, publicPath, buildPathClient, buildPathWorkerFile } = getProjectPaths(appPath);
|
|
@@ -102,14 +102,15 @@ async function runDev({
|
|
|
102
102
|
let isInitialBuild = true;
|
|
103
103
|
let initialBuildDurationMs = 0;
|
|
104
104
|
let initialBuildStartTimeMs = Date.now();
|
|
105
|
+
const liveReload = remixConfig.future.v2_dev ? await setupLiveReload(remixConfig.devServerPort) : void 0;
|
|
105
106
|
let miniOxygen;
|
|
106
107
|
async function safeStartMiniOxygen() {
|
|
107
108
|
if (miniOxygen)
|
|
108
109
|
return;
|
|
109
110
|
miniOxygen = await startMiniOxygen({
|
|
110
111
|
root,
|
|
111
|
-
port,
|
|
112
|
-
watch:
|
|
112
|
+
port: portFlag,
|
|
113
|
+
watch: !liveReload,
|
|
113
114
|
buildPathWorkerFile,
|
|
114
115
|
buildPathClient,
|
|
115
116
|
env: await envPromise
|
|
@@ -145,13 +146,15 @@ View GraphiQL API browser: ${graphiqlUrl}`)]
|
|
|
145
146
|
},
|
|
146
147
|
{
|
|
147
148
|
reloadConfig,
|
|
148
|
-
onBuildStart() {
|
|
149
|
+
onBuildStart(ctx) {
|
|
149
150
|
if (!isInitialBuild && !skipRebuildLogs) {
|
|
150
151
|
outputInfo(LOG_REBUILDING);
|
|
151
152
|
console.time(LOG_REBUILT);
|
|
152
153
|
}
|
|
154
|
+
liveReload?.onBuildStart(ctx);
|
|
153
155
|
},
|
|
154
|
-
|
|
156
|
+
onBuildManifest: liveReload?.onBuildManifest,
|
|
157
|
+
async onBuildFinish(context, duration, succeeded) {
|
|
155
158
|
if (isInitialBuild) {
|
|
156
159
|
await copyingFiles;
|
|
157
160
|
initialBuildDurationMs = Date.now() - initialBuildStartTimeMs;
|
|
@@ -162,16 +165,21 @@ View GraphiQL API browser: ${graphiqlUrl}`)]
|
|
|
162
165
|
if (!miniOxygen)
|
|
163
166
|
console.log("");
|
|
164
167
|
}
|
|
165
|
-
if (!miniOxygen) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
if (!miniOxygen && !await serverBundleExists()) {
|
|
169
|
+
return renderFatalError({
|
|
170
|
+
name: "BuildError",
|
|
171
|
+
type: 0,
|
|
172
|
+
message: "MiniOxygen cannot start because the server bundle has not been generated.",
|
|
173
|
+
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."
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (succeeded) {
|
|
177
|
+
if (!miniOxygen) {
|
|
178
|
+
await safeStartMiniOxygen();
|
|
179
|
+
} else if (liveReload) {
|
|
180
|
+
await miniOxygen.reload({ worker: true });
|
|
173
181
|
}
|
|
174
|
-
|
|
182
|
+
liveReload?.onAppReady(context);
|
|
175
183
|
}
|
|
176
184
|
},
|
|
177
185
|
async onFileCreated(file) {
|
|
@@ -6,7 +6,7 @@ import { AbortError } from '@shopify/cli-kit/node/error';
|
|
|
6
6
|
import { AbortController } from '@shopify/cli-kit/node/abort';
|
|
7
7
|
import { commonFlags, flagsToCamelObject, parseProcessFlags } from '../../lib/flags.js';
|
|
8
8
|
import { checkHydrogenVersion } from '../../lib/check-version.js';
|
|
9
|
-
import {
|
|
9
|
+
import { STYLING_CHOICES } from './../../lib/setups/css/index.js';
|
|
10
10
|
import { I18N_CHOICES } from '../../lib/setups/i18n/index.js';
|
|
11
11
|
import { supressNodeExperimentalWarnings } from '../../lib/process.js';
|
|
12
12
|
import { setupRemoteTemplate, setupLocalStarterTemplate } from '../../lib/onboarding/index.js';
|
|
@@ -58,9 +58,9 @@ class Init extends Command {
|
|
|
58
58
|
`Invalid URL structure strategy: ${flags.markets}. Must be one of ${I18N_CHOICES.join(", ")}`
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
|
-
if (flags.styling && !
|
|
61
|
+
if (flags.styling && !STYLING_CHOICES.includes(flags.styling)) {
|
|
62
62
|
throw new AbortError(
|
|
63
|
-
`Invalid styling strategy: ${flags.styling}. Must be one of ${
|
|
63
|
+
`Invalid styling strategy: ${flags.styling}. Must be one of ${STYLING_CHOICES.join(", ")}`
|
|
64
64
|
);
|
|
65
65
|
}
|
|
66
66
|
await runInit(flagsToCamelObject(flags));
|
|
@@ -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,7 +1,7 @@
|
|
|
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
6
|
|
|
7
7
|
class Preview extends Command {
|
|
@@ -16,7 +16,7 @@ class Preview extends Command {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
async function runPreview({
|
|
19
|
-
port,
|
|
19
|
+
port = DEFAULT_PORT,
|
|
20
20
|
path: appPath
|
|
21
21
|
}) {
|
|
22
22
|
if (!process.env.NODE_ENV)
|
|
@@ -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,
|
|
@@ -2,6 +2,7 @@ import type {EntryContext} from '@shopify/remix-oxygen';
|
|
|
2
2
|
import {RemixServer} from '@remix-run/react';
|
|
3
3
|
import isbot from 'isbot';
|
|
4
4
|
import {renderToReadableStream} from 'react-dom/server';
|
|
5
|
+
import {createContentSecurityPolicy} from '@shopify/hydrogen';
|
|
5
6
|
|
|
6
7
|
export default async function handleRequest(
|
|
7
8
|
request: Request,
|
|
@@ -9,9 +10,14 @@ export default async function handleRequest(
|
|
|
9
10
|
responseHeaders: Headers,
|
|
10
11
|
remixContext: EntryContext,
|
|
11
12
|
) {
|
|
13
|
+
const {nonce, header, NonceProvider} = createContentSecurityPolicy();
|
|
14
|
+
|
|
12
15
|
const body = await renderToReadableStream(
|
|
13
|
-
<
|
|
16
|
+
<NonceProvider>
|
|
17
|
+
<RemixServer context={remixContext} url={request.url} />
|
|
18
|
+
</NonceProvider>,
|
|
14
19
|
{
|
|
20
|
+
nonce,
|
|
15
21
|
signal: request.signal,
|
|
16
22
|
onError(error) {
|
|
17
23
|
// eslint-disable-next-line no-console
|
|
@@ -26,6 +32,8 @@ export default async function handleRequest(
|
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
responseHeaders.set('Content-Type', 'text/html');
|
|
35
|
+
responseHeaders.set('Content-Security-Policy', header);
|
|
36
|
+
|
|
29
37
|
return new Response(body, {
|
|
30
38
|
headers: responseHeaders,
|
|
31
39
|
status: responseStatusCode,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {useNonce} from '@shopify/hydrogen';
|
|
1
2
|
import {defer, type LoaderArgs} from '@shopify/remix-oxygen';
|
|
2
3
|
import {
|
|
3
4
|
Links,
|
|
@@ -5,19 +6,40 @@ import {
|
|
|
5
6
|
Outlet,
|
|
6
7
|
Scripts,
|
|
7
8
|
useCatch,
|
|
9
|
+
LiveReload,
|
|
8
10
|
useMatches,
|
|
9
11
|
useRouteError,
|
|
10
12
|
useLoaderData,
|
|
11
13
|
ScrollRestoration,
|
|
12
14
|
isRouteErrorResponse,
|
|
15
|
+
type ShouldRevalidateFunction,
|
|
13
16
|
} from '@remix-run/react';
|
|
14
|
-
import type {CustomerAccessToken} from '@shopify/hydrogen
|
|
17
|
+
import type {CustomerAccessToken} from '@shopify/hydrogen/storefront-api-types';
|
|
15
18
|
import type {HydrogenSession} from '../server';
|
|
16
19
|
import favicon from '../public/favicon.svg';
|
|
17
20
|
import resetStyles from './styles/reset.css';
|
|
18
21
|
import appStyles from './styles/app.css';
|
|
19
22
|
import {Layout} from '~/components/Layout';
|
|
20
23
|
|
|
24
|
+
// This is important to avoid re-fetching root queries on sub-navigations
|
|
25
|
+
export const shouldRevalidate: ShouldRevalidateFunction = ({
|
|
26
|
+
formMethod,
|
|
27
|
+
currentUrl,
|
|
28
|
+
nextUrl,
|
|
29
|
+
}) => {
|
|
30
|
+
// revalidate when a mutation is performed e.g add to cart, login...
|
|
31
|
+
if (formMethod && formMethod !== 'GET') {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// revalidate when manually revalidating via useRevalidator
|
|
36
|
+
if (currentUrl.toString() === nextUrl.toString()) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return false;
|
|
41
|
+
};
|
|
42
|
+
|
|
21
43
|
export function links() {
|
|
22
44
|
return [
|
|
23
45
|
{rel: 'stylesheet', href: resetStyles},
|
|
@@ -77,6 +99,7 @@ export async function loader({context}: LoaderArgs) {
|
|
|
77
99
|
}
|
|
78
100
|
|
|
79
101
|
export default function App() {
|
|
102
|
+
const nonce = useNonce();
|
|
80
103
|
const data = useLoaderData<typeof loader>();
|
|
81
104
|
|
|
82
105
|
return (
|
|
@@ -91,8 +114,9 @@ export default function App() {
|
|
|
91
114
|
<Layout {...data}>
|
|
92
115
|
<Outlet />
|
|
93
116
|
</Layout>
|
|
94
|
-
<ScrollRestoration />
|
|
95
|
-
<Scripts />
|
|
117
|
+
<ScrollRestoration nonce={nonce} />
|
|
118
|
+
<Scripts nonce={nonce} />
|
|
119
|
+
<LiveReload nonce={nonce} />
|
|
96
120
|
</body>
|
|
97
121
|
</html>
|
|
98
122
|
);
|
|
@@ -101,6 +125,7 @@ export default function App() {
|
|
|
101
125
|
export function ErrorBoundary() {
|
|
102
126
|
const error = useRouteError();
|
|
103
127
|
const [root] = useMatches();
|
|
128
|
+
const nonce = useNonce();
|
|
104
129
|
let errorMessage = 'Unknown error';
|
|
105
130
|
let errorStatus = 500;
|
|
106
131
|
|
|
@@ -131,8 +156,9 @@ export function ErrorBoundary() {
|
|
|
131
156
|
)}
|
|
132
157
|
</div>
|
|
133
158
|
</Layout>
|
|
134
|
-
<ScrollRestoration />
|
|
135
|
-
<Scripts />
|
|
159
|
+
<ScrollRestoration nonce={nonce} />
|
|
160
|
+
<Scripts nonce={nonce} />
|
|
161
|
+
<LiveReload nonce={nonce} />
|
|
136
162
|
</body>
|
|
137
163
|
</html>
|
|
138
164
|
);
|
|
@@ -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,10 +1,9 @@
|
|
|
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 = () => {
|
|
7
|
-
return [{title: `Hydrogen |
|
|
6
|
+
return [{title: `Hydrogen | Blogs`}];
|
|
8
7
|
};
|
|
9
8
|
|
|
10
9
|
export const loader = async ({request, context: {storefront}}: LoaderArgs) => {
|
|
@@ -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,
|