refactor(translator): extract framework-agnostic translator-core (keystone — FieldLike + pure predicates)#60
Open
SearheiParkhamchuk wants to merge 4 commits into
Open
refactor(translator): extract framework-agnostic translator-core (keystone — FieldLike + pure predicates)#60SearheiParkhamchuk wants to merge 4 commits into
SearheiParkhamchuk wants to merge 4 commits into
Conversation
…e + pure predicates) Keystone slice of the @repo/translator-core extraction. Makes src/server/shared/field-traversal/** free of any payload import: a structural FieldLike type family replaces payload `Field` types across the FieldWalker contract, and the field-classification predicates are re-implemented locally instead of imported from `payload/shared`. No behavior change — type re-annotation over unchanged logic. Guarded by: - parity test: local predicates vs payload/shared on a fixture of every field type - conformance (tsgo): payload `Field` assignable to FieldLike; containers excluded from LeafFieldLike - boundary scan: no payload import in field-traversal/** Full suite green (793 tests), tsgo clean, oxlint clean. Extraction roadmap (tracked on this branch): - [x] 1. Re-implement kernel field predicates as pure functions over FieldLike - [x] 2. Define FieldLike across the full FieldWalker contract (LeafFieldLike) - [x] 3. Widen field.custom / guard accessors to structural input - [ ] 4. Own Lexical Serialized* types from `lexical`, not @payloadcms/richtext-lexical - [ ] 5. Fix cross-layer dep edges (modules->features, server->client) + boundary lint - [ ] 6. Read-only id-path ContentProjector + branded IdPath (revises provenance phase 2) - [ ] 7. Create @repo/translator-core, move agnostic surface, enforce no-payload in CI Design: docs/plans/2026-06-26-translator-core-extraction-design.md docs/plans/2026-06-26-architecture-review.md docs/plans/2026-06-26-translation-provenance-and-lifecycle-design.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCZ4rvA5GpDBgch29vLBi1
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
7 tasks
…lized* types) WHY: shared/lexical is part of the framework-agnostic core surface for the @repo/translator-core extraction, but types.ts imported the Serialized* Lexical types from @payloadcms/richtext-lexical — a banned framework dependency for the core. WHAT: - Replace the @payloadcms/richtext-lexical import in shared/lexical/types.ts with locally-owned structural types (SerializedLexicalNode/SerializedTextNode/ SerializedRootNode), a structural superset of what the layer reads. - Add a conformance test: Payload's real Serialized* nodes stay assignable to the local types (tsgo-enforced). - Add a boundary test: shared/lexical imports no payload/@payloadcms. TESTS: new conformance + boundary tests in shared/lexical; full package suite green (801 tests), tsgo + oxlint clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ndary lint WHY: prep for @repo/translator-core — remove wrong-direction dependency edges and guard the already-agnostic zones so payload can't leak back in. No behavior change. WHAT: - Relocate shared contracts to the neutral src/types/ leaf: FieldTranslationResult/ FieldTranslationNotice (kills a client->server-feature import), CollectionSchemaMap, RawPayloadComponentExport. Barrels re-export to keep the public surface stable. - Invert translation-levels: the composition factories (documentLevel/collectionLevel/ fieldLevel/useDocTranslationApi) move up to a new src/composition/levels/ layer (named by role - the composition root beside plugin.ts); modules/translation-levels keeps only the abstract mechanism (types + PluginConfigBuilder) and no longer imports features/client. - Add a zone-scoped oxlint no-restricted-imports boundary (root oxlint.config.ts) for field-traversal/ + lexical/ - bans payload/@payloadcms/next/react and relative features/** & client/** edges - mirroring the analytics precedent; test files exempt. - Consolidate the two per-dir no-payload scans into one parametrized no-payload-boundary.test.ts; both zones ban payload + @payloadcms in lockstep with the lint. TESTS: full suite green (801); inversion guarded by plugin.test.ts; boundary lint verified to fire on an injected payload import. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
What
Long-lived branch for extracting a framework-agnostic
@repo/translator-core. This first pushlands the keystone that unblocks everything else:
src/server/shared/field-traversal/**is nowfree of any
payloadimport.FieldLiketype family (incl. positiveLeafFieldLikewithnever-guards) replacesPayload
Fieldtypes across the entireFieldWalkercontract.predicates.ts) instead of importedfrom
payload/shared.field.customaccessors widened to structural input.No behavior change — type re-annotation over unchanged logic.
Why
A
/sp-architecture-reviewshowed the original "coupled to Payload only via theFieldtype"framing was false at runtime (
kernel.tsranpayload/sharedpredicates; walker callbacks namedPayload types). See
docs/plans/2026-06-26-architecture-review.mdand...-translator-core-extraction-design.md(both added here).Roadmap (this branch accumulates the slices)
FieldLikeFieldLikeacross the fullFieldWalkercontract (LeafFieldLike)field.custom/ guard accessors to structural inputSerialized*types fromlexical, not@payloadcms/richtext-lexicalmodules→features,server→client) + boundary lintContentProjector+ brandedIdPath(revises provenance phase 2)@repo/translator-core, move agnostic surface, enforce no-payload in CIVerification
payload/sharedon a fixture of every field typeFieldassignable toFieldLike; containers excluded fromLeafFieldLikepayloadimport infield-traversal/**tsgoclean,oxlintclean.Part of #59
🤖 Generated with Claude Code