@graphcommerce/magento-store 5.2.0-canary.16 → 5.2.0-canary.18
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/CHANGELOG.md +8 -0
- package/package.json +8 -8
- package/utils/redirectOrNotFound.ts +65 -54
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 5.2.0-canary.18
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1790](https://github.com/graphcommerce-org/graphcommerce/pull/1790) [`875a595da`](https://github.com/graphcommerce-org/graphcommerce/commit/875a595da5f52b77bc2535cf4a660267b0046a1e) - ApolloClient cache would balloon with all redirects and make sure redirects work ([@LaurensFranken](https://github.com/LaurensFranken))
|
|
8
|
+
|
|
9
|
+
## 5.2.0-canary.17
|
|
10
|
+
|
|
3
11
|
## 5.2.0-canary.16
|
|
4
12
|
|
|
5
13
|
## 5.2.0-canary.15
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/magento-store",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "5.2.0-canary.
|
|
5
|
+
"version": "5.2.0-canary.18",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -12,15 +12,15 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@graphcommerce/eslint-config-pwa": "5.2.0-canary.
|
|
16
|
-
"@graphcommerce/prettier-config-pwa": "5.2.0-canary.
|
|
17
|
-
"@graphcommerce/typescript-config-pwa": "5.2.0-canary.
|
|
15
|
+
"@graphcommerce/eslint-config-pwa": "5.2.0-canary.18",
|
|
16
|
+
"@graphcommerce/prettier-config-pwa": "5.2.0-canary.18",
|
|
17
|
+
"@graphcommerce/typescript-config-pwa": "5.2.0-canary.18"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@graphcommerce/graphql": "5.2.0-canary.
|
|
21
|
-
"@graphcommerce/graphql-mesh": "5.2.0-canary.
|
|
22
|
-
"@graphcommerce/image": "5.2.0-canary.
|
|
23
|
-
"@graphcommerce/next-ui": "5.2.0-canary.
|
|
20
|
+
"@graphcommerce/graphql": "5.2.0-canary.18",
|
|
21
|
+
"@graphcommerce/graphql-mesh": "5.2.0-canary.18",
|
|
22
|
+
"@graphcommerce/image": "5.2.0-canary.18",
|
|
23
|
+
"@graphcommerce/next-ui": "5.2.0-canary.18"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@lingui/react": "^3.13.2",
|
|
@@ -11,20 +11,25 @@ export type RedirectOr404Return = Promise<
|
|
|
11
11
|
| { notFound: true; revalidate?: number | boolean }
|
|
12
12
|
>
|
|
13
13
|
|
|
14
|
-
const notFound = () => {
|
|
14
|
+
const notFound = (from: string, reason: string) => {
|
|
15
15
|
flushMeasurePerf()
|
|
16
|
+
console.log(`[redirectOrNotFound: /${from}] ${reason}`)
|
|
16
17
|
return { notFound: true, revalidate: 60 * 20 } as const
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
const redirect = (to: string, permanent: boolean, locale?: string) => {
|
|
20
|
+
const redirect = (from: string, to: string, permanent: boolean, locale?: string) => {
|
|
20
21
|
const prefix = locale === defaultLocale() ? '' : `/${locale}`
|
|
21
22
|
const destination = `${prefix}${to}`
|
|
22
23
|
|
|
23
24
|
flushMeasurePerf()
|
|
24
25
|
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
27
|
+
console.log(
|
|
28
|
+
`[redirectOrNotFound: /${prefix}/${from}] ${
|
|
29
|
+
permanent ? 'Permanent' : 'Temporary'
|
|
30
|
+
} redirect to ${destination}`,
|
|
31
|
+
)
|
|
25
32
|
if (process.env.NODE_ENV === 'development') {
|
|
26
|
-
// eslint-disable-next-line no-console
|
|
27
|
-
console.log(`${permanent ? 'Permanent' : 'Temporary'} redirect to ${to}`)
|
|
28
33
|
// eslint-disable-next-line no-param-reassign
|
|
29
34
|
permanent = false
|
|
30
35
|
}
|
|
@@ -37,75 +42,81 @@ export async function redirectOrNotFound(
|
|
|
37
42
|
params?: ParsedUrlQuery,
|
|
38
43
|
locale?: string,
|
|
39
44
|
): RedirectOr404Return {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.join('/')
|
|
45
|
+
// Create a URL from the params provided.
|
|
46
|
+
const from = Object.values(params ?? {})
|
|
47
|
+
.map((v) => (Array.isArray(v) ? v.join('/') : v))
|
|
48
|
+
.join('/')
|
|
45
49
|
|
|
50
|
+
try {
|
|
46
51
|
// Get the configured suffixes from the store config
|
|
47
52
|
const { product_url_suffix: prodSuffix, category_url_suffix: catSuffix } =
|
|
48
53
|
(await client.query({ query: StoreConfigDocument })).data.storeConfig ?? {}
|
|
49
54
|
|
|
50
|
-
const candidates = new Set([
|
|
55
|
+
const candidates = new Set([from])
|
|
51
56
|
|
|
52
|
-
// If the
|
|
53
|
-
// if the
|
|
57
|
+
// If the incomming URL contains a suffix, we check if the URL without the suffix exists
|
|
58
|
+
// if the incomming URL does not contain a suffix, we check if the URL with the suffix exists
|
|
54
59
|
const suffixes = [prodSuffix, catSuffix].filter(nonNullable)
|
|
55
60
|
suffixes.forEach((suffix) => {
|
|
56
|
-
candidates.add(
|
|
57
|
-
urlKey.endsWith(suffix) ? urlKey.slice(0, -suffix.length) : `${urlKey}${suffix}`,
|
|
58
|
-
)
|
|
61
|
+
candidates.add(from.endsWith(suffix) ? from.slice(0, -suffix.length) : `${from}${suffix}`)
|
|
59
62
|
})
|
|
60
63
|
|
|
61
|
-
const routePromises = [...candidates].map(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
const routePromises = [...candidates].map(
|
|
65
|
+
async (url) =>
|
|
66
|
+
(
|
|
67
|
+
await client.query({
|
|
68
|
+
query: HandleRedirectDocument,
|
|
69
|
+
variables: { url },
|
|
70
|
+
fetchPolicy: 'no-cache',
|
|
71
|
+
})
|
|
72
|
+
).data,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
const routeData = (await Promise.all(routePromises)).find(nonNullable)
|
|
76
|
+
|
|
77
|
+
if (!routeData?.route)
|
|
78
|
+
return notFound(
|
|
79
|
+
from,
|
|
80
|
+
`no redirect candidates found for these paths: ${[...candidates.values()].join(',')}`,
|
|
81
|
+
)
|
|
68
82
|
|
|
69
|
-
const
|
|
70
|
-
routeData
|
|
83
|
+
const redirectUrl =
|
|
84
|
+
routeData?.route?.relative_url && routeData?.route?.relative_url !== from
|
|
71
85
|
? routeData.route.relative_url
|
|
72
86
|
: undefined
|
|
73
87
|
|
|
74
88
|
// There is a URL, so we need to check if it can be found in the database.
|
|
75
89
|
const permanent = routeData.route?.redirect_code === 301
|
|
76
90
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
'DownloadableProduct',
|
|
86
|
-
])
|
|
87
|
-
) {
|
|
88
|
-
if (process.env.NEXT_PUBLIC_SINGLE_PRODUCT_PAGE !== '1') {
|
|
89
|
-
console.warn('Redirects are only supported for NEXT_PUBLIC_SINGLE_PRODUCT_PAGE')
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (relativeUrl) {
|
|
93
|
-
return redirect(`/p/${relativeUrl}`, permanent, locale)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (routeData.products?.items?.find((i) => i?.url_key === routeData.route?.url_key)) {
|
|
97
|
-
return redirect(`/p/${routeData.route?.url_key}`, permanent, locale)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return notFound()
|
|
101
|
-
}
|
|
91
|
+
const isProduct = isTypename(routeData.route, [
|
|
92
|
+
'ConfigurableProduct',
|
|
93
|
+
'BundleProduct',
|
|
94
|
+
'SimpleProduct',
|
|
95
|
+
'VirtualProduct',
|
|
96
|
+
'DownloadableProduct',
|
|
97
|
+
'GroupedProduct',
|
|
98
|
+
])
|
|
102
99
|
|
|
103
|
-
if (
|
|
104
|
-
|
|
100
|
+
if (isProduct) {
|
|
101
|
+
if (process.env.NEXT_PUBLIC_SINGLE_PRODUCT_PAGE !== '1')
|
|
102
|
+
return notFound(from, 'Redirects are only supported for single product pages.')
|
|
103
|
+
|
|
104
|
+
if (redirectUrl) return redirect(from, `/p/${redirectUrl}`, permanent, locale)
|
|
105
|
+
|
|
106
|
+
if (!routeData.products?.items?.find((i) => i?.url_key === routeData.route?.url_key))
|
|
107
|
+
return notFound(from, `Route found, but product isn't returned from products query`)
|
|
108
|
+
|
|
109
|
+
return redirect(from, `/p/${routeData.route?.url_key}`, true, locale)
|
|
105
110
|
}
|
|
111
|
+
|
|
112
|
+
if (redirectUrl) return redirect(from, `/${redirectUrl}`, permanent, locale)
|
|
113
|
+
|
|
114
|
+
return notFound(from, `Route found, but no redirect URL`)
|
|
106
115
|
} catch (e) {
|
|
107
|
-
|
|
116
|
+
if (e instanceof Error) {
|
|
117
|
+
return notFound(from, `Error while redirecting: ${e.message}`)
|
|
118
|
+
}
|
|
119
|
+
console.log(e)
|
|
120
|
+
return notFound(from, `Error while redirecting`)
|
|
108
121
|
}
|
|
109
|
-
|
|
110
|
-
return notFound()
|
|
111
122
|
}
|