@shopify/cli-hydrogen 8.4.6 → 9.0.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/assets/hydrogen/starter/CHANGELOG.md +147 -0
- package/dist/assets/hydrogen/starter/app/components/ProductForm.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/root.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/routes/[sitemap.xml].tsx +6 -166
- package/dist/assets/hydrogen/starter/app/routes/cart.tsx +2 -1
- package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +3 -1
- package/dist/assets/hydrogen/starter/app/routes/sitemap.$type.$page[.xml].tsx +24 -0
- package/dist/assets/hydrogen/starter/package.json +10 -10
- package/dist/assets/hydrogen/starter/storefrontapi.generated.d.ts +11 -37
- package/dist/commands/hydrogen/build.js +4 -1
- package/dist/commands/hydrogen/check.js +2 -1
- package/dist/commands/hydrogen/deploy.js +1 -1
- package/dist/commands/hydrogen/dev.js +1 -2
- package/dist/commands/hydrogen/preview.js +1 -2
- package/dist/index.d.ts +0 -63
- package/dist/lib/classic-compiler/build.js +1 -1
- package/dist/lib/{missing-routes.js → route-validator.js} +27 -1
- package/dist/lib/setups/routes/generate.js +1 -1
- package/oclif.manifest.json +2 -12
- package/package.json +8 -8
|
@@ -1,5 +1,152 @@
|
|
|
1
1
|
# skeleton
|
|
2
2
|
|
|
3
|
+
## 2024.10.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Stabilize `getSitemap`, `getSitemapIndex` and implement on skeleton ([#2589](https://github.com/Shopify/hydrogen/pull/2589)) by [@juanpprieto](https://github.com/juanpprieto)
|
|
8
|
+
|
|
9
|
+
1. Update the `getSitemapIndex` at `/app/routes/[sitemap.xml].tsx`
|
|
10
|
+
|
|
11
|
+
```diff
|
|
12
|
+
- import {unstable__getSitemapIndex as getSitemapIndex} from '@shopify/hydrogen';
|
|
13
|
+
+ import {getSitemapIndex} from '@shopify/hydrogen';
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
2. Update the `getSitemap` at `/app/routes/sitemap.$type.$page[.xml].tsx`
|
|
17
|
+
|
|
18
|
+
```diff
|
|
19
|
+
- import {unstable__getSitemap as getSitemap} from '@shopify/hydrogen';
|
|
20
|
+
+ import {getSitemap} from '@shopify/hydrogen';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For a reference implementation please see the skeleton template sitemap routes
|
|
24
|
+
|
|
25
|
+
- [**Breaking change**] ([#2588](https://github.com/Shopify/hydrogen/pull/2588)) by [@wizardlyhel](https://github.com/wizardlyhel)
|
|
26
|
+
|
|
27
|
+
Set up Customer Privacy without the Shopify's cookie banner by default.
|
|
28
|
+
|
|
29
|
+
If you are using Shopify's cookie banner to handle user consent in your app, you need to set `withPrivacyBanner: true` to the consent config. Without this update, the Shopify cookie banner will not appear.
|
|
30
|
+
|
|
31
|
+
```diff
|
|
32
|
+
return defer({
|
|
33
|
+
...
|
|
34
|
+
consent: {
|
|
35
|
+
checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN,
|
|
36
|
+
storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN,
|
|
37
|
+
+ withPrivacyBanner: true,
|
|
38
|
+
// localize the privacy banner
|
|
39
|
+
country: args.context.storefront.i18n.country,
|
|
40
|
+
language: args.context.storefront.i18n.language,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- Update to 2024-10 SFAPI ([#2570](https://github.com/Shopify/hydrogen/pull/2570)) by [@wizardlyhel](https://github.com/wizardlyhel)
|
|
46
|
+
|
|
47
|
+
- [**Breaking change**] ([#2546](https://github.com/Shopify/hydrogen/pull/2546)) by [@frandiox](https://github.com/frandiox)
|
|
48
|
+
|
|
49
|
+
Update `createWithCache` to make it harder to accidentally cache undesired results. `request` is now mandatory prop when initializing `createWithCache`.
|
|
50
|
+
|
|
51
|
+
```diff
|
|
52
|
+
// server.ts
|
|
53
|
+
export default {
|
|
54
|
+
async fetch(
|
|
55
|
+
request: Request,
|
|
56
|
+
env: Env,
|
|
57
|
+
executionContext: ExecutionContext,
|
|
58
|
+
): Promise<Response> {
|
|
59
|
+
try {
|
|
60
|
+
// ...
|
|
61
|
+
- const withCache = createWithCache({cache, waitUntil});
|
|
62
|
+
+ const withCache = createWithCache({cache, waitUntil, request});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`createWithCache` now returns an object with two utility functions: `withCache.run` and `withCache.fetch`. Both have a new prop `shouldCacheResult` that must be defined.
|
|
66
|
+
|
|
67
|
+
The original `withCache` callback function is now `withCache.run`. This is useful to run _multiple_ fetch calls and merge their responses, or run any arbitrary code. It caches anything you return, but you can throw if you don't want to cache anything.
|
|
68
|
+
|
|
69
|
+
```diff
|
|
70
|
+
const withCache = createWithCache({cache, waitUntil, request});
|
|
71
|
+
|
|
72
|
+
const fetchMyCMS = (query) => {
|
|
73
|
+
- return withCache(['my-cms', query], CacheLong(), async (params) => {
|
|
74
|
+
+ return withCache.run({
|
|
75
|
+
+ cacheKey: ['my-cms', query],
|
|
76
|
+
+ cacheStrategy: CacheLong(),
|
|
77
|
+
+ // Cache if there are no data errors or a specific data that make this result not suited for caching
|
|
78
|
+
+ shouldCacheResult: (result) => !result?.errors,
|
|
79
|
+
+ }, async(params) => {
|
|
80
|
+
const response = await fetch('my-cms.com/api', {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
body: query,
|
|
83
|
+
});
|
|
84
|
+
if (!response.ok) throw new Error(response.statusText);
|
|
85
|
+
const {data, error} = await response.json();
|
|
86
|
+
if (error || !data) throw new Error(error ?? 'Missing data');
|
|
87
|
+
params.addDebugData({displayName: 'My CMS query', response});
|
|
88
|
+
return data;
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
New `withCache.fetch` is for caching simple fetch requests. This method caches the responses if they are OK responses, and you can pass `shouldCacheResponse`, `cacheKey`, etc. to modify behavior. `data` is the consumed body of the response (we need to consume to cache it).
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const withCache = createWithCache({cache, waitUntil, request});
|
|
97
|
+
|
|
98
|
+
const {data, response} = await withCache.fetch<{data: T; error: string}>(
|
|
99
|
+
'my-cms.com/api',
|
|
100
|
+
{
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers: {'Content-type': 'application/json'},
|
|
103
|
+
body,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
cacheStrategy: CacheLong(),
|
|
107
|
+
// Cache if there are no data errors or a specific data that make this result not suited for caching
|
|
108
|
+
shouldCacheResponse: (result) => !result?.error,
|
|
109
|
+
cacheKey: ['my-cms', body],
|
|
110
|
+
displayName: 'My CMS query',
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- [**Breaking change**] ([#2585](https://github.com/Shopify/hydrogen/pull/2585)) by [@wizardlyhel](https://github.com/wizardlyhel)
|
|
116
|
+
|
|
117
|
+
Deprecate usages of `product.options.values` and use `product.options.optionValues` instead.
|
|
118
|
+
|
|
119
|
+
1. Update your product graphql query to use the new `optionValues` field.
|
|
120
|
+
|
|
121
|
+
```diff
|
|
122
|
+
const PRODUCT_FRAGMENT = `#graphql
|
|
123
|
+
fragment Product on Product {
|
|
124
|
+
id
|
|
125
|
+
title
|
|
126
|
+
options {
|
|
127
|
+
name
|
|
128
|
+
- values
|
|
129
|
+
+ optionValues {
|
|
130
|
+
+ name
|
|
131
|
+
+ }
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
2. Update your `<VariantSelector>` to use the new `optionValues` field.
|
|
136
|
+
|
|
137
|
+
```diff
|
|
138
|
+
<VariantSelector
|
|
139
|
+
handle={product.handle}
|
|
140
|
+
- options={product.options.filter((option) => option.values.length > 1)}
|
|
141
|
+
+ options={product.options.filter((option) => option.optionValues.length > 1)}
|
|
142
|
+
variants={variants}
|
|
143
|
+
>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
- Updated dependencies [[`d97cd56e`](https://github.com/Shopify/hydrogen/commit/d97cd56e859abf8dd005fef2589d99e07fa87b6e), [`809c9f3d`](https://github.com/Shopify/hydrogen/commit/809c9f3d342b56dd3c0d340cb733e6f00053b71d), [`8c89f298`](https://github.com/Shopify/hydrogen/commit/8c89f298a8d9084ee510fb4d0d17766ec43c249c), [`a253ef97`](https://github.com/Shopify/hydrogen/commit/a253ef971acb08f2ee3a2743ca5c901c2922acc0), [`84a66b1e`](https://github.com/Shopify/hydrogen/commit/84a66b1e9d07bd6d6a10e5379ad3350b6bbecde9), [`227035e7`](https://github.com/Shopify/hydrogen/commit/227035e7e11df5fec5ac475b98fa6a318bdbe366), [`ac12293c`](https://github.com/Shopify/hydrogen/commit/ac12293c7b36e1b278bc929c682c65779c300cc7), [`c7c9f2eb`](https://github.com/Shopify/hydrogen/commit/c7c9f2ebd869a9d361504a10566c268e88b6096a), [`76cd4f9b`](https://github.com/Shopify/hydrogen/commit/76cd4f9ba3dd8eff4433d72f4422c06a7d567537), [`8337e534`](https://github.com/Shopify/hydrogen/commit/8337e5342ecca563fab557c3e833485466456cd5)]:
|
|
147
|
+
- @shopify/hydrogen@2024.10.0
|
|
148
|
+
- @shopify/remix-oxygen@2.0.9
|
|
149
|
+
|
|
3
150
|
## 2024.7.10
|
|
4
151
|
|
|
5
152
|
### Patch Changes
|
|
@@ -21,7 +21,7 @@ export function ProductForm({
|
|
|
21
21
|
<div className="product-form">
|
|
22
22
|
<VariantSelector
|
|
23
23
|
handle={product.handle}
|
|
24
|
-
options={product.options.filter((option) => option.
|
|
24
|
+
options={product.options.filter((option) => option.optionValues.length > 1)}
|
|
25
25
|
variants={variants}
|
|
26
26
|
>
|
|
27
27
|
{({option}) => <ProductOptions key={option.name} option={option} />}
|
|
@@ -73,7 +73,7 @@ export async function loader(args: LoaderFunctionArgs) {
|
|
|
73
73
|
consent: {
|
|
74
74
|
checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN,
|
|
75
75
|
storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN,
|
|
76
|
-
withPrivacyBanner:
|
|
76
|
+
withPrivacyBanner: false,
|
|
77
77
|
// localize the privacy banner
|
|
78
78
|
country: args.context.storefront.i18n.country,
|
|
79
79
|
language: args.context.storefront.i18n.language,
|
|
@@ -1,177 +1,17 @@
|
|
|
1
|
-
import {flattenConnection} from '@shopify/hydrogen';
|
|
2
1
|
import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* the google limit is 50K, however, the storefront API
|
|
7
|
-
* allows querying only 250 resources per pagination page
|
|
8
|
-
*/
|
|
9
|
-
const MAX_URLS = 250;
|
|
10
|
-
|
|
11
|
-
type Entry = {
|
|
12
|
-
url: string;
|
|
13
|
-
lastMod?: string;
|
|
14
|
-
changeFreq?: string;
|
|
15
|
-
image?: {
|
|
16
|
-
url: string;
|
|
17
|
-
title?: string;
|
|
18
|
-
caption?: string;
|
|
19
|
-
};
|
|
20
|
-
};
|
|
2
|
+
import {getSitemapIndex} from '@shopify/hydrogen';
|
|
21
3
|
|
|
22
4
|
export async function loader({
|
|
23
5
|
request,
|
|
24
6
|
context: {storefront},
|
|
25
7
|
}: LoaderFunctionArgs) {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
language: storefront.i18n.language,
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
if (!data) {
|
|
34
|
-
throw new Response('No data found', {status: 404});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const sitemap = generateSitemap({data, baseUrl: new URL(request.url).origin});
|
|
38
|
-
|
|
39
|
-
return new Response(sitemap, {
|
|
40
|
-
headers: {
|
|
41
|
-
'Content-Type': 'application/xml',
|
|
42
|
-
|
|
43
|
-
'Cache-Control': `max-age=${60 * 60 * 24}`,
|
|
44
|
-
},
|
|
8
|
+
const response = await getSitemapIndex({
|
|
9
|
+
storefront,
|
|
10
|
+
request,
|
|
45
11
|
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function xmlEncode(string: string) {
|
|
49
|
-
return string.replace(/[&<>'"]/g, (char) => `&#${char.charCodeAt(0)};`);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function generateSitemap({
|
|
53
|
-
data,
|
|
54
|
-
baseUrl,
|
|
55
|
-
}: {
|
|
56
|
-
data: SitemapQuery;
|
|
57
|
-
baseUrl: string;
|
|
58
|
-
}) {
|
|
59
|
-
const products = flattenConnection(data.products)
|
|
60
|
-
.filter((product) => product.onlineStoreUrl)
|
|
61
|
-
.map((product) => {
|
|
62
|
-
const url = `${baseUrl}/products/${xmlEncode(product.handle)}`;
|
|
63
|
-
|
|
64
|
-
const productEntry: Entry = {
|
|
65
|
-
url,
|
|
66
|
-
lastMod: product.updatedAt,
|
|
67
|
-
changeFreq: 'daily',
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
if (product.featuredImage?.url) {
|
|
71
|
-
productEntry.image = {
|
|
72
|
-
url: xmlEncode(product.featuredImage.url),
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
if (product.title) {
|
|
76
|
-
productEntry.image.title = xmlEncode(product.title);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (product.featuredImage.altText) {
|
|
80
|
-
productEntry.image.caption = xmlEncode(product.featuredImage.altText);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return productEntry;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const collections = flattenConnection(data.collections)
|
|
88
|
-
.filter((collection) => collection.onlineStoreUrl)
|
|
89
|
-
.map((collection) => {
|
|
90
|
-
const url = `${baseUrl}/collections/${collection.handle}`;
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
url,
|
|
94
|
-
lastMod: collection.updatedAt,
|
|
95
|
-
changeFreq: 'daily',
|
|
96
|
-
};
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
const pages = flattenConnection(data.pages)
|
|
100
|
-
.filter((page) => page.onlineStoreUrl)
|
|
101
|
-
.map((page) => {
|
|
102
|
-
const url = `${baseUrl}/pages/${page.handle}`;
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
url,
|
|
106
|
-
lastMod: page.updatedAt,
|
|
107
|
-
changeFreq: 'weekly',
|
|
108
|
-
};
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
const urls = [...products, ...collections, ...pages];
|
|
112
|
-
|
|
113
|
-
return `
|
|
114
|
-
<urlset
|
|
115
|
-
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
|
116
|
-
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
|
|
117
|
-
>
|
|
118
|
-
${urls.map(renderUrlTag).join('')}
|
|
119
|
-
</urlset>`;
|
|
120
|
-
}
|
|
121
12
|
|
|
122
|
-
|
|
123
|
-
const imageTag = image
|
|
124
|
-
? `<image:image>
|
|
125
|
-
<image:loc>${image.url}</image:loc>
|
|
126
|
-
<image:title>${image.title ?? ''}</image:title>
|
|
127
|
-
<image:caption>${image.caption ?? ''}</image:caption>
|
|
128
|
-
</image:image>`.trim()
|
|
129
|
-
: '';
|
|
13
|
+
response.headers.set('Cache-Control', `max-age=${60 * 60 * 24}`);
|
|
130
14
|
|
|
131
|
-
return
|
|
132
|
-
<url>
|
|
133
|
-
<loc>${url}</loc>
|
|
134
|
-
<lastmod>${lastMod}</lastmod>
|
|
135
|
-
<changefreq>${changeFreq}</changefreq>
|
|
136
|
-
${imageTag}
|
|
137
|
-
</url>
|
|
138
|
-
`.trim();
|
|
15
|
+
return response;
|
|
139
16
|
}
|
|
140
17
|
|
|
141
|
-
const SITEMAP_QUERY = `#graphql
|
|
142
|
-
query Sitemap($urlLimits: Int, $language: LanguageCode)
|
|
143
|
-
@inContext(language: $language) {
|
|
144
|
-
products(
|
|
145
|
-
first: $urlLimits
|
|
146
|
-
query: "published_status:'online_store:visible'"
|
|
147
|
-
) {
|
|
148
|
-
nodes {
|
|
149
|
-
updatedAt
|
|
150
|
-
handle
|
|
151
|
-
onlineStoreUrl
|
|
152
|
-
title
|
|
153
|
-
featuredImage {
|
|
154
|
-
url
|
|
155
|
-
altText
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
collections(
|
|
160
|
-
first: $urlLimits
|
|
161
|
-
query: "published_status:'online_store:visible'"
|
|
162
|
-
) {
|
|
163
|
-
nodes {
|
|
164
|
-
updatedAt
|
|
165
|
-
handle
|
|
166
|
-
onlineStoreUrl
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
pages(first: $urlLimits, query: "published_status:'published'") {
|
|
170
|
-
nodes {
|
|
171
|
-
updatedAt
|
|
172
|
-
handle
|
|
173
|
-
onlineStoreUrl
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
` as const;
|
|
@@ -74,7 +74,7 @@ export async function action({request, context}: ActionFunctionArgs) {
|
|
|
74
74
|
|
|
75
75
|
const cartId = result?.cart?.id;
|
|
76
76
|
const headers = cartId ? cart.setCartId(result.cart.id) : new Headers();
|
|
77
|
-
const {cart: cartResult, errors} = result;
|
|
77
|
+
const {cart: cartResult, errors, warnings} = result;
|
|
78
78
|
|
|
79
79
|
const redirectTo = formData.get('redirectTo') ?? null;
|
|
80
80
|
if (typeof redirectTo === 'string') {
|
|
@@ -86,6 +86,7 @@ export async function action({request, context}: ActionFunctionArgs) {
|
|
|
86
86
|
{
|
|
87
87
|
cart: cartResult,
|
|
88
88
|
errors,
|
|
89
|
+
warnings,
|
|
89
90
|
analytics: {
|
|
90
91
|
cartId,
|
|
91
92
|
},
|
|
@@ -242,7 +242,9 @@ const PRODUCT_FRAGMENT = `#graphql
|
|
|
242
242
|
description
|
|
243
243
|
options {
|
|
244
244
|
name
|
|
245
|
-
|
|
245
|
+
optionValues {
|
|
246
|
+
name
|
|
247
|
+
}
|
|
246
248
|
}
|
|
247
249
|
selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) {
|
|
248
250
|
...ProductVariant
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
2
|
+
import {getSitemap} from '@shopify/hydrogen';
|
|
3
|
+
|
|
4
|
+
export async function loader({
|
|
5
|
+
request,
|
|
6
|
+
params,
|
|
7
|
+
context: {storefront},
|
|
8
|
+
}: LoaderFunctionArgs) {
|
|
9
|
+
const response = await getSitemap({
|
|
10
|
+
storefront,
|
|
11
|
+
request,
|
|
12
|
+
params,
|
|
13
|
+
locales: ['EN-US', 'EN-CA', 'FR-CA'],
|
|
14
|
+
getLink: ({type, baseUrl, handle, locale}) => {
|
|
15
|
+
if (!locale) return `${baseUrl}/${type}/${handle}`;
|
|
16
|
+
return `${baseUrl}/${locale}/${type}/${handle}`;
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
response.headers.set('Cache-Control', `max-age=${60 * 60 * 24}`);
|
|
21
|
+
|
|
22
|
+
return response;
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "skeleton",
|
|
3
3
|
"private": true,
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "2024.
|
|
5
|
+
"version": "2024.10.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "shopify hydrogen build --codegen",
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
},
|
|
15
15
|
"prettier": "@shopify/prettier-config",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@remix-run/react": "^2.
|
|
18
|
-
"@remix-run/server-runtime": "^2.
|
|
19
|
-
"@shopify/hydrogen": "2024.
|
|
20
|
-
"@shopify/remix-oxygen": "^2.0.
|
|
17
|
+
"@remix-run/react": "^2.13.1",
|
|
18
|
+
"@remix-run/server-runtime": "^2.13.1",
|
|
19
|
+
"@shopify/hydrogen": "2024.10.0",
|
|
20
|
+
"@shopify/remix-oxygen": "^2.0.9",
|
|
21
21
|
"graphql": "^16.6.0",
|
|
22
22
|
"graphql-tag": "^2.12.6",
|
|
23
23
|
"isbot": "^3.8.0",
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@graphql-codegen/cli": "5.0.2",
|
|
29
|
-
"@remix-run/dev": "^2.
|
|
30
|
-
"@remix-run/eslint-config": "^2.
|
|
31
|
-
"@shopify/cli": "~3.
|
|
32
|
-
"@shopify/hydrogen-codegen": "^0.3.
|
|
33
|
-
"@shopify/mini-oxygen": "^3.0
|
|
29
|
+
"@remix-run/dev": "^2.13.1",
|
|
30
|
+
"@remix-run/eslint-config": "^2.13.1",
|
|
31
|
+
"@shopify/cli": "~3.69.2",
|
|
32
|
+
"@shopify/hydrogen-codegen": "^0.3.2",
|
|
33
|
+
"@shopify/mini-oxygen": "^3.1.0",
|
|
34
34
|
"@shopify/oxygen-workers-types": "^4.1.2",
|
|
35
35
|
"@shopify/prettier-config": "^1.1.2",
|
|
36
36
|
"@total-typescript/ts-reset": "^0.4.2",
|
|
@@ -295,36 +295,6 @@ export type StoreRobotsQueryVariables = StorefrontAPI.Exact<{
|
|
|
295
295
|
|
|
296
296
|
export type StoreRobotsQuery = {shop: Pick<StorefrontAPI.Shop, 'id'>};
|
|
297
297
|
|
|
298
|
-
export type SitemapQueryVariables = StorefrontAPI.Exact<{
|
|
299
|
-
urlLimits?: StorefrontAPI.InputMaybe<StorefrontAPI.Scalars['Int']['input']>;
|
|
300
|
-
language?: StorefrontAPI.InputMaybe<StorefrontAPI.LanguageCode>;
|
|
301
|
-
}>;
|
|
302
|
-
|
|
303
|
-
export type SitemapQuery = {
|
|
304
|
-
products: {
|
|
305
|
-
nodes: Array<
|
|
306
|
-
Pick<
|
|
307
|
-
StorefrontAPI.Product,
|
|
308
|
-
'updatedAt' | 'handle' | 'onlineStoreUrl' | 'title'
|
|
309
|
-
> & {
|
|
310
|
-
featuredImage?: StorefrontAPI.Maybe<
|
|
311
|
-
Pick<StorefrontAPI.Image, 'url' | 'altText'>
|
|
312
|
-
>;
|
|
313
|
-
}
|
|
314
|
-
>;
|
|
315
|
-
};
|
|
316
|
-
collections: {
|
|
317
|
-
nodes: Array<
|
|
318
|
-
Pick<StorefrontAPI.Collection, 'updatedAt' | 'handle' | 'onlineStoreUrl'>
|
|
319
|
-
>;
|
|
320
|
-
};
|
|
321
|
-
pages: {
|
|
322
|
-
nodes: Array<
|
|
323
|
-
Pick<StorefrontAPI.Page, 'updatedAt' | 'handle' | 'onlineStoreUrl'>
|
|
324
|
-
>;
|
|
325
|
-
};
|
|
326
|
-
};
|
|
327
|
-
|
|
328
298
|
export type FeaturedCollectionFragment = Pick<
|
|
329
299
|
StorefrontAPI.Collection,
|
|
330
300
|
'id' | 'title' | 'handle'
|
|
@@ -782,7 +752,11 @@ export type ProductFragment = Pick<
|
|
|
782
752
|
StorefrontAPI.Product,
|
|
783
753
|
'id' | 'title' | 'vendor' | 'handle' | 'descriptionHtml' | 'description'
|
|
784
754
|
> & {
|
|
785
|
-
options: Array<
|
|
755
|
+
options: Array<
|
|
756
|
+
Pick<StorefrontAPI.ProductOption, 'name'> & {
|
|
757
|
+
optionValues: Array<Pick<StorefrontAPI.ProductOptionValue, 'name'>>;
|
|
758
|
+
}
|
|
759
|
+
>;
|
|
786
760
|
selectedVariant?: StorefrontAPI.Maybe<
|
|
787
761
|
Pick<
|
|
788
762
|
StorefrontAPI.ProductVariant,
|
|
@@ -851,7 +825,11 @@ export type ProductQuery = {
|
|
|
851
825
|
StorefrontAPI.Product,
|
|
852
826
|
'id' | 'title' | 'vendor' | 'handle' | 'descriptionHtml' | 'description'
|
|
853
827
|
> & {
|
|
854
|
-
options: Array<
|
|
828
|
+
options: Array<
|
|
829
|
+
Pick<StorefrontAPI.ProductOption, 'name'> & {
|
|
830
|
+
optionValues: Array<Pick<StorefrontAPI.ProductOptionValue, 'name'>>;
|
|
831
|
+
}
|
|
832
|
+
>;
|
|
855
833
|
selectedVariant?: StorefrontAPI.Maybe<
|
|
856
834
|
Pick<
|
|
857
835
|
StorefrontAPI.ProductVariant,
|
|
@@ -1212,10 +1190,6 @@ interface GeneratedQueryTypes {
|
|
|
1212
1190
|
return: StoreRobotsQuery;
|
|
1213
1191
|
variables: StoreRobotsQueryVariables;
|
|
1214
1192
|
};
|
|
1215
|
-
'#graphql\n query Sitemap($urlLimits: Int, $language: LanguageCode)\n @inContext(language: $language) {\n products(\n first: $urlLimits\n query: "published_status:\'online_store:visible\'"\n ) {\n nodes {\n updatedAt\n handle\n onlineStoreUrl\n title\n featuredImage {\n url\n altText\n }\n }\n }\n collections(\n first: $urlLimits\n query: "published_status:\'online_store:visible\'"\n ) {\n nodes {\n updatedAt\n handle\n onlineStoreUrl\n }\n }\n pages(first: $urlLimits, query: "published_status:\'published\'") {\n nodes {\n updatedAt\n handle\n onlineStoreUrl\n }\n }\n }\n': {
|
|
1216
|
-
return: SitemapQuery;
|
|
1217
|
-
variables: SitemapQueryVariables;
|
|
1218
|
-
};
|
|
1219
1193
|
'#graphql\n fragment FeaturedCollection on Collection {\n id\n title\n image {\n id\n url\n altText\n width\n height\n }\n handle\n }\n query FeaturedCollection($country: CountryCode, $language: LanguageCode)\n @inContext(country: $country, language: $language) {\n collections(first: 1, sortKey: UPDATED_AT, reverse: true) {\n nodes {\n ...FeaturedCollection\n }\n }\n }\n': {
|
|
1220
1194
|
return: FeaturedCollectionQuery;
|
|
1221
1195
|
variables: FeaturedCollectionQueryVariables;
|
|
@@ -1260,7 +1234,7 @@ interface GeneratedQueryTypes {
|
|
|
1260
1234
|
return: PoliciesQuery;
|
|
1261
1235
|
variables: PoliciesQueryVariables;
|
|
1262
1236
|
};
|
|
1263
|
-
'#graphql\n query Product(\n $country: CountryCode\n $handle: String!\n $language: LanguageCode\n $selectedOptions: [SelectedOptionInput!]!\n ) @inContext(country: $country, language: $language) {\n product(handle: $handle) {\n ...Product\n }\n }\n #graphql\n fragment Product on Product {\n id\n title\n vendor\n handle\n descriptionHtml\n description\n options {\n name\n
|
|
1237
|
+
'#graphql\n query Product(\n $country: CountryCode\n $handle: String!\n $language: LanguageCode\n $selectedOptions: [SelectedOptionInput!]!\n ) @inContext(country: $country, language: $language) {\n product(handle: $handle) {\n ...Product\n }\n }\n #graphql\n fragment Product on Product {\n id\n title\n vendor\n handle\n descriptionHtml\n description\n options {\n name\n optionValues {\n name\n }\n }\n selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) {\n ...ProductVariant\n }\n variants(first: 1) {\n nodes {\n ...ProductVariant\n }\n }\n seo {\n description\n title\n }\n }\n #graphql\n fragment ProductVariant on ProductVariant {\n availableForSale\n compareAtPrice {\n amount\n currencyCode\n }\n id\n image {\n __typename\n id\n url\n altText\n width\n height\n }\n price {\n amount\n currencyCode\n }\n product {\n title\n handle\n }\n selectedOptions {\n name\n value\n }\n sku\n title\n unitPrice {\n amount\n currencyCode\n }\n }\n\n\n': {
|
|
1264
1238
|
return: ProductQuery;
|
|
1265
1239
|
variables: ProductQueryVariables;
|
|
1266
1240
|
};
|
|
@@ -8,7 +8,7 @@ import { commonFlags, flagsToCamelObject } from '../../lib/flags.js';
|
|
|
8
8
|
import { prepareDiffDirectory } from '../../lib/template-diff.js';
|
|
9
9
|
import { isViteProject, getViteConfig } from '../../lib/vite-config.js';
|
|
10
10
|
import { checkLockfileStatus } from '../../lib/check-lockfile.js';
|
|
11
|
-
import { findMissingRoutes } from '../../lib/
|
|
11
|
+
import { findMissingRoutes, warnReservedRoutes, findReservedRoutes } from '../../lib/route-validator.js';
|
|
12
12
|
import { runClassicCompilerBuild } from '../../lib/classic-compiler/build.js';
|
|
13
13
|
import { hydrogenBundleAnalyzer } from '../../lib/bundle/vite-plugin.js';
|
|
14
14
|
import { BUNDLE_ANALYZER_HTML_FILE, getBundleAnalysisSummary } from '../../lib/bundle/analyzer.js';
|
|
@@ -242,6 +242,9 @@ This build is missing ${missingRoutes.length} route${missingRoutes.length > 1 ?
|
|
|
242
242
|
);
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
|
+
if (!watch && !disableRouteWarning) {
|
|
246
|
+
warnReservedRoutes(findReservedRoutes(remixConfig));
|
|
247
|
+
}
|
|
245
248
|
return {
|
|
246
249
|
async close() {
|
|
247
250
|
codegenProcess?.removeAllListeners("close");
|
|
@@ -2,7 +2,7 @@ import Command from '@shopify/cli-kit/node/base-command';
|
|
|
2
2
|
import { resolvePath } from '@shopify/cli-kit/node/path';
|
|
3
3
|
import { commonFlags } from '../../lib/flags.js';
|
|
4
4
|
import { getRemixConfig } from '../../lib/remix-config.js';
|
|
5
|
-
import { logMissingRoutes, findMissingRoutes } from '../../lib/
|
|
5
|
+
import { logMissingRoutes, findMissingRoutes, warnReservedRoutes, findReservedRoutes } from '../../lib/route-validator.js';
|
|
6
6
|
import { Args } from '@oclif/core';
|
|
7
7
|
|
|
8
8
|
class GenerateRoute extends Command {
|
|
@@ -32,6 +32,7 @@ class GenerateRoute extends Command {
|
|
|
32
32
|
async function runCheckRoutes({ directory }) {
|
|
33
33
|
const remixConfig = await getRemixConfig(directory);
|
|
34
34
|
logMissingRoutes(findMissingRoutes(remixConfig));
|
|
35
|
+
warnReservedRoutes(findReservedRoutes(remixConfig));
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
export { GenerateRoute as default, runCheckRoutes };
|
|
@@ -42,7 +42,7 @@ class Deploy extends Command {
|
|
|
42
42
|
}
|
|
43
43
|
}),
|
|
44
44
|
preview: Flags.boolean({
|
|
45
|
-
description: "Deploys to the Preview environment.
|
|
45
|
+
description: "Deploys to the Preview environment.",
|
|
46
46
|
required: false,
|
|
47
47
|
default: false
|
|
48
48
|
}),
|
|
@@ -7,7 +7,7 @@ import { renderSuccess, renderInfo } from '@shopify/cli-kit/node/ui';
|
|
|
7
7
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
8
8
|
import { removeFile } from '@shopify/cli-kit/node/fs';
|
|
9
9
|
import { setH2OVerbose, isH2Verbose, muteDevLogs, enhanceH2Logs } from '../../lib/log.js';
|
|
10
|
-
import { commonFlags, overrideFlag,
|
|
10
|
+
import { commonFlags, overrideFlag, flagsToCamelObject, DEFAULT_INSPECTOR_PORT, DEFAULT_APP_PORT } from '../../lib/flags.js';
|
|
11
11
|
import { spawnCodegenProcess } from '../../lib/codegen.js';
|
|
12
12
|
import { getAllEnvironmentVariables } from '../../lib/environment-variables.js';
|
|
13
13
|
import { displayDevUpgradeNotice } from './upgrade.js';
|
|
@@ -65,7 +65,6 @@ class Dev extends Command {
|
|
|
65
65
|
default: false
|
|
66
66
|
}),
|
|
67
67
|
// For the classic compiler:
|
|
68
|
-
worker: deprecated("--worker", { isBoolean: true }),
|
|
69
68
|
...overrideFlag(commonFlags.legacyRuntime, {
|
|
70
69
|
"legacy-runtime": {
|
|
71
70
|
description: "[Classic Remix Compiler] " + commonFlags.legacyRuntime["legacy-runtime"].description
|
|
@@ -5,7 +5,7 @@ import { outputInfo } from '@shopify/cli-kit/node/output';
|
|
|
5
5
|
import { resolvePath, joinPath } from '@shopify/cli-kit/node/path';
|
|
6
6
|
import { setH2OVerbose, isH2Verbose, muteDevLogs } from '../../lib/log.js';
|
|
7
7
|
import { getProjectPaths, isClassicProject } from '../../lib/remix-config.js';
|
|
8
|
-
import { commonFlags,
|
|
8
|
+
import { commonFlags, overrideFlag, flagsToCamelObject, DEFAULT_APP_PORT } from '../../lib/flags.js';
|
|
9
9
|
import { startMiniOxygen } from '../../lib/mini-oxygen/index.js';
|
|
10
10
|
import { getAllEnvironmentVariables } from '../../lib/environment-variables.js';
|
|
11
11
|
import { getConfig } from '../../lib/shopify-config.js';
|
|
@@ -23,7 +23,6 @@ class Preview extends Command {
|
|
|
23
23
|
static flags = {
|
|
24
24
|
...commonFlags.path,
|
|
25
25
|
...commonFlags.port,
|
|
26
|
-
worker: deprecated("--worker", { isBoolean: true }),
|
|
27
26
|
...commonFlags.legacyRuntime,
|
|
28
27
|
...commonFlags.env,
|
|
29
28
|
...commonFlags.envBranch,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as _oclif_core from '@oclif/core';
|
|
2
2
|
import * as _oclif_core_lib_interfaces_parser_js from '@oclif/core/lib/interfaces/parser.js';
|
|
3
3
|
import Command from '@shopify/cli-kit/node/base-command';
|
|
4
|
-
import * as _oclif_core_lib_interfaces_alphabet_js from '@oclif/core/lib/interfaces/alphabet.js';
|
|
5
4
|
import Init from './commands/hydrogen/init.js';
|
|
6
5
|
import '@shopify/cli-kit/node/node-package-manager';
|
|
7
6
|
|
|
@@ -89,37 +88,6 @@ declare class Dev extends Command {
|
|
|
89
88
|
'legacy-runtime': _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
|
90
89
|
host: _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
|
91
90
|
'disable-deps-optimizer': _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
|
92
|
-
worker: {
|
|
93
|
-
type: "option";
|
|
94
|
-
name: string;
|
|
95
|
-
char?: _oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase;
|
|
96
|
-
summary?: string;
|
|
97
|
-
description?: string;
|
|
98
|
-
helpLabel?: string;
|
|
99
|
-
helpGroup?: string;
|
|
100
|
-
env?: string;
|
|
101
|
-
hidden?: boolean;
|
|
102
|
-
required?: boolean;
|
|
103
|
-
dependsOn?: string[];
|
|
104
|
-
exclusive?: string[];
|
|
105
|
-
exactlyOne?: string[];
|
|
106
|
-
relationships?: _oclif_core_lib_interfaces_parser_js.Relationship[];
|
|
107
|
-
deprecated?: true | _oclif_core_lib_interfaces_parser_js.Deprecation;
|
|
108
|
-
aliases?: string[];
|
|
109
|
-
charAliases?: (_oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase)[];
|
|
110
|
-
deprecateAliases?: boolean;
|
|
111
|
-
noCacheDefault?: boolean;
|
|
112
|
-
helpValue?: string;
|
|
113
|
-
options?: readonly string[];
|
|
114
|
-
multiple?: boolean;
|
|
115
|
-
multipleNonGreedy?: boolean;
|
|
116
|
-
delimiter?: ",";
|
|
117
|
-
allowStdin?: boolean | "only";
|
|
118
|
-
parse: _oclif_core_lib_interfaces_parser_js.FlagParser<unknown, string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
|
119
|
-
defaultHelp?: unknown;
|
|
120
|
-
input: string[];
|
|
121
|
-
default?: unknown;
|
|
122
|
-
};
|
|
123
91
|
verbose: _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
|
124
92
|
'customer-account-push__unstable': _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
|
125
93
|
diff: _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
|
@@ -264,37 +232,6 @@ declare class Preview extends Command {
|
|
|
264
232
|
'env-branch': _oclif_core_lib_interfaces_parser_js.OptionFlag<string | undefined, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
|
265
233
|
env: _oclif_core_lib_interfaces_parser_js.OptionFlag<string | undefined, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
|
266
234
|
'legacy-runtime': _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
|
267
|
-
worker: {
|
|
268
|
-
type: "option";
|
|
269
|
-
name: string;
|
|
270
|
-
char?: _oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase;
|
|
271
|
-
summary?: string;
|
|
272
|
-
description?: string;
|
|
273
|
-
helpLabel?: string;
|
|
274
|
-
helpGroup?: string;
|
|
275
|
-
env?: string;
|
|
276
|
-
hidden?: boolean;
|
|
277
|
-
required?: boolean;
|
|
278
|
-
dependsOn?: string[];
|
|
279
|
-
exclusive?: string[];
|
|
280
|
-
exactlyOne?: string[];
|
|
281
|
-
relationships?: _oclif_core_lib_interfaces_parser_js.Relationship[];
|
|
282
|
-
deprecated?: true | _oclif_core_lib_interfaces_parser_js.Deprecation;
|
|
283
|
-
aliases?: string[];
|
|
284
|
-
charAliases?: (_oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase)[];
|
|
285
|
-
deprecateAliases?: boolean;
|
|
286
|
-
noCacheDefault?: boolean;
|
|
287
|
-
helpValue?: string;
|
|
288
|
-
options?: readonly string[];
|
|
289
|
-
multiple?: boolean;
|
|
290
|
-
multipleNonGreedy?: boolean;
|
|
291
|
-
delimiter?: ",";
|
|
292
|
-
allowStdin?: boolean | "only";
|
|
293
|
-
parse: _oclif_core_lib_interfaces_parser_js.FlagParser<unknown, string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
|
294
|
-
defaultHelp?: unknown;
|
|
295
|
-
input: string[];
|
|
296
|
-
default?: unknown;
|
|
297
|
-
};
|
|
298
235
|
port: _oclif_core_lib_interfaces_parser_js.OptionFlag<number | undefined, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
|
299
236
|
path: _oclif_core_lib_interfaces_parser_js.OptionFlag<string | undefined, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
|
300
237
|
};
|
|
@@ -5,7 +5,7 @@ import { getPackageManager } from '@shopify/cli-kit/node/node-package-manager';
|
|
|
5
5
|
import colors from '@shopify/cli-kit/node/colors';
|
|
6
6
|
import { getProjectPaths, getRemixConfig, handleRemixImportFail, assertOxygenChecks } from '../remix-config.js';
|
|
7
7
|
import { checkLockfileStatus } from '../check-lockfile.js';
|
|
8
|
-
import { findMissingRoutes } from '../
|
|
8
|
+
import { findMissingRoutes } from '../route-validator.js';
|
|
9
9
|
import { muteRemixLogs, createRemixLogger } from '../log.js';
|
|
10
10
|
import { codegen } from '../codegen.js';
|
|
11
11
|
import { classicBuildBundleAnalysis, classicGetBundleAnalysisSummary } from '../bundle/analyzer.js';
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { renderWarning, renderSuccess } from '@shopify/cli-kit/node/ui';
|
|
2
2
|
|
|
3
|
+
const RESERVED_ROUTES = ["^api/[^/]+/graphql.json", "^cdn/", "^_t/"];
|
|
4
|
+
function findReservedRoutes(config) {
|
|
5
|
+
const routes = /* @__PURE__ */ new Set();
|
|
6
|
+
Object.values(config.routes).filter(
|
|
7
|
+
(route) => RESERVED_ROUTES.some(
|
|
8
|
+
(pattern) => new RegExp(pattern).test(route.path ?? "")
|
|
9
|
+
)
|
|
10
|
+
).forEach((route) => {
|
|
11
|
+
if (route.path) {
|
|
12
|
+
routes.add(route.path);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return [...routes];
|
|
16
|
+
}
|
|
3
17
|
const REQUIRED_ROUTES = [
|
|
4
18
|
"",
|
|
5
19
|
"cart",
|
|
@@ -84,5 +98,17 @@ Including these routes improves compatibility with Shopify\u2019s platform:
|
|
|
84
98
|
});
|
|
85
99
|
}
|
|
86
100
|
}
|
|
101
|
+
function warnReservedRoutes(routes) {
|
|
102
|
+
if (routes.length) {
|
|
103
|
+
renderWarning({
|
|
104
|
+
headline: "Reserved routes present",
|
|
105
|
+
body: `Your Hydrogen project is using ${routes.length} reserved route${routes.length > 1 ? "s" : ""}.
|
|
106
|
+
These routes are reserved by Shopify and may cause issues with your storefront:
|
|
107
|
+
|
|
108
|
+
` + routes.slice(0, LINE_LIMIT - (routes.length <= LINE_LIMIT ? 0 : 1)).map((route) => `\u2022 /${route}`).join("\n") + (routes.length > LINE_LIMIT ? `
|
|
109
|
+
\u2022 ...and ${routes.length - LINE_LIMIT + 1} more` : "")
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
87
113
|
|
|
88
|
-
export { findMissingRoutes, logMissingRoutes };
|
|
114
|
+
export { findMissingRoutes, findReservedRoutes, logMissingRoutes, warnReservedRoutes };
|
|
@@ -22,7 +22,7 @@ const ROUTE_MAP = {
|
|
|
22
22
|
account: "account*",
|
|
23
23
|
search: ["search", "api.predictive-search"],
|
|
24
24
|
robots: "[robots.txt]",
|
|
25
|
-
sitemap: "[sitemap.xml]"
|
|
25
|
+
sitemap: ["[sitemap.xml]", "sitemap.$type.$page[.xml]"]
|
|
26
26
|
};
|
|
27
27
|
let allRouteTemplateFiles = [];
|
|
28
28
|
async function getResolvedRoutes(routeKeys = Object.keys(ROUTE_MAP)) {
|
package/oclif.manifest.json
CHANGED
|
@@ -369,7 +369,7 @@
|
|
|
369
369
|
"type": "option"
|
|
370
370
|
},
|
|
371
371
|
"preview": {
|
|
372
|
-
"description": "Deploys to the Preview environment.
|
|
372
|
+
"description": "Deploys to the Preview environment.",
|
|
373
373
|
"name": "preview",
|
|
374
374
|
"required": false,
|
|
375
375
|
"allowNo": false,
|
|
@@ -669,11 +669,6 @@
|
|
|
669
669
|
"allowNo": false,
|
|
670
670
|
"type": "boolean"
|
|
671
671
|
},
|
|
672
|
-
"worker": {
|
|
673
|
-
"hidden": true,
|
|
674
|
-
"name": "worker",
|
|
675
|
-
"type": "boolean"
|
|
676
|
-
},
|
|
677
672
|
"legacy-runtime": {
|
|
678
673
|
"description": "[Classic Remix Compiler] Runs the app in a Node.js sandbox instead of an Oxygen worker.",
|
|
679
674
|
"env": "SHOPIFY_HYDROGEN_FLAG_LEGACY_RUNTIME",
|
|
@@ -1323,11 +1318,6 @@
|
|
|
1323
1318
|
"multiple": false,
|
|
1324
1319
|
"type": "option"
|
|
1325
1320
|
},
|
|
1326
|
-
"worker": {
|
|
1327
|
-
"hidden": true,
|
|
1328
|
-
"name": "worker",
|
|
1329
|
-
"type": "boolean"
|
|
1330
|
-
},
|
|
1331
1321
|
"legacy-runtime": {
|
|
1332
1322
|
"description": "Runs the app in a Node.js sandbox instead of an Oxygen worker.",
|
|
1333
1323
|
"env": "SHOPIFY_HYDROGEN_FLAG_LEGACY_RUNTIME",
|
|
@@ -1758,5 +1748,5 @@
|
|
|
1758
1748
|
]
|
|
1759
1749
|
}
|
|
1760
1750
|
},
|
|
1761
|
-
"version": "
|
|
1751
|
+
"version": "9.0.0"
|
|
1762
1752
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"@shopify:registry": "https://registry.npmjs.org"
|
|
6
6
|
},
|
|
7
|
-
"version": "
|
|
7
|
+
"version": "9.0.0",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"test:watch": "cross-env SHOPIFY_UNIT_TEST=1 vitest --test-timeout=60000"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@remix-run/dev": "^2.
|
|
19
|
+
"@remix-run/dev": "^2.13.1",
|
|
20
20
|
"@types/diff": "^5.0.2",
|
|
21
21
|
"@types/gunzip-maybe": "^1.4.0",
|
|
22
22
|
"@types/prettier": "^2.7.2",
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"fast-glob": "^3.2.12",
|
|
28
28
|
"flame-chart-js": "2.3.2",
|
|
29
29
|
"get-port": "^7.0.0",
|
|
30
|
-
"type-fest": "^4.
|
|
30
|
+
"type-fest": "^4.26.1",
|
|
31
31
|
"vite": "^5.1.0",
|
|
32
32
|
"vitest": "^1.0.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@ast-grep/napi": "0.11.0",
|
|
36
36
|
"@oclif/core": "3.26.5",
|
|
37
|
-
"@shopify/cli
|
|
38
|
-
"@shopify/oxygen-cli": "4.
|
|
39
|
-
"@shopify/plugin-cloudflare": "3.
|
|
37
|
+
"@shopify/cli": "3.69.2",
|
|
38
|
+
"@shopify/oxygen-cli": "4.5.3",
|
|
39
|
+
"@shopify/plugin-cloudflare": "3.69.2",
|
|
40
40
|
"ansi-escapes": "^6.2.0",
|
|
41
41
|
"chokidar": "3.5.3",
|
|
42
42
|
"cli-truncate": "^4.0.0",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"@graphql-codegen/cli": "^5.0.2",
|
|
57
57
|
"@remix-run/dev": "^2.1.0",
|
|
58
|
-
"@shopify/hydrogen-codegen": "^0.3.
|
|
59
|
-
"@shopify/mini-oxygen": "^3.0
|
|
58
|
+
"@shopify/hydrogen-codegen": "^0.3.2",
|
|
59
|
+
"@shopify/mini-oxygen": "^3.1.0",
|
|
60
60
|
"graphql-config": "^5.0.3",
|
|
61
61
|
"vite": "^5.1.0"
|
|
62
62
|
},
|