@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 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.js.map
92
- //# sourceMappingURL=index.js.map
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-alpha.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.js",
8
+ "main": "./dist/index.cjs",
8
9
  "module": "./dist/index.mjs",
9
10
  "types": "./dist/index.d.ts",
10
11
  "exports": {
11
12
  ".": {
12
- "types": "./dist/index.d.ts",
13
- "import": "./dist/index.mjs",
14
- "require": "./dist/index.js"
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
- "scripts": {
31
- "build": "tsup",
32
- "typecheck": "tsc --noEmit -p tsconfig.json",
33
- "test": "vitest run"
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":";;;AAwFO,IAAM,kBAAA,GAAN,cAAiC,KAAA,CAAM;AAAA,EACnC,IAAA;AAAA,EACT,WAAA,CAAY,SAAiB,IAAA,EAAc;AACzC,IAAA,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAA,CAAG,CAAA;AAC/B,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF;AAEA,IAAM,YAAA,uBAAmB,GAAA,CAAmB;AAAA,EAC1C,QAAA;AAAA,EAAU,QAAA;AAAA,EAAU,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,UAAA;AAAA,EAAY,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ;AAC3F,CAAC,CAAA;AAMM,SAAS,SAAS,GAAA,EAA6B;AACpD,EAAA,IAAI,CAAC,SAAS,GAAG,CAAA,QAAS,IAAI,kBAAA,CAAmB,8BAA8B,GAAG,CAAA;AAClF,EAAA,MAAM,UAAU,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,GAAW,IAAI,OAAA,GAAU,KAAA;AAChE,EAAA,IAAI,CAAC,SAAS,GAAA,CAAI,QAAQ,GAAG,MAAM,IAAI,kBAAA,CAAmB,8BAAA,EAAgC,YAAY,CAAA;AAEtG,EAAA,MAAM,WAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,CAAC,MAAM,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,EAAG;AACtD,IAAA,MAAM,IAAA,GAAO,cAAc,IAAI,CAAA,CAAA;AAC/B,IAAA,IAAI,CAAC,SAAS,GAAG,CAAA,IAAK,CAAC,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA,EAAG;AAC3C,MAAA,MAAM,IAAI,kBAAA,CAAmB,oCAAA,EAAsC,IAAI,CAAA;AAAA,IACzE;AACA,IAAA,MAAM,GAAA,GAAM,GAAA;AAEZ,IAAA,MAAM,SAAoB,EAAC;AAC3B,IAAA,IAAI,UAAA,GAA4B,IAAA;AAChC,IAAA,KAAA,MAAW,CAAC,OAAO,OAAO,CAAA,IAAK,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAG;AACzD,MAAA,MAAM,KAAA,GAAQ,CAAA,EAAG,IAAI,CAAA,QAAA,EAAW,KAAK,CAAA,CAAA;AACrC,MAAA,IAAI,CAAC,SAAS,OAAO,CAAA,QAAS,IAAI,kBAAA,CAAmB,2BAA2B,KAAK,CAAA;AACrF,MAAA,MAAM,IAAA,GAAO,OAAA;AACb,MAAA,IAAI,CAAC,YAAA,CAAa,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG,MAAM,IAAI,kBAAA,CAAmB,CAAA,oBAAA,EAAuB,IAAA,CAAK,IAAI,KAAK,KAAK,CAAA;AACzG,MAAA,IAAI,IAAA,CAAK,IAAA,KAAS,MAAA,KAAW,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,IAAK,IAAA,CAAK,MAAA,CAAO,MAAA,KAAW,CAAA,CAAA,EAAI;AACrF,QAAA,MAAM,IAAI,kBAAA,CAAmB,wCAAA,EAA0C,KAAK,CAAA;AAAA,MAC9E;AACA,MAAA,IAAI,KAAK,OAAA,EAAS;AAChB,QAAA,IAAI,UAAA,EAAY,MAAM,IAAI,kBAAA,CAAmB,uCAAuC,KAAK,CAAA;AACzF,QAAA,UAAA,GAAa,KAAA;AAAA,MACf;AACA,MAAA,MAAA,CAAO,KAAK,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,OAAO,CAAA;AAAA,IACtC;AACA,IAAA,IAAI,CAAC,UAAA,EAAY,MAAM,IAAI,kBAAA,CAAmB,kDAAkD,IAAI,CAAA;AAEpG,IAAA,MAAM,YAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,OAAO,CAAA,IAAK,MAAA,CAAO,QAAQ,GAAA,CAAI,SAAA,IAAa,EAAE,CAAA,EAAG;AAClE,MAAA,MAAM,KAAA,GAAQ,CAAA,EAAG,IAAI,CAAA,WAAA,EAAc,KAAK,CAAA,CAAA;AACxC,MAAA,IAAI,CAAC,SAAS,OAAO,CAAA,QAAS,IAAI,kBAAA,CAAmB,8BAA8B,KAAK,CAAA;AACxF,MAAA,MAAM,IAAA,GAAO,OAAA;AACb,MAAA,IAAI,CAAC,CAAC,WAAA,EAAa,SAAA,EAAW,YAAY,CAAA,CAAE,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,EAAG;AAC/D,QAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,uBAAA,EAA0B,IAAA,CAAK,IAAI,KAAK,KAAK,CAAA;AAAA,MAC5E;AACA,MAAA,IAAI,OAAO,KAAK,MAAA,KAAW,QAAA,QAAgB,IAAI,kBAAA,CAAmB,6BAA6B,KAAK,CAAA;AACpG,MAAA,SAAA,CAAU,KAAK,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,OAAO,CAAA;AAAA,IACzC;AAEA,IAAA,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,EAAO,GAAA,CAAI,SAAS,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,SAAA,EAAW,CAAA;AAAA,EACjF;AAGA,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,QAAA,CAAS,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AACjD,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,KAAA,MAAW,CAAA,IAAK,EAAE,SAAA,EAAW;AAC3B,MAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,EAAG;AACxB,QAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,iBAAA,EAAoB,CAAA,CAAE,MAAM,CAAA,yBAAA,CAAA,EAA6B,CAAA,WAAA,EAAc,CAAA,CAAE,IAAI,CAAA,WAAA,EAAc,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAAA,MAClI;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,OAAA,EAAS,QAAA,EAAU,QAAS,GAAA,CAAI,MAAA,IAAwB,EAAC,EAAE;AACtE;AAGO,SAAS,aAAa,IAAA,EAA6B;AACxD,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AAAE,IAAA,GAAA,GAAM,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EAAG,SAAS,KAAA,EAAO;AAC5C,IAAA,MAAM,IAAI,kBAAA,CAAmB,cAAA,EAAgB,GAAG,CAAA;AAAA,EAClD;AACA,EAAA,OAAO,SAAS,GAAG,CAAA;AACrB;AAEA,SAAS,SAAS,CAAA,EAA0C;AAC1D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE","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"]}