From 0d6bfefd293a37b210b12c2b8eaecc926491b1d4 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 12:35:54 +0000 Subject: [PATCH] fix(types): describe `ClassNameStylePropsSchema` by its two keys (#7578) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `.describe()` on this package is published runtime metadata — it lands in the generated JSON-Schema `description` and in the derived docs — so it is the only label the reader who never sees the const name gets. objectui#5928 renamed the const off `StyleProps` because the like-named TS `StyleProps` is the Tailwind-scale vocabulary (`padding`, `margin`, `gap`, ...) and shares zero keys with these two. That rename reached source readers only: the description went on saying what the retired name said, leaving a reader who meets the schema through generated JSON-Schema hunting `padding` or `gap` under a label that promised them. The string now names the two keys verbatim. The object is untouched — same two optional keys, same accept set, same export name; nothing validates differently. Pinned in `classname-style-describe-7578.test.ts`, read off the live schema exported by the published `@object-ui/types/zod` barrel, with the key set and a neighbouring schema's own description as controls. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s --- .changeset/7578-classname-style-describe.md | 27 ++++++ .../classname-style-describe-7578.test.ts | 84 +++++++++++++++++++ packages/types/src/zod/base.zod.ts | 10 ++- 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 .changeset/7578-classname-style-describe.md create mode 100644 packages/types/src/__tests__/classname-style-describe-7578.test.ts diff --git a/.changeset/7578-classname-style-describe.md b/.changeset/7578-classname-style-describe.md new file mode 100644 index 000000000..c939c9470 --- /dev/null +++ b/.changeset/7578-classname-style-describe.md @@ -0,0 +1,27 @@ +--- +'@object-ui/types': patch +--- + +`ClassNameStylePropsSchema` describes itself by its two keys (objectui#7578). + +The schema's `.describe()` text changes from `Style properties` to +`className and inline style`. **This is published runtime metadata, not a +comment**: on this package `.describe()` is what lands in the generated +JSON-Schema `description` field and in the derived docs, so a consumer that +renders or diffs those will see the new string. The object itself is unchanged — +same two optional keys (`className`, `style`), same accept set, same types, same +export name; nothing validates differently. + +Why it moved. objectui#5928 renamed the const away from `StyleProps`, because +the like-named TypeScript `StyleProps` is the Tailwind-scale vocabulary +(`padding`, `margin`, `gap`, `backgroundColor`, ...) and shares zero keys with +these two. That rename only reached readers who can see the const name; the +description still said what the retired name said, so a reader who meets this +schema through generated JSON-Schema or docs was left hunting `padding` or `gap` +under a label that promised them. Naming the two keys ends that at the one place +that reader actually sees. + +The new text uses the verbatim key spellings, so the label answers "what is in +here" with names the reader can act on. Pinned in +`packages/types/src/__tests__/classname-style-describe-7578.test.ts`, read off +the live schema exported by the published `@object-ui/types/zod` barrel. diff --git a/packages/types/src/__tests__/classname-style-describe-7578.test.ts b/packages/types/src/__tests__/classname-style-describe-7578.test.ts new file mode 100644 index 000000000..70e3ba3bb --- /dev/null +++ b/packages/types/src/__tests__/classname-style-describe-7578.test.ts @@ -0,0 +1,84 @@ +/** + * ObjectUI + * Copyright (c) 2024-present ObjectStack Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * `ClassNameStylePropsSchema.description` names the two keys the object holds + * (objectui#7578). + * + * ## What this file exists to prove + * + * objectui#5928 renamed the const off the over-broad `StyleProps` name; its + * `.describe()` string was deliberately left alone by that PR and went on saying + * exactly what the retired name said. That string is not a comment: on this + * package `.describe()` is runtime metadata that reaches generated JSON-Schema + * and docs, so it is the ONLY label the reader who never sees the const name + * gets. #5928 therefore fixed the half of the problem that is visible in source + * and left the published half standing — this file pins the published half. + * + * The description is read off the LIVE schema object exported by the published + * barrel, not off the source text: a `.describe()` call that stops reaching the + * schema (dropped in a refactor, or shadowed by a later `.describe()` up the + * chain) leaves the source line looking correct while the emitted JSON-Schema + * carries nothing, and only a runtime read tells those two apart. + * + * Three legs on the description, because "not the old string" and "the new + * string" are different facts and a future edit can satisfy one without the + * other: it EQUALS the current literal, it NAMES both keys verbatim so the label + * cannot drift back to a generic word that leaves a reader hunting `padding` or + * `gap` here, and it no longer carries the retired wording. + * + * ## Controls + * + * Two, so a red run here is readable as a description regression and not as + * collateral from something larger: + * - the object's key set is unchanged — this card moved a string, not a shape; + * - a neighbouring schema in the same source file still carries its own + * description, so an edit that swept every `.describe()` in `base.zod.ts` + * reddens here too instead of passing as "the string changed". + */ + +import { describe, it, expect } from 'vitest'; + +// The PUBLISHED path — `@object-ui/types/zod` resolves to this barrel. The +// description travels with the exported schema object, so it has to be read +// through the same door a consumer uses. +import { ClassNameStylePropsSchema, HTMLAttributesSchema } from '../zod/index.zod.js'; + +describe('ClassNameStylePropsSchema.description (objectui#7578)', () => { + it('is the label that names the two keys', () => { + expect(ClassNameStylePropsSchema.description).toBe('className and inline style'); + }); + + it('names both keys verbatim, and no longer carries the retired wording', () => { + const description = ClassNameStylePropsSchema.description ?? ''; + + // Verbatim key spellings: the label has to survive being read with no source + // in view, and the two property names are what the reader can act on. + for (const key of Object.keys(ClassNameStylePropsSchema.shape)) { + expect(description, `the description should name the \`${key}\` key`).toContain(key); + } + + // The retired wording is the one #5928 renamed the const away from; it is + // spelled out here once, as the thing being kept OUT. + expect(description).not.toContain('Style properties'); + }); + + it('control: the object still carries exactly the two keys it describes', () => { + // A string change, not a shape change. If this leg moves, the card that moved + // it owes a decision, not a re-label. + expect(Object.keys(ClassNameStylePropsSchema.shape).sort()).toEqual(['className', 'style']); + }); + + it('control: a neighbouring schema in the same file keeps its own description', () => { + // `HTMLAttributesSchema` is declared a few lines up in `../zod/base.zod.ts` + // and is outside this card's scope. Its description is untouched, so this leg + // stays green across the change above and reddens only if some edit went + // through every `.describe()` in that file. + expect(HTMLAttributesSchema.description).toBe('HTML attributes'); + }); +}); diff --git a/packages/types/src/zod/base.zod.ts b/packages/types/src/zod/base.zod.ts index df31ace4a..f92510e4f 100644 --- a/packages/types/src/zod/base.zod.ts +++ b/packages/types/src/zod/base.zod.ts @@ -429,8 +429,16 @@ export const EventHandlersSchema = z.record(z.string(), z.function()).describe(' * for its own keys there is no like-named declaration left to pair it with, and * the reason it mirrors nothing is recorded against this name in * `../__tests__/zod-mirror-parity.test.ts`'s `EXCLUSIONS`. + * + * The `.describe()` text below names those same two keys, for the half of #5928 + * the rename could not reach (objectui#7578): `.describe()` is runtime metadata + * that feeds generated JSON-Schema and docs, where the const name is never in + * view, so the label is the only thing telling that reader what is in here. The + * generic wording it carried until #7578 was the one the const was renamed away + * from, and it left a reader hunting `padding` or `gap` under this schema in + * exactly the confusion #5928 was filed about, one layer down. */ export const ClassNameStylePropsSchema = z.object({ className: z.string().optional(), style: z.record(z.string(), z.union([z.string(), z.number()])).optional(), -}).describe('Style properties'); +}).describe('className and inline style');