@zmdb/schema 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +30 -0
- package/dist/custom-types/index.d.ts +41 -0
- package/dist/custom-types/index.d.ts.map +1 -0
- package/dist/custom-types/index.js +32 -0
- package/dist/custom-types/index.js.map +1 -0
- package/dist/derive/index.d.ts +122 -0
- package/dist/derive/index.d.ts.map +1 -0
- package/dist/derive/index.js +13 -0
- package/dist/derive/index.js.map +1 -0
- package/dist/derive/query.d.ts +62 -0
- package/dist/derive/query.d.ts.map +1 -0
- package/dist/derive/query.js +18 -0
- package/dist/derive/query.js.map +1 -0
- package/dist/dto/index.d.ts +224 -0
- package/dist/dto/index.d.ts.map +1 -0
- package/dist/dto/index.js +118 -0
- package/dist/dto/index.js.map +1 -0
- package/dist/entity-modeling/index.d.ts +12 -0
- package/dist/entity-modeling/index.d.ts.map +1 -0
- package/dist/entity-modeling/index.js +28 -0
- package/dist/entity-modeling/index.js.map +1 -0
- package/dist/index.d.ts +151 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/index.d.ts +374 -0
- package/dist/ir/index.d.ts.map +1 -0
- package/dist/ir/index.js +735 -0
- package/dist/ir/index.js.map +1 -0
- package/dist/ir/validation-shape.d.ts +46 -0
- package/dist/ir/validation-shape.d.ts.map +1 -0
- package/dist/ir/validation-shape.js +130 -0
- package/dist/ir/validation-shape.js.map +1 -0
- package/dist/ir/vocabulary.d.ts +54 -0
- package/dist/ir/vocabulary.d.ts.map +1 -0
- package/dist/ir/vocabulary.js +51 -0
- package/dist/ir/vocabulary.js.map +1 -0
- package/dist/naming/index.d.ts +26 -0
- package/dist/naming/index.d.ts.map +1 -0
- package/dist/naming/index.js +147 -0
- package/dist/naming/index.js.map +1 -0
- package/dist/openapi/index.d.ts +57 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +98 -0
- package/dist/openapi/index.js.map +1 -0
- package/dist/relations/index.d.ts +23 -0
- package/dist/relations/index.d.ts.map +1 -0
- package/dist/relations/index.js +98 -0
- package/dist/relations/index.js.map +1 -0
- package/dist/tags/index.d.ts +261 -0
- package/dist/tags/index.d.ts.map +1 -0
- package/dist/tags/index.js +64 -0
- package/dist/tags/index.js.map +1 -0
- package/package.json +82 -0
- package/src/custom-types/index.ts +59 -0
- package/src/derive/index.ts +224 -0
- package/src/derive/query.ts +128 -0
- package/src/dto/index.ts +395 -0
- package/src/entity-modeling/index.ts +33 -0
- package/src/index.ts +263 -0
- package/src/ir/index.ts +1085 -0
- package/src/ir/validation-shape.ts +145 -0
- package/src/ir/vocabulary.ts +56 -0
- package/src/naming/index.ts +159 -0
- package/src/openapi/index.ts +133 -0
- package/src/relations/index.ts +134 -0
- package/src/tags/index.ts +284 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { type CoreSchema, type SqlType } from '../index.js';
|
|
2
|
+
export { KNOWN_CONSTRAINT_KINDS, TAG_NAMES } from './vocabulary.js';
|
|
3
|
+
export type { ConstraintKind, TagField } from './vocabulary.js';
|
|
4
|
+
/**
|
|
5
|
+
* Numeric and string bounds. Deliberately a flat record rather than the old
|
|
6
|
+
* `ValidationRule[]`: the four walkers disagreed partly because `TypeDescriptor`
|
|
7
|
+
* had `minimum` and `maxLength` but no `maximum` and no `minLength`, so a
|
|
8
|
+
* `Min<18> & Max<120>` column validated differently depending on which one you
|
|
9
|
+
* asked.
|
|
10
|
+
*/
|
|
11
|
+
export interface Constraints {
|
|
12
|
+
readonly minimum?: number;
|
|
13
|
+
readonly maximum?: number;
|
|
14
|
+
readonly minLength?: number;
|
|
15
|
+
readonly maxLength?: number;
|
|
16
|
+
readonly pattern?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* `integer` is separate from `number` so an emitter can produce
|
|
20
|
+
* `Number.isInteger`, and `date` is separate from `string` so the app type and
|
|
21
|
+
* the wire type can differ without either lying (plan D3).
|
|
22
|
+
*/
|
|
23
|
+
export type ScalarKind = 'string' | 'number' | 'integer' | 'bigint' | 'boolean' | 'date';
|
|
24
|
+
export interface ScalarIR {
|
|
25
|
+
readonly kind: 'scalar';
|
|
26
|
+
readonly scalar: ScalarKind;
|
|
27
|
+
/** Protobuf scalar spelling, when the declaration made width/signedness explicit. */
|
|
28
|
+
readonly proto?: ProtoScalar;
|
|
29
|
+
/** JSON Schema `format`, when the scalar has a conventional one. */
|
|
30
|
+
readonly format?: string;
|
|
31
|
+
readonly constraints?: Constraints;
|
|
32
|
+
}
|
|
33
|
+
export interface LiteralIR {
|
|
34
|
+
readonly kind: 'literal';
|
|
35
|
+
readonly value: string | number | boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface NullIR {
|
|
38
|
+
readonly kind: 'null';
|
|
39
|
+
}
|
|
40
|
+
export interface UndefinedIR {
|
|
41
|
+
readonly kind: 'undefined';
|
|
42
|
+
}
|
|
43
|
+
export interface UnknownIR {
|
|
44
|
+
readonly kind: 'unknown';
|
|
45
|
+
}
|
|
46
|
+
export interface UnionIR {
|
|
47
|
+
readonly kind: 'union';
|
|
48
|
+
readonly members: readonly TypeIR[];
|
|
49
|
+
}
|
|
50
|
+
export interface ArrayIR {
|
|
51
|
+
readonly kind: 'array';
|
|
52
|
+
readonly element: TypeIR;
|
|
53
|
+
readonly constraints?: Constraints;
|
|
54
|
+
}
|
|
55
|
+
export interface TupleIR {
|
|
56
|
+
readonly kind: 'tuple';
|
|
57
|
+
readonly elements: readonly TypeIR[];
|
|
58
|
+
}
|
|
59
|
+
export interface ObjectIR {
|
|
60
|
+
readonly kind: 'object';
|
|
61
|
+
/** Set when the type had a name, so emitters can hoist a shared helper. */
|
|
62
|
+
readonly name?: string;
|
|
63
|
+
readonly properties: readonly PropertyIR[];
|
|
64
|
+
}
|
|
65
|
+
/** A back-reference to a named `ObjectIR` already on the stack. Cycle guard. */
|
|
66
|
+
export interface RefIR {
|
|
67
|
+
readonly kind: 'ref';
|
|
68
|
+
readonly name: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A first-class node, not an absence. A gap has to be visible: the transformer
|
|
72
|
+
* bug fixed in `f70186c6` happened because an unrecognised type produced a
|
|
73
|
+
* *partial* answer that looked like a real one. An `unsupported` node makes the
|
|
74
|
+
* emitter refuse and the build fail with the reason (plan D4).
|
|
75
|
+
*/
|
|
76
|
+
export interface UnsupportedIR {
|
|
77
|
+
readonly kind: 'unsupported';
|
|
78
|
+
readonly reason: string;
|
|
79
|
+
/** The type as written, when the producer can recover it. */
|
|
80
|
+
readonly source?: string;
|
|
81
|
+
}
|
|
82
|
+
export type TypeIR = ScalarIR | LiteralIR | NullIR | UndefinedIR | UnknownIR | UnionIR | ArrayIR | TupleIR | ObjectIR | RefIR | UnsupportedIR;
|
|
83
|
+
export interface PropertyIR {
|
|
84
|
+
readonly name: string;
|
|
85
|
+
readonly type: TypeIR;
|
|
86
|
+
readonly optional: boolean;
|
|
87
|
+
readonly readonly: boolean;
|
|
88
|
+
/** Stable protobuf identity. Required only when this object is emitted as a message. */
|
|
89
|
+
readonly protoField?: number;
|
|
90
|
+
}
|
|
91
|
+
export interface TableOptions {
|
|
92
|
+
readonly shardKey?: readonly string[];
|
|
93
|
+
readonly sortKey?: readonly string[];
|
|
94
|
+
readonly rowstore?: true;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The four cardinalities, as data so a reader can check a string against them.
|
|
98
|
+
*
|
|
99
|
+
* Written this way round — the list first, the type derived — because `../tags` fixes
|
|
100
|
+
* `kind` to a literal per tag, but the reflection reads it back off the checker as a
|
|
101
|
+
* `string`. Deriving the type from the list is what lets that read be a check rather than
|
|
102
|
+
* an assertion, and keeps the two from drifting.
|
|
103
|
+
*/
|
|
104
|
+
export declare const RELATION_KINDS: readonly ['manyToOne', 'oneToMany', 'oneToOne', 'manyToMany'];
|
|
105
|
+
export type RelationKind = (typeof RELATION_KINDS)[number];
|
|
106
|
+
export type ReferentialAction = 'cascade' | 'restrict' | 'set null' | 'set default' | 'no action';
|
|
107
|
+
export interface RelationIR {
|
|
108
|
+
readonly name: string;
|
|
109
|
+
readonly relation: RelationKind;
|
|
110
|
+
readonly target: string;
|
|
111
|
+
/** The foreign-key column, or the join table for `manyToMany`. */
|
|
112
|
+
readonly via: string;
|
|
113
|
+
}
|
|
114
|
+
export interface ForeignKeyIR {
|
|
115
|
+
readonly columns: readonly string[];
|
|
116
|
+
readonly targetTable: string;
|
|
117
|
+
readonly targetColumns: readonly string[];
|
|
118
|
+
}
|
|
119
|
+
/** A SQL type installed by a database extension rather than the closed core vocabulary. */
|
|
120
|
+
export interface ExtensionType {
|
|
121
|
+
readonly extension: string;
|
|
122
|
+
readonly name: string;
|
|
123
|
+
readonly args?: readonly (string | number)[];
|
|
124
|
+
}
|
|
125
|
+
export interface ColumnIR {
|
|
126
|
+
readonly name: string;
|
|
127
|
+
/** The database column name resolved by the build-time naming strategy. */
|
|
128
|
+
readonly physicalName: string;
|
|
129
|
+
/** Abstract SQL type. The dialect renders the spelling — see plan D3. */
|
|
130
|
+
readonly sql: SqlType | ExtensionType;
|
|
131
|
+
readonly nullable: boolean;
|
|
132
|
+
readonly primaryKey: boolean;
|
|
133
|
+
/** Database-generated. Absent from `CreateDTO`, not merely optional. */
|
|
134
|
+
readonly serial: boolean;
|
|
135
|
+
readonly unique: boolean;
|
|
136
|
+
readonly hasDefault: boolean;
|
|
137
|
+
readonly sensitive: boolean;
|
|
138
|
+
readonly length?: number;
|
|
139
|
+
readonly precision?: readonly [number, number];
|
|
140
|
+
/**
|
|
141
|
+
* The permitted values, **sorted**.
|
|
142
|
+
*
|
|
143
|
+
* Not declaration order, and deliberately so. The producer reads
|
|
144
|
+
* `'free' | 'pro' | 'enterprise'` back out of the checker, which normalises string-literal
|
|
145
|
+
* union members and hands them over in its own order — declaration order is simply not
|
|
146
|
+
* recoverable from a type. A set of permitted values has no order to lose, so sorting is
|
|
147
|
+
* what makes this a function of the declaration rather than of the compiler's internals.
|
|
148
|
+
*
|
|
149
|
+
* Emitters may therefore rely on this being stable across TypeScript versions, which the
|
|
150
|
+
* checker's order is not.
|
|
151
|
+
*/
|
|
152
|
+
readonly enum?: readonly string[];
|
|
153
|
+
readonly references?: string;
|
|
154
|
+
readonly onDelete?: ReferentialAction;
|
|
155
|
+
readonly onUpdate?: ReferentialAction;
|
|
156
|
+
readonly codec?: string;
|
|
157
|
+
/**
|
|
158
|
+
* The declared wire type (`WireAs<W>`), for a column whose wire form does not follow
|
|
159
|
+
* from `sql`. A codec's does not: only the declaration knows whether `Money` crosses
|
|
160
|
+
* as a decimal string, a `{ cents }` object or a pair.
|
|
161
|
+
*/
|
|
162
|
+
readonly wire?: TypeIR;
|
|
163
|
+
readonly constraints: Constraints;
|
|
164
|
+
/** Named custom rules (`Rule<'name'>`) an emitter must resolve or refuse. */
|
|
165
|
+
readonly rules: readonly string[];
|
|
166
|
+
readonly default?: unknown;
|
|
167
|
+
/**
|
|
168
|
+
* The declared app type: a `json` column's payload shape, or the type behind a codec.
|
|
169
|
+
*
|
|
170
|
+
* There is nowhere in `ColumnMeta` for this to go, which is why `CoreSchema` carries the
|
|
171
|
+
* IR rather than only its projection — a `Settings & Sql<'json'>` read back off the flags
|
|
172
|
+
* alone is just `json`, and the emitted validator would check nothing about the payload.
|
|
173
|
+
*/
|
|
174
|
+
readonly payload?: TypeIR;
|
|
175
|
+
}
|
|
176
|
+
export interface SchemaIR {
|
|
177
|
+
readonly table: string;
|
|
178
|
+
/** The database table name resolved by the build-time naming strategy. */
|
|
179
|
+
readonly physicalTable: string;
|
|
180
|
+
readonly columns: readonly ColumnIR[];
|
|
181
|
+
readonly primaryKey: readonly string[];
|
|
182
|
+
readonly relations: readonly RelationIR[];
|
|
183
|
+
readonly foreignKeys: readonly ForeignKeyIR[];
|
|
184
|
+
readonly ftsTable?: string | boolean;
|
|
185
|
+
/** The nullable timestamp column managed by soft delete. */
|
|
186
|
+
readonly softDelete?: {
|
|
187
|
+
readonly column: string;
|
|
188
|
+
};
|
|
189
|
+
readonly tableOptions?: TableOptions;
|
|
190
|
+
}
|
|
191
|
+
/** Every `SqlType`, as data. `sql-types.type-test.ts` asserts exhaustiveness. */
|
|
192
|
+
export declare const SQL_TYPES: readonly ["serial", "integer", "bigint", "numeric", "text", "varchar", "boolean", "timestamp", "json", "jsonEnum"];
|
|
193
|
+
/** The closed protobuf scalar vocabulary carried by {@link ScalarIR}. */
|
|
194
|
+
export declare const PROTO_SCALARS: readonly ['int32', 'int64', 'uint32', 'uint64', 'sint32', 'sint64', 'fixed32', 'fixed64', 'sfixed32', 'sfixed64', 'float', 'double', 'bool', 'string', 'bytes'];
|
|
195
|
+
export type ProtoScalar = (typeof PROTO_SCALARS)[number];
|
|
196
|
+
/**
|
|
197
|
+
* The schema value, from the IR — and the only way to get one (REQ-TF-10).
|
|
198
|
+
*
|
|
199
|
+
* The query compiler wants the table name and the column types as *data*, and this is
|
|
200
|
+
* data. `@zmdb/compiler` emits the result of this function as a frozen literal, so
|
|
201
|
+
* `schemaOf<T>()` costs nothing at runtime and the tagged type stays the only place the
|
|
202
|
+
* schema is written.
|
|
203
|
+
*
|
|
204
|
+
* The IR itself is carried through on `ir` rather than left behind. Three things a
|
|
205
|
+
* `ColumnMeta` has no field for — `Numeric<P, S>` precision, a `Codec<'Name'>`, a `json`
|
|
206
|
+
* payload shape — used to be dropped here and were unrecoverable afterwards, because the
|
|
207
|
+
* only way back to an IR was to walk the flags. Keeping the IR makes the value a superset
|
|
208
|
+
* of what it projects rather than a lossy copy, and it is what let `irFromSchema` go: no
|
|
209
|
+
* consumer has to reconstruct from `columns` what the declaration already said.
|
|
210
|
+
*
|
|
211
|
+
* Nothing is registered. A generated literal is not a call and has nowhere to do that,
|
|
212
|
+
* and a global "which schema was that?" lookup is for code that has lost track of its own
|
|
213
|
+
* schema — which type-first code, by construction, has not.
|
|
214
|
+
*/
|
|
215
|
+
export declare function schemaFromIR(ir: SchemaIR): CoreSchema<string>;
|
|
216
|
+
/**
|
|
217
|
+
* The **app** type: what handler code sees. A `timestamp` is a `Date` here, and
|
|
218
|
+
* a `bigint` is a `bigint`.
|
|
219
|
+
*/
|
|
220
|
+
export declare function appTypeOf(col: ColumnIR): TypeIR;
|
|
221
|
+
/**
|
|
222
|
+
* The **wire** type: what a JSON body actually contains. A `timestamp` is an
|
|
223
|
+
* ISO-8601 string, because a `Date` cannot survive JSON, and a `bigint` is a
|
|
224
|
+
* string for the same reason. Anything else matches the app type.
|
|
225
|
+
*/
|
|
226
|
+
export declare function wireTypeOf(col: ColumnIR): TypeIR;
|
|
227
|
+
export type Variant = 'entity' | 'create' | 'update' | 'get' | 'list' | 'search';
|
|
228
|
+
export interface JsonSchemaObject {
|
|
229
|
+
readonly type: 'object';
|
|
230
|
+
readonly properties: Readonly<Record<string, unknown>>;
|
|
231
|
+
readonly required: readonly string[];
|
|
232
|
+
}
|
|
233
|
+
/** A JSON-serialisable value, used by build artifacts that carry schema projections. */
|
|
234
|
+
export type JsonValue = null | boolean | number | string | readonly JsonValue[] | {
|
|
235
|
+
readonly [key: string]: JsonValue;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* A single column's JSON Schema. Emitted from the **wire** type, which is why a
|
|
239
|
+
* `timestamp` becomes `{type:'string',format:'date-time'}` here and a `Date` in
|
|
240
|
+
* `Entity<T>` — one column, two correct answers, each in its own layer.
|
|
241
|
+
*/
|
|
242
|
+
export declare function jsonSchemaForColumn(col: ColumnIR): Record<string, unknown>;
|
|
243
|
+
/**
|
|
244
|
+
* The JSON Schema projection of one structural type.
|
|
245
|
+
*
|
|
246
|
+
* HTTP contracts, validators and other build-time consumers call this after the
|
|
247
|
+
* existing reflector has produced TypeIR. Keeping the projection here prevents a
|
|
248
|
+
* second consumer from interpreting TypeScript types or re-walking schema metadata.
|
|
249
|
+
*/
|
|
250
|
+
export declare function jsonSchemaFromTypeIR(type: TypeIR): Record<string, JsonValue>;
|
|
251
|
+
/**
|
|
252
|
+
* A column, plus whether the shape it was read from makes it optional.
|
|
253
|
+
*
|
|
254
|
+
* This is what the JSON Schema back-end actually consumes, and it exists because a
|
|
255
|
+
* variant name and a derived type are two spellings of the same information.
|
|
256
|
+
* `toJsonSchema(schema, 'create')` names the variant, and the rule is "a column with a
|
|
257
|
+
* default is optional here". `toJsonSchema<CreateDTO<User>>()` names the type, and the
|
|
258
|
+
* type has already applied that rule — `createdAt?: Date & …` is optional because
|
|
259
|
+
* `CreateDTO` made it so.
|
|
260
|
+
*
|
|
261
|
+
* Collapsing both onto `optional` is what keeps REQ-TF-7 structural rather than tested.
|
|
262
|
+
* A second document generator that reads optionality off a type would be a fifth walker
|
|
263
|
+
* (`PLAN-type-first.md` §1) and would drift the way the other four did.
|
|
264
|
+
*/
|
|
265
|
+
export interface ShapeColumnIR {
|
|
266
|
+
readonly column: ColumnIR;
|
|
267
|
+
/** The document does not require this property. */
|
|
268
|
+
readonly optional: boolean;
|
|
269
|
+
}
|
|
270
|
+
/** The columns a document is generated from, in the order they were declared. */
|
|
271
|
+
export type ShapeIR = readonly ShapeColumnIR[];
|
|
272
|
+
/**
|
|
273
|
+
* A variant, rewritten as a shape.
|
|
274
|
+
*
|
|
275
|
+
* The three rules the variants used to spell out inline: an input variant has no
|
|
276
|
+
* database-generated columns at all, a patch requires nothing, and an input column with
|
|
277
|
+
* a default may be left out. Each is exactly what the corresponding derived type does to
|
|
278
|
+
* `Entity<T>`, which is the reason this translation exists rather than a coincidence.
|
|
279
|
+
*
|
|
280
|
+
* `update` also drops the primary key, which is what `UpdateDTO<T>` does and what this
|
|
281
|
+
* function did not: a patch body identifies its row in the URL, so a key in the body is
|
|
282
|
+
* either redundant or an attempt to move the row. It only ever showed for a *non-serial*
|
|
283
|
+
* key, since a serial one was already gone, which is why no existing document changes.
|
|
284
|
+
*/
|
|
285
|
+
export declare function shapeOfVariant(ir: SchemaIR, variant: Variant): ShapeIR;
|
|
286
|
+
/**
|
|
287
|
+
* The document for a shape.
|
|
288
|
+
*
|
|
289
|
+
* `required` is "not optional and not nullable", which is the single rule the three
|
|
290
|
+
* variants were three cases of. A nullable column is never required because the value
|
|
291
|
+
* `null` is admissible for it, so demanding the key adds nothing a validator can act on
|
|
292
|
+
* — that is pre-existing behaviour, preserved deliberately.
|
|
293
|
+
*
|
|
294
|
+
* Sensitive columns are dropped here, in the emitter, and not in the shape. A generated
|
|
295
|
+
* document is published, `Sensitive` means "must not be", and putting the filter at the
|
|
296
|
+
* last step is what makes that unconditional (REQ-TF-6): no variant, and no derived type
|
|
297
|
+
* a caller invents, can route around it. `CreateDTO<User>` deliberately *keeps* a
|
|
298
|
+
* sensitive column — you have to be able to send a password — and its document still
|
|
299
|
+
* must not name it.
|
|
300
|
+
*/
|
|
301
|
+
export declare function jsonSchemaFromShape(shape: ShapeIR): JsonSchemaObject;
|
|
302
|
+
/**
|
|
303
|
+
* The document for a variant. Byte-for-byte the contract `toJsonSchema` already
|
|
304
|
+
* publishes; the point is that it is a pure function of IR, so naming a variant and
|
|
305
|
+
* naming a derived type cannot produce different documents (REQ-TF-7). That AC stops
|
|
306
|
+
* being a test to chase and becomes the only thing the code can do.
|
|
307
|
+
*/
|
|
308
|
+
export declare function jsonSchemaFromIR(ir: SchemaIR, variant?: Variant): JsonSchemaObject;
|
|
309
|
+
/**
|
|
310
|
+
* Which of a column's three types to render (plan D3).
|
|
311
|
+
*
|
|
312
|
+
* `'app'` is what handler code holds: a `timestamp` is a `Date`. `'wire'` is what a JSON
|
|
313
|
+
* body contains: the same column is an ISO-8601 string. A validator has to pick one —
|
|
314
|
+
* accepting both is how the disagreement went unnoticed for so long — so the caller says
|
|
315
|
+
* which side of the boundary it is on.
|
|
316
|
+
*/
|
|
317
|
+
export type Layer = 'app' | 'wire';
|
|
318
|
+
/**
|
|
319
|
+
* A shape as the object type a validator checks against.
|
|
320
|
+
*
|
|
321
|
+
* Unlike the JSON Schema back-end this keeps sensitive columns: a payload validator that
|
|
322
|
+
* silently ignored `passwordHash` would reject every legitimate `create`. REQ-TF-6 is
|
|
323
|
+
* about what gets *published*, and nothing here is published.
|
|
324
|
+
*
|
|
325
|
+
* Column order is preserved rather than sorted, because a `TypeIR` is not a contract
|
|
326
|
+
* anybody serialises — the JSON Schema back-end sorts because a document is published
|
|
327
|
+
* and key order is part of it.
|
|
328
|
+
*/
|
|
329
|
+
export declare function objectTypeFromShape(shape: ShapeIR, layer?: Layer): ObjectIR;
|
|
330
|
+
/** The object type of one variant of one table, at one layer. */
|
|
331
|
+
export declare function objectTypeFromIR(ir: SchemaIR, variant?: Variant, layer?: Layer): ObjectIR;
|
|
332
|
+
/** How one named `Codec<'Name'>` column crosses the boundary. */
|
|
333
|
+
export interface Codec {
|
|
334
|
+
readonly decode: (wire: unknown) => unknown;
|
|
335
|
+
readonly encode: (app: unknown) => unknown;
|
|
336
|
+
}
|
|
337
|
+
/** Codec name → its conversions. Supplied by the application, not by zmdb. */
|
|
338
|
+
export type CodecRegistry = Readonly<Record<string, Codec>>;
|
|
339
|
+
/** One column's value, as the app layer holds it. */
|
|
340
|
+
export declare function decodeWireValue(col: ColumnIR, value: unknown, codecs?: CodecRegistry): unknown;
|
|
341
|
+
/** One column's value, as JSON can carry it. */
|
|
342
|
+
export declare function encodeWireValue(col: ColumnIR, value: unknown, codecs?: CodecRegistry): unknown;
|
|
343
|
+
/**
|
|
344
|
+
* A JSON body as an app-layer payload: the wire→app decode, once, at the boundary.
|
|
345
|
+
*
|
|
346
|
+
* Keys the variant does not have are copied through rather than dropped, because dropping
|
|
347
|
+
* them here would hide them from the repository's excess check — the decoder's job is to
|
|
348
|
+
* convert, and deciding what a payload may contain belongs to exactly one place.
|
|
349
|
+
*/
|
|
350
|
+
export declare function decodeWire(ir: SchemaIR, variant: Variant, body: Readonly<Record<string, unknown>>, codecs?: CodecRegistry): Record<string, unknown>;
|
|
351
|
+
/**
|
|
352
|
+
* A value that came out of a database, as the app layer holds it — the third layer's
|
|
353
|
+
* crossing (plan D3).
|
|
354
|
+
*
|
|
355
|
+
* Written in terms of what *arrived* rather than in terms of the dialect, and that is the
|
|
356
|
+
* whole design: `pg` hands back a `Date` for a `timestamptz` and a string for an `int8`,
|
|
357
|
+
* SQLite hands back the `TEXT` it stored and a `number` for an `INTEGER`, and a third
|
|
358
|
+
* driver will do something else again. Asking "is this already the app value?" answers all
|
|
359
|
+
* of them, and keeps this function out of the dialect's business — which is the constraint
|
|
360
|
+
* the whole IR is written under.
|
|
361
|
+
*
|
|
362
|
+
* `timestamp` and `bigint` are the only core types whose app values need a distinct JSON
|
|
363
|
+
* wire form. The db crossing also handles extension vectors: their app and wire forms are
|
|
364
|
+
* both number arrays, but a driver without pgvector's parser can return the database text
|
|
365
|
+
* form instead.
|
|
366
|
+
*/
|
|
367
|
+
export declare function decodeDbValue(col: ColumnIR, value: unknown): unknown;
|
|
368
|
+
/** Which columns `decodeDbValue` can change — so a read path can skip the walk entirely. */
|
|
369
|
+
export declare function dbDecodedColumns(ir: SchemaIR): readonly ColumnIR[];
|
|
370
|
+
/** A row as a JSON body: the app→wire encode, for a response. */
|
|
371
|
+
export declare function encodeWire(ir: SchemaIR, row: Readonly<Record<string, unknown>>, codecs?: CodecRegistry): Record<string, unknown>;
|
|
372
|
+
export { discriminantOf, expectedForConstraint, expectedForDiscriminant, expectedOf, hasExcessCheck, messageFor, } from './validation-shape.js';
|
|
373
|
+
export type { ConstraintKeyword, Discriminant, DiscriminantArm } from './validation-shape.js';
|
|
374
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ir/index.ts"],"names":[],"mappings":"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"}
|