Skip to content

Commit be7dc37

Browse files
authored
Using native storage for default label (#2643)
While working on #2632 I realized that native storage is actually the right place for it
1 parent 38cc4c1 commit be7dc37

8 files changed

Lines changed: 20 additions & 48 deletions

express-zod-api/src/documentation-helpers.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
TagObject,
2424
} from "openapi3-ts/oas31";
2525
import * as R from "ramda";
26-
import { globalRegistry, z } from "zod/v4";
26+
import { z } from "zod/v4";
2727
import { ResponseVariant } from "./api-response";
2828
import {
2929
FlatObject,
@@ -47,7 +47,7 @@ import { ezFileBrand } from "./file-schema";
4747
import { IOSchema } from "./io-schema";
4848
import { flattenIO } from "./json-schema-helpers";
4949
import { Alternatives } from "./logical-container";
50-
import { getBrand, metaSymbol } from "./metadata";
50+
import { getBrand } from "./metadata";
5151
import { Method } from "./method";
5252
import { ProprietaryBrand } from "./proprietary-schemas";
5353
import { ezRawBrand } from "./raw-schema";
@@ -101,16 +101,6 @@ const samples = {
101101
export const reformatParamsInPath = (path: string) =>
102102
path.replace(routePathParamsRegex, (param) => `{${param.slice(1)}}`);
103103

104-
export const depictDefault: Depicter = ({ zodSchema, jsonSchema }) => {
105-
const value =
106-
globalRegistry.get(zodSchema)?.[metaSymbol]?.defaultLabel ??
107-
jsonSchema.default;
108-
return {
109-
...jsonSchema,
110-
default: typeof value === "bigint" ? String(value) : value,
111-
};
112-
};
113-
114104
export const depictUpload: Depicter = ({}, ctx) => {
115105
if (ctx.isResponse)
116106
throw new DocumentationError("Please use ez.upload() only for input.", ctx);
@@ -398,7 +388,6 @@ export const depictRequestParams = ({
398388
const depicters: Partial<Record<FirstPartyKind | ProprietaryBrand, Depicter>> =
399389
{
400390
nullable: depictNullable,
401-
default: depictDefault,
402391
union: depictUnion,
403392
bigint: depictBigInt,
404393
intersection: depictIntersection,

express-zod-api/src/metadata.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ export const metaSymbol = Symbol.for("express-zod-api");
77

88
export interface Metadata {
99
examples: unknown[];
10-
/** @override ZodDefault::_zod.def.defaultValue() in depictDefault */
11-
defaultLabel?: string;
1210
}
1311

1412
export const mixExamples = <A extends z.ZodType, B extends z.ZodType>(

express-zod-api/src/zod-plugin.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ declare module "zod/v4/core" {
2626
interface GlobalMeta {
2727
[metaSymbol]?: Metadata;
2828
deprecated?: boolean;
29+
default?: unknown; // can be an actual value or a label like "Today"
2930
}
3031
}
3132

@@ -36,7 +37,7 @@ declare module "zod/v4" {
3637
deprecated(): this;
3738
}
3839
interface ZodDefault<T extends $ZodType = $ZodType> extends ZodType {
39-
/** @desc Change the default value in the generated Documentation to a label */
40+
/** @desc Change the default value in the generated Documentation to a label, alias for .meta({ default }) */
4041
label(label: string): this;
4142
}
4243
interface ZodObject<
@@ -106,11 +107,9 @@ const deprecationSetter = function (this: z.ZodType) {
106107
};
107108

108109
const labelSetter = function (this: z.ZodDefault, defaultLabel: string) {
109-
const { [metaSymbol]: internal = { examples: [] }, ...rest } =
110-
this.meta() || {};
111110
return this.meta({
112-
...rest, // @todo this may no longer be required since it seems that .meta() merges now, not just overrides
113-
[metaSymbol]: { ...internal, defaultLabel },
111+
...this.meta(), // @todo this may no longer be required since it seems that .meta() merges now, not just overrides
112+
default: defaultLabel,
114113
});
115114
};
116115

express-zod-api/tests/__snapshots__/documentation-helpers.spec.ts.snap

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,6 @@ DocumentationError({
4545
})
4646
`;
4747

48-
exports[`Documentation helpers > depictDefault() > Feature #1706: should override the default value by a label from metadata 1`] = `
49-
{
50-
"default": "Today",
51-
"format": "date-time",
52-
}
53-
`;
54-
5548
exports[`Documentation helpers > depictEnum() > should set type 1`] = `
5649
{
5750
"enum": [

express-zod-api/tests/__snapshots__/documentation.spec.ts.snap

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,15 @@ paths:
980980
default: 123
981981
exclusiveMinimum: 0
982982
maximum: 9007199254740991
983+
- name: labeledDate
984+
in: query
985+
required: false
986+
description: GET /v1/getSomething Parameter
987+
schema:
988+
type: string
989+
default: Today
990+
format: date-time
991+
pattern: ^((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?(Z)$
983992
responses:
984993
"200":
985994
description: GET /v1/getSomething Positive response

express-zod-api/tests/documentation-helpers.spec.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
defaultIsHeader,
1515
reformatParamsInPath,
1616
depictNullable,
17-
depictDefault,
1817
depictRaw,
1918
depictUpload,
2019
depictFile,
@@ -120,22 +119,6 @@ describe("Documentation helpers", () => {
120119
});
121120
});
122121

123-
describe("depictDefault()", () => {
124-
test("Feature #1706: should override the default value by a label from metadata", () => {
125-
const zodSchema = z.iso
126-
.datetime()
127-
.default(() => new Date().toISOString())
128-
.label("Today");
129-
const jsonSchema: JSONSchema.BaseSchema = {
130-
default: "2025-05-21",
131-
format: "date-time",
132-
};
133-
expect(
134-
depictDefault({ zodSchema, jsonSchema }, responseCtx),
135-
).toMatchSnapshot();
136-
});
137-
});
138-
139122
describe("depictRaw()", () => {
140123
test("should extract the raw property", () => {
141124
const jsonSchema: JSONSchema.BaseSchema = {

express-zod-api/tests/documentation.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ describe("Documentation", () => {
8787
optDefault: z.string().optional().default("test"),
8888
nullish: z.boolean().nullish(),
8989
nuDefault: z.int().positive().nullish().default(123),
90+
labeledDate: z.iso
91+
.datetime()
92+
.default(() => new Date().toISOString())
93+
.label("Today"), // Feature #1706
9094
}),
9195
output: z.object({
9296
nullable: z.string().nullable(),

express-zod-api/tests/zod-plugin.spec.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,7 @@ describe("Zod Runtime Plugin", () => {
6565
const schema = z.iso.datetime().default(() => new Date().toISOString());
6666
expect(schema).toHaveProperty("label");
6767
const schemaWithMeta = schema.label("Today");
68-
expect(schemaWithMeta.meta()?.[metaSymbol]).toHaveProperty(
69-
"defaultLabel",
70-
"Today",
71-
);
68+
expect(schemaWithMeta.meta()).toHaveProperty("default", "Today");
7269
});
7370
});
7471

0 commit comments

Comments
 (0)