@jini-ai/cms 0.3.4 → 0.3.6
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/README.md +22 -17
- package/dist/content-types/agent-tools.d.ts.map +1 -1
- package/dist/content-types/agent-tools.js +1 -1
- package/dist/content-types/agent-tools.js.map +1 -1
- package/dist/content-types/errors.d.ts +19 -1
- package/dist/content-types/errors.d.ts.map +1 -1
- package/dist/content-types/errors.js +22 -1
- package/dist/content-types/errors.js.map +1 -1
- package/dist/content-types/index-provisioning.d.ts +56 -10
- package/dist/content-types/index-provisioning.d.ts.map +1 -1
- package/dist/content-types/index-provisioning.js +86 -13
- package/dist/content-types/index-provisioning.js.map +1 -1
- package/dist/content-types/index.d.ts +15 -3
- package/dist/content-types/index.d.ts.map +1 -1
- package/dist/content-types/index.js +14 -2
- package/dist/content-types/index.js.map +1 -1
- package/dist/content-types/lifecycle.js +3 -3
- package/dist/content-types/lifecycle.js.map +1 -1
- package/dist/content-types/types.d.ts +64 -3
- package/dist/content-types/types.d.ts.map +1 -1
- package/dist/content-types/types.js +67 -3
- package/dist/content-types/types.js.map +1 -1
- package/dist/content-types/write-service.d.ts +18 -3
- package/dist/content-types/write-service.d.ts.map +1 -1
- package/dist/content-types/write-service.js +28 -2
- package/dist/content-types/write-service.js.map +1 -1
- package/dist/core/ports.d.ts +12 -2
- package/dist/core/ports.d.ts.map +1 -1
- package/dist/entries/field-validation.d.ts.map +1 -1
- package/dist/entries/field-validation.js +96 -1
- package/dist/entries/field-validation.js.map +1 -1
- package/dist/entries/write-service.d.ts +14 -0
- package/dist/entries/write-service.d.ts.map +1 -1
- package/dist/entries/write-service.js +2 -2
- package/dist/entries/write-service.js.map +1 -1
- package/dist/identity/admin-crud-service.d.ts +28 -0
- package/dist/identity/admin-crud-service.d.ts.map +1 -1
- package/dist/identity/admin-crud-service.js +30 -0
- package/dist/identity/admin-crud-service.js.map +1 -1
- package/dist/identity/auth-service.d.ts +32 -1
- package/dist/identity/auth-service.d.ts.map +1 -1
- package/dist/identity/auth-service.js +44 -15
- package/dist/identity/auth-service.js.map +1 -1
- package/dist/identity/index.d.ts +4 -1
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +4 -1
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/seed.d.ts +14 -2
- package/dist/identity/seed.d.ts.map +1 -1
- package/dist/identity/seed.js +197 -45
- package/dist/identity/seed.js.map +1 -1
- package/dist/media/blob-store.fs.d.ts +7 -0
- package/dist/media/blob-store.fs.d.ts.map +1 -1
- package/dist/media/blob-store.fs.js +12 -2
- package/dist/media/blob-store.fs.js.map +1 -1
- package/dist/media/content-type-sniffer.d.ts +1 -1
- package/dist/media/content-type-sniffer.d.ts.map +1 -1
- package/dist/media/content-type-sniffer.js +52 -4
- package/dist/media/content-type-sniffer.js.map +1 -1
- package/dist/media/html-attributes.d.ts +90 -0
- package/dist/media/html-attributes.d.ts.map +1 -0
- package/dist/media/html-attributes.js +161 -0
- package/dist/media/html-attributes.js.map +1 -0
- package/dist/media/image-transformer.sharp.d.ts +35 -1
- package/dist/media/image-transformer.sharp.d.ts.map +1 -1
- package/dist/media/image-transformer.sharp.js +44 -2
- package/dist/media/image-transformer.sharp.js.map +1 -1
- package/dist/media/index.d.ts +2 -1
- package/dist/media/index.d.ts.map +1 -1
- package/dist/media/index.js +2 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/media-service.d.ts +93 -1
- package/dist/media/media-service.d.ts.map +1 -1
- package/dist/media/media-service.js +254 -7
- package/dist/media/media-service.js.map +1 -1
- package/dist/media/ports.d.ts +8 -1
- package/dist/media/ports.d.ts.map +1 -1
- package/dist/media/rendition-service.d.ts +7 -1
- package/dist/media/rendition-service.d.ts.map +1 -1
- package/dist/media/rendition-service.js +10 -4
- package/dist/media/rendition-service.js.map +1 -1
- package/dist/media/repo.memory.d.ts +4 -0
- package/dist/media/repo.memory.d.ts.map +1 -1
- package/dist/media/repo.memory.js +3 -0
- package/dist/media/repo.memory.js.map +1 -1
- package/dist/media/tool-registrations.d.ts +6 -2
- package/dist/media/tool-registrations.d.ts.map +1 -1
- package/dist/media/tool-registrations.js +19 -2
- package/dist/media/tool-registrations.js.map +1 -1
- package/dist/media/types.d.ts +26 -0
- package/dist/media/types.d.ts.map +1 -1
- package/dist/media/types.js.map +1 -1
- package/dist/navigation/agent-tools.d.ts.map +1 -1
- package/dist/navigation/agent-tools.js +8 -1
- package/dist/navigation/agent-tools.js.map +1 -1
- package/dist/navigation/index.d.ts +10 -1
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +10 -1
- package/dist/navigation/index.js.map +1 -1
- package/dist/navigation/menu-service.d.ts +60 -4
- package/dist/navigation/menu-service.d.ts.map +1 -1
- package/dist/navigation/menu-service.js +106 -8
- package/dist/navigation/menu-service.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Content-model capability for Jini-hosted products.
|
|
4
4
|
|
|
5
|
-
> **Status:
|
|
6
|
-
>
|
|
7
|
-
>
|
|
5
|
+
> **Status: implemented, port in progress.** Created 2026-08-02 as an empty shell; the port has
|
|
6
|
+
> been landing since. Measured 2026-09-05 at `v0.3.4`: 131 non-test source files / 21,718 lines
|
|
7
|
+
> under `src/` (34,938 including tests), 11 domain trees, and 14 public subpath exports wired in
|
|
8
|
+
> `package.json`. Some domain modules named under [Port inventory](#port-inventory) have not moved
|
|
9
|
+
> yet — check `src/` and the `exports` map for what is actually reachable today rather than
|
|
10
|
+
> trusting this paragraph's counts.
|
|
8
11
|
|
|
9
12
|
## Layers
|
|
10
13
|
|
|
@@ -48,15 +51,17 @@ the first commit means that failure mode cannot recur here.
|
|
|
48
51
|
|
|
49
52
|
## Port inventory
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
The kernel went first — the source repo's `src/core/{ports,commands,events,tools}` — because every
|
|
55
|
+
domain module depends on it. Domain modules followed in no particular order: the source repo's git
|
|
56
|
+
history shows they essentially never co-change with each other, so each ports independently without
|
|
57
|
+
coordination.
|
|
52
58
|
|
|
53
|
-
**
|
|
54
|
-
|
|
59
|
+
**Landed** (directories under `src/`, each with its own subpath export):
|
|
60
|
+
`core`, `content-types`, `entries`, `identity`, `media`, `navigation`, `presentation`, `settings`,
|
|
61
|
+
`taxonomy`, `workspace`, and the `server` adapter layer.
|
|
55
62
|
|
|
56
|
-
**
|
|
57
|
-
|
|
58
|
-
`taxonomy`, `entries`, `content-types`, `media`, `seo`, `comments`, `forms`, `navigation`,
|
|
59
|
-
`redirects`, `widgets`, `newsletter`, `members`.
|
|
63
|
+
**Still to move:** `post`, `seo`, `comments`, `forms`, `redirects`, `widgets`, `newsletter`,
|
|
64
|
+
`members`. (`widgets` has an `exports` entry but no `src/widgets/` tree yet.)
|
|
60
65
|
|
|
61
66
|
**Explicitly not ported:**
|
|
62
67
|
|
|
@@ -74,11 +79,11 @@ pnpm --filter @jini-ai/cms typecheck
|
|
|
74
79
|
pnpm --filter @jini-ai/cms test
|
|
75
80
|
```
|
|
76
81
|
|
|
77
|
-
##
|
|
82
|
+
## Open cleanup
|
|
78
83
|
|
|
79
|
-
- **Add coverage thresholds.** `vitest.config.ts`
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
- **Delete
|
|
83
|
-
entry
|
|
84
|
-
|
|
84
|
+
- **Add coverage thresholds.** `vitest.config.ts` still has none. That was a deliberate omission
|
|
85
|
+
while the package was a placeholder; it no longer is, so the reason has expired. Set them against
|
|
86
|
+
what the ported modules actually measure — siblings run 98–100%.
|
|
87
|
+
- **Delete `CMS_SERVER_LAYER`** (`src/server/index.ts`). It existed only to give the `/server`
|
|
88
|
+
entry point something real to resolve, and real exports have since landed. Its `/core`
|
|
89
|
+
counterpart `CMS_CORE_LAYER` is already gone.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-tools.d.ts","sourceRoot":"","sources":["../../src/content-types/agent-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,uBAAuB,GAAG,aAAa,CAAC;AAEnF,MAAM,MAAM,uBAAuB,GAAG,sCAAsC,GAAG,WAAW,GAAG,MAAM,CAAC;AAEpG,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,mBAAmB,CAAC;IACjC,aAAa,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACjD;
|
|
1
|
+
{"version":3,"file":"agent-tools.d.ts","sourceRoot":"","sources":["../../src/content-types/agent-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,uBAAuB,GAAG,aAAa,CAAC;AAEnF,MAAM,MAAM,uBAAuB,GAAG,sCAAsC,GAAG,WAAW,GAAG,MAAM,CAAC;AAEpG,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,mBAAmB,CAAC;IACjC,aAAa,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACjD;AA4DD;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,EAAE,mBAAmB,EA+E7D,CAAC"}
|
|
@@ -44,7 +44,7 @@ const FIELD_DEF_SCHEMA = {
|
|
|
44
44
|
kind: {
|
|
45
45
|
type: "string",
|
|
46
46
|
enum: [...CONTENT_TYPE_FIELD_KINDS],
|
|
47
|
-
description: "One of the
|
|
47
|
+
description: "One of the supported storage kinds. No other value is accepted. 'json' is storage-only: it may not be combined with queryable: true.",
|
|
48
48
|
},
|
|
49
49
|
required: { type: "boolean", description: "Whether an entry must supply this field. Must be a real boolean, not a string." },
|
|
50
50
|
queryable: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-tools.js","sourceRoot":"","sources":["../../src/content-types/agent-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AA4BtD,uGAAuG;AACvG,MAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC;IACnD,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,0BAA0B;YACnC,WAAW,EAAE,qGAAqG;SACnH;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,GAAG,wBAAwB,CAAC;YACnC,WAAW,
|
|
1
|
+
{"version":3,"file":"agent-tools.js","sourceRoot":"","sources":["../../src/content-types/agent-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AA4BtD,uGAAuG;AACvG,MAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC;IACnD,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,0BAA0B;YACnC,WAAW,EAAE,qGAAqG;SACnH;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,GAAG,wBAAwB,CAAC;YACnC,WAAW,EACT,sIAAsI;SACzI;QACD,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,gFAAgF,EAAE;QAC5H,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gIAAgI;SAC9I;KACF;CACO,CAAC;AAEX,yFAAyF;AACzF,MAAM,eAAe,GAAG;IACtB,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,EAAE;CACN,CAAC;AAEX,oEAAoE;AACpE,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE,GAAG;IACb,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,0HAA0H;CAC/H,CAAC;AAEX,6FAA6F;AAC7F,MAAM,uBAAuB,GAAG;IAC9B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,+JAA+J;CACpK,CAAC;AAEX,+GAA+G;AAC/G,MAAM,sBAAsB,GAAG;IAC7B,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC;IACpC,UAAU,EAAE;QACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,0BAA0B,EAAE,WAAW,EAAE,yBAAyB,EAAE;QACpG,eAAe,EAAE,uBAAuB;KACzC;CACO,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAA0B;IACjE;QACE,IAAI,EAAE,+BAA+B;QACrC,WAAW,EACT,gRAAgR;QAClR,WAAW,EAAE,MAAM;QACnB,aAAa,EAAE,EAAE,UAAU,EAAE,wBAAwB,EAAE;QACvD,WAAW,EAAE,eAAe;KAC7B;IACD;QACE,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,gIAAgI;QAC7I,WAAW,EAAE,MAAM;QACnB,aAAa,EAAE,EAAE,UAAU,EAAE,wBAAwB,EAAE;KACxD;IACD;QACE,IAAI,EAAE,6BAA6B;QACnC,WAAW,EAAE,sIAAsI;QACnJ,WAAW,EAAE,uBAAuB;QACpC,aAAa,EAAE,EAAE,UAAU,EAAE,0BAA0B,EAAE;QACzD,cAAc,EAAE,sCAAsC;KACvD;IACD;QACE,IAAI,EAAE,iCAAiC;QACvC,WAAW,EAAE,gEAAgE;QAC7E,WAAW,EAAE,uBAAuB;QACpC,aAAa,EAAE,EAAE,UAAU,EAAE,0BAA0B,EAAE;QACzD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,oBAAoB,EAAE,KAAK;YAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC;YACpC,UAAU,EAAE;gBACV,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,0BAA0B;oBACnC,WAAW,EAAE,sIAAsI;iBACpJ;gBACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oDAAoD,EAAE;gBAC5F,MAAM,EAAE,aAAa;aACtB;SACF;KACF;IACD;QACE,IAAI,EAAE,wCAAwC;QAC9C,WAAW,EAAE,8CAA8C;QAC3D,WAAW,EAAE,uBAAuB;QACpC,aAAa,EAAE,EAAE,UAAU,EAAE,0BAA0B,EAAE;QACzD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,oBAAoB,EAAE,KAAK;YAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,iBAAiB,CAAC;YAC9C,UAAU,EAAE;gBACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,0BAA0B,EAAE,WAAW,EAAE,yBAAyB,EAAE;gBACpG,MAAM,EAAE,aAAa;gBACrB,eAAe,EAAE,uBAAuB;aACzC;SACF;KACF;IACD;QACE,IAAI,EAAE,oCAAoC;QAC1C,WAAW,EAAE,sEAAsE;QACnF,WAAW,EAAE,uBAAuB;QACpC,aAAa,EAAE,EAAE,UAAU,EAAE,0BAA0B,EAAE;QACzD,WAAW,EAAE,sBAAsB;KACpC;IACD;QACE,IAAI,EAAE,qCAAqC;QAC3C,WAAW,EAAE,uDAAuD;QACpE,WAAW,EAAE,uBAAuB;QACpC,aAAa,EAAE,EAAE,UAAU,EAAE,0BAA0B,EAAE;QACzD,WAAW,EAAE,sBAAsB;KACpC;IACD;QACE,IAAI,EAAE,oCAAoC;QAC1C,WAAW,EAAE,8FAA8F;QAC3G,WAAW,EAAE,uBAAuB;QACpC,aAAa,EAAE,EAAE,UAAU,EAAE,0BAA0B,EAAE;QACzD,WAAW,EAAE,sBAAsB;KACpC;CACF,CAAC"}
|
|
@@ -28,10 +28,28 @@ export declare class ReservedContentTypeKeyError extends Error {
|
|
|
28
28
|
export declare class InvalidFieldNameGrammarError extends Error {
|
|
29
29
|
constructor(message: string);
|
|
30
30
|
}
|
|
31
|
-
/** CIC U-001-B1 / U-002-B1 guard 4 — a field `kind` is not one of the closed
|
|
31
|
+
/** CIC U-001-B1 / U-002-B1 guard 4 — a field `kind` is not one of the closed field-kind enum. */
|
|
32
32
|
export declare class InvalidFieldKindError extends Error {
|
|
33
33
|
constructor(message: string);
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* CIC U-002-B1 guard 4b — a field declares a STORAGE-ONLY `kind` (`json`) together with
|
|
37
|
+
* `queryable: true`. The kind itself is legal and the field may be declared and written; what is
|
|
38
|
+
* rejected is the pairing, because a storage-only kind has no `CAST` target and therefore no index
|
|
39
|
+
* to provision.
|
|
40
|
+
*
|
|
41
|
+
* DELIBERATELY A SUBCLASS of {@link InvalidFieldKindError}, not a sibling. The fronting HTTP
|
|
42
|
+
* boundaries map rejections with a fixed `instanceof` list and fall through to
|
|
43
|
+
* `500 INTERNAL_ERROR`; they live in consuming applications, outside this package, and cannot be
|
|
44
|
+
* updated in lockstep with it. A sibling class would therefore turn a validation rejection into a
|
|
45
|
+
* 500 at every existing boundary the day this shipped. Subclassing keeps every such boundary at
|
|
46
|
+
* `400 VALIDATION_ERROR` with no coordinated change, and the relationship is honest — this IS a
|
|
47
|
+
* rejection of the field's kind, in the context the kind was used. `.name` still distinguishes it
|
|
48
|
+
* for any caller that wants the finer signal.
|
|
49
|
+
*/
|
|
50
|
+
export declare class StorageOnlyFieldNotQueryableError extends InvalidFieldKindError {
|
|
51
|
+
constructor(message: string);
|
|
52
|
+
}
|
|
35
53
|
/**
|
|
36
54
|
* A `fields` payload whose STRUCTURE is wrong — not a value that failed a domain rule, but a
|
|
37
55
|
* shape the `ContentTypeFieldDef[]` contract does not describe at all (a non-array, a non-object
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/content-types/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED,gGAAgG;AAChG,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED,2FAA2F;AAC3F,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED,6EAA6E;AAC7E,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,OAAO,EAAE,MAAM;CAI5B;AAED,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/content-types/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED,gGAAgG;AAChG,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED,2FAA2F;AAC3F,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED,6EAA6E;AAC7E,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,OAAO,EAAE,MAAM;CAI5B;AAED,iGAAiG;AACjG,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iCAAkC,SAAQ,qBAAqB;gBAC9D,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,kBAAkB,CAAU;IAC5C,QAAQ,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;gBAE7D,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CAK5E;AAED,8FAA8F;AAC9F,qBAAa,8BAA+B,SAAQ,KAAK;gBAC3C,OAAO,EAAE,MAAM;CAI5B;AAED,+FAA+F;AAC/F,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED,0FAA0F;AAC1F,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAG,kBAAkB,CAAU;IAC5C,QAAQ,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;gBAEzB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAED,6GAA6G;AAC7G,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAED,iGAAiG;AACjG,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAK7C"}
|
|
@@ -40,13 +40,34 @@ export class InvalidFieldNameGrammarError extends Error {
|
|
|
40
40
|
this.name = "InvalidFieldNameGrammarError";
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
/** CIC U-001-B1 / U-002-B1 guard 4 — a field `kind` is not one of the closed
|
|
43
|
+
/** CIC U-001-B1 / U-002-B1 guard 4 — a field `kind` is not one of the closed field-kind enum. */
|
|
44
44
|
export class InvalidFieldKindError extends Error {
|
|
45
45
|
constructor(message) {
|
|
46
46
|
super(message);
|
|
47
47
|
this.name = "InvalidFieldKindError";
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* CIC U-002-B1 guard 4b — a field declares a STORAGE-ONLY `kind` (`json`) together with
|
|
52
|
+
* `queryable: true`. The kind itself is legal and the field may be declared and written; what is
|
|
53
|
+
* rejected is the pairing, because a storage-only kind has no `CAST` target and therefore no index
|
|
54
|
+
* to provision.
|
|
55
|
+
*
|
|
56
|
+
* DELIBERATELY A SUBCLASS of {@link InvalidFieldKindError}, not a sibling. The fronting HTTP
|
|
57
|
+
* boundaries map rejections with a fixed `instanceof` list and fall through to
|
|
58
|
+
* `500 INTERNAL_ERROR`; they live in consuming applications, outside this package, and cannot be
|
|
59
|
+
* updated in lockstep with it. A sibling class would therefore turn a validation rejection into a
|
|
60
|
+
* 500 at every existing boundary the day this shipped. Subclassing keeps every such boundary at
|
|
61
|
+
* `400 VALIDATION_ERROR` with no coordinated change, and the relationship is honest — this IS a
|
|
62
|
+
* rejection of the field's kind, in the context the kind was used. `.name` still distinguishes it
|
|
63
|
+
* for any caller that wants the finer signal.
|
|
64
|
+
*/
|
|
65
|
+
export class StorageOnlyFieldNotQueryableError extends InvalidFieldKindError {
|
|
66
|
+
constructor(message) {
|
|
67
|
+
super(message);
|
|
68
|
+
this.name = "StorageOnlyFieldNotQueryableError";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
50
71
|
/**
|
|
51
72
|
* A `fields` payload whose STRUCTURE is wrong — not a value that failed a domain rule, but a
|
|
52
73
|
* shape the `ContentTypeFieldDef[]` contract does not describe at all (a non-array, a non-object
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/content-types/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,gGAAgG;AAChG,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,2FAA2F;AAC3F,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IACpD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACrD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAC7C,CAAC;CACF;AAED,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/content-types/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ContentTypeFieldKind } from "./types.js";
|
|
1
|
+
import { type ContentTypeFieldKind, type IndexableFieldKind } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* @file CIC U-001 — the `kind`->`CAST` fixed lookup table, the identifier grammar
|
|
4
4
|
* gate, the workspace-scoped queryable-index naming scheme, and the before/after index-transition
|
|
@@ -8,8 +8,34 @@ import { type ContentTypeFieldKind } from "./types.js";
|
|
|
8
8
|
* THIS IS THE HIGHEST-SECURITY-SEVERITY MODULE IN THE 5-PACKAGE PIPELINE — every value that ends
|
|
9
9
|
* up inside a `CREATE INDEX ... CAST(json_extract(fields,'$.ext.{ns}.{field}') AS {type})`
|
|
10
10
|
* statement is produced here, and only here:
|
|
11
|
-
* - `mapFieldKindToCast`
|
|
12
|
-
*
|
|
11
|
+
* - `mapFieldKindToCast` (U-001-B1). STATE THE INVARIANT PRECISELY, because an earlier version
|
|
12
|
+
* of this comment did not and the imprecision was itself a hazard: it said "a fixed, hardcoded
|
|
13
|
+
* 5-entry table", which reads as though the ENTRY COUNT were the defense. It is not. Neither
|
|
14
|
+
* the number of keys nor the number of distinct values is the security boundary.
|
|
15
|
+
*
|
|
16
|
+
* THE DEFENSE IS: this function returns a VALUE FROM THE TABLE and never returns, echoes, or
|
|
17
|
+
* interpolates its own ARGUMENT. The function has exactly one `return`, and it is a table
|
|
18
|
+
* lookup. Therefore the set of strings that can reach a `CAST(... AS {type})` position is
|
|
19
|
+
* exactly the set of string literals written into `KIND_TO_CAST_LITERAL` in this source file —
|
|
20
|
+
* compile-time constants, every one — no matter what an operator, an agent, or an attacker
|
|
21
|
+
* supplies as `kind`. A 50-entry table of literals would be exactly as safe as a 5-entry one.
|
|
22
|
+
*
|
|
23
|
+
* What follows from that, and what a maintainer actually needs to know:
|
|
24
|
+
* * Adding a KEY whose value is an existing literal cannot widen the DDL alphabet. It is not
|
|
25
|
+
* a security event and does not need to be feared as one. (`relation: "TEXT"` is exactly
|
|
26
|
+
* this: `"TEXT"` was already present twice.)
|
|
27
|
+
* * Adding a new VALUE does widen it, and must be reviewed as a DDL change.
|
|
28
|
+
* * Returning, concatenating, or template-interpolating `kind` itself — or reading the table
|
|
29
|
+
* with a fallback such as `?? kind` — BREAKS the invariant outright. That is the edit to
|
|
30
|
+
* refuse, and it is the one the old "5-entry" phrasing gave no way to recognise.
|
|
31
|
+
* The reachable-value set is pinned executably by `HISTORICAL_DDL_ALPHABET` in
|
|
32
|
+
* `__tests__/field-kind-widening.test.ts`, so this claim is a failing test and not only prose.
|
|
33
|
+
*
|
|
34
|
+
* Degraded failure mode, stated so the blast radius is known: if every runtime guard below
|
|
35
|
+
* were deleted, a storage-only kind would reach the table and `KIND_TO_CAST_LITERAL["json"]`
|
|
36
|
+
* would evaluate to `undefined` — a SQL syntax error and a loud broken feature, never an
|
|
37
|
+
* operator-controlled string. Total guard removal degrades this module to unavailable, not to
|
|
38
|
+
* injectable. That is the property worth preserving through any future change.
|
|
13
39
|
* - `validateIdentifierGrammar`/`buildQueryableFieldIndexName` gate every `key`/field name
|
|
14
40
|
* through `^[a-z][a-z0-9_]{0,63}$` before it can reach an index-name segment or JSON-path
|
|
15
41
|
* literal (U-001-B2), and join grammar-gated segments with `/` — a delimiter outside the
|
|
@@ -18,6 +44,11 @@ import { type ContentTypeFieldKind } from "./types.js";
|
|
|
18
44
|
* `(key, field)` pair never collide on index identity.
|
|
19
45
|
*
|
|
20
46
|
* How it relates to the project:
|
|
47
|
+
* `resolveFieldIndexTransition` deliberately still ACCEPTS a storage-only kind on its `none` and
|
|
48
|
+
* `teardown` arms while rejecting it on the two provisioning arms. Teardown must stay reachable:
|
|
49
|
+
* an index left behind by a bypassed or since-added guard has to remain droppable, and a resolver
|
|
50
|
+
* that refused to look at the kind at all could never order that cleanup.
|
|
51
|
+
*
|
|
21
52
|
* `write-service.ts`'s `registerContentType`/`updateContentTypeFields` call
|
|
22
53
|
* `resolveFieldIndexTransition` once per field (never two independent kind/queryable branches —
|
|
23
54
|
* CIC U-003-B1) and hand the result to the injected `indexProvisioner` port, which is the only
|
|
@@ -44,12 +75,23 @@ export declare const IDENTIFIER_GRAMMAR_PATTERN = "^[a-z][a-z0-9_]{0,63}$";
|
|
|
44
75
|
*/
|
|
45
76
|
export declare function validateIdentifierGrammar(value: string): boolean;
|
|
46
77
|
/**
|
|
47
|
-
* Maps
|
|
48
|
-
* {@link InvalidFieldKindError} for anything not exactly one of
|
|
49
|
-
*
|
|
50
|
-
*
|
|
78
|
+
* Maps an INDEXABLE field `kind` to its fixed `CAST(... AS {type})` type token. Throws
|
|
79
|
+
* {@link InvalidFieldKindError} for anything that is not exactly one of `INDEXABLE_FIELD_KINDS` —
|
|
80
|
+
* including a storage-only kind such as `json`, which is a legal kind to declare but has no CAST
|
|
81
|
+
* target. This is a lookup, never a template, so an adversarial payload can never reach the
|
|
82
|
+
* returned string (U-001-B1).
|
|
83
|
+
*
|
|
84
|
+
* The PARAMETER type is deliberately the wider `ContentTypeFieldKind`. Narrowing it would be a
|
|
85
|
+
* breaking change for `@jini-ai/cms`'s public consumers (`content-types/index.ts` documents this
|
|
86
|
+
* function as what a host's own DDL provisioner calls, and Tovu re-exports it), and it would also
|
|
87
|
+
* make the runtime guard below unreachable-looking to a reader while remaining fully reachable to
|
|
88
|
+
* an untyped JavaScript caller. The runtime gate — not the signature — is what excludes
|
|
89
|
+
* storage-only kinds.
|
|
90
|
+
*
|
|
91
|
+
* Behavior for the five original scalars is unchanged in every respect: `isIndexableFieldKind` and
|
|
92
|
+
* `isContentTypeFieldKind` agree on all five, and each still returns the identical literal.
|
|
51
93
|
*
|
|
52
|
-
* @complexity O(1) — a fixed-size object lookup.
|
|
94
|
+
* @complexity O(1) — a fixed-size object lookup behind a fixed-size membership test.
|
|
53
95
|
* @overallScore 100
|
|
54
96
|
*/
|
|
55
97
|
export declare function mapFieldKindToCast(kind: ContentTypeFieldKind): string;
|
|
@@ -75,8 +117,12 @@ export type FieldIndexState = {
|
|
|
75
117
|
} | undefined;
|
|
76
118
|
export interface FieldIndexTransition {
|
|
77
119
|
action: "none" | "provision" | "teardown" | "reprovision";
|
|
78
|
-
/**
|
|
79
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Present only for `provision`/`reprovision` — always the field's POST-call kind, and always
|
|
122
|
+
* INDEXABLE. A storage-only kind cannot be `queryable` (rejected by `write-service.ts`'s guard
|
|
123
|
+
* 4b, which runs before any transition is resolved), so it can never reach these two arms.
|
|
124
|
+
*/
|
|
125
|
+
newKind?: IndexableFieldKind;
|
|
80
126
|
}
|
|
81
127
|
/**
|
|
82
128
|
* CIC U-003-B1 — resolves a single field's index transition from ONE before/after comparison of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-provisioning.d.ts","sourceRoot":"","sources":["../../src/content-types/index-provisioning.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"index-provisioning.d.ts","sourceRoot":"","sources":["../../src/content-types/index-provisioning.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EAExB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AAKnE;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhE;AA2BD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAOrE;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAYT;AAED,gHAAgH;AAChH,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC;AAE7F,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,CAAC;IAC1D;;;;OAIG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAsBD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,eAAe,CAAC;CACxB,GAAG,oBAAoB,CAavB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { InvalidFieldKindError, InvalidFieldNameGrammarError, InvalidKeyGrammarError } from "./errors.js";
|
|
3
|
-
import {
|
|
3
|
+
import { INDEXABLE_FIELD_KINDS, isIndexableFieldKind, } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* @file CIC U-001 — the `kind`->`CAST` fixed lookup table, the identifier grammar
|
|
6
6
|
* gate, the workspace-scoped queryable-index naming scheme, and the before/after index-transition
|
|
@@ -10,8 +10,34 @@ import { CONTENT_TYPE_FIELD_KINDS, isContentTypeFieldKind } from "./types.js";
|
|
|
10
10
|
* THIS IS THE HIGHEST-SECURITY-SEVERITY MODULE IN THE 5-PACKAGE PIPELINE — every value that ends
|
|
11
11
|
* up inside a `CREATE INDEX ... CAST(json_extract(fields,'$.ext.{ns}.{field}') AS {type})`
|
|
12
12
|
* statement is produced here, and only here:
|
|
13
|
-
* - `mapFieldKindToCast`
|
|
14
|
-
*
|
|
13
|
+
* - `mapFieldKindToCast` (U-001-B1). STATE THE INVARIANT PRECISELY, because an earlier version
|
|
14
|
+
* of this comment did not and the imprecision was itself a hazard: it said "a fixed, hardcoded
|
|
15
|
+
* 5-entry table", which reads as though the ENTRY COUNT were the defense. It is not. Neither
|
|
16
|
+
* the number of keys nor the number of distinct values is the security boundary.
|
|
17
|
+
*
|
|
18
|
+
* THE DEFENSE IS: this function returns a VALUE FROM THE TABLE and never returns, echoes, or
|
|
19
|
+
* interpolates its own ARGUMENT. The function has exactly one `return`, and it is a table
|
|
20
|
+
* lookup. Therefore the set of strings that can reach a `CAST(... AS {type})` position is
|
|
21
|
+
* exactly the set of string literals written into `KIND_TO_CAST_LITERAL` in this source file —
|
|
22
|
+
* compile-time constants, every one — no matter what an operator, an agent, or an attacker
|
|
23
|
+
* supplies as `kind`. A 50-entry table of literals would be exactly as safe as a 5-entry one.
|
|
24
|
+
*
|
|
25
|
+
* What follows from that, and what a maintainer actually needs to know:
|
|
26
|
+
* * Adding a KEY whose value is an existing literal cannot widen the DDL alphabet. It is not
|
|
27
|
+
* a security event and does not need to be feared as one. (`relation: "TEXT"` is exactly
|
|
28
|
+
* this: `"TEXT"` was already present twice.)
|
|
29
|
+
* * Adding a new VALUE does widen it, and must be reviewed as a DDL change.
|
|
30
|
+
* * Returning, concatenating, or template-interpolating `kind` itself — or reading the table
|
|
31
|
+
* with a fallback such as `?? kind` — BREAKS the invariant outright. That is the edit to
|
|
32
|
+
* refuse, and it is the one the old "5-entry" phrasing gave no way to recognise.
|
|
33
|
+
* The reachable-value set is pinned executably by `HISTORICAL_DDL_ALPHABET` in
|
|
34
|
+
* `__tests__/field-kind-widening.test.ts`, so this claim is a failing test and not only prose.
|
|
35
|
+
*
|
|
36
|
+
* Degraded failure mode, stated so the blast radius is known: if every runtime guard below
|
|
37
|
+
* were deleted, a storage-only kind would reach the table and `KIND_TO_CAST_LITERAL["json"]`
|
|
38
|
+
* would evaluate to `undefined` — a SQL syntax error and a loud broken feature, never an
|
|
39
|
+
* operator-controlled string. Total guard removal degrades this module to unavailable, not to
|
|
40
|
+
* injectable. That is the property worth preserving through any future change.
|
|
15
41
|
* - `validateIdentifierGrammar`/`buildQueryableFieldIndexName` gate every `key`/field name
|
|
16
42
|
* through `^[a-z][a-z0-9_]{0,63}$` before it can reach an index-name segment or JSON-path
|
|
17
43
|
* literal (U-001-B2), and join grammar-gated segments with `/` — a delimiter outside the
|
|
@@ -20,6 +46,11 @@ import { CONTENT_TYPE_FIELD_KINDS, isContentTypeFieldKind } from "./types.js";
|
|
|
20
46
|
* `(key, field)` pair never collide on index identity.
|
|
21
47
|
*
|
|
22
48
|
* How it relates to the project:
|
|
49
|
+
* `resolveFieldIndexTransition` deliberately still ACCEPTS a storage-only kind on its `none` and
|
|
50
|
+
* `teardown` arms while rejecting it on the two provisioning arms. Teardown must stay reachable:
|
|
51
|
+
* an index left behind by a bypassed or since-added guard has to remain droppable, and a resolver
|
|
52
|
+
* that refused to look at the kind at all could never order that cleanup.
|
|
53
|
+
*
|
|
23
54
|
* `write-service.ts`'s `registerContentType`/`updateContentTypeFields` call
|
|
24
55
|
* `resolveFieldIndexTransition` once per field (never two independent kind/queryable branches —
|
|
25
56
|
* CIC U-003-B1) and hand the result to the injected `indexProvisioner` port, which is the only
|
|
@@ -52,6 +83,13 @@ export function validateIdentifierGrammar(value) {
|
|
|
52
83
|
/**
|
|
53
84
|
* U-001-B1 — the fixed, hardcoded `kind` -> SQL `CAST` type-token table. Every value here is a
|
|
54
85
|
* plain uppercase SQL type token with no quotes/parens/whitespace; never built by concatenation.
|
|
86
|
+
*
|
|
87
|
+
* Keyed by `IndexableFieldKind`, NOT `ContentTypeFieldKind`: a storage-only kind has no CAST
|
|
88
|
+
* target, and typing the table over the wider union would force one to be invented — which is the
|
|
89
|
+
* actual hazard this split exists to prevent. The `Record` is what makes exhaustiveness
|
|
90
|
+
* compiler-enforced: adding a member to `INDEXABLE_FIELD_KINDS` fails the build until an entry
|
|
91
|
+
* appears here. Do not replace it with a `Partial`, an index signature, or a lookup with a
|
|
92
|
+
* fallback — each of those converts a build failure into a runtime surprise on the DDL path.
|
|
55
93
|
*/
|
|
56
94
|
const KIND_TO_CAST_LITERAL = {
|
|
57
95
|
text: "TEXT",
|
|
@@ -59,19 +97,36 @@ const KIND_TO_CAST_LITERAL = {
|
|
|
59
97
|
real: "REAL",
|
|
60
98
|
boolean: "BOOLEAN",
|
|
61
99
|
datetime: "TEXT",
|
|
100
|
+
/**
|
|
101
|
+
* A foreign entity id, stored with `text`'s storage class. This adds a KEY to the table and no
|
|
102
|
+
* new VALUE to the DDL alphabet — `"TEXT"` already appears twice above — so the set of strings
|
|
103
|
+
* reachable from a `CAST(... AS {type})` position is unchanged by its presence.
|
|
104
|
+
*/
|
|
105
|
+
relation: "TEXT",
|
|
62
106
|
};
|
|
63
107
|
/**
|
|
64
|
-
* Maps
|
|
65
|
-
* {@link InvalidFieldKindError} for anything not exactly one of
|
|
66
|
-
*
|
|
67
|
-
*
|
|
108
|
+
* Maps an INDEXABLE field `kind` to its fixed `CAST(... AS {type})` type token. Throws
|
|
109
|
+
* {@link InvalidFieldKindError} for anything that is not exactly one of `INDEXABLE_FIELD_KINDS` —
|
|
110
|
+
* including a storage-only kind such as `json`, which is a legal kind to declare but has no CAST
|
|
111
|
+
* target. This is a lookup, never a template, so an adversarial payload can never reach the
|
|
112
|
+
* returned string (U-001-B1).
|
|
113
|
+
*
|
|
114
|
+
* The PARAMETER type is deliberately the wider `ContentTypeFieldKind`. Narrowing it would be a
|
|
115
|
+
* breaking change for `@jini-ai/cms`'s public consumers (`content-types/index.ts` documents this
|
|
116
|
+
* function as what a host's own DDL provisioner calls, and Tovu re-exports it), and it would also
|
|
117
|
+
* make the runtime guard below unreachable-looking to a reader while remaining fully reachable to
|
|
118
|
+
* an untyped JavaScript caller. The runtime gate — not the signature — is what excludes
|
|
119
|
+
* storage-only kinds.
|
|
68
120
|
*
|
|
69
|
-
*
|
|
121
|
+
* Behavior for the five original scalars is unchanged in every respect: `isIndexableFieldKind` and
|
|
122
|
+
* `isContentTypeFieldKind` agree on all five, and each still returns the identical literal.
|
|
123
|
+
*
|
|
124
|
+
* @complexity O(1) — a fixed-size object lookup behind a fixed-size membership test.
|
|
70
125
|
* @overallScore 100
|
|
71
126
|
*/
|
|
72
127
|
export function mapFieldKindToCast(kind) {
|
|
73
|
-
if (!
|
|
74
|
-
throw new InvalidFieldKindError(`'${String(kind)}' is not
|
|
128
|
+
if (!isIndexableFieldKind(kind)) {
|
|
129
|
+
throw new InvalidFieldKindError(`'${String(kind)}' is not an indexable field kind (${INDEXABLE_FIELD_KINDS.join("|")}) — U-001-B1`);
|
|
75
130
|
}
|
|
76
131
|
return KIND_TO_CAST_LITERAL[kind];
|
|
77
132
|
}
|
|
@@ -107,6 +162,23 @@ export function buildQueryableFieldIndexName(params) {
|
|
|
107
162
|
}
|
|
108
163
|
return `q/${workspaceIndexSegment(params.workspaceId)}/${params.contentTypeKey}/${params.fieldName}`;
|
|
109
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Narrows a post-call field kind for the two arms that hand a kind to the index provisioner.
|
|
167
|
+
*
|
|
168
|
+
* Expected to be unreachable: `write-service.ts`'s guard chain rejects `queryable: true` on a
|
|
169
|
+
* storage-only kind before any transition is resolved. Asserted rather than cast away so that a
|
|
170
|
+
* future caller which bypasses that chain fails loudly here — at the last point before a kind
|
|
171
|
+
* becomes an index — instead of silently provisioning an index for an unindexable kind.
|
|
172
|
+
*
|
|
173
|
+
* @complexity O(1).
|
|
174
|
+
* @overallScore 100
|
|
175
|
+
*/
|
|
176
|
+
function assertIndexableForProvisioning(kind) {
|
|
177
|
+
if (!isIndexableFieldKind(kind)) {
|
|
178
|
+
throw new InvalidFieldKindError(`storage-only kind '${String(kind)}' reached index provisioning; only (${INDEXABLE_FIELD_KINDS.join("|")}) may be queryable — U-001-B1`);
|
|
179
|
+
}
|
|
180
|
+
return kind;
|
|
181
|
+
}
|
|
110
182
|
/**
|
|
111
183
|
* CIC U-003-B1 — resolves a single field's index transition from ONE before/after comparison of
|
|
112
184
|
* its `(kind, queryable)` pair, never from two independent branches that each assume the other
|
|
@@ -123,10 +195,11 @@ export function resolveFieldIndexTransition(params) {
|
|
|
123
195
|
return { action: "none" };
|
|
124
196
|
if (beforeQueryable && !afterQueryable)
|
|
125
197
|
return { action: "teardown" };
|
|
126
|
-
if (!beforeQueryable && afterQueryable)
|
|
127
|
-
return { action: "provision", newKind: params.after.kind };
|
|
198
|
+
if (!beforeQueryable && afterQueryable) {
|
|
199
|
+
return { action: "provision", newKind: assertIndexableForProvisioning(params.after.kind) };
|
|
200
|
+
}
|
|
128
201
|
if (params.before.kind !== params.after.kind) {
|
|
129
|
-
return { action: "reprovision", newKind: params.after.kind };
|
|
202
|
+
return { action: "reprovision", newKind: assertIndexableForProvisioning(params.after.kind) };
|
|
130
203
|
}
|
|
131
204
|
return { action: "none" };
|
|
132
205
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-provisioning.js","sourceRoot":"","sources":["../../src/content-types/index-provisioning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1G,OAAO,
|
|
1
|
+
{"version":3,"file":"index-provisioning.js","sourceRoot":"","sources":["../../src/content-types/index-provisioning.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,14 @@
|
|
|
6
6
|
*
|
|
7
7
|
* See `../entries/index.js`'s header for why these two ship as separate subpaths rather than one.
|
|
8
8
|
*/
|
|
9
|
-
export type { ContentTypeFieldKind, ContentTypeFieldDef, ContentTypeStatus, ContentTypeRecord, ActorPrincipalKind, ActorIdentityInput, Result, } from "./types.js";
|
|
10
|
-
|
|
9
|
+
export type { ContentTypeFieldKind, IndexableFieldKind, StorageOnlyFieldKind, ContentTypeFieldDef, ContentTypeStatus, ContentTypeRecord, ActorPrincipalKind, ActorIdentityInput, Result, } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* `CONTENT_TYPE_FIELD_KINDS`/`isContentTypeFieldKind` answer "may this kind be DECLARED and
|
|
12
|
+
* STORED". `INDEXABLE_FIELD_KINDS`/`isIndexableFieldKind` answer the narrower "may this kind be
|
|
13
|
+
* `queryable`, and therefore reach `mapFieldKindToCast`". A host writing its own DDL provisioner
|
|
14
|
+
* needs the second pair, not the first — they are no longer the same set.
|
|
15
|
+
*/
|
|
16
|
+
export { CONTENT_TYPE_FIELD_KINDS, CONTENT_TYPE_SCALAR_KINDS, INDEXABLE_FIELD_KINDS, STORAGE_ONLY_FIELD_KINDS, isContentTypeFieldKind, isIndexableFieldKind, } from "./types.js";
|
|
11
17
|
export type { ContentTypeListPort } from "./list.js";
|
|
12
18
|
export { listContentTypes } from "./list.js";
|
|
13
19
|
export { parseContentTypeFieldDefs } from "./field-defs.js";
|
|
@@ -18,7 +24,13 @@ export { parseContentTypeFieldDefs } from "./field-defs.js";
|
|
|
18
24
|
* module's own and are deliberately distinct from the same-named classes on `../entries/index.js`
|
|
19
25
|
* and `../core/commands/command.js` — a consumer must catch the one it actually called into.
|
|
20
26
|
*/
|
|
21
|
-
export { ForbiddenError, InvalidKeyGrammarError, ReservedContentTypeKeyError, InvalidFieldNameGrammarError, InvalidFieldKindError,
|
|
27
|
+
export { ForbiddenError, InvalidKeyGrammarError, ReservedContentTypeKeyError, InvalidFieldNameGrammarError, InvalidFieldKindError,
|
|
28
|
+
/**
|
|
29
|
+
* A SUBCLASS of `InvalidFieldKindError` — an existing boundary whose `instanceof` list already
|
|
30
|
+
* carries the parent maps this to the same `400 VALIDATION_ERROR` with no change. Catch it by
|
|
31
|
+
* name only if the finer distinction matters.
|
|
32
|
+
*/
|
|
33
|
+
StorageOnlyFieldNotQueryableError, InvalidFieldShapeError, QueryableFieldCapExceededError, VersionConflictError, ContentTypeNotFoundError, ValidationError, ContentTypeLifecycleError, CleanupNotEligibleError, } from "./errors.js";
|
|
22
34
|
/**
|
|
23
35
|
* The queryable-field index machinery. `IDENTIFIER_GRAMMAR_PATTERN` is exported because it is the
|
|
24
36
|
* single definition of the identifier grammar — the published agent-tool schemas reference it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content-types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,GACP,MAAM,YAAY,CAAC;AACpB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content-types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,GACP,MAAM,YAAY,CAAC;AACpB;;;;;GAKG;AACH,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;;;;GAMG;AACH,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,qBAAqB;AACrB;;;;GAIG;AACH,iCAAiC,EACjC,sBAAsB,EACtB,8BAA8B,EAC9B,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAErB;;;;;;GAMG;AACH,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,EAClB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,WAAW,EACX,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,2BAA2B,EAC3B,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElF,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,+BAA+B,EAC/B,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,YAAY,EACV,+BAA+B,EAC/B,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D;;;;GAIG;AACH,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,sGAAsG;AACtG,OAAO,EACL,4BAA4B,EAC5B,KAAK,mBAAmB,IAAI,+BAA+B,EAC3D,KAAK,mBAAmB,IAAI,+BAA+B,EAC3D,KAAK,uBAAuB,IAAI,mCAAmC,GACpE,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC;;GAEG"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `CONTENT_TYPE_FIELD_KINDS`/`isContentTypeFieldKind` answer "may this kind be DECLARED and
|
|
3
|
+
* STORED". `INDEXABLE_FIELD_KINDS`/`isIndexableFieldKind` answer the narrower "may this kind be
|
|
4
|
+
* `queryable`, and therefore reach `mapFieldKindToCast`". A host writing its own DDL provisioner
|
|
5
|
+
* needs the second pair, not the first — they are no longer the same set.
|
|
6
|
+
*/
|
|
7
|
+
export { CONTENT_TYPE_FIELD_KINDS, CONTENT_TYPE_SCALAR_KINDS, INDEXABLE_FIELD_KINDS, STORAGE_ONLY_FIELD_KINDS, isContentTypeFieldKind, isIndexableFieldKind, } from "./types.js";
|
|
2
8
|
export { listContentTypes } from "./list.js";
|
|
3
9
|
export { parseContentTypeFieldDefs } from "./field-defs.js";
|
|
4
10
|
/**
|
|
@@ -8,7 +14,13 @@ export { parseContentTypeFieldDefs } from "./field-defs.js";
|
|
|
8
14
|
* module's own and are deliberately distinct from the same-named classes on `../entries/index.js`
|
|
9
15
|
* and `../core/commands/command.js` — a consumer must catch the one it actually called into.
|
|
10
16
|
*/
|
|
11
|
-
export { ForbiddenError, InvalidKeyGrammarError, ReservedContentTypeKeyError, InvalidFieldNameGrammarError, InvalidFieldKindError,
|
|
17
|
+
export { ForbiddenError, InvalidKeyGrammarError, ReservedContentTypeKeyError, InvalidFieldNameGrammarError, InvalidFieldKindError,
|
|
18
|
+
/**
|
|
19
|
+
* A SUBCLASS of `InvalidFieldKindError` — an existing boundary whose `instanceof` list already
|
|
20
|
+
* carries the parent maps this to the same `400 VALIDATION_ERROR` with no change. Catch it by
|
|
21
|
+
* name only if the finer distinction matters.
|
|
22
|
+
*/
|
|
23
|
+
StorageOnlyFieldNotQueryableError, InvalidFieldShapeError, QueryableFieldCapExceededError, VersionConflictError, ContentTypeNotFoundError, ValidationError, ContentTypeLifecycleError, CleanupNotEligibleError, } from "./errors.js";
|
|
12
24
|
export { IDENTIFIER_GRAMMAR_PATTERN, validateIdentifierGrammar, mapFieldKindToCast, buildQueryableFieldIndexName, resolveFieldIndexTransition, } from "./index-provisioning.js";
|
|
13
25
|
export { registerContentType, updateContentTypeFields } from "./write-service.js";
|
|
14
26
|
export { deprecateContentType, reactivateContentType, tombstoneContentType, } from "./lifecycle.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content-types/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content-types/index.ts"],"names":[],"mappings":"AAmBA;;;;;GAKG;AACH,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;;;;GAMG;AACH,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,qBAAqB;AACrB;;;;GAIG;AACH,iCAAiC,EACjC,sBAAsB,EACtB,8BAA8B,EAC9B,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAUrB,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,EAClB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAajC,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AASlF,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAQxB,OAAO,EACL,+BAA+B,EAC/B,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAejC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D;;;;GAIG;AACH,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,sGAAsG;AACtG,OAAO,EACL,4BAA4B,GAI7B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,GAExB,MAAM,yBAAyB,CAAC;AAEjC;;GAEG"}
|
|
@@ -16,7 +16,7 @@ async function resolveActiveOrDeprecated(repo, workspaceId, key) {
|
|
|
16
16
|
*/
|
|
17
17
|
export async function deprecateContentType(required) {
|
|
18
18
|
const { deps, input } = required;
|
|
19
|
-
const authResult = await deps.authorize({ principalId: input.actorId, permission: "admin.collections.manage", workspaceId: input.workspaceId });
|
|
19
|
+
const authResult = await deps.authorize({ principalId: input.actorId, permission: "admin.collections.manage", workspaceId: input.workspaceId, entityType: "content-type" });
|
|
20
20
|
if (!authResult.allowed) {
|
|
21
21
|
return { ok: false, error: new ForbiddenError(`principal '${input.actorId}' cannot deprecate content type '${input.key}' (${authResult.reason})`) };
|
|
22
22
|
}
|
|
@@ -58,7 +58,7 @@ export async function deprecateContentType(required) {
|
|
|
58
58
|
*/
|
|
59
59
|
export async function reactivateContentType(required) {
|
|
60
60
|
const { deps, input } = required;
|
|
61
|
-
const authResult = await deps.authorize({ principalId: input.actorId, permission: "admin.collections.manage", workspaceId: input.workspaceId });
|
|
61
|
+
const authResult = await deps.authorize({ principalId: input.actorId, permission: "admin.collections.manage", workspaceId: input.workspaceId, entityType: "content-type" });
|
|
62
62
|
if (!authResult.allowed) {
|
|
63
63
|
return { ok: false, error: new ForbiddenError(`principal '${input.actorId}' cannot reactivate content type '${input.key}' (${authResult.reason})`) };
|
|
64
64
|
}
|
|
@@ -103,7 +103,7 @@ export async function reactivateContentType(required) {
|
|
|
103
103
|
*/
|
|
104
104
|
export async function tombstoneContentType(required) {
|
|
105
105
|
const { deps, input } = required;
|
|
106
|
-
const authResult = await deps.authorize({ principalId: input.actorId, permission: "admin.collections.manage", workspaceId: input.workspaceId });
|
|
106
|
+
const authResult = await deps.authorize({ principalId: input.actorId, permission: "admin.collections.manage", workspaceId: input.workspaceId, entityType: "content-type" });
|
|
107
107
|
if (!authResult.allowed) {
|
|
108
108
|
return { ok: false, error: new ForbiddenError(`principal '${input.actorId}' cannot tombstone content type '${input.key}' (${authResult.reason})`) };
|
|
109
109
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/content-types/lifecycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAqCxH,KAAK,UAAU,yBAAyB,CACtC,IAAyB,EACzB,WAAmB,EACnB,GAAW;IAEX,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,wBAAwB,CAAC,iBAAiB,GAAG,iCAAiC,WAAW,GAAG,CAAC,EAAE,CAAC;IACjI,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC;AAOD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAsC;IAEtC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAEjC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/content-types/lifecycle.ts"],"names":[],"mappings":"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"}
|