@beechcms/core 0.6.7 → 0.8.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/.tsbuildinfo +1 -1
- package/dist/antivirus/antivirus.interface.d.ts +12 -0
- package/dist/antivirus/antivirus.interface.d.ts.map +1 -0
- package/dist/antivirus/antivirus.interface.js +3 -0
- package/dist/antivirus/noop-antivirus.provider.d.ts +6 -0
- package/dist/antivirus/noop-antivirus.provider.d.ts.map +1 -0
- package/dist/antivirus/noop-antivirus.provider.js +8 -0
- package/dist/antivirus/virustotal-antivirus.provider.d.ts +8 -0
- package/dist/antivirus/virustotal-antivirus.provider.d.ts.map +1 -0
- package/dist/antivirus/virustotal-antivirus.provider.js +48 -0
- package/dist/common/hooks.d.ts +3 -0
- package/dist/common/hooks.d.ts.map +1 -1
- package/dist/content/richtext/richtext-render.d.ts.map +1 -1
- package/dist/content/richtext/richtext-render.js +14 -1
- package/dist/content/seed.repository.d.ts +22 -0
- package/dist/content/seed.repository.d.ts.map +1 -1
- package/dist/dashboard-layout/seed-layout.d.ts.map +1 -1
- package/dist/dashboard-layout/seed-layout.js +13 -6
- package/dist/engine/ddl.d.ts +15 -0
- package/dist/engine/ddl.d.ts.map +1 -1
- package/dist/engine/ddl.js +30 -1
- package/dist/engine/policies.d.ts.map +1 -1
- package/dist/engine/policies.js +5 -0
- package/dist/engine/seed-registry.d.ts.map +1 -1
- package/dist/engine/seed-registry.js +23 -4
- package/dist/engine/seed-types-generator.d.ts.map +1 -1
- package/dist/engine/seed-types-generator.js +8 -5
- package/dist/engine/seed-validation.d.ts +7 -0
- package/dist/engine/seed-validation.d.ts.map +1 -1
- package/dist/engine/seed-validation.js +59 -1
- package/dist/engine/types.d.ts +7 -0
- package/dist/engine/types.d.ts.map +1 -1
- package/dist/engine/validation/richtext-sanitizer.d.ts.map +1 -1
- package/dist/engine/validation/richtext-sanitizer.js +2 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -1
- package/dist/media/file-types.d.ts +103 -9
- package/dist/media/file-types.d.ts.map +1 -1
- package/dist/media/file-types.js +336 -52
- package/dist/media/magic-bytes.d.ts +21 -0
- package/dist/media/magic-bytes.d.ts.map +1 -0
- package/dist/media/magic-bytes.js +66 -0
- package/dist/oauth/authorization-code.repository.d.ts +33 -0
- package/dist/oauth/authorization-code.repository.d.ts.map +1 -0
- package/dist/oauth/authorization-code.repository.js +3 -0
- package/dist/oauth/client.repository.d.ts +17 -0
- package/dist/oauth/client.repository.d.ts.map +1 -0
- package/dist/oauth/client.repository.js +3 -0
- package/dist/oauth/consent.repository.d.ts +25 -0
- package/dist/oauth/consent.repository.d.ts.map +1 -0
- package/dist/oauth/consent.repository.js +3 -0
- package/dist/oauth/pkce.d.ts +21 -0
- package/dist/oauth/pkce.d.ts.map +1 -0
- package/dist/oauth/pkce.js +47 -0
- package/dist/oauth/role-guard.d.ts +32 -0
- package/dist/oauth/role-guard.d.ts.map +1 -0
- package/dist/oauth/role-guard.js +14 -0
- package/dist/oauth/scopes.d.ts +27 -0
- package/dist/oauth/scopes.d.ts.map +1 -0
- package/dist/oauth/scopes.js +41 -0
- package/dist/oauth/token.repository.d.ts +46 -0
- package/dist/oauth/token.repository.d.ts.map +1 -0
- package/dist/oauth/token.repository.js +3 -0
- package/dist/observability/activity-logger.d.ts +1 -1
- package/dist/observability/activity-logger.d.ts.map +1 -1
- package/dist/rate-limit/rate-limiter.d.ts +13 -5
- package/dist/rate-limit/rate-limiter.d.ts.map +1 -1
- package/dist/rate-limit/token-bucket-rate-limiter.d.ts +20 -0
- package/dist/rate-limit/token-bucket-rate-limiter.d.ts.map +1 -0
- package/dist/rate-limit/token-bucket-rate-limiter.js +63 -0
- package/dist/search/vector-extractor.d.ts +11 -0
- package/dist/search/vector-extractor.d.ts.map +1 -0
- package/dist/search/vector-extractor.js +25 -0
- package/dist/search/vector.repository.d.ts +13 -0
- package/dist/search/vector.repository.d.ts.map +1 -0
- package/dist/search/vector.repository.js +3 -0
- package/dist/security/time-trap-token.repository.d.ts +9 -0
- package/dist/security/time-trap-token.repository.d.ts.map +1 -0
- package/dist/security/time-trap-token.repository.js +3 -0
- package/dist/security/time-trap.d.ts +7 -0
- package/dist/security/time-trap.d.ts.map +1 -0
- package/dist/security/time-trap.js +49 -0
- package/dist/webhook-crypto.d.ts +2 -0
- package/dist/webhook-crypto.d.ts.map +1 -1
- package/dist/webhook-crypto.js +2 -2
- package/dist/webhooks/webhook-crypto.d.ts +2 -0
- package/dist/webhooks/webhook-crypto.d.ts.map +1 -1
- package/dist/webhooks/webhook-crypto.js +2 -2
- package/package.json +20 -12
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { IAntivirusProvider, AntivirusScanResult } from './antivirus.interface.js';
|
|
2
|
+
export declare class NoopAntivirusProvider implements IAntivirusProvider {
|
|
3
|
+
readonly name = "noop";
|
|
4
|
+
scan(_fileBuffer: ArrayBuffer | Uint8Array, _filename: string): Promise<AntivirusScanResult>;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=noop-antivirus.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noop-antivirus.provider.d.ts","sourceRoot":"","sources":["../../src/antivirus/noop-antivirus.provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEvF,qBAAa,qBAAsB,YAAW,kBAAkB;IAC9D,QAAQ,CAAC,IAAI,UAAS;IAEhB,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAGnG"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2024–2026 Flavio De Musso
|
|
3
|
+
export class NoopAntivirusProvider {
|
|
4
|
+
name = 'noop';
|
|
5
|
+
async scan(_fileBuffer, _filename) {
|
|
6
|
+
return { status: 'skipped', provider: this.name, details: 'Antivirus scanning disabled' };
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IAntivirusProvider, AntivirusScanResult } from './antivirus.interface.js';
|
|
2
|
+
export declare class VirusTotalAntivirusProvider implements IAntivirusProvider {
|
|
3
|
+
private readonly apiKey?;
|
|
4
|
+
readonly name = "virustotal";
|
|
5
|
+
constructor(apiKey?: string | undefined);
|
|
6
|
+
scan(fileBuffer: ArrayBuffer | Uint8Array, filename: string): Promise<AntivirusScanResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=virustotal-antivirus.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virustotal-antivirus.provider.d.ts","sourceRoot":"","sources":["../../src/antivirus/virustotal-antivirus.provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEvF,qBAAa,2BAA4B,YAAW,kBAAkB;IAExD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IADpC,QAAQ,CAAC,IAAI,gBAAe;gBACC,MAAM,CAAC,EAAE,MAAM,YAAA;IAEtC,IAAI,CAAC,UAAU,EAAE,WAAW,GAAG,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;CA2CjG"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2024–2026 Flavio De Musso
|
|
3
|
+
export class VirusTotalAntivirusProvider {
|
|
4
|
+
apiKey;
|
|
5
|
+
name = 'virustotal';
|
|
6
|
+
constructor(apiKey) {
|
|
7
|
+
this.apiKey = apiKey;
|
|
8
|
+
}
|
|
9
|
+
async scan(fileBuffer, filename) {
|
|
10
|
+
if (!this.apiKey) {
|
|
11
|
+
return { status: 'skipped', provider: this.name, details: 'API key not configured' };
|
|
12
|
+
}
|
|
13
|
+
const bytes = fileBuffer instanceof Uint8Array ? fileBuffer : new Uint8Array(fileBuffer);
|
|
14
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);
|
|
15
|
+
const hash = Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
16
|
+
try {
|
|
17
|
+
const res = await fetch(`https://www.virustotal.com/api/v3/files/${hash}`, {
|
|
18
|
+
headers: { 'x-apikey': this.apiKey },
|
|
19
|
+
});
|
|
20
|
+
if (res.status === 200) {
|
|
21
|
+
const data = await res.json();
|
|
22
|
+
const stats = data?.data?.attributes?.last_analysis_stats;
|
|
23
|
+
const malicious = (stats?.malicious ?? 0) + (stats?.suspicious ?? 0);
|
|
24
|
+
if (malicious > 0) {
|
|
25
|
+
return { status: 'infected', provider: this.name, details: `Detected by ${malicious} security engines` };
|
|
26
|
+
}
|
|
27
|
+
return { status: 'clean', provider: this.name };
|
|
28
|
+
}
|
|
29
|
+
if (res.status === 404) {
|
|
30
|
+
const formData = new FormData();
|
|
31
|
+
formData.append('file', new Blob([bytes]), filename);
|
|
32
|
+
const uploadRes = await fetch('https://www.virustotal.com/api/v3/files', {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: { 'x-apikey': this.apiKey },
|
|
35
|
+
body: formData,
|
|
36
|
+
});
|
|
37
|
+
if (!uploadRes.ok) {
|
|
38
|
+
return { status: 'error', provider: this.name, details: `Upload scan error: ${uploadRes.status}` };
|
|
39
|
+
}
|
|
40
|
+
return { status: 'clean', provider: this.name, details: 'Queued for background analysis' };
|
|
41
|
+
}
|
|
42
|
+
return { status: 'error', provider: this.name, details: `VirusTotal lookup returned ${res.status}` };
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return { status: 'error', provider: this.name, details: error instanceof Error ? error.message : 'Scan request failed' };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/dist/common/hooks.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ContentRepository } from '../content/content.repository.js';
|
|
2
2
|
import type { Seed } from '../engine/types.js';
|
|
3
|
+
import type { IQueueService } from '../queue/queue.interface.js';
|
|
3
4
|
export interface HookActor {
|
|
4
5
|
id: string;
|
|
5
6
|
role?: string;
|
|
@@ -17,6 +18,8 @@ export interface HookContext {
|
|
|
17
18
|
* scrivere qui bypassa la Botanical Engine.
|
|
18
19
|
*/
|
|
19
20
|
db: unknown;
|
|
21
|
+
/** Optional queue service for enqueuing async jobs from hooks. */
|
|
22
|
+
queue?: IQueueService;
|
|
20
23
|
}
|
|
21
24
|
export interface BeechHooks {
|
|
22
25
|
beforeCreate?: (data: Record<string, any>, ctx: HookContext) => Promise<Record<string, any> | void> | Record<string, any> | void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/common/hooks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AACzE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,IAAI,CAAA;IACV,6FAA6F;IAC7F,UAAU,EAAE,iBAAiB,CAAA;IAC7B,gGAAgG;IAChG,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;;OAIG;IACH,EAAE,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/common/hooks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AACzE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAEhE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,IAAI,CAAA;IACV,6FAA6F;IAC7F,UAAU,EAAE,iBAAiB,CAAA;IAC7B,gGAAgG;IAChG,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;;OAIG;IACH,EAAE,EAAE,OAAO,CAAA;IACX,kEAAkE;IAClE,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,MAAM,WAAW,UAAU;IAGzB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAA;IAChI,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAA;IAC/I,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAGrE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACpF,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACpF,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CACrE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"richtext-render.d.ts","sourceRoot":"","sources":["../../../src/content/richtext/richtext-render.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"richtext-render.d.ts","sourceRoot":"","sources":["../../../src/content/richtext/richtext-render.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AA8D/C;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAQ7E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASrD"}
|
|
@@ -9,6 +9,9 @@ import Superscript from '@tiptap/extension-superscript';
|
|
|
9
9
|
import { Table, TableCell, TableHeader, TableRow } from '@tiptap/extension-table';
|
|
10
10
|
import TextAlign from '@tiptap/extension-text-align';
|
|
11
11
|
import { Mathematics } from '@tiptap/extension-mathematics';
|
|
12
|
+
import { TextStyle } from '@tiptap/extension-text-style';
|
|
13
|
+
import Color from '@tiptap/extension-color';
|
|
14
|
+
import { TaskItem, TaskList } from '@tiptap/extension-list';
|
|
12
15
|
import StarterKit from '@tiptap/starter-kit';
|
|
13
16
|
import { isRichtextEnvelopeV1 } from './richtext.js';
|
|
14
17
|
/**
|
|
@@ -38,6 +41,10 @@ function createRichTextHtmlExtensions() {
|
|
|
38
41
|
Highlight,
|
|
39
42
|
Superscript,
|
|
40
43
|
Subscript,
|
|
44
|
+
TextStyle,
|
|
45
|
+
Color,
|
|
46
|
+
TaskList,
|
|
47
|
+
TaskItem,
|
|
41
48
|
Image.configure({
|
|
42
49
|
allowBase64: false,
|
|
43
50
|
}),
|
|
@@ -76,5 +83,11 @@ export function renderRichText(value) {
|
|
|
76
83
|
const normalized = normalizeRichtextForRender(value);
|
|
77
84
|
if (normalized == null)
|
|
78
85
|
return '';
|
|
79
|
-
|
|
86
|
+
try {
|
|
87
|
+
return generateHTML(normalized, createRichTextHtmlExtensions());
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.warn('[BeechCMS RichText] Failed to render rich text document:', error);
|
|
91
|
+
return '';
|
|
92
|
+
}
|
|
80
93
|
}
|
|
@@ -33,5 +33,27 @@ export interface ISeedRepository {
|
|
|
33
33
|
getRegistryVersion(): Promise<number>;
|
|
34
34
|
/** Atomically increment and return the new token. Call after any write. */
|
|
35
35
|
bumpRegistryVersion(): Promise<number>;
|
|
36
|
+
/** Applies additive DDL, the definition upsert and the registry-version bump as ONE
|
|
37
|
+
* transactional batch, guarded by compare-and-swap on seed_meta.registry_version.
|
|
38
|
+
* All-or-nothing: a guard mismatch or a failing statement writes nothing.
|
|
39
|
+
* The DDL strings MUST come from the core planners — this method never generates SQL. */
|
|
40
|
+
applyAtomic(input: SeedApplyInput): Promise<SeedApplyResult>;
|
|
41
|
+
}
|
|
42
|
+
/** Input for an atomic, OCC-guarded schema apply. */
|
|
43
|
+
export interface SeedApplyInput {
|
|
44
|
+
slug: string;
|
|
45
|
+
/** Full canonical definition to store in `seeds.definition`. */
|
|
46
|
+
definition: Seed;
|
|
47
|
+
/** Additive DDL produced by planCreateSeed / planExtendSeed. Never destructive. */
|
|
48
|
+
ddl: string[];
|
|
49
|
+
/** The registry_version the caller planned against (compare-and-swap guard). */
|
|
50
|
+
expectedVersion: number;
|
|
51
|
+
source?: 'code' | 'runtime';
|
|
52
|
+
}
|
|
53
|
+
export interface SeedApplyResult {
|
|
54
|
+
/** false when the CAS guard did not match — nothing was written. */
|
|
55
|
+
applied: boolean;
|
|
56
|
+
/** The version now in D1: expectedVersion + 1 on success, the live value on conflict. */
|
|
57
|
+
version: number;
|
|
36
58
|
}
|
|
37
59
|
//# sourceMappingURL=seed.repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.repository.d.ts","sourceRoot":"","sources":["../../src/content/seed.repository.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,IAAI,CAAA;IAChB,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,UAAU,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IAC7B,kEAAkE;IAClE,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAChC,wDAAwD;IACxD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAC7C,kGAAkG;IAClG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClF,+EAA+E;IAC/E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC;gFAC4E;IAC5E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,2BAA2B;IAC3B,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,2EAA2E;IAC3E,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"seed.repository.d.ts","sourceRoot":"","sources":["../../src/content/seed.repository.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,IAAI,CAAA;IAChB,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,UAAU,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IAC7B,kEAAkE;IAClE,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAChC,wDAAwD;IACxD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAC7C,kGAAkG;IAClG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClF,+EAA+E;IAC/E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC;gFAC4E;IAC5E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,2BAA2B;IAC3B,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,2EAA2E;IAC3E,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACtC;;;8FAG0F;IAC1F,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;CAC7D;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,gEAAgE;IAChE,UAAU,EAAE,IAAI,CAAA;IAChB,mFAAmF;IACnF,GAAG,EAAE,MAAM,EAAE,CAAA;IACb,gFAAgF;IAChF,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAA;IAChB,yFAAyF;IACzF,OAAO,EAAE,MAAM,CAAA;CAChB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-layout.d.ts","sourceRoot":"","sources":["../../src/dashboard-layout/seed-layout.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAOtD,eAAO,MAAM,sBAAsB;;;;;;;;;;;iBAKjC,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAMrE,eAAO,MAAM,mBAAmB;;iBAE9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;iBAUjC,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAErE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGjB,CAAA;AAChB,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAMjE;;sFAEsF;AACtF,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,WAAW,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,4CAA4C;IAC5C,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,aAAa,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,OAAO,EAAE,CAAC,CAAA;IACV,IAAI,EAAE,SAAS,EAAE,CAAA;CAClB;AAMD,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"seed-layout.d.ts","sourceRoot":"","sources":["../../src/dashboard-layout/seed-layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,14 +36,14 @@ export const seedViewConfigSchema = z.object({
|
|
|
36
36
|
// Branch-type rules used by both the default generator and the validator.
|
|
37
37
|
// ---------------------------------------------------------------------------
|
|
38
38
|
/** Branch types that must occupy a section alone, full width. */
|
|
39
|
-
export const FULL_WIDTH_BRANCH_TYPES = new Set(['richtext']);
|
|
39
|
+
export const FULL_WIDTH_BRANCH_TYPES = new Set(['richtext', 'json']);
|
|
40
40
|
/** Returns true when a branch is a gallery (file + multiple/asset-list). */
|
|
41
41
|
export function isGalleryBranch(branch) {
|
|
42
42
|
return branch.type === 'file'
|
|
43
43
|
&& (branch.multiple === true || branch.format === 'asset-list');
|
|
44
44
|
}
|
|
45
45
|
/** Branch types currently unsupported in the Layout Builder. */
|
|
46
|
-
export const UNSUPPORTED_BRANCH_TYPES = new Set([
|
|
46
|
+
export const UNSUPPORTED_BRANCH_TYPES = new Set([]);
|
|
47
47
|
/** Aliases that are NEVER included in the editor form (handled by other UI). */
|
|
48
48
|
export const SYSTEM_ALIASES = new Set([
|
|
49
49
|
'id', 'slug', 'status', 'created_at', 'updated_at',
|
|
@@ -246,11 +246,18 @@ export function validateLayoutAgainstSeed(layout, seed) {
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
|
-
// Full-width branches must occupy a dedicated section
|
|
249
|
+
// Full-width branches must occupy a dedicated single-column section
|
|
250
250
|
const fullWidthInSection = fieldsInSection.filter(isFullWidthBranch);
|
|
251
|
-
if (fullWidthInSection.length > 0
|
|
252
|
-
|
|
253
|
-
|
|
251
|
+
if (fullWidthInSection.length > 0) {
|
|
252
|
+
if (fieldsInSection.length > 1) {
|
|
253
|
+
for (const fw of fullWidthInSection) {
|
|
254
|
+
errors.push(`Branch '${fw.alias}' (type=${fw.type}) must occupy a dedicated section and cannot share it with other fields.`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (section.columns.length > 1) {
|
|
258
|
+
for (const fw of fullWidthInSection) {
|
|
259
|
+
errors.push(`Branch '${fw.alias}' (type=${fw.type}) must occupy a single-column section.`);
|
|
260
|
+
}
|
|
254
261
|
}
|
|
255
262
|
}
|
|
256
263
|
}
|
package/dist/engine/ddl.d.ts
CHANGED
|
@@ -22,6 +22,13 @@ export declare function tableName(seed: Seed): string;
|
|
|
22
22
|
* @returns The FTS table name.
|
|
23
23
|
*/
|
|
24
24
|
export declare function ftsTableName(seed: Seed): string;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the vector table name for a given Seed.
|
|
27
|
+
*
|
|
28
|
+
* @param seed The seed definition.
|
|
29
|
+
* @returns The vector table name.
|
|
30
|
+
*/
|
|
31
|
+
export declare function vectorTableName(seed: Seed): string;
|
|
25
32
|
/**
|
|
26
33
|
* Determines whether a column is valid for a given Seed (either system column or branch alias).
|
|
27
34
|
*
|
|
@@ -83,6 +90,14 @@ export declare function generateFtsTable(seed: Seed): string | null;
|
|
|
83
90
|
* @returns An array of CREATE TRIGGER SQL statements.
|
|
84
91
|
*/
|
|
85
92
|
export declare function generateFtsTriggers(seed: Seed): string[];
|
|
93
|
+
/**
|
|
94
|
+
* Generates the SQL `CREATE TABLE IF NOT EXISTS vector_{slug}` statement
|
|
95
|
+
* for indexable text/richtext branches.
|
|
96
|
+
*
|
|
97
|
+
* @param seed The seed definition.
|
|
98
|
+
* @returns The CREATE TABLE SQL statement, or null if no branches are indexable.
|
|
99
|
+
*/
|
|
100
|
+
export declare function generateVectorTable(seed: Seed): string | null;
|
|
86
101
|
/**
|
|
87
102
|
* Expected database schema column interface.
|
|
88
103
|
*/
|
package/dist/engine/ddl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ddl.d.ts","sourceRoot":"","sources":["../../src/engine/ddl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,IAAI,EACJ,MAAM,EAOP,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrD;AA6BD;;GAEG;AACH,eAAO,MAAM,cAAc,aAAgE,CAAA;AAG3F;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE5C;AAcD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE/C;AAGD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAG9D;AAGD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAM5D;AAgCD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CA2BtD;AAGD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CA2B5D;AAGD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGpE;AAGD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAyBpD;AAGD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAc1D;AAGD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAgCxD;AAGD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,2BAA2B;IAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACpC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,6CAA6C;IAC7C,IAAI,EAAE,OAAO,CAAA;CACd;AAGD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,EAAE,CA4B7D;AAGD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE/E;AAGD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAkBxE;AAGD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAM5E;AAGD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAapF;AAGD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"ddl.d.ts","sourceRoot":"","sources":["../../src/engine/ddl.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/ddl.js
CHANGED
|
@@ -53,6 +53,15 @@ function draftTableName(seed) {
|
|
|
53
53
|
export function ftsTableName(seed) {
|
|
54
54
|
return `fts_${seed.slug}`;
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Returns the vector table name for a given Seed.
|
|
58
|
+
*
|
|
59
|
+
* @param seed The seed definition.
|
|
60
|
+
* @returns The vector table name.
|
|
61
|
+
*/
|
|
62
|
+
export function vectorTableName(seed) {
|
|
63
|
+
return `vector_${seed.slug}`;
|
|
64
|
+
}
|
|
56
65
|
/**
|
|
57
66
|
* Determines whether a column is valid for a given Seed (either system column or branch alias).
|
|
58
67
|
*
|
|
@@ -202,7 +211,7 @@ export function generateIndexes(seed) {
|
|
|
202
211
|
if (branch.type === 'relation' && branch.multiple === true)
|
|
203
212
|
continue;
|
|
204
213
|
const isRelation = branch.type === 'relation';
|
|
205
|
-
if (!isRelation && branch.
|
|
214
|
+
if (!isRelation && !resolvePolicies(branch).filter)
|
|
206
215
|
continue;
|
|
207
216
|
if (['text', 'number', 'date', 'boolean', 'relation'].includes(branch.type)) {
|
|
208
217
|
indexes.push(`CREATE INDEX IF NOT EXISTS idx_${slug}_${branch.alias} ON ${table}(${branch.alias});`);
|
|
@@ -271,6 +280,25 @@ export function generateFtsTriggers(seed) {
|
|
|
271
280
|
].join('\n'),
|
|
272
281
|
];
|
|
273
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Generates the SQL `CREATE TABLE IF NOT EXISTS vector_{slug}` statement
|
|
285
|
+
* for indexable text/richtext branches.
|
|
286
|
+
*
|
|
287
|
+
* @param seed The seed definition.
|
|
288
|
+
* @returns The CREATE TABLE SQL statement, or null if no branches are indexable.
|
|
289
|
+
*/
|
|
290
|
+
export function generateVectorTable(seed) {
|
|
291
|
+
const rtBranches = indexableSearchBranches(seed);
|
|
292
|
+
if (rtBranches.length === 0)
|
|
293
|
+
return null;
|
|
294
|
+
const table = vectorTableName(seed);
|
|
295
|
+
return [
|
|
296
|
+
`CREATE TABLE IF NOT EXISTS ${table} (`,
|
|
297
|
+
` entry_id TEXT NOT NULL PRIMARY KEY REFERENCES content_${seed.slug}(id) ON DELETE CASCADE,`,
|
|
298
|
+
` vector BLOB NOT NULL`,
|
|
299
|
+
`);`,
|
|
300
|
+
].join('\n');
|
|
301
|
+
}
|
|
274
302
|
/**
|
|
275
303
|
* Returns the list of expected columns for a Seed's table.
|
|
276
304
|
* Used to compare current vs expected schema (diffing).
|
|
@@ -408,6 +436,7 @@ export function generateDropTable(seed) {
|
|
|
408
436
|
stmts.push(`DROP TRIGGER IF EXISTS fts_${slug}_update;`);
|
|
409
437
|
stmts.push(`DROP TRIGGER IF EXISTS fts_${slug}_delete;`);
|
|
410
438
|
stmts.push(`DROP TABLE IF EXISTS ${ftsTableName(seed)};`);
|
|
439
|
+
stmts.push(`DROP TABLE IF EXISTS ${vectorTableName(seed)};`);
|
|
411
440
|
}
|
|
412
441
|
stmts.push(`DROP TABLE IF EXISTS ${tableName(seed)};`);
|
|
413
442
|
return stmts;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../../src/engine/policies.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEhF;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK9D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,cAAc,EAAE,kBAAkB,CAAA;IAClC,6FAA6F;IAC7F,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;IACrC,6FAA6F;IAC7F,gBAAgB,EAAE,MAAM,GAAG,QAAQ,CAAA;IACnC,oFAAoF;IACpF,cAAc,EAAE,MAAM,GAAG,QAAQ,CAAA;CAClC;AAED,0EAA0E;AAC1E,wBAAgB,uBAAuB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAQxE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAmC5E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../../src/engine/policies.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEhF;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK9D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,cAAc,EAAE,kBAAkB,CAAA;IAClC,6FAA6F;IAC7F,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;IACrC,6FAA6F;IAC7F,gBAAgB,EAAE,MAAM,GAAG,QAAQ,CAAA;IACnC,oFAAoF;IACpF,cAAc,EAAE,MAAM,GAAG,QAAQ,CAAA;CAClC;AAED,0EAA0E;AAC1E,wBAAgB,uBAAuB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAQxE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAmC5E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CA2BzF;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,EAAE,IAAI,EACV,KAAK,GAAE,YAAwC,GAC9C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgDzB"}
|
package/dist/engine/policies.js
CHANGED
|
@@ -91,6 +91,10 @@ export function resolvePolicies(branch) {
|
|
|
91
91
|
const defaultFilter = isRepeater || resolved.storage === 'hash' ? false : branch.policies?.filter ?? true;
|
|
92
92
|
const defaultSort = isRepeater || isEncryptedOrHashed ? false : branch.policies?.sort ?? true;
|
|
93
93
|
const defaultSearch = isRepeater || isEncryptedOrHashed ? false : branch.policies?.search ?? true;
|
|
94
|
+
// publicEdit default: true for public fields (unless public: false), false for confidential/internal/restricted
|
|
95
|
+
const defaultPublicEdit = resolved.classification === 'public'
|
|
96
|
+
? (branch.policies?.publicEdit ?? isPublicAllowed)
|
|
97
|
+
: (branch.policies?.publicEdit ?? false);
|
|
94
98
|
return {
|
|
95
99
|
classification: resolved.classification,
|
|
96
100
|
privacy: resolved.storage,
|
|
@@ -99,6 +103,7 @@ export function resolvePolicies(branch) {
|
|
|
99
103
|
filter: defaultFilter,
|
|
100
104
|
sort: defaultSort,
|
|
101
105
|
public: isPublicAllowed,
|
|
106
|
+
publicEdit: defaultPublicEdit,
|
|
102
107
|
};
|
|
103
108
|
}
|
|
104
109
|
const SYSTEM_FIELDS = new Set(['id', 'slug', 'status', 'created_at', 'updated_at', 'version', 'has_pending_draft']);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-registry.d.ts","sourceRoot":"","sources":["../../src/engine/seed-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAI9C,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,IAAI,IAAI,EAAE,CAAA;IAEb;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IAE9B;;;;;OAKG;IACH,kBAAkB,IAAI,IAAI,EAAE,CAAA;IAE5B;;;OAGG;IACH,cAAc,IAAI,IAAI,EAAE,CAAA;IAExB;;;OAGG;IACH,YAAY,IAAI,IAAI,EAAE,CAAA;CACvB;AAID,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;gBAEzB,KAAK,EAAE,IAAI,EAAE;IAkCzB,GAAG,IAAI,IAAI,EAAE;IAIb,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI9B,kBAAkB,IAAI,IAAI,EAAE;IAI5B,cAAc,IAAI,IAAI,EAAE;IAIxB,YAAY,IAAI,IAAI,EAAE;CAGvB;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;CAAG;AAEzD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,MAAM,CAQjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"seed-registry.d.ts","sourceRoot":"","sources":["../../src/engine/seed-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAI9C,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,IAAI,IAAI,EAAE,CAAA;IAEb;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IAE9B;;;;;OAKG;IACH,kBAAkB,IAAI,IAAI,EAAE,CAAA;IAE5B;;;OAGG;IACH,cAAc,IAAI,IAAI,EAAE,CAAA;IAExB;;;OAGG;IACH,YAAY,IAAI,IAAI,EAAE,CAAA;CACvB;AAID,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;gBAEzB,KAAK,EAAE,IAAI,EAAE;IAkCzB,GAAG,IAAI,IAAI,EAAE;IAIb,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI9B,kBAAkB,IAAI,IAAI,EAAE;IAI5B,cAAc,IAAI,IAAI,EAAE;IAIxB,YAAY,IAAI,IAAI,EAAE;CAGvB;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;CAAG;AAEzD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,MAAM,CAQjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CA0F1E"}
|
|
@@ -113,6 +113,8 @@ export function sortSeedsByDependencies(seeds) {
|
|
|
113
113
|
.filter(b => b.type === 'relation' && b.targetSeed)
|
|
114
114
|
.map(b => b.targetSeed));
|
|
115
115
|
for (const target of targets) {
|
|
116
|
+
if (target === seed.slug)
|
|
117
|
+
continue; // self-reference needs no ordering
|
|
116
118
|
// seed depends on target → increment seed's in-degree
|
|
117
119
|
inDegree.set(seed.slug, (inDegree.get(seed.slug) ?? 0) + 1);
|
|
118
120
|
dependents.get(target).push(seed.slug);
|
|
@@ -137,11 +139,28 @@ export function sortSeedsByDependencies(seeds) {
|
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
if (result.length !== seeds.length) {
|
|
140
|
-
//
|
|
141
|
-
const
|
|
142
|
+
// Isolate true cycle members
|
|
143
|
+
const stuck = new Set([...inDegree.entries()]
|
|
142
144
|
.filter(([, deg]) => deg > 0)
|
|
143
|
-
.map(([slug]) => slug)
|
|
144
|
-
|
|
145
|
+
.map(([slug]) => slug));
|
|
146
|
+
const cycleNodes = [...stuck].filter(slug => {
|
|
147
|
+
const visited = new Set();
|
|
148
|
+
const queue = [...(dependents.get(slug) ?? [])].filter(s => stuck.has(s));
|
|
149
|
+
while (queue.length > 0) {
|
|
150
|
+
const curr = queue.shift();
|
|
151
|
+
if (curr === slug)
|
|
152
|
+
return true;
|
|
153
|
+
if (!visited.has(curr)) {
|
|
154
|
+
visited.add(curr);
|
|
155
|
+
for (const next of dependents.get(curr) ?? []) {
|
|
156
|
+
if (stuck.has(next))
|
|
157
|
+
queue.push(next);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
});
|
|
163
|
+
const cycle = (cycleNodes.length > 0 ? cycleNodes : [...stuck]).sort();
|
|
145
164
|
throw new Error(`Cyclic dependency detected among seeds: ${cycle.join(', ')}`);
|
|
146
165
|
}
|
|
147
166
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-types-generator.d.ts","sourceRoot":"","sources":["../../src/engine/seed-types-generator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAe9C,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAMD,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoCtD;AAWD,sDAAsD;AACtD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAYnD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"seed-types-generator.d.ts","sourceRoot":"","sources":["../../src/engine/seed-types-generator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAe9C,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAMD,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoCtD;AAWD,sDAAsD;AACtD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAYnD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAcvD"}
|
|
@@ -78,9 +78,12 @@ export function interfaceForSeed(seed) {
|
|
|
78
78
|
export function generateSeedTypes(seeds) {
|
|
79
79
|
const sorted = [...seeds].sort((a, b) => a.slug.localeCompare(b.slug));
|
|
80
80
|
const interfaces = sorted.map(interfaceForSeed).join('\n');
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
(
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
const registryProps = sorted
|
|
82
|
+
.map(s => ` ${propName({ alias: s.slug })}: ${pascalCase(s.slug)}`)
|
|
83
|
+
.join('\n');
|
|
84
|
+
const databaseRegistry = `export interface BeechDatabase {\n` +
|
|
85
|
+
(registryProps ? registryProps + '\n' : '') +
|
|
86
|
+
`}\n\n` +
|
|
87
|
+
`export type SeedRegistryTypes = BeechDatabase\n`;
|
|
88
|
+
return `${HEADER}\n${interfaces}\n${databaseRegistry}`;
|
|
86
89
|
}
|
|
@@ -7,6 +7,13 @@ import type { Seed } from './types.js';
|
|
|
7
7
|
* exact same guard — do not inline a divergent copy.
|
|
8
8
|
*/
|
|
9
9
|
export declare const BRANCH_ALIAS_RE: RegExp;
|
|
10
|
+
/**
|
|
11
|
+
* Allowed charset for a seed slug identifier.
|
|
12
|
+
* Must consist solely of lowercase ASCII letters, digits, and underscores.
|
|
13
|
+
* Exported so route handlers and validation functions reuse the exact same guard.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SEED_SLUG_RE: RegExp;
|
|
16
|
+
export declare const SLUG_RE: RegExp;
|
|
10
17
|
export interface SeedValidationIssue {
|
|
11
18
|
slug: string;
|
|
12
19
|
messages: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-validation.d.ts","sourceRoot":"","sources":["../../src/engine/seed-validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"seed-validation.d.ts","sourceRoot":"","sources":["../../src/engine/seed-validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAQtC;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,QAAyB,CAAA;AAErD;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAiB,CAAA;AAC1C,eAAO,MAAM,OAAO,QAAe,CAAA;AAGnC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;CACf;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,mBAAmB,EAAE,CAkT5E;AAED,6CAA6C;AAC7C,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAErD"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
// Copyright (c) 2024–2026 Flavio De Musso
|
|
3
3
|
import { AUTOMATION_RESERVED_WORDS } from '../automations/automations-grammar-words.js';
|
|
4
|
+
import { SYSTEM_COLUMNS } from './ddl.js';
|
|
4
5
|
import { sortSeedsByDependencies } from './seed-registry.js';
|
|
5
6
|
import { SQL_RESERVED_WORDS } from './sql-reserved-words.js';
|
|
6
7
|
const BRANCH_ID_RE = /^br_[A-Za-z0-9]+$/;
|
|
@@ -12,6 +13,13 @@ const BRANCH_ID_RE = /^br_[A-Za-z0-9]+$/;
|
|
|
12
13
|
* exact same guard — do not inline a divergent copy.
|
|
13
14
|
*/
|
|
14
15
|
export const BRANCH_ALIAS_RE = /^[a-z][a-zA-Z0-9_]*$/;
|
|
16
|
+
/**
|
|
17
|
+
* Allowed charset for a seed slug identifier.
|
|
18
|
+
* Must consist solely of lowercase ASCII letters, digits, and underscores.
|
|
19
|
+
* Exported so route handlers and validation functions reuse the exact same guard.
|
|
20
|
+
*/
|
|
21
|
+
export const SEED_SLUG_RE = /^[a-z0-9_]+$/;
|
|
22
|
+
export const SLUG_RE = SEED_SLUG_RE;
|
|
15
23
|
/**
|
|
16
24
|
* Pure, console-free, throw-free validation of a seed set.
|
|
17
25
|
* The single seed being created/edited should be validated in the context of
|
|
@@ -113,7 +121,11 @@ export function validateSeedDefinitions(seeds) {
|
|
|
113
121
|
for (const seed of seeds) {
|
|
114
122
|
const messages = [];
|
|
115
123
|
for (const branch of seed.branches) {
|
|
116
|
-
if (
|
|
124
|
+
if (SYSTEM_COLUMNS.has(branch.alias)) {
|
|
125
|
+
messages.push(`branch '${branch.alias}' collides with reserved system column. ` +
|
|
126
|
+
`System columns (id, slug, status, created_at, updated_at) cannot be used as branch aliases.`);
|
|
127
|
+
}
|
|
128
|
+
else if (AUTOMATION_RESERVED_WORDS.has(branch.alias)) {
|
|
117
129
|
messages.push(`branch '${branch.alias}' uses reserved alias. ` +
|
|
118
130
|
`This word is used by the automation template grammar.`);
|
|
119
131
|
}
|
|
@@ -242,6 +254,16 @@ export function validateSeedDefinitions(seeds) {
|
|
|
242
254
|
fatal: true,
|
|
243
255
|
});
|
|
244
256
|
}
|
|
257
|
+
else if (SYSTEM_COLUMNS.has(seed.displayNameAlias)) {
|
|
258
|
+
result.push({
|
|
259
|
+
slug: seed.slug,
|
|
260
|
+
messages: [
|
|
261
|
+
`displayNameAlias '${seed.displayNameAlias}' collides with reserved system column. ` +
|
|
262
|
+
`System columns (id, slug, status, created_at, updated_at) cannot be used as displayNameAlias.`,
|
|
263
|
+
],
|
|
264
|
+
fatal: true,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
245
267
|
else if (SQL_RESERVED_WORDS.has(seed.displayNameAlias.toLowerCase())) {
|
|
246
268
|
result.push({
|
|
247
269
|
slug: seed.slug,
|
|
@@ -253,6 +275,42 @@ export function validateSeedDefinitions(seeds) {
|
|
|
253
275
|
});
|
|
254
276
|
}
|
|
255
277
|
}
|
|
278
|
+
// ── Fatal 13: retentionDays validation ─────────────────────────────────────
|
|
279
|
+
for (const seed of seeds) {
|
|
280
|
+
if (seed.retentionDays !== undefined && (!Number.isInteger(seed.retentionDays) || seed.retentionDays <= 0)) {
|
|
281
|
+
result.push({
|
|
282
|
+
slug: seed.slug,
|
|
283
|
+
messages: [
|
|
284
|
+
`retentionDays must be a positive integer >= 1 (got ${seed.retentionDays}).`,
|
|
285
|
+
],
|
|
286
|
+
fatal: true,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// ── Fatal 14: publicEdit validation ─────────────────────────────────────────
|
|
291
|
+
for (const seed of seeds) {
|
|
292
|
+
const messages = [];
|
|
293
|
+
for (const branch of seed.branches) {
|
|
294
|
+
if (branch.policies?.publicEdit !== undefined && typeof branch.policies.publicEdit !== 'boolean') {
|
|
295
|
+
messages.push(`branch '${branch.alias}': policies.publicEdit must be a boolean`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (messages.length > 0)
|
|
299
|
+
result.push({ slug: seed.slug, messages, fatal: true });
|
|
300
|
+
}
|
|
301
|
+
// ── Fatal 15: seed slug format validation ─────────────────────────────────
|
|
302
|
+
for (const seed of seeds) {
|
|
303
|
+
if (typeof seed.slug !== 'string' || !SEED_SLUG_RE.test(seed.slug)) {
|
|
304
|
+
result.push({
|
|
305
|
+
slug: seed.slug,
|
|
306
|
+
messages: [
|
|
307
|
+
`slug '${seed.slug}' is invalid. Expected format ${SEED_SLUG_RE.source} ` +
|
|
308
|
+
`(lowercase letters, numbers, and underscores only).`,
|
|
309
|
+
],
|
|
310
|
+
fatal: true,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
256
314
|
return result;
|
|
257
315
|
}
|
|
258
316
|
/** Convenience: true iff no fatal issues. */
|
package/dist/engine/types.d.ts
CHANGED
|
@@ -116,6 +116,8 @@ export interface Branch {
|
|
|
116
116
|
sort?: boolean;
|
|
117
117
|
/** Whether the field is included in Public API responses. Default: true. */
|
|
118
118
|
public?: boolean;
|
|
119
|
+
/** Whether the field can be updated via public edit endpoints. Default: false for confidential/internal/restricted, true for public. */
|
|
120
|
+
publicEdit?: boolean;
|
|
119
121
|
};
|
|
120
122
|
/** Advanced options for number fields. Ignored if type !== 'number'. */
|
|
121
123
|
numberOptions?: NumberFieldOptions;
|
|
@@ -216,6 +218,11 @@ export interface Seed {
|
|
|
216
218
|
* Required — UIs use it for display without heuristics.
|
|
217
219
|
*/
|
|
218
220
|
displayNameAlias: string;
|
|
221
|
+
/**
|
|
222
|
+
* Number of days to retain entries before automatic cleanup or anonymization (GDPR compliance).
|
|
223
|
+
* Must be a positive integer (>= 1) when specified.
|
|
224
|
+
*/
|
|
225
|
+
retentionDays?: number;
|
|
219
226
|
/** List of fields (Branch). */
|
|
220
227
|
branches: Branch[];
|
|
221
228
|
/** Optional dashboard-specific UI config. Ignored by the Botanical Engine. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"richtext-sanitizer.d.ts","sourceRoot":"","sources":["../../../src/engine/validation/richtext-sanitizer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"richtext-sanitizer.d.ts","sourceRoot":"","sources":["../../../src/engine/validation/richtext-sanitizer.ts"],"names":[],"mappings":"AA2BA,+DAA+D;AAC/D,UAAU,sBAAsB;IAC9B,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAA;IACd,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAA;IAClB,mEAAmE;IACnE,KAAK,EAAE,OAAO,CAAA;IACd,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAoID;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAgCvF;AA2BD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAS1D"}
|