@prometheus-ags/entity-graph-sdl 3.0.0-alpha.0 → 3.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/CHANGELOG.md +36 -0
- package/README.md +97 -0
- package/dist/{index.js → index.cjs} +2 -2
- package/dist/index.cjs.map +1 -0
- package/package.json +31 -11
- package/dist/index.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# @prometheus-ags/entity-graph-sdl
|
|
2
|
+
|
|
3
|
+
## 3.0.0
|
|
4
|
+
|
|
5
|
+
## 3.0.0-rc.1
|
|
6
|
+
|
|
7
|
+
## 3.0.0
|
|
8
|
+
|
|
9
|
+
### Major Changes
|
|
10
|
+
|
|
11
|
+
- v3.0.0 — Universal Platform Evolution
|
|
12
|
+
|
|
13
|
+
Evolves the React-only entity graph into a cross-platform, multi-framework,
|
|
14
|
+
AI-native, local-first ecosystem.
|
|
15
|
+
- **Monorepo split (breaking, but consumer-safe):** the framework-agnostic core
|
|
16
|
+
is extracted into `@prometheus-ags/entity-graph-core` (zero React). The
|
|
17
|
+
published `@prometheus-ags/prometheus-entity-management` package is the React
|
|
18
|
+
binding over the vanilla core. Existing React hook names remain available,
|
|
19
|
+
while core-only imperative consumers migrate from `useGraphStore.getState()`
|
|
20
|
+
to `graphStore.getState()`; the deprecated core alias remains through the
|
|
21
|
+
next-major removal window.
|
|
22
|
+
- **New framework bindings:** `entity-graph-svelte` (Svelte 5 runes),
|
|
23
|
+
`entity-graph-solid`, `entity-graph-web-components` (Lit 3), `entity-graph-alpine`,
|
|
24
|
+
`entity-graph-htmx` (Node SSE fragment server).
|
|
25
|
+
- **Peer sync:** `entity-graph-sync` with a pluggable SyncProvider — Yjs (default)
|
|
26
|
+
and Loro (reusing the 2.2.0 merge seam).
|
|
27
|
+
- **AI-native:** `entity-graph-a2a` plus `a2ui-react` with official A2UI
|
|
28
|
+
v0.9.1 rendering and default-deny graph actions; legacy
|
|
29
|
+
EntityChat/Copilot/Stream/Diff/Approval APIs live under `./ag-ui`.
|
|
30
|
+
- **Codegen contract:** `entity-graph-sdl` (schema → validated IR).
|
|
31
|
+
- **Native (published outside npm):** `entity-graph-cli` + `entity-graph-mcp`
|
|
32
|
+
(Rust, via crates.io), `entity-graph-tauri` (Tauri v2 plugin), and
|
|
33
|
+
`entity_graph_flutter` (Riverpod 3, via pub.dev).
|
|
34
|
+
|
|
35
|
+
All integrations ship as optional peer dependencies; the core bundle stays
|
|
36
|
+
`zustand + immer`.
|
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# `@prometheus-ags/entity-graph-sdl`
|
|
2
|
+
|
|
3
|
+
The shared Schema Definition Language for Prometheus entity graphs. It validates a JSON document and produces one deterministic intermediate representation (IR) for TypeScript, Rust, Flutter, framework bindings, and other generators.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @prometheus-ags/entity-graph-sdl
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Define a graph
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"version": "1.0",
|
|
16
|
+
"entities": {
|
|
17
|
+
"user": {
|
|
18
|
+
"fields": {
|
|
19
|
+
"id": { "type": "uuid", "primary": true },
|
|
20
|
+
"name": { "type": "string", "required": true }
|
|
21
|
+
},
|
|
22
|
+
"relations": {
|
|
23
|
+
"orders": {
|
|
24
|
+
"type": "hasMany",
|
|
25
|
+
"target": "order",
|
|
26
|
+
"foreignKey": "userId"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"order": {
|
|
31
|
+
"fields": {
|
|
32
|
+
"id": { "type": "uuid", "primary": true },
|
|
33
|
+
"userId": { "type": "uuid", "required": true },
|
|
34
|
+
"total": { "type": "decimal", "required": true }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"config": {
|
|
39
|
+
"localFirst": { "engine": "pglite", "sync": "electric" },
|
|
40
|
+
"ai": { "mcp": true, "a2a": true }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Every entity must contain exactly one `primary: true` field. Relations must reference another entity declared in the same document.
|
|
46
|
+
|
|
47
|
+
## Parse and validate
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import {
|
|
51
|
+
parseSdl,
|
|
52
|
+
parseSdlJson,
|
|
53
|
+
SdlValidationError,
|
|
54
|
+
} from "@prometheus-ags/entity-graph-sdl";
|
|
55
|
+
|
|
56
|
+
const ir = parseSdl({
|
|
57
|
+
version: "1.0",
|
|
58
|
+
entities: {
|
|
59
|
+
user: {
|
|
60
|
+
fields: {
|
|
61
|
+
id: { type: "uuid", primary: true },
|
|
62
|
+
name: { type: "string", required: true },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
console.log(ir.entities[0].primaryKey); // "id"
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
parseSdlJson("{ invalid json }");
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if (error instanceof SdlValidationError) {
|
|
74
|
+
console.error(error.path, error.message);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`parseSdl` accepts an unknown JavaScript value. `parseSdlJson` accepts JSON text. Both return `EntityGraphIR` or throw `SdlValidationError` with the precise failing path.
|
|
80
|
+
|
|
81
|
+
## Supported schema values
|
|
82
|
+
|
|
83
|
+
- scalar types: `string`, `number`, `integer`, `decimal`, `boolean`, `datetime`, `date`, `json`, `enum`, and `uuid`
|
|
84
|
+
- relation types: `belongsTo`, `hasMany`, and `manyToMany`
|
|
85
|
+
- local-first engines: `pglite`, `sqlite`, and `none`
|
|
86
|
+
- sync modes: `electric`, `yjs`, and `none`
|
|
87
|
+
- optional MCP and A2A generation flags
|
|
88
|
+
|
|
89
|
+
Enum fields require a non-empty `values` array. A table name defaults to the entity key and can be overridden with `table`.
|
|
90
|
+
|
|
91
|
+
## Module support
|
|
92
|
+
|
|
93
|
+
The package publishes conditional ESM (`.mjs`/`.d.ts`) and CommonJS (`.cjs`/`.d.cts`) entry points.
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT
|
|
@@ -88,5 +88,5 @@ function isObject(v) {
|
|
|
88
88
|
exports.SdlValidationError = SdlValidationError;
|
|
89
89
|
exports.parseSdl = parseSdl;
|
|
90
90
|
exports.parseSdlJson = parseSdlJson;
|
|
91
|
-
//# sourceMappingURL=index.
|
|
92
|
-
//# sourceMappingURL=index.
|
|
91
|
+
//# sourceMappingURL=index.cjs.map
|
|
92
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @prometheus-ags/entity-graph-sdl\n *\n * The Schema Definition Language (SDL) for the entity graph: a stable JSON/TOML\n * schema format + a parser that produces a validated intermediate\n * representation (IR). Every code generator (Rust CLI, Flutter, framework\n * bindings) consumes the SAME IR so generated targets never diverge.\n *\n * Format (schema.json):\n * {\n * \"version\": \"1.0\",\n * \"entities\": {\n * \"user\": {\n * \"fields\": { \"id\": {\"type\":\"string\",\"primary\":true}, \"name\": {\"type\":\"string\",\"required\":true} },\n * \"relations\": { \"orders\": {\"type\":\"hasMany\",\"target\":\"order\",\"foreignKey\":\"userId\"} }\n * }\n * },\n * \"config\": { \"localFirst\": {\"engine\":\"pglite\",\"sync\":\"electric\"}, \"ai\": {\"mcp\":true,\"a2a\":true} }\n * }\n */\n\n// ── Source format types ───────────────────────────────────────────────────\n\nexport type SdlScalarType =\n | \"string\" | \"number\" | \"integer\" | \"decimal\" | \"boolean\"\n | \"datetime\" | \"date\" | \"json\" | \"enum\" | \"uuid\";\n\nexport interface SdlFieldDef {\n type: SdlScalarType;\n primary?: boolean;\n required?: boolean;\n unique?: boolean;\n default?: unknown;\n /** For enum fields. */\n values?: string[];\n /** Auto-managed by the store/server (e.g. createdAt). */\n auto?: boolean;\n}\n\nexport type SdlRelationKind = \"belongsTo\" | \"hasMany\" | \"manyToMany\";\n\nexport interface SdlRelationDef {\n type: SdlRelationKind;\n target: string;\n foreignKey?: string;\n /** For manyToMany. */\n through?: string;\n}\n\nexport interface SdlEntityDef {\n fields: Record<string, SdlFieldDef>;\n relations?: Record<string, SdlRelationDef>;\n /** Optional table name override (defaults to the entity key). */\n table?: string;\n}\n\nexport interface SdlConfig {\n localFirst?: { engine?: \"pglite\" | \"sqlite\" | \"none\"; sync?: \"electric\" | \"yjs\" | \"none\" };\n ai?: { mcp?: boolean; a2a?: boolean };\n}\n\nexport interface SdlDocument {\n version: string;\n entities: Record<string, SdlEntityDef>;\n config?: SdlConfig;\n}\n\n// ── Validated IR (what generators consume) ────────────────────────────────\n\nexport interface IrField extends SdlFieldDef {\n name: string;\n}\nexport interface IrRelation extends SdlRelationDef {\n name: string;\n}\nexport interface IrEntity {\n name: string;\n table: string;\n primaryKey: string;\n fields: IrField[];\n relations: IrRelation[];\n}\nexport interface EntityGraphIR {\n version: string;\n entities: IrEntity[];\n config: SdlConfig;\n}\n\nexport class SdlValidationError extends Error {\n readonly path: string;\n constructor(message: string, path: string) {\n super(`${message} (at ${path})`);\n this.name = \"SdlValidationError\";\n this.path = path;\n }\n}\n\nconst SCALAR_TYPES = new Set<SdlScalarType>([\n \"string\", \"number\", \"integer\", \"decimal\", \"boolean\", \"datetime\", \"date\", \"json\", \"enum\", \"uuid\",\n]);\n\n/**\n * Parse + validate an SDL document into the generator IR. Throws\n * {@link SdlValidationError} with a precise path on the first problem.\n */\nexport function parseSdl(doc: unknown): EntityGraphIR {\n if (!isObject(doc)) throw new SdlValidationError(\"SDL root must be an object\", \"$\");\n const version = typeof doc.version === \"string\" ? doc.version : \"1.0\";\n if (!isObject(doc.entities)) throw new SdlValidationError(\"`entities` must be an object\", \"$.entities\");\n\n const entities: IrEntity[] = [];\n for (const [name, raw] of Object.entries(doc.entities)) {\n const path = `$.entities.${name}`;\n if (!isObject(raw) || !isObject(raw.fields)) {\n throw new SdlValidationError(\"entity must have a `fields` object\", path);\n }\n const def = raw as unknown as SdlEntityDef;\n\n const fields: IrField[] = [];\n let primaryKey: string | null = null;\n for (const [fname, fdefRaw] of Object.entries(def.fields)) {\n const fpath = `${path}.fields.${fname}`;\n if (!isObject(fdefRaw)) throw new SdlValidationError(\"field must be an object\", fpath);\n const fdef = fdefRaw as SdlFieldDef;\n if (!SCALAR_TYPES.has(fdef.type)) throw new SdlValidationError(`unknown field type \"${fdef.type}\"`, fpath);\n if (fdef.type === \"enum\" && (!Array.isArray(fdef.values) || fdef.values.length === 0)) {\n throw new SdlValidationError(\"enum field requires non-empty `values`\", fpath);\n }\n if (fdef.primary) {\n if (primaryKey) throw new SdlValidationError(\"multiple primary keys not supported\", fpath);\n primaryKey = fname;\n }\n fields.push({ ...fdef, name: fname });\n }\n if (!primaryKey) throw new SdlValidationError(\"entity needs exactly one `primary: true` field\", path);\n\n const relations: IrRelation[] = [];\n for (const [rname, rdefRaw] of Object.entries(def.relations ?? {})) {\n const rpath = `${path}.relations.${rname}`;\n if (!isObject(rdefRaw)) throw new SdlValidationError(\"relation must be an object\", rpath);\n const rdef = rdefRaw as SdlRelationDef;\n if (![\"belongsTo\", \"hasMany\", \"manyToMany\"].includes(rdef.type)) {\n throw new SdlValidationError(`unknown relation type \"${rdef.type}\"`, rpath);\n }\n if (typeof rdef.target !== \"string\") throw new SdlValidationError(\"relation needs a `target`\", rpath);\n relations.push({ ...rdef, name: rname });\n }\n\n entities.push({ name, table: def.table ?? name, primaryKey, fields, relations });\n }\n\n // Cross-reference relation targets.\n const names = new Set(entities.map((e) => e.name));\n for (const e of entities) {\n for (const r of e.relations) {\n if (!names.has(r.target)) {\n throw new SdlValidationError(`relation target \"${r.target}\" is not a defined entity`, `$.entities.${e.name}.relations.${r.name}`);\n }\n }\n }\n\n return { version, entities, config: (doc.config as SdlConfig) ?? {} };\n}\n\n/** Parse SDL from a JSON string. */\nexport function parseSdlJson(json: string): EntityGraphIR {\n let doc: unknown;\n try { doc = JSON.parse(json); } catch (cause) {\n throw new SdlValidationError(\"invalid JSON\", \"$\");\n }\n return parseSdl(doc);\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,35 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prometheus-ags/entity-graph-sdl",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Schema Definition Language (SDL) for the entity graph — the shared contract every code generator (Rust CLI, Flutter, framework bindings) consumes.",
|
|
5
|
+
"author": "Travis James <travis@prometheus.dev>",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"type": "module",
|
|
7
|
-
"main": "./dist/index.
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
8
9
|
"module": "./dist/index.mjs",
|
|
9
10
|
"types": "./dist/index.d.ts",
|
|
10
11
|
"exports": {
|
|
11
12
|
".": {
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.mjs"
|
|
16
|
+
},
|
|
17
|
+
"require": {
|
|
18
|
+
"types": "./dist/index.d.cts",
|
|
19
|
+
"default": "./dist/index.cjs"
|
|
20
|
+
}
|
|
15
21
|
}
|
|
16
22
|
},
|
|
17
23
|
"sideEffects": false,
|
|
18
24
|
"files": [
|
|
19
|
-
"dist"
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md",
|
|
27
|
+
"CHANGELOG.md"
|
|
20
28
|
],
|
|
21
29
|
"publishConfig": {
|
|
22
30
|
"access": "public"
|
|
23
31
|
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
35
|
+
"test": "vitest run"
|
|
36
|
+
},
|
|
24
37
|
"keywords": [
|
|
25
38
|
"entity-graph",
|
|
26
39
|
"schema",
|
|
27
40
|
"sdl",
|
|
28
41
|
"codegen"
|
|
29
42
|
],
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/prometheus-ags/prometheus-entity-management.git",
|
|
46
|
+
"directory": "packages/entity-graph-sdl"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/prometheus-ags/prometheus-entity-management/tree/main/packages/entity-graph-sdl#readme",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/prometheus-ags/prometheus-entity-management/issues"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": "^22.14.0 || ^24.0.0 || >=26.0.0"
|
|
34
54
|
}
|
|
35
|
-
}
|
|
55
|
+
}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @prometheus-ags/entity-graph-sdl\n *\n * The Schema Definition Language (SDL) for the entity graph: a stable JSON/TOML\n * schema format + a parser that produces a validated intermediate\n * representation (IR). Every code generator (Rust CLI, Flutter, framework\n * bindings) consumes the SAME IR so generated targets never diverge.\n *\n * Format (schema.json):\n * {\n * \"version\": \"1.0\",\n * \"entities\": {\n * \"user\": {\n * \"fields\": { \"id\": {\"type\":\"string\",\"primary\":true}, \"name\": {\"type\":\"string\",\"required\":true} },\n * \"relations\": { \"orders\": {\"type\":\"hasMany\",\"target\":\"order\",\"foreignKey\":\"userId\"} }\n * }\n * },\n * \"config\": { \"localFirst\": {\"engine\":\"pglite\",\"sync\":\"electric\"}, \"ai\": {\"mcp\":true,\"a2a\":true} }\n * }\n */\n\n// ── Source format types ───────────────────────────────────────────────────\n\nexport type SdlScalarType =\n | \"string\" | \"number\" | \"integer\" | \"decimal\" | \"boolean\"\n | \"datetime\" | \"date\" | \"json\" | \"enum\" | \"uuid\";\n\nexport interface SdlFieldDef {\n type: SdlScalarType;\n primary?: boolean;\n required?: boolean;\n unique?: boolean;\n default?: unknown;\n /** For enum fields. */\n values?: string[];\n /** Auto-managed by the store/server (e.g. createdAt). */\n auto?: boolean;\n}\n\nexport type SdlRelationKind = \"belongsTo\" | \"hasMany\" | \"manyToMany\";\n\nexport interface SdlRelationDef {\n type: SdlRelationKind;\n target: string;\n foreignKey?: string;\n /** For manyToMany. */\n through?: string;\n}\n\nexport interface SdlEntityDef {\n fields: Record<string, SdlFieldDef>;\n relations?: Record<string, SdlRelationDef>;\n /** Optional table name override (defaults to the entity key). */\n table?: string;\n}\n\nexport interface SdlConfig {\n localFirst?: { engine?: \"pglite\" | \"sqlite\" | \"none\"; sync?: \"electric\" | \"yjs\" | \"none\" };\n ai?: { mcp?: boolean; a2a?: boolean };\n}\n\nexport interface SdlDocument {\n version: string;\n entities: Record<string, SdlEntityDef>;\n config?: SdlConfig;\n}\n\n// ── Validated IR (what generators consume) ────────────────────────────────\n\nexport interface IrField extends SdlFieldDef {\n name: string;\n}\nexport interface IrRelation extends SdlRelationDef {\n name: string;\n}\nexport interface IrEntity {\n name: string;\n table: string;\n primaryKey: string;\n fields: IrField[];\n relations: IrRelation[];\n}\nexport interface EntityGraphIR {\n version: string;\n entities: IrEntity[];\n config: SdlConfig;\n}\n\nexport class SdlValidationError extends Error {\n readonly path: string;\n constructor(message: string, path: string) {\n super(`${message} (at ${path})`);\n this.name = \"SdlValidationError\";\n this.path = path;\n }\n}\n\nconst SCALAR_TYPES = new Set<SdlScalarType>([\n \"string\", \"number\", \"integer\", \"decimal\", \"boolean\", \"datetime\", \"date\", \"json\", \"enum\", \"uuid\",\n]);\n\n/**\n * Parse + validate an SDL document into the generator IR. Throws\n * {@link SdlValidationError} with a precise path on the first problem.\n */\nexport function parseSdl(doc: unknown): EntityGraphIR {\n if (!isObject(doc)) throw new SdlValidationError(\"SDL root must be an object\", \"$\");\n const version = typeof doc.version === \"string\" ? doc.version : \"1.0\";\n if (!isObject(doc.entities)) throw new SdlValidationError(\"`entities` must be an object\", \"$.entities\");\n\n const entities: IrEntity[] = [];\n for (const [name, raw] of Object.entries(doc.entities)) {\n const path = `$.entities.${name}`;\n if (!isObject(raw) || !isObject(raw.fields)) {\n throw new SdlValidationError(\"entity must have a `fields` object\", path);\n }\n const def = raw as unknown as SdlEntityDef;\n\n const fields: IrField[] = [];\n let primaryKey: string | null = null;\n for (const [fname, fdefRaw] of Object.entries(def.fields)) {\n const fpath = `${path}.fields.${fname}`;\n if (!isObject(fdefRaw)) throw new SdlValidationError(\"field must be an object\", fpath);\n const fdef = fdefRaw as SdlFieldDef;\n if (!SCALAR_TYPES.has(fdef.type)) throw new SdlValidationError(`unknown field type \"${fdef.type}\"`, fpath);\n if (fdef.type === \"enum\" && (!Array.isArray(fdef.values) || fdef.values.length === 0)) {\n throw new SdlValidationError(\"enum field requires non-empty `values`\", fpath);\n }\n if (fdef.primary) {\n if (primaryKey) throw new SdlValidationError(\"multiple primary keys not supported\", fpath);\n primaryKey = fname;\n }\n fields.push({ ...fdef, name: fname });\n }\n if (!primaryKey) throw new SdlValidationError(\"entity needs exactly one `primary: true` field\", path);\n\n const relations: IrRelation[] = [];\n for (const [rname, rdefRaw] of Object.entries(def.relations ?? {})) {\n const rpath = `${path}.relations.${rname}`;\n if (!isObject(rdefRaw)) throw new SdlValidationError(\"relation must be an object\", rpath);\n const rdef = rdefRaw as SdlRelationDef;\n if (![\"belongsTo\", \"hasMany\", \"manyToMany\"].includes(rdef.type)) {\n throw new SdlValidationError(`unknown relation type \"${rdef.type}\"`, rpath);\n }\n if (typeof rdef.target !== \"string\") throw new SdlValidationError(\"relation needs a `target`\", rpath);\n relations.push({ ...rdef, name: rname });\n }\n\n entities.push({ name, table: def.table ?? name, primaryKey, fields, relations });\n }\n\n // Cross-reference relation targets.\n const names = new Set(entities.map((e) => e.name));\n for (const e of entities) {\n for (const r of e.relations) {\n if (!names.has(r.target)) {\n throw new SdlValidationError(`relation target \"${r.target}\" is not a defined entity`, `$.entities.${e.name}.relations.${r.name}`);\n }\n }\n }\n\n return { version, entities, config: (doc.config as SdlConfig) ?? {} };\n}\n\n/** Parse SDL from a JSON string. */\nexport function parseSdlJson(json: string): EntityGraphIR {\n let doc: unknown;\n try { doc = JSON.parse(json); } catch (cause) {\n throw new SdlValidationError(\"invalid JSON\", \"$\");\n }\n return parseSdl(doc);\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n"]}
|