@assemora/schema 0.1.0

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.
@@ -0,0 +1,377 @@
1
+ import { fail, ok, } from './types.js';
2
+ /** Adds "may be absent" without touching the wrapped schema. */
3
+ const optionalOf = (inner) => ({
4
+ ...inner,
5
+ isOptional: true,
6
+ parse: (value) => value === undefined ? ok(undefined) : inner.parse(value),
7
+ });
8
+ /** Adds "may be null" without touching the wrapped schema. */
9
+ const nullableOf = (inner) => ({
10
+ ...inner,
11
+ isNullable: true,
12
+ parse: (value) => value === null ? ok(null) : inner.parse(value),
13
+ toJsonSchema: () => ({ ...inner.toJsonSchema(), nullable: true }),
14
+ });
15
+ /**
16
+ * The two modifiers, as combinators, for a schema whose builder is out of reach.
17
+ *
18
+ * `string().optional()` is how a *declaration* says it. These are how a caller holding
19
+ * a `Schema<T>` says the same thing — and by the time a schema crosses a package
20
+ * boundary that is all it is: `@assemora/resources` builds a group's shape out of the
21
+ * schemas its fields carry, and those arrive already erased to the interface. Without
22
+ * these the only way to make one of them absent-able is to rebuild the wrapper object
23
+ * by hand in every package that needs one, which is how the meaning of "optional"
24
+ * comes to differ between two of them.
25
+ */
26
+ export const optional = (inner) => optionalOf(inner);
27
+ export const nullable = (inner) => nullableOf(inner);
28
+ const applyRefinements = (value, refinements) => refinements.map((refine) => refine(value)).filter((issue) => issue !== undefined);
29
+ const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
30
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
31
+ const buildString = (state) => {
32
+ const self = {
33
+ kind: 'string',
34
+ isOptional: false,
35
+ isNullable: false,
36
+ description: state.description,
37
+ parse: (value) => {
38
+ if (typeof value !== 'string')
39
+ return fail('type', 'Expected a string');
40
+ const issues = applyRefinements(value, state.refinements);
41
+ return issues.length > 0 ? { ok: false, issues } : ok(value);
42
+ },
43
+ toJsonSchema: () => ({
44
+ type: 'string',
45
+ ...state.json,
46
+ ...(state.description === undefined ? {} : { description: state.description }),
47
+ }),
48
+ min: (length) => buildString({
49
+ ...state,
50
+ json: { ...state.json, minLength: length },
51
+ refinements: [
52
+ ...state.refinements,
53
+ (value) => value.length < length
54
+ ? {
55
+ path: [],
56
+ code: 'min',
57
+ message: `Must be at least ${length} characters`,
58
+ params: { length },
59
+ }
60
+ : undefined,
61
+ ],
62
+ }),
63
+ max: (length) => buildString({
64
+ ...state,
65
+ json: { ...state.json, maxLength: length },
66
+ refinements: [
67
+ ...state.refinements,
68
+ (value) => value.length > length
69
+ ? {
70
+ path: [],
71
+ code: 'max',
72
+ message: `Must be at most ${length} characters`,
73
+ params: { length },
74
+ }
75
+ : undefined,
76
+ ],
77
+ }),
78
+ pattern: (expression, message = 'Invalid format') => buildString({
79
+ ...state,
80
+ json: { ...state.json, pattern: expression.source },
81
+ refinements: [
82
+ ...state.refinements,
83
+ (value) => (expression.test(value) ? undefined : { path: [], code: 'pattern', message }),
84
+ ],
85
+ }),
86
+ email: () => buildString({
87
+ ...state,
88
+ json: { ...state.json, format: 'email' },
89
+ refinements: [
90
+ ...state.refinements,
91
+ (value) => EMAIL.test(value) ? undefined : { path: [], code: 'email', message: 'Invalid email' },
92
+ ],
93
+ }),
94
+ uuid: () => buildString({
95
+ ...state,
96
+ json: { ...state.json, format: 'uuid' },
97
+ refinements: [
98
+ ...state.refinements,
99
+ (value) => UUID.test(value) ? undefined : { path: [], code: 'uuid', message: 'Invalid UUID' },
100
+ ],
101
+ }),
102
+ describe: (text) => buildString({ ...state, description: text }),
103
+ optional: () => optionalOf(self),
104
+ nullable: () => nullableOf(self),
105
+ };
106
+ return self;
107
+ };
108
+ export const string = () => buildString({ refinements: [], json: {}, description: undefined });
109
+ /** A UUID string. Shorthand for `string().uuid()`, which reads better in a model. */
110
+ export const uuid = () => string().uuid();
111
+ /** An email address. Shorthand for `string().email()`. */
112
+ export const email = () => string().email();
113
+ const buildNumber = (state) => {
114
+ const self = {
115
+ kind: 'number',
116
+ isOptional: false,
117
+ isNullable: false,
118
+ description: state.description,
119
+ parse: (value) => {
120
+ if (typeof value !== 'number' || Number.isNaN(value))
121
+ return fail('type', 'Expected a number');
122
+ const issues = applyRefinements(value, state.refinements);
123
+ return issues.length > 0 ? { ok: false, issues } : ok(value);
124
+ },
125
+ toJsonSchema: () => ({
126
+ type: 'number',
127
+ ...state.json,
128
+ ...(state.description === undefined ? {} : { description: state.description }),
129
+ }),
130
+ min: (minimum) => buildNumber({
131
+ ...state,
132
+ json: { ...state.json, minimum },
133
+ refinements: [
134
+ ...state.refinements,
135
+ (value) => value < minimum
136
+ ? {
137
+ path: [],
138
+ code: 'min',
139
+ message: `Must be at least ${minimum}`,
140
+ params: { minimum },
141
+ }
142
+ : undefined,
143
+ ],
144
+ }),
145
+ max: (maximum) => buildNumber({
146
+ ...state,
147
+ json: { ...state.json, maximum },
148
+ refinements: [
149
+ ...state.refinements,
150
+ (value) => value > maximum
151
+ ? {
152
+ path: [],
153
+ code: 'max',
154
+ message: `Must be at most ${maximum}`,
155
+ params: { maximum },
156
+ }
157
+ : undefined,
158
+ ],
159
+ }),
160
+ integer: () => buildNumber({
161
+ ...state,
162
+ json: { ...state.json, type: 'integer' },
163
+ refinements: [
164
+ ...state.refinements,
165
+ (value) => Number.isInteger(value)
166
+ ? undefined
167
+ : { path: [], code: 'integer', message: 'Must be an integer' },
168
+ ],
169
+ }),
170
+ describe: (text) => buildNumber({ ...state, description: text }),
171
+ optional: () => optionalOf(self),
172
+ nullable: () => nullableOf(self),
173
+ };
174
+ return self;
175
+ };
176
+ export const number = () => buildNumber({ refinements: [], json: {}, description: undefined });
177
+ export const integer = () => number().integer();
178
+ const buildBoolean = (description) => {
179
+ const self = {
180
+ kind: 'boolean',
181
+ isOptional: false,
182
+ isNullable: false,
183
+ description,
184
+ parse: (value) => typeof value === 'boolean' ? ok(value) : fail('type', 'Expected a boolean'),
185
+ toJsonSchema: () => ({
186
+ type: 'boolean',
187
+ ...(description === undefined ? {} : { description }),
188
+ }),
189
+ describe: (text) => buildBoolean(text),
190
+ optional: () => optionalOf(self),
191
+ nullable: () => nullableOf(self),
192
+ };
193
+ return self;
194
+ };
195
+ export const boolean = () => buildBoolean(undefined);
196
+ const buildEnum = (values, description) => {
197
+ const allowed = new Set(values);
198
+ const self = {
199
+ kind: 'enum',
200
+ isOptional: false,
201
+ isNullable: false,
202
+ description,
203
+ values,
204
+ parse: (value) => typeof value === 'string' && allowed.has(value)
205
+ ? ok(value)
206
+ : fail('enum', `Expected one of: ${values.join(', ')}`, [], { values: [...values] }),
207
+ toJsonSchema: () => ({
208
+ type: 'string',
209
+ enum: [...values],
210
+ ...(description === undefined ? {} : { description }),
211
+ }),
212
+ describe: (text) => buildEnum(values, text),
213
+ optional: () => optionalOf(self),
214
+ nullable: () => nullableOf(self),
215
+ };
216
+ return self;
217
+ };
218
+ /** `enumOf('draft', 'published')` infers the literal union, not `string`. */
219
+ export const enumOf = (...values) => buildEnum(values, undefined);
220
+ const buildTimestamp = (description) => {
221
+ const self = {
222
+ kind: 'timestamp',
223
+ isOptional: false,
224
+ isNullable: false,
225
+ description,
226
+ parse: (value) => {
227
+ if (value instanceof Date) {
228
+ return Number.isNaN(value.getTime()) ? fail('type', 'Invalid date') : ok(value);
229
+ }
230
+ if (typeof value === 'string' || typeof value === 'number') {
231
+ const parsed = new Date(value);
232
+ return Number.isNaN(parsed.getTime()) ? fail('type', 'Invalid date') : ok(parsed);
233
+ }
234
+ return fail('type', 'Expected a date');
235
+ },
236
+ toJsonSchema: () => ({
237
+ type: 'string',
238
+ format: 'date-time',
239
+ ...(description === undefined ? {} : { description }),
240
+ }),
241
+ describe: (text) => buildTimestamp(text),
242
+ optional: () => optionalOf(self),
243
+ nullable: () => nullableOf(self),
244
+ };
245
+ return self;
246
+ };
247
+ export const timestamp = () => buildTimestamp(undefined);
248
+ const buildJson = (description) => {
249
+ const self = {
250
+ kind: 'json',
251
+ isOptional: false,
252
+ isNullable: false,
253
+ description,
254
+ parse: (value) => {
255
+ if (value === undefined || typeof value === 'function') {
256
+ return fail('type', 'Expected a JSON value');
257
+ }
258
+ // The caller states the shape through the type argument; JSON has no runtime
259
+ // description of it. Structural checking belongs in an explicit object().
260
+ return ok(value);
261
+ },
262
+ toJsonSchema: () => ({
263
+ ...(description === undefined ? {} : { description }),
264
+ }),
265
+ describe: (text) => buildJson(text),
266
+ optional: () => optionalOf(self),
267
+ nullable: () => nullableOf(self),
268
+ };
269
+ return self;
270
+ };
271
+ /** An opaque JSON payload whose shape the caller declares: `json<UserSettings>()`. */
272
+ export const json = () => buildJson(undefined);
273
+ const buildUnknown = (description) => {
274
+ const self = {
275
+ kind: 'unknown',
276
+ isOptional: false,
277
+ isNullable: false,
278
+ description,
279
+ parse: (value) => ok(value),
280
+ toJsonSchema: () => ({ ...(description === undefined ? {} : { description }) }),
281
+ describe: (text) => buildUnknown(text),
282
+ optional: () => optionalOf(self),
283
+ };
284
+ return self;
285
+ };
286
+ export const unknown = () => buildUnknown(undefined);
287
+ const buildBigInt = (description) => {
288
+ const self = {
289
+ kind: 'bigint',
290
+ isOptional: false,
291
+ isNullable: false,
292
+ description,
293
+ parse: (value) => {
294
+ if (typeof value === 'bigint')
295
+ return ok(value);
296
+ if (typeof value === 'number' && Number.isInteger(value))
297
+ return ok(BigInt(value));
298
+ if (typeof value === 'string' && /^-?\d+$/.test(value))
299
+ return ok(BigInt(value));
300
+ return fail('type', 'Expected a big integer');
301
+ },
302
+ toJsonSchema: () => ({
303
+ type: 'string',
304
+ format: 'int64',
305
+ ...(description === undefined ? {} : { description }),
306
+ }),
307
+ describe: (text) => buildBigInt(text),
308
+ optional: () => optionalOf(self),
309
+ nullable: () => nullableOf(self),
310
+ };
311
+ return self;
312
+ };
313
+ export const bigint = () => buildBigInt(undefined);
314
+ /** Canonical base64. Anything else is not what `contentEncoding` promised. */
315
+ const BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
316
+ const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
317
+ /**
318
+ * Decoded here rather than through `atob` or `Buffer`.
319
+ *
320
+ * This package has no dependencies and runs in a browser, in Node and in a worker
321
+ * (SPEC.md §8), and those two names are not all present in all three.
322
+ */
323
+ const decodeBase64 = (value) => {
324
+ if (!BASE64.test(value))
325
+ return undefined;
326
+ const body = value.replace(/=+$/, '');
327
+ const decoded = new Uint8Array((body.length * 3) >> 2);
328
+ let accumulator = 0;
329
+ let bits = 0;
330
+ let written = 0;
331
+ for (const character of body) {
332
+ const index = ALPHABET.indexOf(character);
333
+ accumulator = (accumulator << 6) | index;
334
+ bits += 6;
335
+ if (bits >= 8) {
336
+ bits -= 8;
337
+ decoded[written] = (accumulator >> bits) & 0xff;
338
+ written += 1;
339
+ }
340
+ }
341
+ return decoded;
342
+ };
343
+ const buildBinary = (description) => {
344
+ const self = {
345
+ kind: 'binary',
346
+ isOptional: false,
347
+ isNullable: false,
348
+ description,
349
+ /**
350
+ * Bytes in process, base64 over the wire.
351
+ *
352
+ * The JSON description says `contentEncoding: base64`, and a schema that
353
+ * publishes an encoding it will not accept is describing something it is not.
354
+ * JSON has no bytes, so an upload arriving over HTTP has no other form.
355
+ */
356
+ parse: (value) => {
357
+ if (value instanceof Uint8Array)
358
+ return ok(value);
359
+ if (typeof value === 'string') {
360
+ const decoded = decodeBase64(value);
361
+ return decoded === undefined ? fail('encoding', 'Expected base64 data') : ok(decoded);
362
+ }
363
+ return fail('type', 'Expected binary data');
364
+ },
365
+ toJsonSchema: () => ({
366
+ type: 'string',
367
+ contentEncoding: 'base64',
368
+ ...(description === undefined ? {} : { description }),
369
+ }),
370
+ describe: (text) => buildBinary(text),
371
+ optional: () => optionalOf(self),
372
+ nullable: () => nullableOf(self),
373
+ };
374
+ return self;
375
+ };
376
+ export const binary = () => buildBinary(undefined);
377
+ //# sourceMappingURL=primitives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.js","sourceRoot":"","sources":["../src/primitives.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * The vocabulary every other layer speaks.
3
+ *
4
+ * A schema carries three things at once: a runtime parser, a compile-time type and
5
+ * a neutral JSON description. One declaration therefore feeds validation, the
6
+ * database, Studio forms, OpenAPI, the SDK and MCP (SPEC.md §3.4, §42).
7
+ */
8
+ /**
9
+ * What a refinement knows about the failure beyond its code.
10
+ *
11
+ * `string().min(9)` fails with `code: 'min'` and `params: { length: 9 }`, and the nine
12
+ * is the whole reason a translated message can exist: a sentence with the number
13
+ * already baked into it can only ever be rewritten, never translated.
14
+ */
15
+ export type IssueParams = Readonly<Record<string, string | number | readonly (string | number)[]>>;
16
+ /**
17
+ * A single validation failure, addressed by its path inside the value.
18
+ *
19
+ * `message` is English and always will be. It is what a developer reads in a log and
20
+ * what a client with no message catalogue of its own can fall back on; `code` plus
21
+ * `params` is what a site with more than one language renders instead. Both travel to
22
+ * the caller — `ValidationError.toPayload` carries the issues beside the field grouping
23
+ * SPEC.md §84 fixes — because dropping the code was what made a form in Ukrainian print
24
+ * `Must be at least 9 characters`.
25
+ */
26
+ export type Issue = {
27
+ readonly path: readonly (string | number)[];
28
+ readonly code: string;
29
+ readonly message: string;
30
+ readonly params?: IssueParams;
31
+ };
32
+ /**
33
+ * Parsing never throws: a caller decides what a failure means. `@assemora/core`
34
+ * turns issues into a `VALIDATION_ERROR` response (SPEC.md §84).
35
+ */
36
+ export type ParseResult<T> = {
37
+ readonly ok: true;
38
+ readonly value: T;
39
+ } | {
40
+ readonly ok: false;
41
+ readonly issues: readonly Issue[];
42
+ };
43
+ /** A JSON Schema fragment, kept structural so no subsystem owns the format. */
44
+ export type JsonSchema = Readonly<Record<string, unknown>>;
45
+ export type SchemaKind = 'string' | 'number' | 'bigint' | 'binary' | 'boolean' | 'enum' | 'timestamp' | 'json' | 'unknown' | 'array' | 'object';
46
+ /**
47
+ * The inferred type travels through `parse`, so no phantom property and no cast is
48
+ * needed to carry it.
49
+ */
50
+ export type Schema<T = unknown> = {
51
+ readonly kind: SchemaKind;
52
+ readonly isOptional: boolean;
53
+ readonly isNullable: boolean;
54
+ readonly description: string | undefined;
55
+ parse(value: unknown): ParseResult<T>;
56
+ toJsonSchema(): JsonSchema;
57
+ };
58
+ /** A schema whose key may be absent from an object. */
59
+ export type OptionalSchema<T> = Schema<T | undefined> & {
60
+ readonly isOptional: true;
61
+ };
62
+ /** The type a schema produces. */
63
+ export type Infer<S> = S extends {
64
+ parse(value: unknown): ParseResult<infer T>;
65
+ } ? T : never;
66
+ /** A record of named schemas — the shape of an object, a command input, a route body. */
67
+ export type Shape = Readonly<Record<string, Schema>>;
68
+ type Simplify<T> = {
69
+ [K in keyof T]: T[K];
70
+ } & {};
71
+ type OptionalKeys<S extends Shape> = {
72
+ [K in keyof S]: S[K] extends {
73
+ readonly isOptional: true;
74
+ } ? K : never;
75
+ }[keyof S];
76
+ /** The type an object shape produces, with optional keys kept optional. */
77
+ export type InferShape<S extends Shape> = Simplify<{
78
+ [K in Exclude<keyof S, OptionalKeys<S>>]: Infer<S[K]>;
79
+ } & {
80
+ [K in OptionalKeys<S>]?: Exclude<Infer<S[K]>, undefined>;
81
+ }>;
82
+ export declare const ok: <T>(value: T) => ParseResult<T>;
83
+ export declare const fail: (code: string, message: string, path?: readonly (string | number)[], params?: IssueParams) => {
84
+ readonly ok: false;
85
+ readonly issues: readonly [{
86
+ readonly path: readonly (string | number)[];
87
+ readonly code: string;
88
+ readonly message: string;
89
+ readonly params?: Readonly<Record<string, string | number | readonly (string | number)[]>>;
90
+ }];
91
+ };
92
+ export declare const failWith: (issues: readonly Issue[]) => ParseResult<never>;
93
+ /** Re-addresses issues from a nested value into the parent's coordinate space. */
94
+ export declare const nest: (key: string | number, issues: readonly Issue[]) => Issue[];
95
+ export {};
96
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The vocabulary every other layer speaks.
3
+ *
4
+ * A schema carries three things at once: a runtime parser, a compile-time type and
5
+ * a neutral JSON description. One declaration therefore feeds validation, the
6
+ * database, Studio forms, OpenAPI, the SDK and MCP (SPEC.md §3.4, §42).
7
+ */
8
+ export const ok = (value) => ({ ok: true, value });
9
+ export const fail = (code, message, path = [], params) => ({
10
+ ok: false,
11
+ issues: [{ path, code, message, ...(params === undefined ? {} : { params }) }],
12
+ });
13
+ export const failWith = (issues) => ({ ok: false, issues });
14
+ /** Re-addresses issues from a nested value into the parent's coordinate space. */
15
+ export const nest = (key, issues) => issues.map((issue) => ({ ...issue, path: [key, ...issue.path] }));
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuFH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAI,KAAQ,EAAkB,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;AAExE,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,IAAY,EACZ,OAAe,EACf,IAAI,GAAiC,EAAE,EACvC,MAAoB,EACpB,EAAE,CACF,CAAC;IACC,EAAE,EAAE,KAAK;IACT,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;CAC/E,CAAU,CAAA;AAEb,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAAwB,EAAsB,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;AAEjG,kFAAkF;AAClF,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,GAAoB,EAAE,MAAwB,EAAW,EAAE,CAC9E,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@assemora/schema",
3
+ "version": "0.1.0",
4
+ "description": "Schema primitives: field definitions, type inference, neutral JSON representation",
5
+ "license": "Apache-2.0",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/assemora/assemora.git",
12
+ "directory": "packages/schema"
13
+ },
14
+ "type": "module",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ }
20
+ },
21
+ "main": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "files": [
24
+ "dist",
25
+ "!dist/.tsbuildinfo"
26
+ ],
27
+ "scripts": {
28
+ "build": "tsc -b tsconfig.build.json",
29
+ "typecheck": "tsc -p tsconfig.json --noEmit",
30
+ "clean": "rm -rf dist *.tsbuildinfo"
31
+ }
32
+ }