@cogenta/schema 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/define-collection.d.ts +8 -0
  2. package/dist/define-collection.d.ts.map +1 -0
  3. package/dist/define-collection.js +311 -0
  4. package/dist/define-collection.js.map +1 -0
  5. package/dist/errors.d.ts +16 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/errors.js +18 -0
  8. package/dist/errors.js.map +1 -0
  9. package/dist/fields.d.ts +117 -0
  10. package/dist/fields.d.ts.map +1 -0
  11. package/dist/fields.js +107 -0
  12. package/dist/fields.js.map +1 -0
  13. package/dist/generate-schema-json.d.ts +61 -0
  14. package/dist/generate-schema-json.d.ts.map +1 -0
  15. package/dist/generate-schema-json.js +128 -0
  16. package/dist/generate-schema-json.js.map +1 -0
  17. package/dist/generate-types.d.ts +5 -0
  18. package/dist/generate-types.d.ts.map +1 -0
  19. package/dist/generate-types.js +220 -0
  20. package/dist/generate-types.js.map +1 -0
  21. package/dist/id.d.ts +8 -0
  22. package/dist/id.d.ts.map +1 -0
  23. package/dist/id.js +8 -0
  24. package/dist/id.js.map +1 -0
  25. package/dist/index.d.ts +28 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +22 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/rich-text.d.ts +164 -0
  30. package/dist/rich-text.d.ts.map +1 -0
  31. package/dist/rich-text.js +97 -0
  32. package/dist/rich-text.js.map +1 -0
  33. package/dist/routing/ids.d.ts +18 -0
  34. package/dist/routing/ids.d.ts.map +1 -0
  35. package/dist/routing/ids.js +41 -0
  36. package/dist/routing/ids.js.map +1 -0
  37. package/dist/routing/index.d.ts +13 -0
  38. package/dist/routing/index.d.ts.map +1 -0
  39. package/dist/routing/index.js +7 -0
  40. package/dist/routing/index.js.map +1 -0
  41. package/dist/routing/redirects.d.ts +76 -0
  42. package/dist/routing/redirects.d.ts.map +1 -0
  43. package/dist/routing/redirects.js +237 -0
  44. package/dist/routing/redirects.js.map +1 -0
  45. package/dist/routing/resolve.d.ts +38 -0
  46. package/dist/routing/resolve.d.ts.map +1 -0
  47. package/dist/routing/resolve.js +23 -0
  48. package/dist/routing/resolve.js.map +1 -0
  49. package/dist/routing/router.d.ts +51 -0
  50. package/dist/routing/router.d.ts.map +1 -0
  51. package/dist/routing/router.js +132 -0
  52. package/dist/routing/router.js.map +1 -0
  53. package/dist/routing/slug-change.d.ts +39 -0
  54. package/dist/routing/slug-change.d.ts.map +1 -0
  55. package/dist/routing/slug-change.js +44 -0
  56. package/dist/routing/slug-change.js.map +1 -0
  57. package/dist/routing/slug.d.ts +82 -0
  58. package/dist/routing/slug.d.ts.map +1 -0
  59. package/dist/routing/slug.js +124 -0
  60. package/dist/routing/slug.js.map +1 -0
  61. package/dist/routing/slugify.d.ts +29 -0
  62. package/dist/routing/slugify.d.ts.map +1 -0
  63. package/dist/routing/slugify.js +104 -0
  64. package/dist/routing/slugify.js.map +1 -0
  65. package/dist/scheduling/index.d.ts +3 -0
  66. package/dist/scheduling/index.d.ts.map +1 -0
  67. package/dist/scheduling/index.js +2 -0
  68. package/dist/scheduling/index.js.map +1 -0
  69. package/dist/scheduling/publish.d.ts +71 -0
  70. package/dist/scheduling/publish.d.ts.map +1 -0
  71. package/dist/scheduling/publish.js +122 -0
  72. package/dist/scheduling/publish.js.map +1 -0
  73. package/dist/search/extract.d.ts +25 -0
  74. package/dist/search/extract.d.ts.map +1 -0
  75. package/dist/search/extract.js +188 -0
  76. package/dist/search/extract.js.map +1 -0
  77. package/dist/search/index.d.ts +36 -0
  78. package/dist/search/index.d.ts.map +1 -0
  79. package/dist/search/index.js +44 -0
  80. package/dist/search/index.js.map +1 -0
  81. package/dist/search/mysql.d.ts +7 -0
  82. package/dist/search/mysql.d.ts.map +1 -0
  83. package/dist/search/mysql.js +121 -0
  84. package/dist/search/mysql.js.map +1 -0
  85. package/dist/search/postgres.d.ts +9 -0
  86. package/dist/search/postgres.d.ts.map +1 -0
  87. package/dist/search/postgres.js +167 -0
  88. package/dist/search/postgres.js.map +1 -0
  89. package/dist/search/query.d.ts +35 -0
  90. package/dist/search/query.d.ts.map +1 -0
  91. package/dist/search/query.js +116 -0
  92. package/dist/search/query.js.map +1 -0
  93. package/dist/search/sqlite.d.ts +16 -0
  94. package/dist/search/sqlite.d.ts.map +1 -0
  95. package/dist/search/sqlite.js +166 -0
  96. package/dist/search/sqlite.js.map +1 -0
  97. package/dist/search/table.d.ts +49 -0
  98. package/dist/search/table.d.ts.map +1 -0
  99. package/dist/search/table.js +86 -0
  100. package/dist/search/table.js.map +1 -0
  101. package/dist/search/text.d.ts +42 -0
  102. package/dist/search/text.d.ts.map +1 -0
  103. package/dist/search/text.js +56 -0
  104. package/dist/search/text.js.map +1 -0
  105. package/dist/search/types.d.ts +98 -0
  106. package/dist/search/types.d.ts.map +1 -0
  107. package/dist/search/types.js +2 -0
  108. package/dist/search/types.js.map +1 -0
  109. package/dist/store/columns.d.ts +33 -0
  110. package/dist/store/columns.d.ts.map +1 -0
  111. package/dist/store/columns.js +113 -0
  112. package/dist/store/columns.js.map +1 -0
  113. package/dist/store/cursor.d.ts +23 -0
  114. package/dist/store/cursor.d.ts.map +1 -0
  115. package/dist/store/cursor.js +36 -0
  116. package/dist/store/cursor.js.map +1 -0
  117. package/dist/store/diff.d.ts +59 -0
  118. package/dist/store/diff.d.ts.map +1 -0
  119. package/dist/store/diff.js +124 -0
  120. package/dist/store/diff.js.map +1 -0
  121. package/dist/store/fragments.d.ts +13 -0
  122. package/dist/store/fragments.d.ts.map +1 -0
  123. package/dist/store/fragments.js +25 -0
  124. package/dist/store/fragments.js.map +1 -0
  125. package/dist/store/index.d.ts +22 -0
  126. package/dist/store/index.d.ts.map +1 -0
  127. package/dist/store/index.js +16 -0
  128. package/dist/store/index.js.map +1 -0
  129. package/dist/store/naming.d.ts +25 -0
  130. package/dist/store/naming.d.ts.map +1 -0
  131. package/dist/store/naming.js +80 -0
  132. package/dist/store/naming.js.map +1 -0
  133. package/dist/store/read-only.d.ts +16 -0
  134. package/dist/store/read-only.d.ts.map +1 -0
  135. package/dist/store/read-only.js +36 -0
  136. package/dist/store/read-only.js.map +1 -0
  137. package/dist/store/store.d.ts +52 -0
  138. package/dist/store/store.d.ts.map +1 -0
  139. package/dist/store/store.js +706 -0
  140. package/dist/store/store.js.map +1 -0
  141. package/dist/store/tables.d.ts +40 -0
  142. package/dist/store/tables.d.ts.map +1 -0
  143. package/dist/store/tables.js +267 -0
  144. package/dist/store/tables.js.map +1 -0
  145. package/dist/store/types.d.ts +105 -0
  146. package/dist/store/types.d.ts.map +1 -0
  147. package/dist/store/types.js +2 -0
  148. package/dist/store/types.js.map +1 -0
  149. package/dist/store/uuid.d.ts +6 -0
  150. package/dist/store/uuid.d.ts.map +1 -0
  151. package/dist/store/uuid.js +64 -0
  152. package/dist/store/uuid.js.map +1 -0
  153. package/dist/store/values.d.ts +40 -0
  154. package/dist/store/values.d.ts.map +1 -0
  155. package/dist/store/values.js +160 -0
  156. package/dist/store/values.js.map +1 -0
  157. package/dist/system-fields.d.ts +60 -0
  158. package/dist/system-fields.d.ts.map +1 -0
  159. package/dist/system-fields.js +73 -0
  160. package/dist/system-fields.js.map +1 -0
  161. package/dist/types.d.ts +101 -0
  162. package/dist/types.d.ts.map +1 -0
  163. package/dist/types.js +32 -0
  164. package/dist/types.js.map +1 -0
  165. package/dist/validation.d.ts +54 -0
  166. package/dist/validation.d.ts.map +1 -0
  167. package/dist/validation.js +183 -0
  168. package/dist/validation.js.map +1 -0
  169. package/package.json +43 -0
@@ -0,0 +1,25 @@
1
+ /** `publishedAt` becomes `published_at`. Digits stay attached to what precedes them. */
2
+ export declare function toSnakeCase(name: string): string;
3
+ export declare function entriesTable(collection: string): string;
4
+ /**
5
+ * One row per block, never a JSON array in the content row (contract A).
6
+ *
7
+ * Three features depend on blocks being rows: answering "which pages use this
8
+ * medium" for the media library, invalidating cache tags on publication, and
9
+ * chunking content per block for RAG. None of them survive a JSON column.
10
+ */
11
+ export declare function blocksTable(collection: string): string;
12
+ export declare function versionsTable(collection: string): string;
13
+ /** The join table of a `many: true` relation. */
14
+ export declare function relationTable(collection: string, field: string): string;
15
+ export declare function indexName(table: string, suffix: string): string;
16
+ export declare function columnFor(field: string): string;
17
+ /**
18
+ * Columns the engine owns. A user field that lands on one of these is refused
19
+ * rather than silently shadowed — `updated_at` written by an editor would break
20
+ * every ordering and every cache decision in the product.
21
+ */
22
+ export declare const SYSTEM_COLUMNS: readonly ['id', 'created_at', 'updated_at', 'created_by', 'updated_by', 'status', 'locale', 'translation_of', 'version', 'provenance', 'provenance_detail'];
23
+ export type SystemColumn = (typeof SYSTEM_COLUMNS)[number];
24
+ export declare function isSystemColumn(column: string): column is SystemColumn;
25
+ //# sourceMappingURL=naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/store/naming.ts"],"names":[],"mappings":"AAiCA,wFAAwF;AACxF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,iDAAiD;AACjD,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,YACzB,IAAI,EACJ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,mBAAmB,CACX,CAAA;AAEV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;AAE1D,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,YAAY,CAErE"}
@@ -0,0 +1,80 @@
1
+ import { CogentaError } from '@cogenta/core';
2
+ /**
3
+ * Physical names, derived from the schema in exactly one place.
4
+ *
5
+ * The rule is that nothing outside this file ever builds a table or column name
6
+ * by concatenation: the migration generator, the store and the tests must agree
7
+ * on the same string, and a second spelling of it is a silent data loss waiting
8
+ * for the day someone renames a collection.
9
+ */
10
+ const PREFIX = 'cogenta_';
11
+ /**
12
+ * MySQL refuses an identifier longer than 64 characters, and truncating one
13
+ * would make two collections collide on the same table. Failing at schema load
14
+ * with a name in the message costs a rename; failing at migration time on the
15
+ * one dialect nobody develops against costs a day.
16
+ */
17
+ const MAX_IDENTIFIER_LENGTH = 64;
18
+ function checked(name) {
19
+ if (name.length > MAX_IDENTIFIER_LENGTH) {
20
+ throw new CogentaError({
21
+ code: 'CONFIG_INVALID',
22
+ message: `The generated SQL identifier "${name}" is ${name.length} characters long.`,
23
+ hint: `MySQL allows at most ${MAX_IDENTIFIER_LENGTH}. Shorten the collection or field name.`,
24
+ details: { name },
25
+ });
26
+ }
27
+ return name;
28
+ }
29
+ /** `publishedAt` becomes `published_at`. Digits stay attached to what precedes them. */
30
+ export function toSnakeCase(name) {
31
+ return name.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();
32
+ }
33
+ export function entriesTable(collection) {
34
+ return checked(`${PREFIX}${toSnakeCase(collection)}`);
35
+ }
36
+ /**
37
+ * One row per block, never a JSON array in the content row (contract A).
38
+ *
39
+ * Three features depend on blocks being rows: answering "which pages use this
40
+ * medium" for the media library, invalidating cache tags on publication, and
41
+ * chunking content per block for RAG. None of them survive a JSON column.
42
+ */
43
+ export function blocksTable(collection) {
44
+ return checked(`${entriesTable(collection)}_blocks`);
45
+ }
46
+ export function versionsTable(collection) {
47
+ return checked(`${entriesTable(collection)}_versions`);
48
+ }
49
+ /** The join table of a `many: true` relation. */
50
+ export function relationTable(collection, field) {
51
+ return checked(`${entriesTable(collection)}_${toSnakeCase(field)}`);
52
+ }
53
+ export function indexName(table, suffix) {
54
+ return checked(`${table}_${suffix}`);
55
+ }
56
+ export function columnFor(field) {
57
+ return checked(toSnakeCase(field));
58
+ }
59
+ /**
60
+ * Columns the engine owns. A user field that lands on one of these is refused
61
+ * rather than silently shadowed — `updated_at` written by an editor would break
62
+ * every ordering and every cache decision in the product.
63
+ */
64
+ export const SYSTEM_COLUMNS = [
65
+ 'id',
66
+ 'created_at',
67
+ 'updated_at',
68
+ 'created_by',
69
+ 'updated_by',
70
+ 'status',
71
+ 'locale',
72
+ 'translation_of',
73
+ 'version',
74
+ 'provenance',
75
+ 'provenance_detail',
76
+ ];
77
+ export function isSystemColumn(column) {
78
+ return SYSTEM_COLUMNS.includes(column);
79
+ }
80
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/store/naming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C;;;;;;;GAOG;AAEH,MAAM,MAAM,GAAG,UAAU,CAAA;AAEzB;;;;;GAKG;AACH,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAEhC,SAAS,OAAO,CAAC,IAAY;IAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACxC,MAAM,IAAI,YAAY,CAAC;YACrB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,iCAAiC,IAAI,QAAQ,IAAI,CAAC,MAAM,mBAAmB;YACpF,IAAI,EAAE,wBAAwB,qBAAqB,yCAAyC;YAC5F,OAAO,EAAE,EAAE,IAAI,EAAE;SAClB,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;AAClE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,OAAO,OAAO,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;AACvD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,OAAO,OAAO,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,OAAO,OAAO,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;AACxD,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,aAAa,CAAC,UAAkB,EAAE,KAAa;IAC7D,OAAO,OAAO,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;AACrE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,MAAc;IACrD,OAAO,OAAO,CAAC,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI;IACJ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,gBAAgB;IAChB,SAAS;IACT,YAAY;IACZ,mBAAmB;CACX,CAAA;AAIV,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAQ,cAAoC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;AAC/D,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { ContentStore } from './store.js';
2
+ import type { ContentValues } from './types.js';
3
+ /**
4
+ * "Commencer par une démo en lecture seule" (L9 tâche 12, playground). Wraps
5
+ * any `ContentStore` so every mutating method refuses instead of writing —
6
+ * `create`/`update`/`delete`/`publish`/`unpublish`/`restore` — while every
7
+ * read (`read`/`list`/`history`/`readVersion`/`diff`/`translations`/
8
+ * `resolveLocale`) passes straight through, unchanged.
9
+ *
10
+ * A single wrap at the store level protects every consumer built on top of
11
+ * it — REST's `ContentService` and GraphQL's gateway both construct their
12
+ * stores from the same `storeFor` closure in `serve.ts`, so wrapping there
13
+ * covers both transports with one guard, not two.
14
+ */
15
+ export declare function withReadOnlyStore<TValues extends ContentValues = ContentValues>(store: ContentStore<TValues>): ContentStore<TValues>;
16
+ //# sourceMappingURL=read-only.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-only.d.ts","sourceRoot":"","sources":["../../src/store/read-only.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,SAAS,aAAa,GAAG,aAAa,EAC7E,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,GAC3B,YAAY,CAAC,OAAO,CAAC,CAsBvB"}
@@ -0,0 +1,36 @@
1
+ import { CogentaError } from '@cogenta/core';
2
+ /**
3
+ * "Commencer par une démo en lecture seule" (L9 tâche 12, playground). Wraps
4
+ * any `ContentStore` so every mutating method refuses instead of writing —
5
+ * `create`/`update`/`delete`/`publish`/`unpublish`/`restore` — while every
6
+ * read (`read`/`list`/`history`/`readVersion`/`diff`/`translations`/
7
+ * `resolveLocale`) passes straight through, unchanged.
8
+ *
9
+ * A single wrap at the store level protects every consumer built on top of
10
+ * it — REST's `ContentService` and GraphQL's gateway both construct their
11
+ * stores from the same `storeFor` closure in `serve.ts`, so wrapping there
12
+ * covers both transports with one guard, not two.
13
+ */
14
+ export function withReadOnlyStore(store) {
15
+ // `async` so a synchronous refusal still surfaces as a rejected promise —
16
+ // every `ContentStore` method is `Promise`-returning, and a caller that
17
+ // awaits it (every real caller does) must see a rejection, not a thrown
18
+ // exception at the call site.
19
+ async function refuse() {
20
+ throw new CogentaError({
21
+ code: 'CONTENT_READ_ONLY',
22
+ message: 'This instance is read-only; the requested change was not saved.',
23
+ hint: 'This is a read-only demo instance (e.g. a playground). Reads work normally; writes are refused, not silently dropped.',
24
+ });
25
+ }
26
+ return {
27
+ ...store,
28
+ create: () => refuse(),
29
+ update: () => refuse(),
30
+ delete: () => refuse(),
31
+ publish: () => refuse(),
32
+ unpublish: () => refuse(),
33
+ restore: () => refuse(),
34
+ };
35
+ }
36
+ //# sourceMappingURL=read-only.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-only.js","sourceRoot":"","sources":["../../src/store/read-only.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAI5C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAA4B;IAE5B,0EAA0E;IAC1E,wEAAwE;IACxE,wEAAwE;IACxE,8BAA8B;IAC9B,KAAK,UAAU,MAAM;QACnB,MAAM,IAAI,YAAY,CAAC;YACrB,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,iEAAiE;YAC1E,IAAI,EAAE,uHAAuH;SAC9H,CAAC,CAAA;IACJ,CAAC;IAED,OAAO;QACL,GAAG,KAAK;QACR,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE;QACtB,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE;QACtB,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE;QACtB,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE;QACvB,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE;QACzB,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE;KACxB,CAAA;AACH,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { type DatabaseHandle } from '@cogenta/core';
2
+ import type { CollectionDefinition } from '../types.js';
3
+ import { type ContentDiff } from './diff.js';
4
+ import type { ContentEntry, ContentValues, CreateInput, EntryState, ListOptions, LocaleResolution, Page, ResolveLocaleOptions, UpdateInput, VersionSummary } from './types.js';
5
+ /**
6
+ * The persistence layer of a collection.
7
+ *
8
+ * Three ideas hold it together, and everything else follows from them:
9
+ *
10
+ * 1. **The entry table holds the live state** — what the public renderer reads.
11
+ * A draft of an already-published entry is a row in the versions table, not a
12
+ * mutation of the live row. That is what makes "the public role can never
13
+ * reach a draft" a property of the storage rather than of a filter someone
14
+ * has to remember to write.
15
+ * 2. **Blocks are rows, keyed by `(entry, version, zone, key)`** (contract A).
16
+ * The live blocks are those at the entry's own version, so publishing a draft
17
+ * is a version number moving, not a block rewrite.
18
+ * 3. **One row per locale** (ADR-0014), so `status`, `version` and publication
19
+ * are per language by construction, not by convention.
20
+ */
21
+ export interface ContentStoreOptions {
22
+ readonly db: DatabaseHandle;
23
+ readonly collection: CollectionDefinition;
24
+ /** The locale an entry gets when the caller does not say. */
25
+ readonly defaultLocale?: string;
26
+ /** Injectable so tests can pin time; nothing else should pass it. */
27
+ readonly now?: () => Date;
28
+ readonly newId?: () => string;
29
+ }
30
+ export interface ContentStore<TValues extends ContentValues = ContentValues> {
31
+ create(input: CreateInput<TValues>): Promise<ContentEntry<TValues>>;
32
+ read(id: string, options?: {
33
+ readonly state?: EntryState;
34
+ }): Promise<ContentEntry<TValues> | null>;
35
+ update(id: string, input: UpdateInput<TValues>): Promise<ContentEntry<TValues>>;
36
+ delete(id: string): Promise<boolean>;
37
+ list(options?: ListOptions): Promise<Page<ContentEntry<TValues>>>;
38
+ publish(id: string, input?: {
39
+ readonly publishedBy?: string | null;
40
+ }): Promise<ContentEntry<TValues>>;
41
+ unpublish(id: string, input?: {
42
+ readonly status?: 'draft' | 'archived';
43
+ }): Promise<ContentEntry<TValues>>;
44
+ history(id: string): Promise<readonly VersionSummary[]>;
45
+ readVersion(id: string, version: number): Promise<ContentEntry<TValues> | null>;
46
+ restore(id: string, version: number, input?: UpdateInput<TValues>): Promise<ContentEntry<TValues>>;
47
+ diff(id: string, from: number, to: number): Promise<ContentDiff>;
48
+ translations(id: string): Promise<readonly ContentEntry<TValues>[]>;
49
+ resolveLocale(id: string, locale: string, options: ResolveLocaleOptions): Promise<LocaleResolution<TValues>>;
50
+ }
51
+ export declare function createContentStore<TValues extends ContentValues = ContentValues>(options: ContentStoreOptions): ContentStore<TValues>;
52
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store/store.ts"],"names":[],"mappings":"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"}