-
Notifications
You must be signed in to change notification settings - Fork 20
Fix magento #1229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix magento #1229
Changes from all commits
3bc38b1
d991a39
d4a4d64
ff0ee77
58ab6cd
22295f6
25f7eff
2f80287
3d25fb1
c14167d
06bac79
406ba74
bedb938
348f60e
66115eb
2119b8c
b7c2179
c1d38d7
1207c78
748d73e
6439061
5cbe0c4
e75e261
ff812ad
64b2ab8
a374746
51d1f89
16b1870
3469b06
be4c86a
30241f6
155e704
13d1c67
5d6c389
4bc67b9
aa1b847
200fdce
cc22bdf
d75c070
841e1eb
6313069
9b6f63c
363b8ce
62e5b7a
d16bffb
b31f254
3de937e
7cd3d61
0018ed4
c558826
90a522a
05b002a
55b020d
3bb4092
758534e
c1427da
062a7c2
d4afb7a
dedab2a
263d43f
b7a7f8a
641d5e0
dfa0126
4c72d75
aa036a3
15aac88
4a9fc49
2b8efe9
dda9e42
1f50791
b2b8aaa
c9d0886
fe087e6
334a084
547d0b4
c350a50
5979978
680a455
93516e3
a92e6cb
281be66
7327cfa
2e4a54f
23cf73e
5594e9d
4740de7
1862e78
fd76a0f
0c2485d
d1fd632
8b4af89
6859a65
a7d62af
29f66d9
1fe1935
68db6a9
6a57333
36fa306
d77f46f
f5761aa
4f76c23
d4b9fb8
33d2550
c9921b7
a627bc7
8e17c01
a873b2c
54c077a
63292b8
08b4521
207e295
29233a6
77d305e
821ef5d
a5eeed8
1bb38d2
6336f7b
c47574d
c71f5d0
f40988e
52f2004
5a3f049
84bbfa2
ec71a40
53c8444
e178bc0
6ac6d73
5234070
982760e
d2c50be
804e2a5
c6dafb7
d7f0724
ec77d18
d20f382
d672044
9e8d039
00f58c2
1c5ad9e
09d09ea
ddbea98
ecad329
4653ef3
3ee7f21
9028aa2
86fddab
d5489a1
c2c8c0b
6454ce7
ebbe958
eeadf2e
0bfa281
a507126
e802844
9901f65
20e7cba
92bcb5d
001a81b
286f1d4
b506ac1
306b573
bae3a3d
811c72d
c0073d3
a100a28
1e5c5f0
95bc842
fcad203
92f36cc
08212db
8f13eb4
0ab00f5
ab3be7e
916ad95
2dfd29f
4483789
00cfd81
cbb08c8
81eca84
e0b70d9
9002535
c749eda
d810f8c
9ed5b5c
87ca199
bf22b63
79c0c46
26c8958
61547b1
92c5757
851be32
f24844d
7a1dbc9
95fc62f
e9e1ad3
7efc594
6aa264d
63bd5ae
58f886d
d4a4d09
4e5cae5
bf38c84
0d52e33
0e86a21
2eab4d3
577aa36
72c4237
c221f56
5b4c881
6b00b80
8adeb89
c7090fe
ffe62e6
57c4e1c
afd6afc
a0e93d9
df1d8b5
ae2aa3c
050e865
0c858c3
a19a629
2a524c8
cd2ab8f
ed7a706
aee931c
8f4d14a
a1479a3
ce3d492
85d965d
2e0c9c4
5179900
91250e4
af886e4
1c9bb7c
8f677fc
0522ce2
ca00e8d
a5b98a0
c7c5677
21a0599
dce76fe
7a6cff6
7647606
fe156be
d7ce899
10da010
dd97fc1
0bf931a
852da95
acab327
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,9 @@ | ||
| // deno-lint-ignore-file no-explicit-any | ||
| import { DecoRequestInit } from "./fetch.ts"; | ||
| import { createHttpClient, HttpClientOptions } from "./http.ts"; | ||
|
|
||
| const decoCacheArgLength = 55; | ||
|
|
||
| interface GraphqlClientOptions extends Omit<HttpClientOptions, "base"> { | ||
| endpoint: string; | ||
| } | ||
|
|
@@ -10,24 +13,33 @@ interface GraphQLResponse<D> { | |
| errors: unknown[]; | ||
| } | ||
|
|
||
| type GraphQLAPI<D = unknown> = Record<string, { | ||
| response: GraphQLResponse<D>; | ||
| body: { | ||
| query: string; | ||
| variables?: Record<string, unknown>; | ||
| operationName?: string; | ||
| }; | ||
| }>; | ||
| type GraphQLAPI<D = unknown> = Record< | ||
| string, | ||
| { | ||
| response: GraphQLResponse<D>; | ||
| body?: { | ||
| query: string; | ||
| variables?: Record<string, unknown>; | ||
| operationName?: string; | ||
| }; | ||
| } | ||
| >; | ||
|
|
||
| interface GraphQLQueryProps<V> { | ||
| query: string; | ||
| fragments?: string[]; | ||
| variables?: V; | ||
| operationName?: string; | ||
| } | ||
|
|
||
| export const gql = (query: TemplateStringsArray, ...fragments: string[]) => | ||
| query.reduce((a, c, i) => `${a}${fragments[i - 1]}${c}`); | ||
|
|
||
| export const createGraphqlClient = ( | ||
| { endpoint, ...rest }: GraphqlClientOptions, | ||
| ) => { | ||
| export const createGraphqlClient = ({ | ||
| endpoint, | ||
| ...rest | ||
| }: GraphqlClientOptions) => { | ||
| const url = new URL(endpoint); | ||
| const key = `POST ${url.pathname}`; | ||
|
|
||
| const defaultHeaders = new Headers(rest.headers); | ||
| defaultHeaders.set("content-type", "application/json"); | ||
| defaultHeaders.set("accept", "application/json"); | ||
|
|
@@ -40,21 +52,24 @@ export const createGraphqlClient = ( | |
|
|
||
| return { | ||
| query: async <D, V>( | ||
| { query = "", fragments = [], variables, operationName }: { | ||
| query: string; | ||
| fragments?: string[]; | ||
| variables?: V; | ||
| operationName?: string; | ||
| }, | ||
| init?: RequestInit, | ||
| { | ||
| query = "", | ||
| fragments = [], | ||
| variables, | ||
| operationName, | ||
| }: GraphQLQueryProps<V>, | ||
| init?: DecoRequestInit, | ||
| ): Promise<D> => { | ||
| const { data, errors } = await http[key as any]({}, { | ||
| ...init, | ||
| body: { | ||
| query: [query, ...fragments].join("\n"), | ||
| variables: variables as any, | ||
| operationName, | ||
| }, | ||
| const { key, props } = getMethodAndProps<V>({ | ||
| query, | ||
| fragments, | ||
| variables, | ||
| operationName, | ||
| url, | ||
| }); | ||
| const { searchParams, body } = getParamsAndBody({ key, props, init }); | ||
| const { data, errors } = await http[key as any](searchParams, { | ||
| ...body, | ||
| }).then((res) => res.json()); | ||
|
|
||
| if (Array.isArray(errors) && errors.length > 0) { | ||
|
|
@@ -65,3 +80,100 @@ export const createGraphqlClient = ( | |
| }, | ||
| }; | ||
| }; | ||
|
|
||
| const getMethodAndProps = <V>({ | ||
| query, | ||
| fragments, | ||
| url, | ||
| operationName, | ||
| variables, | ||
| }: GraphQLQueryProps<V> & { url: URL }) => { | ||
| const fullQuery = joinQueryArgs({ | ||
| query, | ||
| fragments, | ||
| }); | ||
| const stringfiedVariables = stringfyVariables<V>({ variables }); | ||
| const minifiedQuery = minifyString(fullQuery); | ||
| const postMethodBool = isPostMethodRequired( | ||
| url.href, | ||
| minifiedQuery, | ||
| stringfiedVariables, | ||
| operationName, | ||
| ); | ||
|
|
||
| const { key, executableQuery, executableVariables } = postMethodBool | ||
| ? { | ||
| key: `POST ${url.pathname}`, | ||
| executableQuery: fullQuery, | ||
| executableVariables: variables, | ||
| } | ||
| : { | ||
| key: `GET ${url.pathname}`, | ||
| executableQuery: minifiedQuery, | ||
| executableVariables: stringfiedVariables, | ||
| }; | ||
|
|
||
| return { | ||
| key, | ||
| props: { | ||
| query: executableQuery, | ||
| variables: executableVariables, | ||
| operationName, | ||
| }, | ||
| }; | ||
| }; | ||
|
|
||
| const getParamsAndBody = ({ | ||
| key, | ||
| props, | ||
| init, | ||
| }: ReturnType<typeof getMethodAndProps> & { init?: DecoRequestInit }) => { | ||
| if (key.startsWith("POST")) { | ||
| return { searchParams: {}, body: { body: props, ...init } }; | ||
| } | ||
| return { searchParams: { ...props }, body: { ...init } }; | ||
| }; | ||
|
Comment on lines
+126
to
+135
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Harden GET/POST param packing and avoid
Apply: -const getParamsAndBody = ({
+const getParamsAndBody = ({
key,
props,
init,
}: ReturnType<typeof getMethodAndProps> & { init?: DecoRequestInit }) => {
if (key.startsWith("POST")) {
- return { searchParams: {}, body: { body: props, ...init } };
+ const bodyJson = JSON.stringify(props);
+ return { searchParams: {}, init: { ...(init ?? {}), body: bodyJson } };
}
- return { searchParams: { ...props }, body: { ...init } };
+ const searchParams: Record<string, string> = {};
+ if (props.query) searchParams.query = props.query;
+ if (props.operationName) searchParams.operationName = props.operationName;
+ if (typeof props.variables === "string" && props.variables.length > 0) {
+ searchParams.variables = props.variables;
+ }
+ return { searchParams, init: { ...(init ?? {}) } };
};
🤖 Prompt for AI Agents |
||
|
|
||
| const minifyString = (s: string): string => { | ||
| s = s.replace( | ||
| /\{([^{}]*)\}/g, | ||
| (_, p1) => `{${p1.replace(/\s+/g, " ").trim()}}`, | ||
| ); | ||
| s = s | ||
| .replace(/[\r\n]+/g, " ") | ||
| .replace(/\s+/g, " ") | ||
| .replace(/\s*{\s*/g, "{") | ||
| .replace(/\s*}\s*/g, "}") | ||
| .replace(/\s*:\s*/g, ":") | ||
| .replace(/\s*\(\s*/g, "(") | ||
| .replace(/\s*\)\s*/g, ")"); | ||
| return s.trim(); | ||
| }; | ||
|
|
||
| const joinQueryArgs = ({ | ||
| query, | ||
| fragments = [], | ||
| }: Pick<GraphQLQueryProps<any>, "query" | "fragments">) => | ||
| [query, ...fragments].join("\n"); | ||
|
|
||
| const stringfyVariables = <V>({ | ||
| variables, | ||
| }: Pick<GraphQLQueryProps<V>, "variables">) => JSON.stringify(variables); | ||
|
|
||
| const isPostMethodRequired = ( | ||
| href: string, | ||
| query: string, | ||
| variables: string, | ||
| operationName?: string, | ||
| ): boolean => { | ||
| if (query.startsWith("mutation")) { | ||
| return true; | ||
| } | ||
|
|
||
| const urlLength = `${href}?query=${encodeURI(query)}&variables=${ | ||
| encodeURI( | ||
| variables, | ||
| ) | ||
| }&operationname=${operationName}`; | ||
| return urlLength.length + decoCacheArgLength > 2000; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -101,6 +101,20 @@ const optimizeVTEX = (opts: OptimizationOptions) => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return src.href; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const optimizeMagento = (opts: OptimizationOptions) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { originalSrc, width, height } = opts; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const url = new URL(originalSrc); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.searchParams.set("width", `${width}`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.searchParams.set("height", `${height}`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.searchParams.set("canvas", `${width}:${height}`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.searchParams.set("optimize", "low"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.searchParams.set("fit", opts.fit === "cover" ? "" : "bounds"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return url.href; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+104
to
+115
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle optional Line 110 constructs the Additionally, line 112 sets the 🔧 Proposed fix const optimizeMagento = (opts: OptimizationOptions) => {
const { originalSrc, width, height } = opts;
const url = new URL(originalSrc);
url.searchParams.set("width", `${width}`);
- url.searchParams.set("height", `${height}`);
- url.searchParams.set("canvas", `${width}:${height}`);
+ if (height) {
+ url.searchParams.set("height", `${height}`);
+ url.searchParams.set("canvas", `${width}:${height}`);
+ }
url.searchParams.set("optimize", "low");
- url.searchParams.set("fit", opts.fit === "cover" ? "" : "bounds");
+ if (opts.fit !== "cover") {
+ url.searchParams.set("fit", "bounds");
+ }
return url.href;
};📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const getOptimizedMediaUrl = (opts: OptimizationOptions) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { originalSrc, width, height, fit } = opts; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -109,6 +123,10 @@ export const getOptimizedMediaUrl = (opts: OptimizationOptions) => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!isImageOptmizationEnabled()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (originalSrc.includes("media/catalog/product")) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return optimizeMagento(opts); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (originalSrc.startsWith("https://cdn.vnda.")) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return optmizeVNDA(opts); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import type { FunctionContext, LoaderFunction } from "@deco/deco"; | ||
| import { RequestURLParam } from "./requestToParam.ts"; | ||
|
|
||
| export interface Props { | ||
| /** | ||
| * @description Path name to remove from the URL - Stringfied regex. Example: "/product/" transform "/product/my-sku" in "my-sku". "/product/|/store" transform "/product/my-sku/store" in "my-sku" | ||
| * @format dynamic-options | ||
| */ | ||
| pathname?: string; | ||
| } | ||
|
|
||
| /** | ||
| * @title Get params from request pathname. | ||
| * @description Set a pathname to remove from url and extract a slug | ||
| */ | ||
| const requestToParam: LoaderFunction< | ||
| Props, | ||
| RequestURLParam, | ||
| FunctionContext | ||
| > = (req, ctx) => { | ||
| const url = new URL(req.url); | ||
| const regex = new RegExp("(" + ctx.state.$live.pathname + ")", "g"); | ||
| return { | ||
| data: url.pathname.toString().replace(regex, ""), | ||
| }; | ||
| }; | ||
|
|
||
| export default requestToParam; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
POST body may not be JSON‑stringified;
init.bodycan override payload.getParamsAndBodyreturns{ body: props, ...init }for POST; ifcreateHttpClientdoesn’t stringify, requests may send[object Object]or fail....initafterbody: propscan replace the computed body.Ensure JSON string body and keep
propsas the final body.Apply:
And update helper (see next comment).