@fougere/schema 0.2.0-alpha.1 → 0.3.0-alpha.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.
- package/dist/EntityDeclarations.d.ts +22 -0
- package/dist/EntityDeclarations.d.ts.map +1 -0
- package/dist/EntityDeclarations.js +19 -0
- package/dist/EntityDeclarations.js.map +1 -0
- package/dist/Field.d.ts +21 -0
- package/dist/Field.d.ts.map +1 -0
- package/dist/Field.js +50 -0
- package/dist/Field.js.map +1 -0
- package/dist/Schema.d.ts +67 -0
- package/dist/Schema.d.ts.map +1 -0
- package/dist/Schema.js +152 -0
- package/dist/Schema.js.map +1 -0
- package/dist/SchemaView.d.ts +18 -0
- package/dist/SchemaView.d.ts.map +1 -0
- package/dist/SchemaView.js +2 -0
- package/dist/SchemaView.js.map +1 -0
- package/dist/axis/Axis.d.ts +10 -0
- package/dist/axis/Axis.d.ts.map +1 -0
- package/dist/axis/Axis.js +9 -0
- package/dist/axis/Axis.js.map +1 -0
- package/dist/axis/Meta.d.ts +4 -0
- package/dist/axis/Meta.d.ts.map +1 -0
- package/dist/axis/Meta.js +2 -0
- package/dist/axis/Meta.js.map +1 -0
- package/dist/axis/boundary/Boundaries.d.ts +20 -0
- package/dist/axis/boundary/Boundaries.d.ts.map +1 -0
- package/dist/axis/boundary/Boundaries.js +31 -0
- package/dist/axis/boundary/Boundaries.js.map +1 -0
- package/dist/axis/boundary/Boundary.d.ts +26 -0
- package/dist/axis/boundary/Boundary.d.ts.map +1 -0
- package/dist/axis/boundary/Boundary.js +53 -0
- package/dist/axis/boundary/Boundary.js.map +1 -0
- package/dist/axis/boundary/axis.d.ts +4 -0
- package/dist/axis/boundary/axis.d.ts.map +1 -0
- package/dist/axis/boundary/axis.js +29 -0
- package/dist/axis/boundary/axis.js.map +1 -0
- package/dist/axis/lifecycle/Generators.d.ts +4 -0
- package/dist/axis/lifecycle/Generators.d.ts.map +1 -0
- package/dist/axis/lifecycle/Generators.js +8 -0
- package/dist/axis/lifecycle/Generators.js.map +1 -0
- package/dist/axis/lifecycle/Lifecycle.d.ts +28 -0
- package/dist/axis/lifecycle/Lifecycle.d.ts.map +1 -0
- package/dist/axis/lifecycle/Lifecycle.js +38 -0
- package/dist/axis/lifecycle/Lifecycle.js.map +1 -0
- package/dist/axis/lifecycle/apply.d.ts +8 -0
- package/dist/axis/lifecycle/apply.d.ts.map +1 -0
- package/dist/axis/lifecycle/apply.js +72 -0
- package/dist/axis/lifecycle/apply.js.map +1 -0
- package/dist/axis/lifecycle/axis.d.ts +4 -0
- package/dist/axis/lifecycle/axis.d.ts.map +1 -0
- package/dist/axis/lifecycle/axis.js +46 -0
- package/dist/axis/lifecycle/axis.js.map +1 -0
- package/dist/axis/role/Relation.d.ts +10 -0
- package/dist/axis/role/Relation.d.ts.map +1 -0
- package/dist/axis/role/Relation.js +6 -0
- package/dist/axis/role/Relation.js.map +1 -0
- package/dist/axis/role/Role.d.ts +38 -0
- package/dist/axis/role/Role.d.ts.map +1 -0
- package/dist/axis/role/Role.js +50 -0
- package/dist/axis/role/Role.js.map +1 -0
- package/dist/axis/role/axis.d.ts +5 -0
- package/dist/axis/role/axis.d.ts.map +1 -0
- package/dist/axis/role/axis.js +101 -0
- package/dist/axis/role/axis.js.map +1 -0
- package/dist/axis/shape/Formats.d.ts +8 -0
- package/dist/axis/shape/Formats.d.ts.map +1 -0
- package/dist/axis/shape/Formats.js +10 -0
- package/dist/axis/shape/Formats.js.map +1 -0
- package/dist/axis/shape/Shape.d.ts +58 -0
- package/dist/axis/shape/Shape.d.ts.map +1 -0
- package/dist/axis/shape/Shape.js +52 -0
- package/dist/axis/shape/Shape.js.map +1 -0
- package/dist/card/Descriptor.d.ts +55 -0
- package/dist/card/Descriptor.d.ts.map +1 -0
- package/dist/card/Descriptor.js +2 -0
- package/dist/card/Descriptor.js.map +1 -0
- package/dist/card/describe.d.ts +12 -0
- package/dist/card/describe.d.ts.map +1 -0
- package/dist/card/describe.js +83 -0
- package/dist/card/describe.js.map +1 -0
- package/dist/card/diff.d.ts +140 -0
- package/dist/card/diff.d.ts.map +1 -0
- package/dist/card/diff.js +123 -0
- package/dist/card/diff.js.map +1 -0
- package/dist/card/reconstruct.d.ts +11 -0
- package/dist/card/reconstruct.d.ts.map +1 -0
- package/dist/card/reconstruct.js +83 -0
- package/dist/card/reconstruct.js.map +1 -0
- package/dist/card/typescript.d.ts +17 -0
- package/dist/card/typescript.d.ts.map +1 -0
- package/dist/card/typescript.js +93 -0
- package/dist/card/typescript.js.map +1 -0
- package/dist/clean.d.ts +2 -0
- package/dist/clean.d.ts.map +1 -0
- package/dist/{projections/card.js → clean.js} +1 -2
- package/dist/clean.js.map +1 -0
- package/dist/constraint/FieldGroup.d.ts +21 -0
- package/dist/constraint/FieldGroup.d.ts.map +1 -0
- package/dist/constraint/FieldGroup.js +65 -0
- package/dist/constraint/FieldGroup.js.map +1 -0
- package/dist/constraint/Unique.d.ts +4 -0
- package/dist/constraint/Unique.d.ts.map +1 -0
- package/dist/constraint/Unique.js +4 -0
- package/dist/constraint/Unique.js.map +1 -0
- package/dist/entity.d.ts +4 -116
- package/dist/entity.d.ts.map +1 -1
- package/dist/entity.js +13 -289
- package/dist/entity.js.map +1 -1
- package/dist/index.d.ts +35 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -26
- package/dist/index.js.map +1 -1
- package/dist/judge/Judge.d.ts +14 -0
- package/dist/judge/Judge.d.ts.map +1 -0
- package/dist/judge/Judge.js +161 -0
- package/dist/judge/Judge.js.map +1 -0
- package/dist/judge/cases.d.ts +50 -0
- package/dist/judge/cases.d.ts.map +1 -0
- package/dist/judge/cases.js +100 -0
- package/dist/judge/cases.js.map +1 -0
- package/dist/judge/form.d.ts +11 -0
- package/dist/judge/form.d.ts.map +1 -0
- package/dist/judge/form.js +18 -0
- package/dist/judge/form.js.map +1 -0
- package/dist/judge/options.d.ts +4 -0
- package/dist/judge/options.d.ts.map +1 -0
- package/dist/judge/options.js +2 -0
- package/dist/judge/options.js.map +1 -0
- package/dist/judge/result.d.ts +17 -0
- package/dist/judge/result.d.ts.map +1 -0
- package/dist/judge/result.js +2 -0
- package/dist/judge/result.js.map +1 -0
- package/dist/name.d.ts +1 -14
- package/dist/name.d.ts.map +1 -1
- package/dist/name.js +3 -14
- package/dist/name.js.map +1 -1
- package/dist/projection/encode.d.ts +3 -0
- package/dist/projection/encode.d.ts.map +1 -0
- package/dist/projection/encode.js +19 -0
- package/dist/projection/encode.js.map +1 -0
- package/dist/projection/io.d.ts +4 -0
- package/dist/projection/io.d.ts.map +1 -0
- package/dist/projection/io.js +29 -0
- package/dist/projection/io.js.map +1 -0
- package/dist/projection/source.d.ts +7 -0
- package/dist/projection/source.d.ts.map +1 -0
- package/dist/projection/source.js +11 -0
- package/dist/projection/source.js.map +1 -0
- package/dist/{projections → projection}/standard.d.ts +0 -8
- package/dist/projection/standard.d.ts.map +1 -0
- package/dist/projection/standard.js +2 -0
- package/dist/projection/standard.js.map +1 -0
- package/dist/same.d.ts +6 -0
- package/dist/same.d.ts.map +1 -0
- package/dist/same.js +35 -0
- package/dist/same.js.map +1 -0
- package/dist/vocabulary/bool.d.ts +1 -1
- package/dist/vocabulary/bool.d.ts.map +1 -1
- package/dist/vocabulary/bool.js +2 -2
- package/dist/vocabulary/bool.js.map +1 -1
- package/dist/vocabulary/created.d.ts +2 -12
- package/dist/vocabulary/created.d.ts.map +1 -1
- package/dist/vocabulary/created.js +3 -14
- package/dist/vocabulary/created.js.map +1 -1
- package/dist/vocabulary/date.d.ts +1 -1
- package/dist/vocabulary/date.d.ts.map +1 -1
- package/dist/vocabulary/date.js +2 -2
- package/dist/vocabulary/date.js.map +1 -1
- package/dist/vocabulary/email.d.ts +1 -2
- package/dist/vocabulary/email.d.ts.map +1 -1
- package/dist/vocabulary/email.js +0 -1
- package/dist/vocabulary/email.js.map +1 -1
- package/dist/vocabulary/immutable.d.ts +2 -8
- package/dist/vocabulary/immutable.d.ts.map +1 -1
- package/dist/vocabulary/immutable.js +4 -10
- package/dist/vocabulary/immutable.js.map +1 -1
- package/dist/vocabulary/indexed.d.ts +2 -18
- package/dist/vocabulary/indexed.d.ts.map +1 -1
- package/dist/vocabulary/indexed.js +2 -20
- package/dist/vocabulary/indexed.js.map +1 -1
- package/dist/vocabulary/json.d.ts +3 -16
- package/dist/vocabulary/json.d.ts.map +1 -1
- package/dist/vocabulary/json.js +12 -9
- package/dist/vocabulary/json.js.map +1 -1
- package/dist/vocabulary/list.d.ts +2 -16
- package/dist/vocabulary/list.d.ts.map +1 -1
- package/dist/vocabulary/list.js +3 -15
- package/dist/vocabulary/list.js.map +1 -1
- package/dist/vocabulary/many.d.ts +2 -6
- package/dist/vocabulary/many.d.ts.map +1 -1
- package/dist/vocabulary/many.js +4 -7
- package/dist/vocabulary/many.js.map +1 -1
- package/dist/vocabulary/nullable.d.ts +2 -8
- package/dist/vocabulary/nullable.d.ts.map +1 -1
- package/dist/vocabulary/nullable.js +5 -12
- package/dist/vocabulary/nullable.js.map +1 -1
- package/dist/vocabulary/number.d.ts +1 -1
- package/dist/vocabulary/number.d.ts.map +1 -1
- package/dist/vocabulary/number.js +2 -2
- package/dist/vocabulary/number.js.map +1 -1
- package/dist/vocabulary/oneOf.d.ts +1 -8
- package/dist/vocabulary/oneOf.d.ts.map +1 -1
- package/dist/vocabulary/oneOf.js +2 -2
- package/dist/vocabulary/oneOf.js.map +1 -1
- package/dist/vocabulary/optional.d.ts +2 -9
- package/dist/vocabulary/optional.d.ts.map +1 -1
- package/dist/vocabulary/optional.js +6 -14
- package/dist/vocabulary/optional.js.map +1 -1
- package/dist/vocabulary/primary.d.ts +4 -17
- package/dist/vocabulary/primary.d.ts.map +1 -1
- package/dist/vocabulary/primary.js +10 -13
- package/dist/vocabulary/primary.js.map +1 -1
- package/dist/vocabulary/readOnly.d.ts +2 -9
- package/dist/vocabulary/readOnly.d.ts.map +1 -1
- package/dist/vocabulary/readOnly.js +5 -11
- package/dist/vocabulary/readOnly.js.map +1 -1
- package/dist/vocabulary/ref.d.ts +2 -7
- package/dist/vocabulary/ref.d.ts.map +1 -1
- package/dist/vocabulary/ref.js +3 -8
- package/dist/vocabulary/ref.js.map +1 -1
- package/dist/vocabulary/text.d.ts +2 -2
- package/dist/vocabulary/text.d.ts.map +1 -1
- package/dist/vocabulary/text.js +2 -2
- package/dist/vocabulary/text.js.map +1 -1
- package/dist/vocabulary/unique.d.ts +2 -22
- package/dist/vocabulary/unique.d.ts.map +1 -1
- package/dist/vocabulary/unique.js +5 -24
- package/dist/vocabulary/unique.js.map +1 -1
- package/dist/vocabulary/updated.d.ts +2 -7
- package/dist/vocabulary/updated.d.ts.map +1 -1
- package/dist/vocabulary/updated.js +1 -7
- package/dist/vocabulary/updated.js.map +1 -1
- package/dist/vocabulary/url.d.ts +1 -2
- package/dist/vocabulary/url.d.ts.map +1 -1
- package/dist/vocabulary/url.js +0 -1
- package/dist/vocabulary/url.js.map +1 -1
- package/dist/vocabulary/vocabulary.d.ts +5 -0
- package/dist/vocabulary/vocabulary.d.ts.map +1 -0
- package/dist/vocabulary/vocabulary.js +31 -0
- package/dist/vocabulary/vocabulary.js.map +1 -0
- package/dist/vocabulary/writeOnly.d.ts +2 -8
- package/dist/vocabulary/writeOnly.d.ts.map +1 -1
- package/dist/vocabulary/writeOnly.js +5 -10
- package/dist/vocabulary/writeOnly.js.map +1 -1
- package/package.json +2 -2
- package/dist/field/boundary.d.ts +0 -86
- package/dist/field/boundary.d.ts.map +0 -1
- package/dist/field/boundary.js +0 -94
- package/dist/field/boundary.js.map +0 -1
- package/dist/field/field.d.ts +0 -64
- package/dist/field/field.d.ts.map +0 -1
- package/dist/field/field.js +0 -28
- package/dist/field/field.js.map +0 -1
- package/dist/field/index.d.ts +0 -7
- package/dist/field/index.d.ts.map +0 -1
- package/dist/field/index.js +0 -9
- package/dist/field/index.js.map +0 -1
- package/dist/field/lifecycle.d.ts +0 -40
- package/dist/field/lifecycle.d.ts.map +0 -1
- package/dist/field/lifecycle.js +0 -27
- package/dist/field/lifecycle.js.map +0 -1
- package/dist/field/meta.d.ts +0 -9
- package/dist/field/meta.d.ts.map +0 -1
- package/dist/field/meta.js +0 -7
- package/dist/field/meta.js.map +0 -1
- package/dist/field/role.d.ts +0 -54
- package/dist/field/role.d.ts.map +0 -1
- package/dist/field/role.js +0 -55
- package/dist/field/role.js.map +0 -1
- package/dist/field/shape.d.ts +0 -77
- package/dist/field/shape.d.ts.map +0 -1
- package/dist/field/shape.js +0 -49
- package/dist/field/shape.js.map +0 -1
- package/dist/hints.d.ts +0 -33
- package/dist/hints.d.ts.map +0 -1
- package/dist/hints.js +0 -2
- package/dist/hints.js.map +0 -1
- package/dist/projections/card.d.ts +0 -117
- package/dist/projections/card.d.ts.map +0 -1
- package/dist/projections/card.js.map +0 -1
- package/dist/projections/describe.d.ts +0 -25
- package/dist/projections/describe.d.ts.map +0 -1
- package/dist/projections/describe.js +0 -136
- package/dist/projections/describe.js.map +0 -1
- package/dist/projections/encode.d.ts +0 -11
- package/dist/projections/encode.d.ts.map +0 -1
- package/dist/projections/encode.js +0 -26
- package/dist/projections/encode.js.map +0 -1
- package/dist/projections/io.d.ts +0 -30
- package/dist/projections/io.d.ts.map +0 -1
- package/dist/projections/io.js +0 -52
- package/dist/projections/io.js.map +0 -1
- package/dist/projections/lifecycle.d.ts +0 -43
- package/dist/projections/lifecycle.d.ts.map +0 -1
- package/dist/projections/lifecycle.js +0 -115
- package/dist/projections/lifecycle.js.map +0 -1
- package/dist/projections/reconstruct.d.ts +0 -36
- package/dist/projections/reconstruct.d.ts.map +0 -1
- package/dist/projections/reconstruct.js +0 -149
- package/dist/projections/reconstruct.js.map +0 -1
- package/dist/projections/source.d.ts +0 -41
- package/dist/projections/source.d.ts.map +0 -1
- package/dist/projections/source.js +0 -37
- package/dist/projections/source.js.map +0 -1
- package/dist/projections/standard.d.ts.map +0 -1
- package/dist/projections/standard.js +0 -10
- package/dist/projections/standard.js.map +0 -1
- package/dist/projections/typescript.d.ts +0 -53
- package/dist/projections/typescript.d.ts.map +0 -1
- package/dist/projections/typescript.js +0 -184
- package/dist/projections/typescript.js.map +0 -1
- package/dist/projections/validation.d.ts +0 -57
- package/dist/projections/validation.d.ts.map +0 -1
- package/dist/projections/validation.js +0 -148
- package/dist/projections/validation.js.map +0 -1
- package/dist/unique.d.ts +0 -65
- package/dist/unique.d.ts.map +0 -1
- package/dist/unique.js +0 -80
- package/dist/unique.js.map +0 -1
package/dist/field/boundary.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { anatomy } from './shape.js';
|
|
2
|
-
// ─── Registries (open, extensible — same spirit as FougereHints) ──
|
|
3
|
-
const decoders = new Map();
|
|
4
|
-
const encoders = new Map();
|
|
5
|
-
const aliases = new Map();
|
|
6
|
-
export function registerDecoder(name, fn) {
|
|
7
|
-
decoders.set(name, fn);
|
|
8
|
-
}
|
|
9
|
-
export function registerEncoder(name, fn) {
|
|
10
|
-
encoders.set(name, fn);
|
|
11
|
-
}
|
|
12
|
-
/** Register a named boundary — the alias a field can reference. */
|
|
13
|
-
export function registerBoundaryAlias(name, boundary) {
|
|
14
|
-
aliases.set(name, boundary);
|
|
15
|
-
}
|
|
16
|
-
// ─── Built-ins ───────────────────────────────────────
|
|
17
|
-
const identityDecoder = (value) => ({ value });
|
|
18
|
-
const identityEncoder = (value) => value;
|
|
19
|
-
// `isoDate`: the only non-identity built-in. Inbound accepts a Date or an ISO-ish
|
|
20
|
-
// string and yields a Date; outbound yields an ISO string. Validity is already
|
|
21
|
-
// guaranteed by `shape` (the date predicate) before decode runs.
|
|
22
|
-
registerDecoder('isoDate', (value) => {
|
|
23
|
-
if (value instanceof Date)
|
|
24
|
-
return { value };
|
|
25
|
-
if (typeof value === 'string') {
|
|
26
|
-
const d = new Date(value);
|
|
27
|
-
return Number.isNaN(d.getTime()) ? { error: 'Invalid date' } : { value: d };
|
|
28
|
-
}
|
|
29
|
-
return { error: 'Expected a date' };
|
|
30
|
-
});
|
|
31
|
-
registerEncoder('isoDate', (value) => value instanceof Date ? value.toISOString() : value);
|
|
32
|
-
registerBoundaryAlias('isoDate', { in: { decode: 'isoDate' }, out: { encode: 'isoDate' } });
|
|
33
|
-
/** Default boundary derived from a field's shape. A date-time string → isoDate, else identity. */
|
|
34
|
-
function defaultBoundaryForShape(shape) {
|
|
35
|
-
const base = anatomy(shape).base;
|
|
36
|
-
if (base && base.type === 'string' && base.format === 'date-time')
|
|
37
|
-
return aliases.get('isoDate');
|
|
38
|
-
return {};
|
|
39
|
-
}
|
|
40
|
-
// ─── Resolution ──────────────────────────────────────
|
|
41
|
-
/** The field's DECLARED boundary in normal form (alias resolved) — no derived default. */
|
|
42
|
-
export function declaredBoundary(field) {
|
|
43
|
-
const ref = field.boundary;
|
|
44
|
-
if (ref === undefined)
|
|
45
|
-
return {};
|
|
46
|
-
if (typeof ref === 'string') {
|
|
47
|
-
const alias = aliases.get(ref);
|
|
48
|
-
if (!alias)
|
|
49
|
-
throw new Error(`Unknown boundary alias: '${ref}'`);
|
|
50
|
-
return alias;
|
|
51
|
-
}
|
|
52
|
-
return ref;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* The field's EFFECTIVE boundary: declared rules win per direction, the
|
|
56
|
-
* shape-derived default fills the rest. This is the reader every consumer of
|
|
57
|
-
* the axis goes through — `boundaryOf(f).in === 'closed'` is the read-only
|
|
58
|
-
* test, `.out === 'closed'` the write-only one.
|
|
59
|
-
*/
|
|
60
|
-
export function boundaryOf(field) {
|
|
61
|
-
const declared = declaredBoundary(field);
|
|
62
|
-
const derived = defaultBoundaryForShape(field.shape);
|
|
63
|
-
return { in: declared.in ?? derived.in, out: declared.out ?? derived.out };
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* A field's effective conversion functions. The permission facet is not read
|
|
67
|
-
* here: a `'closed'` direction converts as identity — its rejection/omission
|
|
68
|
-
* happens in the readers (validation, encode) BEFORE any conversion.
|
|
69
|
-
*
|
|
70
|
-
* A NAMED codec that no one registered throws, exactly like an unknown alias
|
|
71
|
-
* (`declaredBoundary`). It used to fall back to identity: a frond declared
|
|
72
|
-
* `{ decode: 'celsius' }`, the consumer never called `registerDecoder`, and the
|
|
73
|
-
* value arrived unconverted while the card said it had been converted — the same
|
|
74
|
-
* silent loss this repo measured on Remult (`validate: [null, null]`) and on
|
|
75
|
-
* zod v4 (a computed default frozen at export). One axis, two spellings, one
|
|
76
|
-
* failure mode.
|
|
77
|
-
*
|
|
78
|
-
* It throws where the conversion is needed, not at boot: nothing walks every
|
|
79
|
-
* field at startup. Loud and late beats silent and never.
|
|
80
|
-
*/
|
|
81
|
-
export function resolveBoundary(field) {
|
|
82
|
-
const boundary = boundaryOf(field);
|
|
83
|
-
return {
|
|
84
|
-
decode: typeof boundary.in === 'object' ? named(decoders, boundary.in.decode, 'decoder') : identityDecoder,
|
|
85
|
-
encode: typeof boundary.out === 'object' ? named(encoders, boundary.out.encode, 'encoder') : identityEncoder,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
function named(registry, name, kind) {
|
|
89
|
-
const fn = registry.get(name);
|
|
90
|
-
if (!fn)
|
|
91
|
-
throw new Error(`Unknown boundary ${kind}: '${name}'. Register it with register${kind[0].toUpperCase()}${kind.slice(1)}('${name}', …).`);
|
|
92
|
-
return fn;
|
|
93
|
-
}
|
|
94
|
-
//# sourceMappingURL=boundary.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"boundary.js","sourceRoot":"","sources":["../../src/field/boundary.ts"],"names":[],"mappings":"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"}
|
package/dist/field/field.d.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { Shape } from './shape.js';
|
|
2
|
-
import type { Role } from './role.js';
|
|
3
|
-
import type { Lifecycle } from './lifecycle.js';
|
|
4
|
-
import type { BoundaryRef } from './boundary.js';
|
|
5
|
-
import type { Meta } from './meta.js';
|
|
6
|
-
/**
|
|
7
|
-
* A field — the single source of truth, decomposed on four orthogonal axes
|
|
8
|
-
* plus one documentary compartment:
|
|
9
|
-
* `shape` (is the value valid? — nullability included, as the `[T,'null']` union),
|
|
10
|
-
* `role` (place in the entity graph), `lifecycle` (who writes the value, at which
|
|
11
|
-
* moment), `boundary` (how a value crosses wire↔domain), `meta` (human-facing,
|
|
12
|
-
* never decides). Adapters read the axes they care about; nothing reads all of
|
|
13
|
-
* them at once. `boundary` is usually absent — its default is derived from
|
|
14
|
-
* `shape` and the slot only overrides it.
|
|
15
|
-
*
|
|
16
|
-
* @typeParam T - the data type this field carries (phantom, TS inference only)
|
|
17
|
-
* @typeParam A - "auto-supplied at creation" (primary/auto/default/optional) →
|
|
18
|
-
* the field is optional in `new X(input)`. Phantom, type-level only.
|
|
19
|
-
*/
|
|
20
|
-
export interface Field<T = unknown, A extends boolean = false> {
|
|
21
|
-
readonly __brand: 'fougere_field';
|
|
22
|
-
readonly shape?: Shape;
|
|
23
|
-
readonly role?: Role;
|
|
24
|
-
readonly lifecycle?: Lifecycle;
|
|
25
|
-
readonly boundary?: BoundaryRef;
|
|
26
|
-
readonly meta?: Meta;
|
|
27
|
-
/** Phantom — data type, never read at runtime. */
|
|
28
|
-
readonly _type?: T;
|
|
29
|
-
/** Phantom — auto-at-creation flag, never read at runtime. */
|
|
30
|
-
readonly _auto?: A;
|
|
31
|
-
}
|
|
32
|
-
/** Any field, regardless of its T/A parameters — the correct generic bound. */
|
|
33
|
-
export type AnyField = Field<any, boolean>;
|
|
34
|
-
/** A record of fields — the input to `entity()` and every derivation. */
|
|
35
|
-
export type Fields = Record<string, AnyField>;
|
|
36
|
-
export interface FieldInit {
|
|
37
|
-
shape?: Shape;
|
|
38
|
-
role?: Role;
|
|
39
|
-
lifecycle?: Lifecycle;
|
|
40
|
-
boundary?: BoundaryRef;
|
|
41
|
-
meta?: Meta;
|
|
42
|
-
}
|
|
43
|
-
export declare function createField<T, A extends boolean = false>(init?: FieldInit): Field<T, A>;
|
|
44
|
-
/**
|
|
45
|
-
* Copy a field, overriding only the named axes — every OTHER axis is preserved.
|
|
46
|
-
* This is the invariant every field transform must hold: change what you mean,
|
|
47
|
-
* keep the rest. Enumerating axes by hand (the old `optional`/`primary`) silently
|
|
48
|
-
* drops whatever axis was added last — `codec` did exactly that. Spread + override,
|
|
49
|
-
* so a future 6th slot travels for free. (Spread props skip excess-property checks,
|
|
50
|
-
* so the field's `__brand`/phantoms ride along harmlessly and `createField` resets them.)
|
|
51
|
-
*/
|
|
52
|
-
export declare function cloneField(field: AnyField, overrides?: FieldInit): AnyField;
|
|
53
|
-
/** Duck type for anything with fields — Entity, SchemaConstructor. */
|
|
54
|
-
export interface SchemaLike {
|
|
55
|
-
getFields(): Fields;
|
|
56
|
-
/** The view's validation mode (patch…) — carried by SchemaConstructor, optional on bare wrappers. */
|
|
57
|
-
getOpts?(): {
|
|
58
|
-
patch?: boolean;
|
|
59
|
-
};
|
|
60
|
-
/** Field groups unique together — carried by SchemaConstructor, absent on bare wrappers. */
|
|
61
|
-
getUnique?(): ReadonlyArray<ReadonlyArray<string>> | undefined;
|
|
62
|
-
}
|
|
63
|
-
export declare function isField(value: unknown): value is AnyField;
|
|
64
|
-
//# sourceMappingURL=field.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/field/field.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,OAAO,GAAG,KAAK;IAC3D,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,kDAAkD;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnB,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;CACpB;AAED,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAE3C,yEAAyE;AACzE,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAE9C,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,GAAG,KAAK,EAAE,IAAI,GAAE,SAAc,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAS3F;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,GAAE,SAAc,GAAG,QAAQ,CAE/E;AAED,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,SAAS,IAAI,MAAM,CAAC;IACpB,qGAAqG;IACrG,OAAO,CAAC,IAAI;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAChC,4FAA4F;IAC5F,SAAS,CAAC,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;CAChE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAOzD"}
|
package/dist/field/field.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export function createField(init = {}) {
|
|
2
|
-
return {
|
|
3
|
-
__brand: 'fougere_field',
|
|
4
|
-
shape: init.shape,
|
|
5
|
-
role: init.role,
|
|
6
|
-
lifecycle: init.lifecycle,
|
|
7
|
-
boundary: init.boundary,
|
|
8
|
-
meta: init.meta,
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Copy a field, overriding only the named axes — every OTHER axis is preserved.
|
|
13
|
-
* This is the invariant every field transform must hold: change what you mean,
|
|
14
|
-
* keep the rest. Enumerating axes by hand (the old `optional`/`primary`) silently
|
|
15
|
-
* drops whatever axis was added last — `codec` did exactly that. Spread + override,
|
|
16
|
-
* so a future 6th slot travels for free. (Spread props skip excess-property checks,
|
|
17
|
-
* so the field's `__brand`/phantoms ride along harmlessly and `createField` resets them.)
|
|
18
|
-
*/
|
|
19
|
-
export function cloneField(field, overrides = {}) {
|
|
20
|
-
return createField({ ...field, ...overrides });
|
|
21
|
-
}
|
|
22
|
-
export function isField(value) {
|
|
23
|
-
return (typeof value === 'object' &&
|
|
24
|
-
value !== null &&
|
|
25
|
-
'__brand' in value &&
|
|
26
|
-
value.__brand === 'fougere_field');
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=field.js.map
|
package/dist/field/field.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"field.js","sourceRoot":"","sources":["../../src/field/field.ts"],"names":[],"mappings":"AA+CA,MAAM,UAAU,WAAW,CAA+B,IAAI,GAAc,EAAE;IAC5E,OAAO;QACL,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,KAAe,EAAE,SAAS,GAAc,EAAE;IACnE,OAAO,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;AACjD,CAAC;AAWD,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,SAAS,IAAI,KAAK;QACjB,KAAa,CAAC,OAAO,KAAK,eAAe,CAC3C,CAAC;AACJ,CAAC"}
|
package/dist/field/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export { type Shape, type ShapeType, type BaseShape, type ShapeAnatomy, type StringFormat, nullableShape, anatomy, isNullable, } from './shape.js';
|
|
2
|
-
export { type Role, type Relation, type EntityConstructor, toTargetThunk, uniqueMembers } from './role.js';
|
|
3
|
-
export { type Lifecycle, type GeneratorRef, registerGenerator, resolveCustomGenerator, } from './lifecycle.js';
|
|
4
|
-
export { type Boundary, type BoundaryRef, type Decoder, type Encoder, resolveBoundary, declaredBoundary, boundaryOf, registerDecoder, registerEncoder, registerBoundaryAlias, } from './boundary.js';
|
|
5
|
-
export { type Meta } from './meta.js';
|
|
6
|
-
export { type Field, type AnyField, type Fields, type FieldInit, type SchemaLike, createField, cloneField, isField, } from './field.js';
|
|
7
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/field/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,aAAa,EACb,OAAO,EACP,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3G,OAAO,EACL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,eAAe,EACf,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EACL,KAAK,KAAK,EACV,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,UAAU,EACf,WAAW,EACX,UAAU,EACV,OAAO,GACR,MAAM,YAAY,CAAC"}
|
package/dist/field/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// The primitive — a Field decomposed on four orthogonal axes plus the meta
|
|
2
|
-
// compartment. Each axis lives in its own file; this barrel is the
|
|
3
|
-
// package-internal (and index-level) view.
|
|
4
|
-
export { nullableShape, anatomy, isNullable, } from './shape.js';
|
|
5
|
-
export { toTargetThunk, uniqueMembers } from './role.js';
|
|
6
|
-
export { registerGenerator, resolveCustomGenerator, } from './lifecycle.js';
|
|
7
|
-
export { resolveBoundary, declaredBoundary, boundaryOf, registerDecoder, registerEncoder, registerBoundaryAlias, } from './boundary.js';
|
|
8
|
-
export { createField, cloneField, isField, } from './field.js';
|
|
9
|
-
//# sourceMappingURL=index.js.map
|
package/dist/field/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/field/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,mEAAmE;AACnE,2CAA2C;AAC3C,OAAO,EAML,aAAa,EACb,OAAO,EACP,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAoD,aAAa,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3G,OAAO,EAGL,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAKL,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,eAAe,EACf,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAML,WAAW,EACX,UAAU,EACV,OAAO,GACR,MAAM,YAAY,CAAC"}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generator TOKEN — a built-in preset or a name registered via
|
|
3
|
-
* {@link registerGenerator}. Never a closure: a function would silently vanish
|
|
4
|
-
* through describe/reconstruct (JSON.stringify drops it without an error) and
|
|
5
|
-
* the remote frond would pay. With a name, the failure is loud and local
|
|
6
|
-
* ("unknown generator") instead of silent and at the neighbour's.
|
|
7
|
-
*/
|
|
8
|
-
export type GeneratorRef = 'cuid2' | 'uuid' | 'nanoid' | (string & {});
|
|
9
|
-
export interface Lifecycle {
|
|
10
|
-
/**
|
|
11
|
-
* The CREATE rule — what happens when the input omits the value:
|
|
12
|
-
* - key absent → required, the caller must supply it
|
|
13
|
-
* - `{ value }` → filled with this literal (a `default`)
|
|
14
|
-
* - `'now'` → stamped `new Date()` (a managed creation timestamp)
|
|
15
|
-
* - `{ generate }` → the storage adapter stamps a fresh id at insert
|
|
16
|
-
* - `'optional'` → absence permitted, nothing produced
|
|
17
|
-
* A supplied value is always accepted (create); restricting WHAT a surface
|
|
18
|
-
* accepts is a derivation (`pick`), never a rule here.
|
|
19
|
-
*/
|
|
20
|
-
create?: {
|
|
21
|
-
value: unknown;
|
|
22
|
-
} | 'now' | {
|
|
23
|
-
generate: GeneratorRef;
|
|
24
|
-
} | 'optional';
|
|
25
|
-
/**
|
|
26
|
-
* The UPDATE rule — what happens on a patch:
|
|
27
|
-
* - key absent → the field is only written if the client supplies it
|
|
28
|
-
* - `'now'` → stamped `new Date()` at every update even when absent
|
|
29
|
-
* (the canonical `updatedAt`); a supplied value is accepted
|
|
30
|
-
* - `'forbidden'` → immutable: supplying the field in a patch is a
|
|
31
|
-
* validation error; absent, nothing happens
|
|
32
|
-
* The validation only JUDGES these rules; realising `'now'` (stamping) is the
|
|
33
|
-
* storage adapter's role at the point of persistence — same split as create.
|
|
34
|
-
*/
|
|
35
|
-
update?: 'now' | 'forbidden';
|
|
36
|
-
}
|
|
37
|
-
export declare function registerGenerator(name: string, fn: () => string): void;
|
|
38
|
-
/** A registered custom generator, or undefined (built-in presets live storage-side). */
|
|
39
|
-
export declare function resolveCustomGenerator(ref: GeneratorRef): (() => string) | undefined;
|
|
40
|
-
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/field/lifecycle.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEvE,MAAM,WAAW,SAAS;IACxB;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,GAAG,KAAK,GAAG;QAAE,QAAQ,EAAE,YAAY,CAAA;KAAE,GAAG,UAAU,CAAC;IAC9E;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC;CAC9B;AAgBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,MAAM,GAAG,IAAI,CAEtE;AAED,wFAAwF;AACxF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,YAAY,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAEpF"}
|
package/dist/field/lifecycle.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// ─── Axis 3 · lifecycle — WHO WRITES THE VALUE, AT WHICH MOMENT ────
|
|
2
|
-
// The normal form is indexed by the situation (the write moment); reading is a
|
|
3
|
-
// key access plus a switch on a named token — never an interpreter function.
|
|
4
|
-
// The interpretation happened ONCE, at declaration (the vocabulary translates
|
|
5
|
-
// its sugar into this form). Declarative, named only — never an opaque closure
|
|
6
|
-
// (a value mutation invisible to adapters is forbidden).
|
|
7
|
-
// (Coercion — converting a supplied value — is NOT here; that is the `boundary` axis.)
|
|
8
|
-
// ─── Generator registry (open, same spirit as the boundary registries) ──
|
|
9
|
-
// CUSTOM generators, declared once per module:
|
|
10
|
-
// registerGenerator('monId', () => …) → primary({ generate: 'monId' })
|
|
11
|
-
//
|
|
12
|
-
// The BUILT-IN presets (cuid2/uuid/nanoid) used to be resolved by each storage adapter,
|
|
13
|
-
// on the grounds that this package took no dependency. It took one already
|
|
14
|
-
// (`@cfworker/json-schema`, for the other projection), and the arrangement put the
|
|
15
|
-
// inversion in plain sight: a generator YOU invented reached every adapter, and the
|
|
16
|
-
// three the framework ships did not — so a second adapter honoured `cuid2` differently
|
|
17
|
-
// or not at all. They live with the realization now (`projections/lifecycle.ts`), which
|
|
18
|
-
// consults this registry first.
|
|
19
|
-
const generators = new Map();
|
|
20
|
-
export function registerGenerator(name, fn) {
|
|
21
|
-
generators.set(name, fn);
|
|
22
|
-
}
|
|
23
|
-
/** A registered custom generator, or undefined (built-in presets live storage-side). */
|
|
24
|
-
export function resolveCustomGenerator(ref) {
|
|
25
|
-
return generators.get(ref);
|
|
26
|
-
}
|
|
27
|
-
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/field/lifecycle.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,+EAA+E;AAC/E,6EAA6E;AAC7E,8EAA8E;AAC9E,+EAA+E;AAC/E,yDAAyD;AACzD,uFAAuF;AAoCvF,2EAA2E;AAC3E,+CAA+C;AAC/C,2EAA2E;AAC3E,EAAE;AACF,wFAAwF;AACxF,2EAA2E;AAC3E,mFAAmF;AACnF,oFAAoF;AACpF,uFAAuF;AACvF,wFAAwF;AACxF,gCAAgC;AAEhC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEnD,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,EAAgB;IAC9D,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,sBAAsB,CAAC,GAAiB;IACtD,OAAO,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC"}
|
package/dist/field/meta.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export interface Meta {
|
|
2
|
-
/**
|
|
3
|
-
* Human-readable annotation. Read by CLI help (`cli/bridge.ts`) and carried by the
|
|
4
|
-
* portable card — that is the whole current reach. No OpenAPI generation exists in
|
|
5
|
-
* this repo, and `schema-graphql` never reads meta.
|
|
6
|
-
*/
|
|
7
|
-
description?: string;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=meta.d.ts.map
|
package/dist/field/meta.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/field/meta.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,IAAI;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
package/dist/field/meta.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
// ─── meta — the documentary compartment (NOT an axis) ────────────
|
|
2
|
-
// Universal, human-facing information. The contract is strict and holds: NO consumer
|
|
3
|
-
// ever DECIDES by reading meta — the axes govern behaviour, meta informs humans.
|
|
4
|
-
// Per-consumer specifics belong to `hints`, not here. Future candidates of the same
|
|
5
|
-
// nature: title, example, deprecated.
|
|
6
|
-
export {};
|
|
7
|
-
//# sourceMappingURL=meta.js.map
|
package/dist/field/meta.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/field/meta.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,qFAAqF;AACrF,iFAAiF;AACjF,oFAAoF;AACpF,sCAAsC"}
|
package/dist/field/role.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export type EntityConstructor = abstract new (...args: any[]) => any;
|
|
2
|
-
/**
|
|
3
|
-
* Normalize a relation target to a lazy thunk. A target may be given as the entity
|
|
4
|
-
* class directly (`ref(Author)`) or as a thunk (`ref(() => Author)`) — the thunk
|
|
5
|
-
* form is needed for circular/forward references, where the class isn't defined yet
|
|
6
|
-
* when `entity({...})` is evaluated. An entity class is recognized by its static
|
|
7
|
-
* `getFields`; anything else is treated as the thunk itself.
|
|
8
|
-
*/
|
|
9
|
-
export declare function toTargetThunk<E extends EntityConstructor>(target: E | (() => E)): () => E;
|
|
10
|
-
export interface Relation {
|
|
11
|
-
to: () => EntityConstructor;
|
|
12
|
-
kind: 'one' | 'many';
|
|
13
|
-
onDelete?: 'cascade' | 'restrict' | 'set null';
|
|
14
|
-
}
|
|
15
|
-
export interface Role {
|
|
16
|
-
primary?: boolean;
|
|
17
|
-
/**
|
|
18
|
-
* The unique constraints this field is a member of — one member list per constraint.
|
|
19
|
-
*
|
|
20
|
-
* A constraint is a NAMED SET of fields, and a lone `unique(slug)` is the degenerate
|
|
21
|
-
* case: a set of one. So there is one shape, not two — `boolean` could say "unique on
|
|
22
|
-
* its own" and nothing else, neither "unique together with docId" nor "in two
|
|
23
|
-
* constraints at once".
|
|
24
|
-
*
|
|
25
|
-
* **An empty member list denotes the field carrying it.** `unique(text())` applies to a
|
|
26
|
-
* field that does not yet know its own key — `slug` exists only once `entity({...})`
|
|
27
|
-
* assembles the object — so the self-reference is written as `[]` and stays that way:
|
|
28
|
-
* nothing to resolve, nothing to remap when a view renames the key, and a reader that
|
|
29
|
-
* never went through `entity()` still reads something true. A group with named members
|
|
30
|
-
* comes from the entity's own declaration (`entity(fields, { unique: [[...]] })`), which
|
|
31
|
-
* is where a fact about a pair belongs — no field holds it alone.
|
|
32
|
-
*
|
|
33
|
-
* So NEVER read a group directly — {@link uniqueMembers} is the accessor.
|
|
34
|
-
*/
|
|
35
|
-
unique?: ReadonlyArray<ReadonlyArray<string>>;
|
|
36
|
-
index?: boolean;
|
|
37
|
-
relation?: Relation;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* The constraint a member list denotes, resolved against the field carrying it — the
|
|
41
|
-
* accessor every reader of `role.unique` goes through.
|
|
42
|
-
*
|
|
43
|
-
* ```ts
|
|
44
|
-
* uniqueMembers([], 'slug') // ['slug'] — the self-reference
|
|
45
|
-
* uniqueMembers(['listId', 'docId'], 'docId') // ['listId','docId'] — already named
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* `ownKey` is the half the field is missing, and only its holder can supply it: iterate
|
|
49
|
-
* `Object.entries(getFields())`, never the field alone. Two spellings for one constraint
|
|
50
|
-
* is the price of a self-reference that survives `rename()` untouched; this function is
|
|
51
|
-
* what makes them one, and it is why the two forms never need to be compared as data.
|
|
52
|
-
*/
|
|
53
|
-
export declare function uniqueMembers(group: ReadonlyArray<string>, ownKey: string): string[];
|
|
54
|
-
//# sourceMappingURL=role.d.ts.map
|
package/dist/field/role.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"role.d.ts","sourceRoot":"","sources":["../../src/field/role.ts"],"names":[],"mappings":"AA4BA,MAAM,MAAM,iBAAiB,GAAG,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,iBAAiB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAEzF;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,iBAAiB,CAAC;IAC5B,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;CAChD;AAED,MAAM,WAAW,IAAI;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAEpF"}
|
package/dist/field/role.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// ─── Axis 2 · role — place in the entity graph ────────────
|
|
2
|
-
// What no value validator expresses: identity and relations. Read by the storage and
|
|
3
|
-
// transport adapters, and ALSO by validation — `relation.kind === 'many'` decides that
|
|
4
|
-
// an absent collection defaults to `[]` and that a supplied one must be an array
|
|
5
|
-
// (`projections/validation.ts`). The earlier claim "never by validation" was false.
|
|
6
|
-
//
|
|
7
|
-
// `unique` and `index` are STORAGE facts, and the only axis member realized outside the
|
|
8
|
-
// framework: `unique(...)`/`indexed(...)` set them, the DDL emits the constraint and the
|
|
9
|
-
// index, and the database enforces uniqueness on every write — including ones Fougere
|
|
10
|
-
// never saw. A collision therefore surfaces as the driver's error, never as a
|
|
11
|
-
// `validate()` failure: judging one value can never see the other rows.
|
|
12
|
-
//
|
|
13
|
-
// ⚠️ READING `unique` — the one member of this axis that is not self-contained. A member
|
|
14
|
-
// list may be EMPTY, denoting the field that carries it, so a reader that walks the array
|
|
15
|
-
// literally sees a group of no fields. Every reader goes through `uniqueMembers(group,
|
|
16
|
-
// key)`, which needs the field's key — the half a field does not have (`slug` is named by
|
|
17
|
-
// the object literal `entity({...})` receives, one call up).
|
|
18
|
-
//
|
|
19
|
-
// for (const [key, field] of Object.entries(schema.getFields()))
|
|
20
|
-
// for (const group of field.role?.unique ?? [])
|
|
21
|
-
// uniqueMembers(group, key) // ← always. `[]` at key `slug` means `['slug']`.
|
|
22
|
-
//
|
|
23
|
-
// The in-repo readers do this (`schema-sql/src/table.ts`, `projections/describe.ts`). A
|
|
24
|
-
// consumer reading a CARD never meets the empty form: `describe` resolves it on the way
|
|
25
|
-
// out, so the wire always names its members — which is the point of resolving it there
|
|
26
|
-
// and not in `entity()`. Keeping it unresolved in memory is what makes `rename()` free:
|
|
27
|
-
// a self-reference names no key, so there is nothing to remap when the key moves.
|
|
28
|
-
/**
|
|
29
|
-
* Normalize a relation target to a lazy thunk. A target may be given as the entity
|
|
30
|
-
* class directly (`ref(Author)`) or as a thunk (`ref(() => Author)`) — the thunk
|
|
31
|
-
* form is needed for circular/forward references, where the class isn't defined yet
|
|
32
|
-
* when `entity({...})` is evaluated. An entity class is recognized by its static
|
|
33
|
-
* `getFields`; anything else is treated as the thunk itself.
|
|
34
|
-
*/
|
|
35
|
-
export function toTargetThunk(target) {
|
|
36
|
-
return 'getFields' in target ? () => target : target;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* The constraint a member list denotes, resolved against the field carrying it — the
|
|
40
|
-
* accessor every reader of `role.unique` goes through.
|
|
41
|
-
*
|
|
42
|
-
* ```ts
|
|
43
|
-
* uniqueMembers([], 'slug') // ['slug'] — the self-reference
|
|
44
|
-
* uniqueMembers(['listId', 'docId'], 'docId') // ['listId','docId'] — already named
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* `ownKey` is the half the field is missing, and only its holder can supply it: iterate
|
|
48
|
-
* `Object.entries(getFields())`, never the field alone. Two spellings for one constraint
|
|
49
|
-
* is the price of a self-reference that survives `rename()` untouched; this function is
|
|
50
|
-
* what makes them one, and it is why the two forms never need to be compared as data.
|
|
51
|
-
*/
|
|
52
|
-
export function uniqueMembers(group, ownKey) {
|
|
53
|
-
return group.length === 0 ? [ownKey] : [...group];
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=role.js.map
|
package/dist/field/role.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"role.js","sourceRoot":"","sources":["../../src/field/role.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,qFAAqF;AACrF,uFAAuF;AACvF,iFAAiF;AACjF,oFAAoF;AACpF,EAAE;AACF,wFAAwF;AACxF,yFAAyF;AACzF,sFAAsF;AACtF,8EAA8E;AAC9E,wEAAwE;AACxE,EAAE;AACF,yFAAyF;AACzF,0FAA0F;AAC1F,uFAAuF;AACvF,0FAA0F;AAC1F,6DAA6D;AAC7D,EAAE;AACF,mEAAmE;AACnE,oDAAoD;AACpD,wFAAwF;AACxF,EAAE;AACF,wFAAwF;AACxF,wFAAwF;AACxF,uFAAuF;AACvF,wFAAwF;AACxF,kFAAkF;AAIlF;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAA8B,MAAqB;IAC9E,OAAO,WAAW,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAW,CAAC,CAAC,CAAE,MAAkB,CAAC;AACzE,CAAC;AAiCD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,KAA4B,EAAE,MAAc;IACxE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;AACpD,CAAC"}
|
package/dist/field/shape.d.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
export type StringFormat = 'date-time' | 'date' | 'time' | 'email' | 'uuid' | 'uri';
|
|
2
|
-
/** A base type name, alone or in the nullable union form. */
|
|
3
|
-
type Nullably<T extends string> = T | readonly [T, 'null'];
|
|
4
|
-
interface StringConstraints {
|
|
5
|
-
minLength?: number;
|
|
6
|
-
maxLength?: number;
|
|
7
|
-
pattern?: string;
|
|
8
|
-
enum?: readonly (string | null)[];
|
|
9
|
-
format?: StringFormat;
|
|
10
|
-
}
|
|
11
|
-
interface NumericConstraints {
|
|
12
|
-
minimum?: number;
|
|
13
|
-
maximum?: number;
|
|
14
|
-
}
|
|
15
|
-
interface ArrayConstraints {
|
|
16
|
-
items: Shape;
|
|
17
|
-
minItems?: number;
|
|
18
|
-
maxItems?: number;
|
|
19
|
-
}
|
|
20
|
-
interface ObjectConstraints {
|
|
21
|
-
properties?: Record<string, unknown>;
|
|
22
|
-
required?: readonly string[];
|
|
23
|
-
}
|
|
24
|
-
export type Shape = ({
|
|
25
|
-
type: Nullably<'string'>;
|
|
26
|
-
} & StringConstraints) | ({
|
|
27
|
-
type: Nullably<'number'> | Nullably<'integer'>;
|
|
28
|
-
} & NumericConstraints) | {
|
|
29
|
-
type: Nullably<'boolean'>;
|
|
30
|
-
} | ({
|
|
31
|
-
type: Nullably<'array'>;
|
|
32
|
-
} & ArrayConstraints) | ({
|
|
33
|
-
type: Nullably<'object'>;
|
|
34
|
-
} & ObjectConstraints);
|
|
35
|
-
/** The BASE type names — what `anatomy(shape).base?.type` narrows to for a dispatch. */
|
|
36
|
-
export type ShapeType = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object';
|
|
37
|
-
/**
|
|
38
|
-
* `Shape` with `type` guaranteed scalar — what `anatomy` returns as `base`, the
|
|
39
|
-
* ONLY form consumers dispatch on. A scalar literal is a real discriminant, so
|
|
40
|
-
* `switch (base?.type)` narrows; the raw `Shape` union can't (the `[T,'null']`
|
|
41
|
-
* tuple is not a unit type).
|
|
42
|
-
*/
|
|
43
|
-
export type BaseShape = ({
|
|
44
|
-
type: 'string';
|
|
45
|
-
} & StringConstraints) | ({
|
|
46
|
-
type: 'number' | 'integer';
|
|
47
|
-
} & NumericConstraints) | {
|
|
48
|
-
type: 'boolean';
|
|
49
|
-
} | ({
|
|
50
|
-
type: 'array';
|
|
51
|
-
} & ArrayConstraints) | ({
|
|
52
|
-
type: 'object';
|
|
53
|
-
} & ObjectConstraints);
|
|
54
|
-
/**
|
|
55
|
-
* Write side: make a shape's grammar accept `null` — the type becomes the union
|
|
56
|
-
* `[T, 'null']`, and `null` joins `enum` when present (an enum is a closed value
|
|
57
|
-
* set; null must be IN it to be legal). Idempotent.
|
|
58
|
-
*/
|
|
59
|
-
export declare function nullableShape(shape: Shape): Shape;
|
|
60
|
-
/** A shape split back into its base grammar and its nullability. */
|
|
61
|
-
export interface ShapeAnatomy {
|
|
62
|
-
/** The shape stripped of `null` (scalar `type`, `enum` without null) — dispatch on THIS. */
|
|
63
|
-
base?: BaseShape;
|
|
64
|
-
nullable: boolean;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Read side — the single customs post at the standard's border. Every consumer
|
|
68
|
-
* that dispatches on a shape's type MUST come through here: `shape.type` may be
|
|
69
|
-
* the union `[T, 'null']`, and a direct `shape.type === 'string'` comparison
|
|
70
|
-
* fails silently on it. Cached per shape reference (shapes are stable — the
|
|
71
|
-
* derivations copy field refs, they never rebuild shapes).
|
|
72
|
-
*/
|
|
73
|
-
export declare function anatomy(shape?: Shape): ShapeAnatomy;
|
|
74
|
-
/** Sugar for the most common read: does this shape's grammar accept `null`? */
|
|
75
|
-
export declare function isNullable(shape?: Shape): boolean;
|
|
76
|
-
export {};
|
|
77
|
-
//# sourceMappingURL=shape.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../../src/field/shape.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAEpF,6DAA6D;AAC7D,KAAK,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAI3D,UAAU,iBAAiB;IAAG,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAE;AAClJ,UAAU,kBAAkB;IAAG,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;AAGnE,UAAU,gBAAgB;IAAG,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;AAIjF,UAAU,iBAAiB;IAAG,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE;AAElG,MAAM,MAAM,KAAK,GACb,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;CAAE,GAAG,iBAAiB,CAAC,GAClD,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,kBAAkB,CAAC,GACzE;IAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;CAAE,GAC7B,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;CAAE,GAAG,gBAAgB,CAAC,GAChD,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;CAAE,GAAG,iBAAiB,CAAC,CAAC;AAEvD,wFAAwF;AACxF,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEzF;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GACjB,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,iBAAiB,CAAC,GACxC,CAAC;IAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAA;CAAE,GAAG,kBAAkB,CAAC,GACrD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB,CAAC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,gBAAgB,CAAC,GACtC,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,iBAAiB,CAAC,CAAC;AAI7C;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAOjD;AAED,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,4FAA4F;IAC5F,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAKD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,YAAY,CAiBnD;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAEjD"}
|
package/dist/field/shape.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// ─── nullableShape / anatomy — the two gates of the union ──────────
|
|
2
|
-
/**
|
|
3
|
-
* Write side: make a shape's grammar accept `null` — the type becomes the union
|
|
4
|
-
* `[T, 'null']`, and `null` joins `enum` when present (an enum is a closed value
|
|
5
|
-
* set; null must be IN it to be legal). Idempotent.
|
|
6
|
-
*/
|
|
7
|
-
export function nullableShape(shape) {
|
|
8
|
-
if (Array.isArray(shape.type))
|
|
9
|
-
return shape;
|
|
10
|
-
const out = { ...shape, type: [shape.type, 'null'] };
|
|
11
|
-
if ('enum' in out && out.enum && !out.enum.includes(null)) {
|
|
12
|
-
out.enum = [...out.enum, null];
|
|
13
|
-
}
|
|
14
|
-
return out;
|
|
15
|
-
}
|
|
16
|
-
const anatomies = new WeakMap();
|
|
17
|
-
const NO_SHAPE = { base: undefined, nullable: false };
|
|
18
|
-
/**
|
|
19
|
-
* Read side — the single customs post at the standard's border. Every consumer
|
|
20
|
-
* that dispatches on a shape's type MUST come through here: `shape.type` may be
|
|
21
|
-
* the union `[T, 'null']`, and a direct `shape.type === 'string'` comparison
|
|
22
|
-
* fails silently on it. Cached per shape reference (shapes are stable — the
|
|
23
|
-
* derivations copy field refs, they never rebuild shapes).
|
|
24
|
-
*/
|
|
25
|
-
export function anatomy(shape) {
|
|
26
|
-
if (!shape)
|
|
27
|
-
return NO_SHAPE;
|
|
28
|
-
let a = anatomies.get(shape);
|
|
29
|
-
if (!a) {
|
|
30
|
-
if (Array.isArray(shape.type)) {
|
|
31
|
-
const baseType = shape.type.find((t) => t !== 'null');
|
|
32
|
-
const base = { ...shape, type: baseType };
|
|
33
|
-
if ('enum' in base && base.enum) {
|
|
34
|
-
base.enum = base.enum.filter((v) => v !== null);
|
|
35
|
-
}
|
|
36
|
-
a = { base, nullable: true };
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
a = { base: shape, nullable: false };
|
|
40
|
-
}
|
|
41
|
-
anatomies.set(shape, a);
|
|
42
|
-
}
|
|
43
|
-
return a;
|
|
44
|
-
}
|
|
45
|
-
/** Sugar for the most common read: does this shape's grammar accept `null`? */
|
|
46
|
-
export function isNullable(shape) {
|
|
47
|
-
return anatomy(shape).nullable;
|
|
48
|
-
}
|
|
49
|
-
//# sourceMappingURL=shape.js.map
|
package/dist/field/shape.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shape.js","sourceRoot":"","sources":["../../src/field/shape.ts"],"names":[],"mappings":"AA+DA,sEAAsE;AAEtE;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAY;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,GAAG,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAAsB,CAAC;IACzE,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzD,GAA4C,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AASD,MAAM,SAAS,GAAG,IAAI,OAAO,EAAwB,CAAC;AACtD,MAAM,QAAQ,GAAiB,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAEpE;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;YACtD,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAe,CAAC;YACvD,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC/B,IAA6C,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YAC5F,CAAC;YACD,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,CAAC,GAAG,EAAE,IAAI,EAAE,KAAkB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QACpD,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC;AACjC,CAAC"}
|
package/dist/hints.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { Fields } from "./field/index.js";
|
|
2
|
-
/**
|
|
3
|
-
* Open registry of per-consumer hints — the escape hatch for the irreducible
|
|
4
|
-
* bits a single neutral field can't carry (e.g. "store `body` as a `tsvector`
|
|
5
|
-
* with a GIN index", which validation and the API must ignore).
|
|
6
|
-
*
|
|
7
|
-
* EMPTY here on purpose: `@fougere/schema` names no adapter and depends on none.
|
|
8
|
-
* Each adapter augments this from its OWN package via declaration merging —
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* declare module '@fougere/schema' {
|
|
12
|
-
* interface FougereHints<K extends string> {
|
|
13
|
-
* sql?: Partial<Record<K, { columnType?: string; index?: string }>>;
|
|
14
|
-
* }
|
|
15
|
-
* }
|
|
16
|
-
* ```
|
|
17
|
-
*
|
|
18
|
-
* `K` is the entity's field-key union, so a hint's inner keys are constrained to
|
|
19
|
-
* real fields. Until an adapter augments it the registry is `{}` — there is simply
|
|
20
|
-
* nothing to hint against, and the constraint materialises once an adapter is in
|
|
21
|
-
* the compilation. No dependency inversion: schema never names an adapter.
|
|
22
|
-
*/
|
|
23
|
-
export interface FougereHints<K extends string> {
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Per-consumer hints for an entity, keyed by registered adapter. Only adapters
|
|
27
|
-
* present in {@link FougereHints} are accepted; unknown adapters, unknown fields
|
|
28
|
-
* and unknown options are all rejected at the call site.
|
|
29
|
-
*/
|
|
30
|
-
export type Hints<TFields extends Fields> = {
|
|
31
|
-
[A in keyof FougereHints<Extract<keyof TFields, string>>]?: FougereHints<Extract<keyof TFields, string>>[A];
|
|
32
|
-
};
|
|
33
|
-
//# sourceMappingURL=hints.d.ts.map
|