@aphexcms/cms-core 7.0.0 → 8.0.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/api/documents.d.ts +19 -0
- package/dist/api/documents.d.ts.map +1 -1
- package/dist/api/documents.js +21 -0
- package/dist/api/schemas/documents.d.ts +3 -0
- package/dist/api/schemas/documents.d.ts.map +1 -1
- package/dist/api/schemas/documents.js +12 -0
- package/dist/cli/generate-types.d.ts.map +1 -1
- package/dist/cli/generate-types.js +133 -19
- package/dist/cli/generate-types.js.map +1 -1
- package/dist/components/AdminApp.svelte +74 -47
- package/dist/components/AdminApp.svelte.d.ts.map +1 -1
- package/dist/components/admin/DocumentEditor.svelte +65 -2
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/confirm-dialog/ConfirmDialogHost.svelte +8 -6
- package/dist/components/admin/confirm-dialog/ConfirmDialogHost.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ArrayField.svelte +149 -2
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ReferenceField.svelte +198 -125
- package/dist/components/admin/fields/ReferenceField.svelte.d.ts +9 -2
- package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +1 -1
- package/dist/components/layout/Sidebar.svelte +1 -1
- package/dist/components/layout/sidebar/AppSidebar.svelte +2 -1
- package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts.map +1 -1
- package/dist/components/layout/sidebar/NavMain.svelte +9 -2
- package/dist/components/layout/sidebar/NavMain.svelte.d.ts +2 -0
- package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +1 -1
- package/dist/db/interfaces/index.d.ts +3 -1
- package/dist/db/interfaces/index.d.ts.map +1 -1
- package/dist/db/interfaces/reference.d.ts +43 -0
- package/dist/db/interfaces/reference.d.ts.map +1 -0
- package/dist/db/interfaces/reference.js +4 -0
- package/dist/db/utils/reference-resolver.d.ts +4 -6
- package/dist/db/utils/reference-resolver.d.ts.map +1 -1
- package/dist/db/utils/reference-resolver.js +33 -31
- package/dist/document-refresh.svelte.d.ts +3 -0
- package/dist/document-refresh.svelte.d.ts.map +1 -0
- package/dist/document-refresh.svelte.js +21 -0
- package/dist/graphql/resolvers.d.ts.map +1 -1
- package/dist/graphql/resolvers.js +61 -1
- package/dist/graphql/schema.d.ts.map +1 -1
- package/dist/graphql/schema.js +10 -0
- package/dist/lib/api/documents.d.ts +19 -0
- package/dist/lib/api/documents.d.ts.map +1 -1
- package/dist/lib/api/documents.js +21 -0
- package/dist/lib/api/documents.js.map +1 -1
- package/dist/lib/api/schemas/documents.d.ts +3 -0
- package/dist/lib/api/schemas/documents.d.ts.map +1 -1
- package/dist/lib/api/schemas/documents.js +12 -0
- package/dist/lib/api/schemas/documents.js.map +1 -1
- package/dist/lib/db/interfaces/index.d.ts +3 -1
- package/dist/lib/db/interfaces/index.d.ts.map +1 -1
- package/dist/lib/db/interfaces/reference.d.ts +43 -0
- package/dist/lib/db/interfaces/reference.d.ts.map +1 -0
- package/dist/lib/db/interfaces/reference.js +5 -0
- package/dist/lib/db/interfaces/reference.js.map +1 -0
- package/dist/lib/db/utils/reference-resolver.d.ts +4 -6
- package/dist/lib/db/utils/reference-resolver.d.ts.map +1 -1
- package/dist/lib/db/utils/reference-resolver.js +33 -31
- package/dist/lib/db/utils/reference-resolver.js.map +1 -1
- package/dist/lib/document-refresh.svelte.d.ts +3 -0
- package/dist/lib/document-refresh.svelte.d.ts.map +1 -0
- package/dist/lib/document-refresh.svelte.js +22 -0
- package/dist/lib/document-refresh.svelte.js.map +1 -0
- package/dist/lib/graphql/resolvers.d.ts.map +1 -1
- package/dist/lib/graphql/resolvers.js +61 -1
- package/dist/lib/graphql/resolvers.js.map +1 -1
- package/dist/lib/graphql/schema.d.ts.map +1 -1
- package/dist/lib/graphql/schema.js +10 -0
- package/dist/lib/graphql/schema.js.map +1 -1
- package/dist/lib/local-api/collection-api.d.ts +10 -1
- package/dist/lib/local-api/collection-api.d.ts.map +1 -1
- package/dist/lib/local-api/collection-api.js +39 -1
- package/dist/lib/local-api/collection-api.js.map +1 -1
- package/dist/lib/local-api/index.d.ts +29 -0
- package/dist/lib/local-api/index.d.ts.map +1 -1
- package/dist/lib/local-api/index.js +66 -2
- package/dist/lib/local-api/index.js.map +1 -1
- package/dist/lib/schema-utils/validator.js +21 -11
- package/dist/lib/schema-utils/validator.js.map +1 -1
- package/dist/lib/server/api/index.d.ts.map +1 -1
- package/dist/lib/server/api/index.js +3 -1
- package/dist/lib/server/api/index.js.map +1 -1
- package/dist/lib/server/api/routes/documents-by-id.d.ts.map +1 -1
- package/dist/lib/server/api/routes/documents-by-id.js +23 -0
- package/dist/lib/server/api/routes/documents-by-id.js.map +1 -1
- package/dist/lib/server/api/routes/documents.d.ts.map +1 -1
- package/dist/lib/server/api/routes/documents.js +29 -1
- package/dist/lib/server/api/routes/documents.js.map +1 -1
- package/dist/lib/services/references-service.d.ts +35 -0
- package/dist/lib/services/references-service.d.ts.map +1 -0
- package/dist/lib/services/references-service.js +60 -0
- package/dist/lib/services/references-service.js.map +1 -0
- package/dist/lib/types/schemas.d.ts +8 -0
- package/dist/lib/types/schemas.d.ts.map +1 -1
- package/dist/lib/utils/preview.d.ts +2 -3
- package/dist/lib/utils/preview.d.ts.map +1 -1
- package/dist/lib/utils/preview.js +35 -8
- package/dist/lib/utils/preview.js.map +1 -1
- package/dist/lib/utils/reference-walk.d.ts +8 -0
- package/dist/lib/utils/reference-walk.d.ts.map +1 -0
- package/dist/lib/utils/reference-walk.js +39 -0
- package/dist/lib/utils/reference-walk.js.map +1 -0
- package/dist/local-api/collection-api.d.ts +10 -1
- package/dist/local-api/collection-api.d.ts.map +1 -1
- package/dist/local-api/collection-api.js +39 -1
- package/dist/local-api/index.d.ts +29 -0
- package/dist/local-api/index.d.ts.map +1 -1
- package/dist/local-api/index.js +66 -2
- package/dist/schema-utils/validator.js +21 -11
- package/dist/server/api/index.d.ts.map +1 -1
- package/dist/server/api/index.js +3 -1
- package/dist/server/api/routes/documents-by-id.d.ts.map +1 -1
- package/dist/server/api/routes/documents-by-id.js +23 -0
- package/dist/server/api/routes/documents.d.ts.map +1 -1
- package/dist/server/api/routes/documents.js +29 -1
- package/dist/services/references-service.d.ts +35 -0
- package/dist/services/references-service.d.ts.map +1 -0
- package/dist/services/references-service.js +59 -0
- package/dist/types/schemas.d.ts +8 -0
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/utils/preview.d.ts +2 -3
- package/dist/utils/preview.d.ts.map +1 -1
- package/dist/utils/preview.js +35 -8
- package/dist/utils/reference-walk.d.ts +8 -0
- package/dist/utils/reference-walk.d.ts.map +1 -0
- package/dist/utils/reference-walk.js +38 -0
- package/package.json +3 -3
|
@@ -32,25 +32,49 @@ function toPreviewString(value) {
|
|
|
32
32
|
* — the first non-empty string wins.
|
|
33
33
|
*/
|
|
34
34
|
const DEFAULT_TITLE_FIELDS = ['title', 'heading', 'name', 'label'];
|
|
35
|
+
/**
|
|
36
|
+
* Run `preview.prepare` if defined: resolve every dot-path in `select`,
|
|
37
|
+
* pass the resolved selection map to `prepare`, and return the result.
|
|
38
|
+
* Returns `null` when no `prepare` is configured — callers should fall
|
|
39
|
+
* back to direct `select.title` / `select.subtitle` reads in that case.
|
|
40
|
+
*/
|
|
41
|
+
function runPrepare(item, schema) {
|
|
42
|
+
const prepare = schema?.preview?.prepare;
|
|
43
|
+
if (!prepare)
|
|
44
|
+
return null;
|
|
45
|
+
const select = schema?.preview?.select ?? {};
|
|
46
|
+
const selection = {};
|
|
47
|
+
for (const [key, path] of Object.entries(select)) {
|
|
48
|
+
selection[key] = readPath(item, path);
|
|
49
|
+
}
|
|
50
|
+
return prepare(selection);
|
|
51
|
+
}
|
|
35
52
|
/**
|
|
36
53
|
* Resolve the title to display for an item (array row, document list row,
|
|
37
|
-
* reference picker row).
|
|
38
|
-
*
|
|
39
|
-
* names, then the schema's own title, then the type name.
|
|
54
|
+
* reference picker row). Precedence: `preview.prepare()` → `select.title`
|
|
55
|
+
* dot-path → conventional field names → schema title → type name.
|
|
40
56
|
*/
|
|
41
57
|
export function resolvePreviewTitle(item, schema, defaultTypeLabel) {
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
44
|
-
const resolved = toPreviewString(
|
|
58
|
+
const prepared = runPrepare(item, schema);
|
|
59
|
+
if (prepared) {
|
|
60
|
+
const resolved = toPreviewString(prepared.title);
|
|
45
61
|
if (resolved)
|
|
46
62
|
return resolved;
|
|
47
63
|
}
|
|
48
64
|
else {
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
const configured = schema?.preview?.select?.title;
|
|
66
|
+
if (configured) {
|
|
67
|
+
const resolved = toPreviewString(readPath(item, configured));
|
|
51
68
|
if (resolved)
|
|
52
69
|
return resolved;
|
|
53
70
|
}
|
|
71
|
+
else {
|
|
72
|
+
for (const name of DEFAULT_TITLE_FIELDS) {
|
|
73
|
+
const resolved = toPreviewString(item?.[name]);
|
|
74
|
+
if (resolved)
|
|
75
|
+
return resolved;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
54
78
|
}
|
|
55
79
|
return schema?.title ?? defaultTypeLabel ?? 'Untitled';
|
|
56
80
|
}
|
|
@@ -60,6 +84,9 @@ export function resolvePreviewTitle(item, schema, defaultTypeLabel) {
|
|
|
60
84
|
* should branch on the null and skip rendering the subtitle line.
|
|
61
85
|
*/
|
|
62
86
|
export function resolvePreviewSubtitle(item, schema) {
|
|
87
|
+
const prepared = runPrepare(item, schema);
|
|
88
|
+
if (prepared)
|
|
89
|
+
return toPreviewString(prepared.subtitle);
|
|
63
90
|
const configured = schema?.preview?.select?.subtitle;
|
|
64
91
|
if (!configured)
|
|
65
92
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/lib/utils/preview.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAS,EAAE,IAAY;IAC/C,IAAI,OAAO,GAAQ,IAAI,CAAC;IACxB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,SAAS,CAAC;QACtC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACjC,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9E,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAClC,IAAS,EACT,MAAqC,EACrC,gBAAyB;IAEzB,MAAM,UAAU,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/lib/utils/preview.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAS,EAAE,IAAY;IAC/C,IAAI,OAAO,GAAQ,IAAI,CAAC;IACxB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,SAAS,CAAC;QACtC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACjC,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9E,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,SAAS,UAAU,CAClB,IAAS,EACT,MAAqC;IAErC,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;IAC7C,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,SAAS,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAClC,IAAS,EACT,MAAqC,EACrC,gBAAyB;IAEzB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,IAAI,QAAQ,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;IAC/B,CAAC;SAAM,CAAC;QACP,MAAM,UAAU,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;QAClD,IAAI,UAAU,EAAE,CAAC;YAChB,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;YAC7D,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;QAC/B,CAAC;aAAM,CAAC;YACP,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;gBACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC/C,IAAI,QAAQ;oBAAE,OAAO,QAAQ,CAAC;YAC/B,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,MAAM,EAAE,KAAK,IAAI,gBAAgB,IAAI,UAAU,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACrC,IAAS,EACT,MAAqC;IAErC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,IAAI,QAAQ;QAAE,OAAO,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC;IACrD,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SchemaType } from '../types/schemas.js';
|
|
2
|
+
/**
|
|
3
|
+
* Collect all referenced document IDs from a doc's data. The `schema` and
|
|
4
|
+
* `registry` params are accepted for API compatibility but no longer used —
|
|
5
|
+
* the unified ref shape makes them unnecessary.
|
|
6
|
+
*/
|
|
7
|
+
export declare function collectReferenceIds(data: unknown, _schema?: SchemaType | null, _registry?: SchemaType[]): string[];
|
|
8
|
+
//# sourceMappingURL=reference-walk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-walk.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/reference-walk.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,EAC3B,SAAS,CAAC,EAAE,UAAU,EAAE,GACtB,MAAM,EAAE,CAIV"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Walks a document's data and collects every reference's target ID. Both
|
|
2
|
+
// singular and array refs share the same on-disk shape now —
|
|
3
|
+
// `{ _type: 'reference', _ref }` — so this can be schema-less.
|
|
4
|
+
//
|
|
5
|
+
// Asset references (image/file) wrap an Asset, not a document, and aren't
|
|
6
|
+
// subject to the publish workflow — so they're skipped (we only collect
|
|
7
|
+
// ids whose marker is exactly 'reference').
|
|
8
|
+
/**
|
|
9
|
+
* Collect all referenced document IDs from a doc's data. The `schema` and
|
|
10
|
+
* `registry` params are accepted for API compatibility but no longer used —
|
|
11
|
+
* the unified ref shape makes them unnecessary.
|
|
12
|
+
*/
|
|
13
|
+
export function collectReferenceIds(data, _schema, _registry) {
|
|
14
|
+
const ids = new Set();
|
|
15
|
+
walk(data, ids);
|
|
16
|
+
return Array.from(ids);
|
|
17
|
+
}
|
|
18
|
+
function walk(value, ids) {
|
|
19
|
+
if (value == null)
|
|
20
|
+
return;
|
|
21
|
+
if (Array.isArray(value)) {
|
|
22
|
+
for (const item of value)
|
|
23
|
+
walk(item, ids);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (typeof value !== 'object')
|
|
27
|
+
return;
|
|
28
|
+
const obj = value;
|
|
29
|
+
if (obj._type === 'reference' && typeof obj._ref === 'string' && obj._ref) {
|
|
30
|
+
ids.add(obj._ref);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
for (const key of Object.keys(obj)) {
|
|
34
|
+
if (key.startsWith('_'))
|
|
35
|
+
continue;
|
|
36
|
+
walk(obj[key], ids);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=reference-walk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-walk.js","sourceRoot":"","sources":["../../../src/lib/utils/reference-walk.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,6DAA6D;AAC7D,+DAA+D;AAC/D,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,4CAA4C;AAI5C;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAClC,IAAa,EACb,OAA2B,EAC3B,SAAwB;IAExB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAChB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,IAAI,CAAC,KAAc,EAAE,GAAgB;IAC7C,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO;IAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC1C,OAAO;IACR,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO;IACtC,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3E,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO;IACR,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IACrB,CAAC;AACF,CAAC"}
|
|
@@ -2,6 +2,7 @@ import type { DocumentCache } from '../cache/index.js';
|
|
|
2
2
|
import type { DatabaseAdapter } from '../db/index.js';
|
|
3
3
|
import type { HierarchyService } from '../services/hierarchy-service.js';
|
|
4
4
|
import type { VersionService } from '../services/version-service.js';
|
|
5
|
+
import type { ReferencesService } from '../services/references-service.js';
|
|
5
6
|
import type { Where, WhereTyped, FindOptions, FindResult } from '../types/filters.js';
|
|
6
7
|
import type { Document } from '../types/document.js';
|
|
7
8
|
import type { LocalAPIContext } from './types.js';
|
|
@@ -43,7 +44,15 @@ export declare class CollectionAPI<T = Document> {
|
|
|
43
44
|
private documentCache?;
|
|
44
45
|
private hierarchyService?;
|
|
45
46
|
private versionService?;
|
|
46
|
-
|
|
47
|
+
private referencesService?;
|
|
48
|
+
private schemaRegistry?;
|
|
49
|
+
constructor(collectionName: string, databaseAdapter: DatabaseAdapter, _schema: SchemaType, permissions: PermissionChecker, documentCache?: (DocumentCache | null) | undefined, hierarchyService?: HierarchyService | undefined, versionService?: VersionService | undefined, referencesService?: ReferencesService | undefined, schemaRegistry?: SchemaType[] | undefined);
|
|
50
|
+
/**
|
|
51
|
+
* Refresh the back-reference index for this doc using the freshly-saved
|
|
52
|
+
* draftData. Best-effort: failures are logged inside the service and
|
|
53
|
+
* never thrown — a stale ref index doesn't block the user's save.
|
|
54
|
+
*/
|
|
55
|
+
private syncReferences;
|
|
47
56
|
/**
|
|
48
57
|
* Get the schema for this collection
|
|
49
58
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-api.d.ts","sourceRoot":"","sources":["../../src/lib/local-api/collection-api.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAwB,KAAK,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"collection-api.d.ts","sourceRoot":"","sources":["../../src/lib/local-api/collection-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// Collection API - provides type-safe CRUD operations for a single collection
|
|
4
4
|
import { singletonId } from '../schema-utils/singleton.js';
|
|
5
5
|
import { validateDocumentData } from '../field-validation/utils.js';
|
|
6
|
+
import { collectReferenceIds } from '../utils/reference-walk.js';
|
|
6
7
|
import { hiddenReadFields, hiddenWriteFields, dropLockedWrites, stripHiddenFields } from '../field-access.js';
|
|
7
8
|
const EMPTY_SET = new Set();
|
|
8
9
|
/**
|
|
@@ -79,7 +80,9 @@ export class CollectionAPI {
|
|
|
79
80
|
documentCache;
|
|
80
81
|
hierarchyService;
|
|
81
82
|
versionService;
|
|
82
|
-
|
|
83
|
+
referencesService;
|
|
84
|
+
schemaRegistry;
|
|
85
|
+
constructor(collectionName, databaseAdapter, _schema, permissions, documentCache, hierarchyService, versionService, referencesService, schemaRegistry) {
|
|
83
86
|
this.collectionName = collectionName;
|
|
84
87
|
this.databaseAdapter = databaseAdapter;
|
|
85
88
|
this._schema = _schema;
|
|
@@ -87,9 +90,21 @@ export class CollectionAPI {
|
|
|
87
90
|
this.documentCache = documentCache;
|
|
88
91
|
this.hierarchyService = hierarchyService;
|
|
89
92
|
this.versionService = versionService;
|
|
93
|
+
this.referencesService = referencesService;
|
|
94
|
+
this.schemaRegistry = schemaRegistry;
|
|
90
95
|
// Validate collection exists
|
|
91
96
|
this.permissions.validateCollection(collectionName);
|
|
92
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Refresh the back-reference index for this doc using the freshly-saved
|
|
100
|
+
* draftData. Best-effort: failures are logged inside the service and
|
|
101
|
+
* never thrown — a stale ref index doesn't block the user's save.
|
|
102
|
+
*/
|
|
103
|
+
async syncReferences(organizationId, documentId, data) {
|
|
104
|
+
if (!this.referencesService)
|
|
105
|
+
return;
|
|
106
|
+
await this.referencesService.syncReferencesFor(organizationId, documentId, data, this._schema, this.schemaRegistry ?? []);
|
|
107
|
+
}
|
|
93
108
|
/**
|
|
94
109
|
* Get the schema for this collection
|
|
95
110
|
*/
|
|
@@ -326,6 +341,7 @@ export class CollectionAPI {
|
|
|
326
341
|
createdBy: context.user?.id,
|
|
327
342
|
id: options?.id
|
|
328
343
|
});
|
|
344
|
+
await this.syncReferences(context.organizationId, document.id, validationResult.normalizedData);
|
|
329
345
|
// Create initial draft version
|
|
330
346
|
if (this.versionService && !options?.skipVersioning) {
|
|
331
347
|
await this.versionService.createVersion(this.databaseAdapter, context.organizationId, document.id, 'draft', validationResult.normalizedData, context.user?.id);
|
|
@@ -398,6 +414,7 @@ export class CollectionAPI {
|
|
|
398
414
|
if (!document) {
|
|
399
415
|
return null;
|
|
400
416
|
}
|
|
417
|
+
await this.syncReferences(context.organizationId, id, validationResult.normalizedData);
|
|
401
418
|
if (options?.publish) {
|
|
402
419
|
await this.permissions.canPublish(context, this.collectionName, document);
|
|
403
420
|
// Block publish if validation fails
|
|
@@ -488,6 +505,27 @@ export class CollectionAPI {
|
|
|
488
505
|
.join('; ');
|
|
489
506
|
throw new Error(`Cannot publish: validation errors - ${errorMessage}`);
|
|
490
507
|
}
|
|
508
|
+
// Guard: block publish if any referenced document is not published
|
|
509
|
+
const refIds = collectReferenceIds(document.draftData);
|
|
510
|
+
if (refIds.length > 0) {
|
|
511
|
+
const unpublished = [];
|
|
512
|
+
for (const refId of refIds) {
|
|
513
|
+
const refDoc = await this.databaseAdapter.findByDocIdAdvanced(context.organizationId, refId);
|
|
514
|
+
if (refDoc && !refDoc.publishedData) {
|
|
515
|
+
const data = refDoc.draftData;
|
|
516
|
+
const title = data?.title ||
|
|
517
|
+
data?.name ||
|
|
518
|
+
refDoc.id;
|
|
519
|
+
unpublished.push({ id: refDoc.id, type: refDoc.type, title });
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
if (unpublished.length > 0) {
|
|
523
|
+
const names = unpublished
|
|
524
|
+
.map((d) => `"${d.title}" (${d.type})`)
|
|
525
|
+
.join(', ');
|
|
526
|
+
throw new Error(`Cannot publish — ${unpublished.length} referenced document(s) are not published: ${names}`);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
491
529
|
// Validation passed - proceed with publish (with version if service available)
|
|
492
530
|
const publishedDocument = this.versionService
|
|
493
531
|
? await this.versionService.publishWithVersion(this.databaseAdapter, context.organizationId, id)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CMSConfig } from '../types/config.js';
|
|
2
2
|
import type { DatabaseAdapter } from '../db/index.js';
|
|
3
3
|
import { VersionService } from '../services/version-service.js';
|
|
4
|
+
import { ReferencesService } from '../services/references-service.js';
|
|
4
5
|
import type { FindOptions } from '../types/filters.js';
|
|
5
6
|
import type { SchemaType } from '../types/schemas.js';
|
|
6
7
|
import { CollectionAPI } from './collection-api.js';
|
|
@@ -50,6 +51,7 @@ export declare class LocalAPI {
|
|
|
50
51
|
private documentCache;
|
|
51
52
|
private hierarchyService;
|
|
52
53
|
versionService: VersionService;
|
|
54
|
+
referencesService: ReferencesService;
|
|
53
55
|
private permissions;
|
|
54
56
|
private schemas;
|
|
55
57
|
constructor(config: CMSConfig, userAdapter: DatabaseAdapter, systemAdapter?: DatabaseAdapter);
|
|
@@ -83,6 +85,33 @@ export declare class LocalAPI {
|
|
|
83
85
|
type: string;
|
|
84
86
|
document: unknown;
|
|
85
87
|
} | null>;
|
|
88
|
+
/**
|
|
89
|
+
* Find all documents that reference the given target — the back-reference
|
|
90
|
+
* lookup that powers the unpublish guard. Returns lightweight rows
|
|
91
|
+
* (id/type/status); callers fetch full docs separately if they need data.
|
|
92
|
+
*/
|
|
93
|
+
getBackReferences(context: LocalAPIContext, refId: string): Promise<Array<{
|
|
94
|
+
id: string;
|
|
95
|
+
type: string;
|
|
96
|
+
status: string | null;
|
|
97
|
+
}>>;
|
|
98
|
+
/**
|
|
99
|
+
* Batch lookup — fetch many documents by ID in one call. Routes through
|
|
100
|
+
* each doc's collection so the returned shape matches `collection.findByID`
|
|
101
|
+
* (perms applied, transformed, hidden fields stripped). Org hierarchy is
|
|
102
|
+
* resolved once for the whole batch and threaded into each per-collection
|
|
103
|
+
* call.
|
|
104
|
+
*
|
|
105
|
+
* Heterogeneous batches (mixed types) leave T as the default `unknown`;
|
|
106
|
+
* homogeneous callers (e.g. an array-of-references-to-one-type) can
|
|
107
|
+
* narrow it: `findDocumentsByIds<MenuItem>(ctx, ids)`.
|
|
108
|
+
*
|
|
109
|
+
* Missing/forbidden IDs are dropped from the result rather than thrown —
|
|
110
|
+
* callers compare result length to input length to detect gaps. If/when
|
|
111
|
+
* an adapter exposes a true `WHERE id IN (...)` batch we can short-circuit
|
|
112
|
+
* the per-id collection round-trips here without changing call sites.
|
|
113
|
+
*/
|
|
114
|
+
findDocumentsByIds<T = unknown>(context: LocalAPIContext, ids: string[], options?: Partial<FindOptions<T>>): Promise<T[]>;
|
|
86
115
|
}
|
|
87
116
|
/**
|
|
88
117
|
* Create and initialize the Local API
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/local-api/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAYjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAE3B,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;CAGjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,QAAQ;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/local-api/index.ts"],"names":[],"mappings":"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"}
|
package/dist/local-api/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { DocumentCache } from '../cache/index.js';
|
|
5
5
|
import { HierarchyService } from '../services/hierarchy-service.js';
|
|
6
6
|
import { VersionService } from '../services/version-service.js';
|
|
7
|
+
import { ReferencesService } from '../services/references-service.js';
|
|
7
8
|
import { CollectionAPI } from './collection-api.js';
|
|
8
9
|
/**
|
|
9
10
|
* CollectionAPI methods that compute synchronously and don't touch the DB.
|
|
@@ -53,6 +54,7 @@ export class LocalAPI {
|
|
|
53
54
|
documentCache;
|
|
54
55
|
hierarchyService;
|
|
55
56
|
versionService;
|
|
57
|
+
referencesService;
|
|
56
58
|
permissions;
|
|
57
59
|
schemas;
|
|
58
60
|
constructor(config, userAdapter, systemAdapter) {
|
|
@@ -64,6 +66,7 @@ export class LocalAPI {
|
|
|
64
66
|
this.versionService = new VersionService({
|
|
65
67
|
maxVersions: config.versioning?.maxVersions ?? 25
|
|
66
68
|
});
|
|
69
|
+
this.referencesService = new ReferencesService(userAdapter);
|
|
67
70
|
// Build schema map for quick lookups
|
|
68
71
|
this.schemas = new Map(config.schemaTypes
|
|
69
72
|
.filter((schema) => schema.type === 'document')
|
|
@@ -80,7 +83,7 @@ export class LocalAPI {
|
|
|
80
83
|
const documentSchemas = this.config.schemaTypes.filter((s) => s.type === 'document');
|
|
81
84
|
for (const schema of documentSchemas) {
|
|
82
85
|
// Create a proxy that selects the correct adapter based on context
|
|
83
|
-
const collectionAPI = new Proxy(new CollectionAPI(schema.name, this.userAdapter, schema, this.permissions, this.documentCache, this.hierarchyService, this.versionService), {
|
|
86
|
+
const collectionAPI = new Proxy(new CollectionAPI(schema.name, this.userAdapter, schema, this.permissions, this.documentCache, this.hierarchyService, this.versionService, this.referencesService, this.config.schemaTypes), {
|
|
84
87
|
get: (target, prop) => {
|
|
85
88
|
const method = target[prop];
|
|
86
89
|
// Sync, pure-computation methods bypass the adapter-swap
|
|
@@ -97,7 +100,7 @@ export class LocalAPI {
|
|
|
97
100
|
const context = args[0];
|
|
98
101
|
const adapter = this.getAdapter(context);
|
|
99
102
|
// Create new CollectionAPI with the correct adapter
|
|
100
|
-
const api = new CollectionAPI(schema.name, adapter, schema, this.permissions, this.documentCache, this.hierarchyService, this.versionService);
|
|
103
|
+
const api = new CollectionAPI(schema.name, adapter, schema, this.permissions, this.documentCache, this.hierarchyService, this.versionService, new ReferencesService(adapter), this.config.schemaTypes);
|
|
101
104
|
// Call the method on the new instance
|
|
102
105
|
return api[prop].apply(api, args);
|
|
103
106
|
};
|
|
@@ -154,6 +157,67 @@ export class LocalAPI {
|
|
|
154
157
|
return null;
|
|
155
158
|
return { type: rawDoc.type, document: rawDoc };
|
|
156
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Find all documents that reference the given target — the back-reference
|
|
162
|
+
* lookup that powers the unpublish guard. Returns lightweight rows
|
|
163
|
+
* (id/type/status); callers fetch full docs separately if they need data.
|
|
164
|
+
*/
|
|
165
|
+
async getBackReferences(context, refId) {
|
|
166
|
+
const adapter = this.getAdapter(context);
|
|
167
|
+
return adapter.findBackReferences(context.organizationId, refId);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Batch lookup — fetch many documents by ID in one call. Routes through
|
|
171
|
+
* each doc's collection so the returned shape matches `collection.findByID`
|
|
172
|
+
* (perms applied, transformed, hidden fields stripped). Org hierarchy is
|
|
173
|
+
* resolved once for the whole batch and threaded into each per-collection
|
|
174
|
+
* call.
|
|
175
|
+
*
|
|
176
|
+
* Heterogeneous batches (mixed types) leave T as the default `unknown`;
|
|
177
|
+
* homogeneous callers (e.g. an array-of-references-to-one-type) can
|
|
178
|
+
* narrow it: `findDocumentsByIds<MenuItem>(ctx, ids)`.
|
|
179
|
+
*
|
|
180
|
+
* Missing/forbidden IDs are dropped from the result rather than thrown —
|
|
181
|
+
* callers compare result length to input length to detect gaps. If/when
|
|
182
|
+
* an adapter exposes a true `WHERE id IN (...)` batch we can short-circuit
|
|
183
|
+
* the per-id collection round-trips here without changing call sites.
|
|
184
|
+
*/
|
|
185
|
+
async findDocumentsByIds(context, ids, options) {
|
|
186
|
+
if (ids.length === 0)
|
|
187
|
+
return [];
|
|
188
|
+
const adapter = this.getAdapter(context);
|
|
189
|
+
// Resolve org hierarchy once for the whole batch; thread into each
|
|
190
|
+
// per-id call so collection.findByID skips its own hierarchy lookup.
|
|
191
|
+
let filterOrganizationIds = options?.filterOrganizationIds;
|
|
192
|
+
if (!filterOrganizationIds && this.hierarchyService) {
|
|
193
|
+
filterOrganizationIds = await this.hierarchyService.getOrgIdsWithChildren(context.organizationId);
|
|
194
|
+
}
|
|
195
|
+
// First: cheap type lookups so we know which collection to route through.
|
|
196
|
+
const typeLookups = await Promise.all(ids.map((id) => adapter
|
|
197
|
+
.findByDocIdAdvanced(context.organizationId, id, { filterOrganizationIds })
|
|
198
|
+
.then((row) => (row ? { id, type: row.type } : null))));
|
|
199
|
+
// Second: per-collection findByID for each resolved doc. Fan out in
|
|
200
|
+
// parallel; collection.findByID enforces perms and applies the
|
|
201
|
+
// standard processing pipeline.
|
|
202
|
+
const docs = await Promise.all(typeLookups.map(async (lookup) => {
|
|
203
|
+
if (!lookup)
|
|
204
|
+
return null;
|
|
205
|
+
const collection = this.collections[lookup.type];
|
|
206
|
+
if (!collection)
|
|
207
|
+
return null;
|
|
208
|
+
try {
|
|
209
|
+
return (await collection.findByID(context, lookup.id, {
|
|
210
|
+
...options,
|
|
211
|
+
filterOrganizationIds
|
|
212
|
+
}));
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Permission denied or similar — drop silently per the contract.
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}));
|
|
219
|
+
return docs.filter((d) => d != null);
|
|
220
|
+
}
|
|
157
221
|
}
|
|
158
222
|
// Global Local API instance
|
|
159
223
|
let localAPIInstance = null;
|
|
@@ -57,6 +57,21 @@ export function validateSchemaReferences(schemas) {
|
|
|
57
57
|
// Check array field references
|
|
58
58
|
if (field.type === 'array' && field.of) {
|
|
59
59
|
for (const arrayType of field.of) {
|
|
60
|
+
// Reference items inside an array must declare `to` and target known schemas
|
|
61
|
+
if (arrayType.type === 'reference') {
|
|
62
|
+
const to = arrayType.to;
|
|
63
|
+
if (!Array.isArray(to) || to.length === 0) {
|
|
64
|
+
errors.push(`Schema "${parentSchema}" field "${field.name}" has a reference array item missing "to" — declare allowed target document types`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
for (const target of to) {
|
|
68
|
+
if (!schemaNames.has(target.type)) {
|
|
69
|
+
errors.push(`Schema "${parentSchema}" field "${field.name}" reference array item targets unknown document type "${target.type}"`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
60
75
|
// Skip validation for primitive types and inline objects
|
|
61
76
|
if (primitiveTypes.includes(arrayType.type)) {
|
|
62
77
|
continue;
|
|
@@ -123,17 +138,12 @@ export function validateSchemaReferences(schemas) {
|
|
|
123
138
|
if (schema.preview?.select) {
|
|
124
139
|
const fieldNames = new Set(schema.fields?.map((f) => f.name) || []);
|
|
125
140
|
const rootOf = (path) => path.split('.', 1)[0] ?? path;
|
|
126
|
-
|
|
127
|
-
!
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
errors.push(`Schema "${schema.name}" preview.select.subtitle references unknown field "${schema.preview.select.subtitle}"`);
|
|
133
|
-
}
|
|
134
|
-
if (schema.preview.select.media &&
|
|
135
|
-
!fieldNames.has(rootOf(schema.preview.select.media))) {
|
|
136
|
-
errors.push(`Schema "${schema.name}" preview.select.media references unknown field "${schema.preview.select.media}"`);
|
|
141
|
+
for (const [key, path] of Object.entries(schema.preview.select)) {
|
|
142
|
+
if (typeof path !== 'string' || !path)
|
|
143
|
+
continue;
|
|
144
|
+
if (!fieldNames.has(rootOf(path))) {
|
|
145
|
+
errors.push(`Schema "${schema.name}" preview.select.${key} references unknown field "${path}"`);
|
|
146
|
+
}
|
|
137
147
|
}
|
|
138
148
|
}
|
|
139
149
|
// Validate orderings
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAoB7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,SAAS,EAAE;QACV,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,kGAY7B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAoB7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,SAAS,EAAE;QACV,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,kGAY7B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QAsCrD;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC5B,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,IAEzC,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,uBAejD"}
|
package/dist/server/api/index.js
CHANGED
|
@@ -52,8 +52,10 @@ export function mountAphexBuiltins(app) {
|
|
|
52
52
|
app.route('/documents', documentsQueryRouter);
|
|
53
53
|
app.route('/documents', documentsPublishRouter);
|
|
54
54
|
app.route('/documents', documentVersionsRouter);
|
|
55
|
-
|
|
55
|
+
// documentsRouter has the literal `/by-ids` batch endpoint, which must
|
|
56
|
+
// mount before documentsByIdRouter or `:id` will swallow it.
|
|
56
57
|
app.route('/documents', documentsRouter);
|
|
58
|
+
app.route('/documents', documentsByIdRouter);
|
|
57
59
|
// Assets — same precedence rule: specific paths before parametric.
|
|
58
60
|
// `/assets/bulk` and `/assets/references/counts` must register before
|
|
59
61
|
// `/assets/:id` or Hono will capture them as `:id = "bulk"` etc.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-by-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-by-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,QAAQ,CA6N5C,CAAC"}
|
|
@@ -148,4 +148,27 @@ export const documentsByIdRouter = new Hono()
|
|
|
148
148
|
message: error instanceof Error ? error.message : 'Unknown error'
|
|
149
149
|
}, 500);
|
|
150
150
|
}
|
|
151
|
+
})
|
|
152
|
+
.get('/:id/back-references', async (c) => {
|
|
153
|
+
try {
|
|
154
|
+
const { localAPI } = c.var.aphexCMS;
|
|
155
|
+
const context = authToContext(c.var.auth);
|
|
156
|
+
const id = c.req.param('id');
|
|
157
|
+
if (!id) {
|
|
158
|
+
return c.json({ success: false, error: 'Document ID is required' }, 400);
|
|
159
|
+
}
|
|
160
|
+
const refs = await localAPI.getBackReferences(context, id);
|
|
161
|
+
return c.json({ success: true, data: refs });
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
cmsLogger.error('Failed to fetch back-references:', error);
|
|
165
|
+
if (error instanceof PermissionError) {
|
|
166
|
+
return c.json({ success: false, error: 'Forbidden', message: error.message }, 403);
|
|
167
|
+
}
|
|
168
|
+
return c.json({
|
|
169
|
+
success: false,
|
|
170
|
+
error: 'Failed to fetch back-references',
|
|
171
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
172
|
+
}, 500);
|
|
173
|
+
}
|
|
151
174
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC,eAAO,MAAM,eAAe,EAAE,IAAI,CAAC,QAAQ,CAyMxC,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { zValidator } from '@hono/zod-validator';
|
|
|
3
3
|
import { authToContext } from '../../../local-api/auth-helpers.js';
|
|
4
4
|
import { PermissionError } from '../../../local-api/permissions.js';
|
|
5
5
|
import { cmsLogger } from '../../../utils/logger.js';
|
|
6
|
-
import { createDocumentRequest, listDocumentsQuery } from '../../../api/schemas/documents.js';
|
|
6
|
+
import { createDocumentRequest, getDocumentsByIdsQuery, listDocumentsQuery } from '../../../api/schemas/documents.js';
|
|
7
7
|
const DEFAULT_PAGE_SIZE = 20;
|
|
8
8
|
const DEFAULT_PAGE = 1;
|
|
9
9
|
export const documentsRouter = new Hono()
|
|
@@ -83,6 +83,34 @@ export const documentsRouter = new Hono()
|
|
|
83
83
|
message: error instanceof Error ? error.message : 'Unknown error'
|
|
84
84
|
}, 500);
|
|
85
85
|
}
|
|
86
|
+
})
|
|
87
|
+
.get('/by-ids', zValidator('query', getDocumentsByIdsQuery, (result, c) => {
|
|
88
|
+
if (!result.success) {
|
|
89
|
+
return c.json({
|
|
90
|
+
success: false,
|
|
91
|
+
error: 'Invalid query parameters',
|
|
92
|
+
issues: result.error.issues
|
|
93
|
+
}, 400);
|
|
94
|
+
}
|
|
95
|
+
}), async (c) => {
|
|
96
|
+
try {
|
|
97
|
+
const { localAPI } = c.var.aphexCMS;
|
|
98
|
+
const context = authToContext(c.var.auth);
|
|
99
|
+
const { ids } = c.req.valid('query');
|
|
100
|
+
const docs = await localAPI.findDocumentsByIds(context, ids);
|
|
101
|
+
return c.json({ success: true, data: docs });
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
cmsLogger.error('Failed to batch-fetch documents:', error);
|
|
105
|
+
if (error instanceof PermissionError) {
|
|
106
|
+
return c.json({ success: false, error: 'Forbidden', message: error.message }, 403);
|
|
107
|
+
}
|
|
108
|
+
return c.json({
|
|
109
|
+
success: false,
|
|
110
|
+
error: 'Failed to fetch documents',
|
|
111
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
112
|
+
}, 500);
|
|
113
|
+
}
|
|
86
114
|
})
|
|
87
115
|
.post('/', zValidator('json', createDocumentRequest, (result, c) => {
|
|
88
116
|
if (!result.success) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DatabaseAdapter } from '../db/interfaces.js';
|
|
2
|
+
import type { SchemaType } from '../types/schemas.js';
|
|
3
|
+
/**
|
|
4
|
+
* Maintains the back-reference index. After every doc save the collection-API
|
|
5
|
+
* calls into here with the doc's draftData (the freshly-saved version) and
|
|
6
|
+
* its schema; we walk the data via the schema-aware walker, dedupe the
|
|
7
|
+
* resulting ref IDs, and atomically replace the rows for that referencer.
|
|
8
|
+
*
|
|
9
|
+
* Failures are logged but never thrown — a stale ref index is bad UX (the
|
|
10
|
+
* publish/unpublish guards may be wrong), but it shouldn't block the user's
|
|
11
|
+
* save. The boot-time backfill catches up gaps when the studio restarts.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ReferencesService {
|
|
14
|
+
private databaseAdapter;
|
|
15
|
+
constructor(databaseAdapter: DatabaseAdapter);
|
|
16
|
+
/**
|
|
17
|
+
* Sync the back-reference rows for a single document. Idempotent —
|
|
18
|
+
* safe to call repeatedly with the same data.
|
|
19
|
+
*/
|
|
20
|
+
syncReferencesFor(organizationId: string, documentId: string, data: unknown, schema: SchemaType | null, registry: SchemaType[]): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Boot-time backfill — if the references table is empty for an org,
|
|
23
|
+
* scan every document and rebuild the index. Idempotent and cheap when
|
|
24
|
+
* the index already has rows (the empty check short-circuits).
|
|
25
|
+
*
|
|
26
|
+
* Skipped silently in error paths — boot must keep going even if the
|
|
27
|
+
* scan can't run (missing perms, connection issues, etc).
|
|
28
|
+
*/
|
|
29
|
+
backfillIfEmpty(organizationId: string, schemas: SchemaType[], listAllDocuments: () => Promise<Array<{
|
|
30
|
+
id: string;
|
|
31
|
+
type: string;
|
|
32
|
+
data: unknown;
|
|
33
|
+
}>>): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=references-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"references-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/references-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD;;;;;;;;;GASG;AACH,qBAAa,iBAAiB;IACjB,OAAO,CAAC,eAAe;gBAAf,eAAe,EAAE,eAAe;IAEpD;;;OAGG;IACG,iBAAiB,CACtB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,UAAU,GAAG,IAAI,EACzB,QAAQ,EAAE,UAAU,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC;IAShB;;;;;;;OAOG;IACG,eAAe,CACpB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,UAAU,EAAE,EACrB,gBAAgB,EAAE,MAAM,OAAO,CAC9B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAClD,GACC,OAAO,CAAC,IAAI,CAAC;CAwBhB"}
|