Skip to content

feat: validate subscription destinations and add the missing update actions - #426

Open
korsvanloon wants to merge 1 commit into
mainfrom
feat/subscription-destination-validation
Open

feat: validate subscription destinations and add the missing update actions#426
korsvanloon wants to merge 1 commit into
mainfrom
feat/subscription-destination-validation

Conversation

@korsvanloon

Copy link
Copy Markdown
Collaborator

Addresses the concrete half of #76.

Destination validation

src/schemas/generated/common.ts has DestinationSchema = z.object({ type: z.string() }) — the generator flattens the Destination union to its base type. So in strict mode a draft like

{ "destination": { "type": "SQS", "queueUrl": "https://…/orders" } }

was accepted, missing region entirely. That is the gap the issue describes: the Terraform provider sees no error when properties are missing.

The destination is now validated as a z.discriminatedUnion("type", …) over the seven types the SDK models: SQS, SNS, EventBridge, GoogleCloudPubSub, EventGrid, AzureServiceBus, ConfluentCloud. It lives in a hand-written src/schemas/subscription.ts (the generated directory says not to edit it) and extends SubscriptionDraftSchema, so everything else in the draft still uses the generated schema.

Note this only bites with strict: trueAbstractService.post only validates drafts in strict mode. Worth knowing for the Terraform provider's use of the mock.

Update actions

SubscriptionUpdateHandler only had setKey. Added changeDestination, setChanges, setEvents and setMessages, which is the full SubscriptionUpdateAction union.

What is left of #76

The issue asks for a "proper mock implementation" in general; delivering an actual test message to a destination (the TestDestination behaviour, currently faked by the hardcoded 0000000000 account id) is not part of this PR, so I have marked the commit Refs #76 rather than Fixes.

Coverage

subscription.test.ts: an incomplete SQS destination and an unknown destination type both rejected in strict mode, plus one test applying all five update actions in a single request.

Full suite: 793 passing.

@changeset-bot

changeset-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cd44ee2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@labdigital/commercetools-mock Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@korsvanloon

Copy link
Copy Markdown
Collaborator Author

Following up on the same point raised in #421 — whether this should come from the generator instead of being hand-written.

I checked, and the flattening is deliberate: generateDiscriminatedUnionSchema in scripts/generate-schemas.ts emits a real union only for a single variant, and for multiple variants it generates the base object shape. collectDependencies mirrors that, following the mapping only when there are five variants or fewer. Destination has eight, so it comes out as { type: string }. I regenerated against the current spec to confirm that is still the case, and it is.

So this PR keeps the hand-written schema, in src/schemas/ rather than src/schemas/generated/.

If you would rather have it come out of the generator, the change is contained to generateDiscriminatedUnionSchema plus the variant threshold — but it would turn every other discriminated union in the spec (FieldType, ShippingRateTier, ProductDiscountValue, CartDiscountValue, and so on) into a strict union at the same time. That is a real behaviour change for anyone running with strict: true, so it seemed like your call rather than something to slip into this PR. Happy to do it if you want it.

…ctions

The generated DestinationSchema is just { type: string }, because the spec models
Destination as a union and the generator flattens that to the base type. So even
in strict mode a draft whose destination was missing required properties was
accepted — which is the gap that started this issue: a consumer generating
subscriptions gets no error for an incomplete destination.

The destination is now checked against a discriminated union covering SQS, SNS,
EventBridge, GoogleCloudPubSub, EventGrid, AzureServiceBus and ConfluentCloud.
It lives in src/schemas/subscription.ts rather than in the generated directory,
and extends the generated draft schema so the rest of the draft keeps using it.

Also implements changeDestination, setChanges, setEvents and setMessages; setKey
was the only action the update handler had.

Refs #76
@korsvanloon
korsvanloon force-pushed the feat/subscription-destination-validation branch from 80050b4 to cd44ee2 Compare August 27, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant