Repository navigation
fix(types,docs): AutoNumberFieldMetadata declares the spec's autonumberFormat, and the auto-number page teaches it (objectui#12282) - #12298
Conversation
…erFormat, and the auto-number page teaches it (objectui#12282) `AutoNumberFieldMetadata` declares `autonumberFormat`, typed by reference to `@objectstack/spec`'s `FieldSchema.autonumberFormat`, the key the spec prefers on a new field. `format` stays, documented as the shorthand that predates it; when a field sets both, `autonumberFormat` wins (`resolveAutonumberFormat`). The auto-number docs page's typed literals and format templates use `autonumberFormat`, and one line teaches `format` as the shorthand. Claude-Session: https://claude.ai/code/session_015YrgVw7e65cs1ndbebt46G Co-authored-by: Claude <noreply@anthropic.com>
…tonumber-format-type Brings in PR objectui#12293 (objectui#12242), which edits other interfaces in packages/types/src/field-types.ts. Claude-Session: https://claude.ai/code/session_015YrgVw7e65cs1ndbebt46G Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Read at 2026-10-13T03:34Z · PR objectui#12298 (draft, base ① Derived judgmentsEvery accept-set and public-surface change the diff implies, each judged:
② Semver level
③ Boundary flags
No flag is escalated. Check-runs on the head33 check-runs on this head, every one Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #12282
Clause-②: yes
AutoNumberFieldMetadata(@object-ui/types) declaresautonumberFormat, typed by reference to@objectstack/spec'sFieldSchema.autonumberFormat, and keepsformatas the shorthand. The auto-number docs page teachesautonumberFormatfor a new field andformatas the shorthand, and says which one wins.What changed
packages/types/src/field-types.ts,AutoNumberFieldMetadataonly.autonumberFormat?: SpecField['autonumberFormat'], in the file's existing by-reference idiom (import type { Field as SpecField } from '@objectstack/spec/data').autonumberFormat, then a non-emptyformat, then the contract default{0000}. That is whatresolveAutonumberFormat(@objectstack/spec/data) does.format?: stringstays, with a new docblock calling it the shorthand.starting_numbertombstone's docblock now says the number is minted fromautonumberFormator its shorthandformat.content/docs/fields/auto-number.mdx.invoiceNumber,orderNumber) carryautonumberFormat.formatas the older shorthand (format: 'INV-{0000}'). It also saysautonumberFormatwins when a field sets both.format:toautonumberFormat:. Every pattern and its comment is unchanged: the nine pattern and comment pairs were compared by script before and after, and they are equal.packages/types/src/__tests__/autonumber-format-declared-12282.test.ts.type-checkthroughtsconfig.test.json: the member equalsSpecField['autonumberFormat']. Fresh literals carryingautonumberFormat,format(the control) and both keys compile.FieldSchema.safeParseaccepts all three literals, behind a control that refuses an undeclared key by name.resolveAutonumberFormatreturnsautonumberFormatwhen both keys are set, andformatwhen it is alone..changeset/12282-types-autonumber-format.md:@object-ui/types, minor.Premises checked against
mainbefore the editAutoNumberFieldMetadatadeclaredtype: 'autonumber',format?: stringandstarting_number?: never, and noautonumberFormat.@objectstack/specis 17.7.0. ItsFieldSchemadeclaresautonumberFormat: z.string().optional(). Itsformatdescribe callsformat"the shorthand that predatesautonumberFormat, which wins when both are present".resolveAutonumberFormattakes a non-emptyautonumberFormat, then a non-emptyformat, then{0000}. Probed:{ autonumberFormat: 'A-{0000}', format: 'F-{0000}' }givesA-{0000}, and{ autonumberFormat: '', format: 'F' }givesF.autonumberFormatwhentype == 'autonumber'. app-shell'spredicate.test.tslists it among the Studio sub-fields.Clause-② reading: the built
.d.ts, base vs headI measured this with the TypeScript compiler API on
packages/types/dist, built at base5d3f437a(themaintip this branch merges) and at headaae05a1a:exportsentries resolve and export the same names: 1222 entry and name pairs, the same set at base and head. The same reading at the original base,45ae6b89againste9325f4c, gave the same result.AutoNumberFieldMetadatamembers: exactly one is added,autonumberFormat?: string | undefined. No member is removed or retyped.Reverse check (one-off, no permanent test file)
I started from the committed implementation (
e9325f4c). objectstack'sscripts/ablation-replace.mjsdeleted the declaration lineautonumberFormat?: SpecField['autonumberFormat'];: the anchor hit once and went from 1 to 0, and the blob went froma067fe16to19c4a973. The tool held the mutation while these legs ran:tsc -p tsconfig.test.json(thetype-checktest leg): exit 2. TS2353 on both fresh literals that carryautonumberFormat, and TS2339 on the by-reference assertion and the two runtime reads.check:doc-snippets: I rebuilt@object-ui/typeswith the mutation, and the declaration count indist/field-types.d.tsread 0. The gate then exited 1: 789 of 789 blocks judged, 2 failed. Both failures are the typed literals oncontent/docs/fields/auto-number.mdx, with TS2353.git diff HEADis empty, andgit status --porcelainis empty. I rebuilt the package from HEAD, and the declaration count indistread 1 again.Gates (all on head
aae05a1a, after mergingorigin/main, which includes PR objectui#12293)check:doc-snippets--build-filterclosure (34 filters, which includes@object-ui/types), built withturbo run build --concurrency=2under the shared verify lock: 35 of 35 tasks,VERDICT command-exit 0.pnpm --filter @object-ui/types type-check, which echoedtsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json: exit 0. The new pin is in thetsconfig.test.jsonprogram (--listFilesOnly).pnpm exec vitest run packages/types/: 374 files, 10237 tests passed. The new pin run alone: 5 passed.pnpm check:doc-snippets: exit 0, "Semantic phase: 790 of 790 block(s) judged, 0 failed."pnpm check:doc-examples: exit 0, "Every covered@examplecompiles, or fails exactly as its ledger row declares."node scripts/check-doc-links.mjs: exit 0, "Links are valid across 17 scan roots."check:doc-fences,check:doc-types,check:doc-json,check:doc-example-idscheck:readme-exports,check:spec-symbolscheck:changeset-claims,check:pending-changeset-literals,node scripts/check-changeset-fixed.mjs,node scripts/check-changeset-presence.mjs(1 changeset declared for 1 released package)check:control-bytescheck:new-line-citations: "0 new citation(s)"type-check:coverage,check:test-path-rootspnpm exec vitest run scripts/__tests__/: 187 files passed and 2 skipped; 5632 tests passed and 2 skipped;VERDICT command-exit 0.node scripts/check-governed-queue-guard.mjs --teston the four changed paths: NOT GOVERNED.pnpm lintisturbo run lint, and@object-ui/types'lintscript iseslint .against the rooteslint.config.js. I ran that sameeslint .inpackages/types.--format json: 455 files, 0 errors.field-types.tshas 3no-explicit-anywarnings, the same 3 as at base. The new pin has none.eslint.config.jssets noparserOptions.projectorprojectService, so type-aware linting is not enabled. This diff therefore cannot move the verdict on any file it does not touch. The.mdxand.mdfiles fall outside eslint's**/*.{ts,tsx}rule blocks.Acceptance notes
mainduring this run and is merged into this branch. Its diff and this one touch disjoint interfaces infield-types.ts. It adds no member-level census overAutoNumberFieldMetadata, soautonumberFormatowes no row there.strict-face-read-keys-11070.test.tsrecords keys that a registered renderer reads onform.fields[]entries. No renderer readsautonumberFormat: the backend mints the value, andAutoNumberFieldprints it as stored. So it is not added there.@object-ui/typesREADME lists noAutoNumberFieldMetadatakeys, so it is unchanged.resolveCellRendererType(@object-ui/fields) reads a field'sformatgenerically, but only acts on textual base types. Soformatnever changes how anautonumbercell draws. Noted, not a finding.Session:
https://claude.ai/code/session_015YrgVw7e65cs1ndbebt46GGenerated by Claude Code