fix(richtext): read element types from interfaces and type aliases - #747
Merged
Conversation
`@hey-api/openapi-ts` emits object schemas as `export interface X { … }` in the
version that produced the committed `types.gen.ts` and as `export type X = { … }`
in the version the lockfile now resolves. The element-types generator matched
`ts.isInterfaceDeclaration` only, so regenerating the overlay types made it find
zero `RichTextFieldValue*` declarations and write an empty
`StoryblokRichTextElementByType`, with a zero exit code. The breakage only
surfaced later and elsewhere, as `TS2536` in `@storyblok/angular`, which indexes
that interface by element name.
Accept both declaration shapes, and throw when no declarations match instead of
emitting an empty map, so a future generator change fails at generation time.
`generateElementTypes` now delegates to `generateElementTypesFromSource`, which
takes the source text, so the parser is testable without touching the filesystem.
The committed output had drifted from what the generator produces today, in two
independent ways, and nothing in CI can catch it because CI never regenerates.
- The spec-derived overlay types (`packages/{cli,richtext}/src/generated/overlay/
types.gen.ts`) predate the `@hey-api/openapi-ts` version the lockfile resolves,
so their object schemas were still emitted as interfaces rather than type
aliases. No type-level change, but regenerating them was the trigger for the
empty element types fixed in the previous commit.
- The template-derived types (`packages/*/src/generated/types/*`) predate the
repo-wide oxfmt pass. That pass reformatted `tools/openapi-codegen/templates/`
but could not reformat the consumers' copies, which `.prettierignore` excludes.
Regenerating brings both back in sync. `packages/richtext/src/static/
richtext-element-types.generated.ts` regenerates byte-identical to its committed
content, which confirms the generator fix restores the previous output rather
than changing the public surface.
Contributor
|
@storyblok/angular
@storyblok/astro
@storyblok/api-client
storyblok
@storyblok/experiments
@storyblok/js
storyblok-js-client
@storyblok/lint-config
@storyblok/live-preview
@storyblok/management-api-client
@storyblok/migrations
@storyblok/nuxt
@storyblok/react
@storyblok/region-helper
@storyblok/richtext
@storyblok/schema
@storyblok/svelte
@storyblok/vue
commit: |
`@hey-api/openapi-ts` is a 0.x package whose emitted declaration style is not
configurable and changes across patch releases (0.92.4 emits `export type X =
{ … }` where earlier releases emitted `export interface X { … }`). The
generated output is committed and CI never regenerates it, so a floating
`^0.92.3` let a plain `pnpm install` silently change what the next
regeneration would produce — which is how the richtext element-type map ended
up empty.
Pin it exactly, matching the existing convention in that package for
output-affecting tools (`typescript`, `oxlint`), and document the generator
version as the third input to generation alongside the two spec sources.
Also reword the dual-shape comment in the richtext generator: it read as if we
support several hey-api versions at once, which we do not and should not.
dipankarmaikap
approved these changes
Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Running
pnpm nx run-many -t generate:openapionmaintoday silently emptiesStoryblokRichTextElementByTypeand breaks@storyblok/angular:build:Three pieces of drift combine into it:
@hey-api/openapi-tswas declared as^0.92.3. It is a0.xpackage whose emitted declaration style is not configurable and changes across patch releases: earlier releases emitexport interface X { … }, the 0.92.4 the lockfile resolves emitsexport type X = { … }.packages/{cli,richtext}/src/generated/overlay/types.gen.tsis committed output produced under the older style. Since CI never regenerates (it needs the private spec cache), nothing re-derived it when the resolved version moved.packages/richtext/src/static/generate/richtext-element-types.tsmatchests.isInterfaceDeclarationonly. After a regeneration it finds zeroRichTextFieldValue*declarations, writesexport interface StoryblokRichTextElementByType<TContext = unknown> {}, and exits0.Nothing catches this: the generator succeeds, and the failure surfaces in a different package as a type error.
Changes
generateElementTypes(path)delegates togenerateElementTypesFromSource(source), so the parser is unit-testable; addedrichtext-element-types.test.tscovering both shapes, the export/name filters, and the empty-output guard.@hey-api/openapi-tsto an exact0.92.4, matching howtools/openapi-codegenalready pins its other output-affecting tools (typescript,oxlint). A floating range let a plainpnpm installsilently change what the next regeneration produces; now that can only happen in a deliberate bump PR where regenerating and reviewing the diff is the expected work.tools/openapi-codegen/README.mddocuments the generator version as a third input to generation, alongside the two spec sources..prettierignoreexcludes**/src/generated/).Verification
pnpm --filter @storyblok/openapi-codegen verifypasses, and a fullpnpm nx run-many -t generate:openapi --skip-nx-cacheacross all 7 consumers leaves the tree clean — no drift left.pnpm nx build @storyblok/angular(the original TS2536 failure) passes, as do lint and the richtext test suite.Note for reviewers
The
types.gen.tsdiff is large but mechanical:interface X {→type X = {plus indentation. #719 previously carried the template-derived part of this regeneration; once this lands, that PR's regeneration commit reduces to its own template change.