feat(utils): Provide an utils that allows to convert an array of fields to a complete remote query object (#5161)
**What** For simplicity and compatibility with the front, the fields are stored as an array of strings containing the list of fields that should be selected by a query. In order to reduce the delta between this object shape and what is expected by the remoteQuery when passing an object, we built util to make the translation from fields to config. This will allow us to update the endpoint fields to specify what exactly needs to be selected and based on that we will be able to build the remote query object. Furthermore, it will allow us to drop back the functionality of custom fields and relations. we will still have to take into account the limit constraint of an url size including the parameters if a user want to select everything from a relation. In that case, we might maybe think about handling this case once the modules will export all available relations and fields so that the remote joiner would be able to pass them all automatically if the relation is present but a `*` is passed or no values in the fields during the translation with the util. But this is something we can come up in a separate iteration
This commit is contained in:
committed by
GitHub
parent
f5274c5b4f
commit
cc4169a94c
5
.changeset/lemon-spies-double.md
Normal file
5
.changeset/lemon-spies-double.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/utils": patch
|
||||
---
|
||||
|
||||
feat(utils): Provide an utils that allows to convert an array of fields to a complete remote query object
|
||||
@@ -0,0 +1,81 @@
|
||||
import { stringToRemoteQueryObject } from "../string-to-remote-query-object"
|
||||
|
||||
const fields = [
|
||||
"id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
"url",
|
||||
"metadata",
|
||||
"tags.id",
|
||||
"tags.created_at",
|
||||
"tags.updated_at",
|
||||
"tags.deleted_at",
|
||||
"tags.value",
|
||||
"options.id",
|
||||
"options.created_at",
|
||||
"options.updated_at",
|
||||
"options.deleted_at",
|
||||
"options.title",
|
||||
"options.product_id",
|
||||
"options.metadata",
|
||||
"options.values.id",
|
||||
"options.values.created_at",
|
||||
"options.values.updated_at",
|
||||
"options.values.deleted_at",
|
||||
"options.values.value",
|
||||
"options.values.option_id",
|
||||
"options.values.variant_id",
|
||||
"options.values.metadata",
|
||||
]
|
||||
|
||||
describe("stringToRemoteQueryObject", function () {
|
||||
it("should return a remote query object", function () {
|
||||
const output = stringToRemoteQueryObject({
|
||||
entryPoint: "product",
|
||||
variables: {},
|
||||
fields,
|
||||
})
|
||||
|
||||
expect(output).toEqual({
|
||||
product: {
|
||||
__args: {},
|
||||
fields: [
|
||||
"id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
"url",
|
||||
"metadata",
|
||||
],
|
||||
tags: {
|
||||
fields: ["id", "created_at", "updated_at", "deleted_at", "value"],
|
||||
},
|
||||
|
||||
options: {
|
||||
fields: [
|
||||
"id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
"title",
|
||||
"product_id",
|
||||
"metadata",
|
||||
],
|
||||
values: {
|
||||
fields: [
|
||||
"id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
"value",
|
||||
"option_id",
|
||||
"variant_id",
|
||||
"metadata",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
124
packages/utils/src/common/string-to-remote-query-object.ts
Normal file
124
packages/utils/src/common/string-to-remote-query-object.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Convert a string fields array to a remote query object
|
||||
* @param entryPoint
|
||||
* @param variables
|
||||
* @param fields
|
||||
*
|
||||
* @example
|
||||
* const fields = [
|
||||
* "id",
|
||||
* "created_at",
|
||||
* "updated_at",
|
||||
* "deleted_at",
|
||||
* "url",
|
||||
* "metadata",
|
||||
* "tags.id",
|
||||
* "tags.created_at",
|
||||
* "tags.updated_at",
|
||||
* "tags.deleted_at",
|
||||
* "tags.value",
|
||||
* "options.id",
|
||||
* "options.created_at",
|
||||
* "options.updated_at",
|
||||
* "options.deleted_at",
|
||||
* "options.title",
|
||||
* "options.product_id",
|
||||
* "options.metadata",
|
||||
* "options.values.id",
|
||||
* "options.values.created_at",
|
||||
* "options.values.updated_at",
|
||||
* "options.values.deleted_at",
|
||||
* "options.values.value",
|
||||
* "options.values.option_id",
|
||||
* "options.values.variant_id",
|
||||
* "options.values.metadata",
|
||||
* ]
|
||||
*
|
||||
* const remoteQueryObject = stringToRemoteQueryObject({
|
||||
* entryPoint: "product",
|
||||
* variables: {},
|
||||
* fields,
|
||||
* })
|
||||
*
|
||||
* console.log(remoteQueryObject)
|
||||
* // {
|
||||
* // product: {
|
||||
* // __args: {},
|
||||
* // fields: [
|
||||
* // "id",
|
||||
* // "created_at",
|
||||
* // "updated_at",
|
||||
* // "deleted_at",
|
||||
* // "url",
|
||||
* // "metadata",
|
||||
* // ],
|
||||
* //
|
||||
* // tags: {
|
||||
* // fields: ["id", "created_at", "updated_at", "deleted_at", "value"],
|
||||
* // },
|
||||
* //
|
||||
* // options: {
|
||||
* // fields: [
|
||||
* // "id",
|
||||
* // "created_at",
|
||||
* // "updated_at",
|
||||
* // "deleted_at",
|
||||
* // "title",
|
||||
* // "product_id",
|
||||
* // "metadata",
|
||||
* // ],
|
||||
* // values: {
|
||||
* // fields: [
|
||||
* // "id",
|
||||
* // "created_at",
|
||||
* // "updated_at",
|
||||
* // "deleted_at",
|
||||
* // "value",
|
||||
* // "option_id",
|
||||
* // "variant_id",
|
||||
* // "metadata",
|
||||
* // ],
|
||||
* // },
|
||||
* // },
|
||||
* // },
|
||||
* // }
|
||||
*/
|
||||
export function stringToRemoteQueryObject({
|
||||
entryPoint,
|
||||
variables,
|
||||
fields,
|
||||
}: {
|
||||
entryPoint: string
|
||||
variables?: any
|
||||
fields: string[]
|
||||
}): object {
|
||||
const remoteJoinerConfig: object = {
|
||||
[entryPoint]: {
|
||||
fields: [],
|
||||
},
|
||||
}
|
||||
|
||||
if (variables) {
|
||||
remoteJoinerConfig[entryPoint]["__args"] = variables
|
||||
}
|
||||
|
||||
for (const field of fields) {
|
||||
if (!field.includes(".")) {
|
||||
remoteJoinerConfig[entryPoint]["fields"].push(field)
|
||||
continue
|
||||
}
|
||||
|
||||
const fieldSegments = field.split(".")
|
||||
const fieldProperty = fieldSegments.pop()
|
||||
|
||||
const deepConfigRef = fieldSegments.reduce((acc, curr) => {
|
||||
acc[curr] ??= {}
|
||||
return acc[curr]
|
||||
}, remoteJoinerConfig[entryPoint])
|
||||
|
||||
deepConfigRef["fields"] ??= []
|
||||
deepConfigRef["fields"].push(fieldProperty)
|
||||
}
|
||||
|
||||
return remoteJoinerConfig
|
||||
}
|
||||
Reference in New Issue
Block a user