Fix: Collapse CDN Zones spec onto one tag to unblock generation (@W-23234552@) - #453
#453Fix: Collapse CDN Zones spec onto one tag to unblock generation (@W-23234552@)#453joeluong-sfcc merged 3 commits intomainSalesforceCommerceCloud/commerce-sdk:mainfrom ju/cdn-zones-classname-W-23234552SalesforceCommerceCloud/commerce-sdk:ju/cdn-zones-classname-W-23234552Copy head branch name to clipboard
Conversation
824e2f8 to
a559f45
Compare
…llision (@W-23234552@)
The Zones OAS spec ships with a spec-level `x-sdk-classname: CDNZones` that
openapi-generator threads to every emitted API file's class. When the spec's
operations are split across multiple tags (as of zones-oas 1.3.0 introducing
a `Turnstile` tag), the generator emits one file per tag, each declaring
`export class CDNZones` — causing the auto-generated barrel to fail
`TS2308` on the duplicate name and blocking any bump past 1.2.0.
Passing `--openapi-normalizer SET_TAGS_FOR_ALL_OPERATIONS=zones` to the
generator for the Zones spec forces every operation onto one tag, so the
generator emits a single `ZonesApi.ts` with all operations (Turnstile ops
included) on one class. Consumer surface is unchanged: `import { CDNZones }
from "commerce-sdk"` resolves through the same barrel chain to the same
class.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a559f45 to
0c1a593
Compare
| * preserves the DefaultApi.ts filename shared with every other spec. | ||
| */ | ||
| export function resolveGeneratorFlags(apiSpecDetail: ApiSpecDetail): string { | ||
| if (apiSpecDetail.name === ZONES_SPEC_NAME) { |
There was a problem hiding this comment.
nit: this matches on name ("Zones OAS"). If Zones ever ships as v2, name becomes "Zones OAS V2" (see getAPIDetailsFromExchange), this check is skipped, and the bug comes back with no failing test.
apiName is always "CDNZones" no matter the version, so it is safer. Bonus: it also covers the old "CDN API - Process APIs OAS" name that resolveApiName maps to CDNZones too.
| if (apiSpecDetail.name === ZONES_SPEC_NAME) { | |
| if (apiSpecDetail.apiName === "CDNZones") { |
There was a problem hiding this comment.
Good catch, done — resolveGeneratorFlags now keys off apiSpecDetail.apiName === "CDNZones", so a future Zones v2 rename and the legacy "CDN API - Process APIs OAS" title are both covered.
| expect(flags).to.include("--reserved-words-mappings delete=delete"); | ||
| }); | ||
|
|
||
| it("returns the base flags unchanged for every other spec", () => { |
There was a problem hiding this comment.
Nice test. If you switch the check to apiName, consider adding one more case for a "Zones OAS V2" spec so a future v2 rename can't silently bring the bug back.
There was a problem hiding this comment.
Done — added a "Zones OAS V2" case in src/generate-oas.test.ts that asserts the normalizer flag still gets appended when only the spec title changes.
| flags: resolveGeneratorFlags(apiSpecDetail), | ||
| }); | ||
| } catch (error) { | ||
| console.error(`Error generating SDK for ${name}: ${error}`); |
There was a problem hiding this comment.
nit: this catch logs but does not rethrow, so renderTemplates still exits 0 when a spec fails to generate. A bad normalizer flag would fail silently and only surface later at compile.
Rethrow so the build fails loudly:
| console.error(`Error generating SDK for ${name}: ${error}`); | |
| console.error(`Error generating SDK for ${name}: ${error}`); | |
| throw error; |
There was a problem hiding this comment.
Good callout, done — generateSDKs now rethrows after the console.error so a bad flag fails the render immediately instead of surfacing as a downstream compile error.
…ision back (@W-23234552@) - resolveGeneratorFlags now keys off apiSpecDetail.apiName === "CDNZones" instead of the spec title. apiName is the version-stable identifier — a future "Zones OAS V2" or the legacy "CDN API - Process APIs OAS" title both map to CDNZones and are now covered. - generateSDKs rethrows after logging so a bad generator flag fails the render immediately instead of surfacing as a downstream compile error. - Added a test case for the "Zones OAS V2" title to lock in the guard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t 100% (@W-23234552@)
The `overrides = {}` default introduced a branch (called-with-arg vs
called-without) that no test exercised, dragging the file's branch
coverage to 0% and failing CI's 80% threshold. All three call sites
already pass an object explicitly, so requiring it costs nothing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
The Zones OAS spec ships a spec-level
x-sdk-classname: CDNZonesthat openapi-generator threads to every emitted API file's class. When operations span multiple tags (zones-oas 1.3.0 introduces aTurnstiletag), the generator emits one file per tag — each declaringexport class CDNZones— and the auto-generated barrel failsTS2308on the duplicate. Any bump past zones-oas 1.2.0 is blocked.Concretely, generating
zones-oas-v1=1.3.0onmain(without this fix):npm run compilefails withTS2308: Module './DefaultApi' has already exported a member named 'CDNZones'atapis/index.ts:2.Fix: pass
--openapi-normalizer SET_TAGS_FOR_ALL_OPERATIONS=defaultto the openapi-generator invocation for the Zones spec only. That collapses every operation onto thedefaulttag, so the generator emits a singleDefaultApi.tswith all operations (Turnstile included) on one class — preserving the filename convention every other spec in the SDK already uses.Generating
zones-oas-v1=1.3.0on this branch (with the fix):npm run compileexits clean.Consumer surface is unchanged:
import { CDNZones } from "commerce-sdk"resolves through the same barrel chain to the same class. At pinned 1.2.0 the emittedDefaultApi.ts, model files, and every downstream barrel are byte-identical to base.Test plan
src/generate-oas.test.ts— proven red on base (TS2305: Module './generate-oas' has no exported member 'resolveGeneratorFlags', i.e. the test can't compile without the fix's carrier function) and green on fix (52 passing).npm run test:unit— 52 passing.npm run compile— clean typecheck.npm run lint— clean.DefaultApi.ts,apis/index.ts, all 98 model files,models/index.ts,cdnApiProcessApis/index.ts,cdnApiProcessApis/runtime.ts, and the top-levelrenderedTemplates/index.tsare byte-identical between base and fix.DefaultApi.ts, singleexport class CDNZones, all previous zone endpoints plus the 5 new Turnstile operations (createTurnstileWidget,deleteTurnstileWidget,getTurnstileWidget, etc.) on one class. Cleanapis/index.tsbarrel, no TS2308.Reviewer manual smoke test
To reproduce the 1.3.0 generation locally on this branch:
Expected result:
renderedTemplates/cdnApiProcessApis/apis/contains exactly one API file,DefaultApi.ts, withexport class CDNZones extends BaseClient. NoTurnstileApi.ts, no duplicate class.DefaultApi.tshas all pre-existing zone endpoints plus the 5 new Turnstile operations (createTurnstileWidget,deleteTurnstileWidget,getTurnstileWidget,getTurnstileWidgets,updateTurnstileWidget).TurnstileWidget*model files underrenderedTemplates/cdnApiProcessApis/models/.npm run compileexits 0 (no TS2308 on the barrel).Sanity check on
mainfirst (optional): repeat steps 2–4 onmainandnpm run compilewill fail withTS2308: Module './DefaultApi' has already exported a member named 'CDNZones'atrenderedTemplates/cdnApiProcessApis/apis/index.ts:2— this is the failure this PR resolves.To restore local state after smoke:
git checkout -- api-versions.txt && rm -rf apis/zones-oas-1.3.0 renderedTemplates.Follow-ups
api-versions.txtbump ofzones-oas-v1from 1.2.0 to 1.3.0 belongs in a separate release ticket per the ticket's AC.src/generate-oas.ts:58—resolveApiName's"CDN API - Process APIs OAS"branch is dead (no shipping spec uses that name); the current name is"Zones OAS", handled at line 82. Chore ticket to clean up.resolveApiName,resolveDirectoryName,resolveGeneratorFlags) could collapse into one data-driven config table. Separate Refactor ticket.templatesOas/apis.endpoint.mustache:242emitsconst pathParams = {}without a type annotation. VS Code's defaultnoImplicitAnylights up every generatedDefaultApi.tsin the repo with editor squiggles — cosmetic only, the repotsconfig.jsoncompiles cleanly. Chore ticket to addRecord<string, unknown>to the mustache emit.Ticket
W-23234552