[BUG] @shopware/api-gen not behaving as expected when applying multiple patches.
Current Behavior
The @shopware/api-gen package doesn't work when two patches affect the same schema.
Expected Behavior
I found the patch linked by the npm package here: https://raw.githubusercontent.com/shopware/frontends/main/packages/api-client/api-types/storeApiSchema.overrides.json
But I also want to customize the customFields property to our needs. You can see a minimal example in this repository
(storeApiTypes.overrides.json). Since both apply changes to the Product schema, only the first one (in this case the
shopware default patch) is applied.
Simply checkout this repository and run
pnpm api:generate
The result is the applied patch including the one for calculatedCheapestPrice, but not the patch for customFields.
Swap the order of both patches in api-gen.config.json and the result will change. Now the patch for customFields is
applied but not the patch for calculatedCheapestPrice.
I really don't understand the underlying mechanic as I expected it to apply patches by simply deepmerging all patches
after each other into the storeApiSchema.json and then generating the storeApiTypes.d.ts based on the openAPI specs.
The documentation of @shopware/api-gen states the following:
Partial overrides are applied directly to the JSON schema, so the syntax needs to be correct
Why do I have to use a different schema than the storeApiSchema.json?
The structure there is:
{
"components": {
"schemas": {
"Product": {}
}
}
}
whereas the storeApiTypes.overrides.json requires the following structure:
{
"components": {
"Products": {}
}
}
If I use the same structure as originally defined, it doesn't work at all.
Steps To Reproduce
- Checkout my reproduction repository: https://github.com/max-zinn/api-gen-patch-bug
- read the README.md, it should give enough explanation on the issue.
Anything else?
No response
hey @max-zinn looking at the overrides we currently can override:
- components
- patches
Here's more info on that: https://github.com/shopware/frontends/tree/main/packages/api-gen#partial-overrides
What is the problem in your case:
- you named component
CustomFieldsinstead ofCustomFieldwhen you extended it (but still can be like this if you want) - the problem was
Productoverriding - it already has patches, so you should add yours in array
Working override for you would be (although I would suggest to change CustomFIelds to CustomField):
{
"components": {
"Product": [
{
"properties": {
"customFields": {
"$ref": "#/components/schemas/CustomFields"
}
}
}
],
"CustomFields": {
"properties": {
"my_custom_field": {
"type": "string",
"required": true
}
}
}
}
}
so result is:
Hey @patzick, thanks for the clarification. I understood the documentation as "you can choose array or object syntax to your preferences".
The documentation didn't state that every patch file needs to have the same format of applying patches.
you apply this as 2 independent patches, or combine it as a single patch without array:
I just tested this out and both patch files get only applied if they follow the same structure.
Example:
given this api-gen.config.json
{
"$schema": "https://raw.githubusercontent.com/shopware/frontends/main/packages/api-gen/api-gen.schema.json",
"patches": ["api-types/storeApiTypes2.overrides.json", "api-types/storeApiTypes3.overrides.json"]
}
Following are four variants where there are issues I got confused with:
// api-types/storeApiTypes2.overrides.json
{
"components": {
"Product": {
"required": ["weight"]
}
}
}
// api-types/storeApiTypes3.overrides.json
{
"components": {
"Product": {
"required": ["versionId"]
}
}
}
This works because both files use object syntax for patching the product
// api-types/storeApiTypes2.overrides.json
{
"components": {
"Product": [
{
"required": ["weight"]
}
]
}
}
// api-types/storeApiTypes3.overrides.json
{
"components": {
"Product": [
{
"required": ["versionId"]
}
]
}
}
This also works because both files use array syntax
// api-types/storeApiTypes2.overrides.json
{
"components": {
"Product": {
"required": ["weight"]
}
}
}
// api-types/storeApiTypes3.overrides.json
{
"components": {
"Product": [
{
"required": ["versionId"]
}
]
}
}
This doesn't work, only the first patch is applied
// api-types/storeApiTypes2.overrides.json
{
"components": {
"Product": [
{
"required": ["weight"]
}
]
}
}
// api-types/storeApiTypes3.overrides.json
{
"components": {
"Product": {
"required": ["versionId"]
}
}
}
This doesn't work, only the first patch is applied
If this is intended behaviour, I'd highly suggest updating the README to clearly state this.
I can create a PR with a suggestion for the README.md if you like.
Regarding
you named component CustomFields instead of CustomField when you extended it (but still can be like this if you want)
I didn't want to extendd the existing CustomField because it's not used anywhere in the storeApiSchema.json but since it's a type in the generated output, I have no idea where this type might be used and my change could break something else.
It had no reference to the Product schema as well so I figured I create CustomFields as a new type and $ref it to the Product schema.
that's also fine, it just looked like a typo ;)
So it that working for you in current shape?
sorry missed you typed two comments :)
yes, you're right about not clear info. You're use case is totally valid. I think we can solve this on merging patches - so if there already is patch for specific route we can enforce array under the hood. That's why I'm not closing that one yet as well 🙌
Sounds good, thanks! In any way, I already made some changes to the README.md and posted a PR. It's up to you if you want to accept it and/or make the changes :)
Happy weekend!