graphddb 0.8.1 → 0.9.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/behaviors-DDltNivc.d.ts +217 -0
- package/dist/cdc/index.d.ts +5 -4
- package/dist/cdc/index.js +3 -3
- package/dist/{chunk-HNY2EJPV.js → chunk-KOIJ4SNO.js} +1 -1
- package/dist/{chunk-S2NI4PBW.js → chunk-NWTEUWJD.js} +7 -5
- package/dist/{chunk-LAT64YCZ.js → chunk-SSVG6NQK.js} +657 -18
- package/dist/{chunk-L4QRCHRQ.js → chunk-WOFRHRXY.js} +6 -25
- package/dist/{chunk-T44OB5GU.js → chunk-XZTA4VJH.js} +23 -7
- package/dist/{chunk-GS4C5VGO.js → chunk-YGQ2NO6J.js} +2 -2
- package/dist/{chunk-L2NEDS7U.js → chunk-ZNU7OI5I.js} +241 -8
- package/dist/cli.js +366 -80
- package/dist/index.d.ts +131 -5
- package/dist/index.js +121 -5
- package/dist/internal/index.d.ts +6 -5
- package/dist/internal/index.js +7 -7
- package/dist/{key-DZtjAQDh.d.ts → key-Dne-a20Q.d.ts} +40 -5
- package/dist/linter/index.d.ts +6 -5
- package/dist/{linter-DQY7gUEk.d.ts → linter-Cr1Hnw7n.d.ts} +1 -1
- package/dist/{prepared-artifact-HFealr1q.d.ts → prepared-artifact-BXkARxwO.d.ts} +4 -4
- package/dist/spec/index.d.ts +225 -24
- package/dist/spec/index.js +17 -9
- package/dist/testing/index.d.ts +3 -2
- package/dist/testing/index.js +3 -3
- package/dist/transform/index.d.ts +2 -1
- package/dist/transform/index.js +2 -2
- package/dist/{types-DW__-Icc.d.ts → types-BnFsTZwl.d.ts} +1 -1
- package/dist/{types-2PMXEn5x.d.ts → types-CfxzTEFL.d.ts} +262 -20
- package/docs/python-bridge.md +33 -49
- package/package.json +11 -3
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
buildBridgeBundle,
|
|
4
|
-
buildOperations
|
|
5
|
-
|
|
4
|
+
buildOperations,
|
|
5
|
+
portableIrDocument,
|
|
6
|
+
renderKeyExprToTemplate
|
|
7
|
+
} from "./chunk-SSVG6NQK.js";
|
|
6
8
|
import {
|
|
7
9
|
buildManifest
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-NWTEUWJD.js";
|
|
11
|
+
import "./chunk-XZTA4VJH.js";
|
|
12
|
+
import "./chunk-KOIJ4SNO.js";
|
|
13
|
+
import "./chunk-WOFRHRXY.js";
|
|
12
14
|
import {
|
|
13
15
|
MetadataRegistry
|
|
14
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ZNU7OI5I.js";
|
|
15
17
|
import {
|
|
16
18
|
createDefaultLinter
|
|
17
19
|
} from "./chunk-XTWXMOHD.js";
|
|
@@ -540,6 +542,92 @@ var commandDefinitions = {
|
|
|
540
542
|
}
|
|
541
543
|
]
|
|
542
544
|
},
|
|
545
|
+
"generate.behaviors": {
|
|
546
|
+
"effects": {
|
|
547
|
+
"risk_level": "low",
|
|
548
|
+
"reads": [
|
|
549
|
+
"ts-definitions"
|
|
550
|
+
],
|
|
551
|
+
"writes": [
|
|
552
|
+
"generated-code"
|
|
553
|
+
]
|
|
554
|
+
},
|
|
555
|
+
"options": [
|
|
556
|
+
{
|
|
557
|
+
"name": "lang",
|
|
558
|
+
"schema": {
|
|
559
|
+
"type": "string",
|
|
560
|
+
"enum": [
|
|
561
|
+
"ts",
|
|
562
|
+
"python",
|
|
563
|
+
"go",
|
|
564
|
+
"rust",
|
|
565
|
+
"php"
|
|
566
|
+
]
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
"name": "entry",
|
|
571
|
+
"schema": {
|
|
572
|
+
"type": "string"
|
|
573
|
+
},
|
|
574
|
+
"file": {
|
|
575
|
+
"mode": "read",
|
|
576
|
+
"exists": true,
|
|
577
|
+
"media_type": "application/typescript",
|
|
578
|
+
"encoding": "utf-8"
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
"name": "transactions",
|
|
583
|
+
"schema": {
|
|
584
|
+
"type": "string"
|
|
585
|
+
},
|
|
586
|
+
"file": {
|
|
587
|
+
"mode": "read",
|
|
588
|
+
"exists": true,
|
|
589
|
+
"media_type": "application/typescript",
|
|
590
|
+
"encoding": "utf-8"
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
"name": "contracts",
|
|
595
|
+
"schema": {
|
|
596
|
+
"type": "string"
|
|
597
|
+
},
|
|
598
|
+
"file": {
|
|
599
|
+
"mode": "read",
|
|
600
|
+
"exists": true,
|
|
601
|
+
"media_type": "application/typescript",
|
|
602
|
+
"encoding": "utf-8"
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
"name": "contexts",
|
|
607
|
+
"schema": {
|
|
608
|
+
"type": "string"
|
|
609
|
+
},
|
|
610
|
+
"file": {
|
|
611
|
+
"mode": "read",
|
|
612
|
+
"exists": true,
|
|
613
|
+
"media_type": "application/typescript",
|
|
614
|
+
"encoding": "utf-8"
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
"name": "runtime-import",
|
|
619
|
+
"schema": {
|
|
620
|
+
"type": "string"
|
|
621
|
+
}
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
"name": "out",
|
|
625
|
+
"schema": {
|
|
626
|
+
"type": "string"
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
]
|
|
630
|
+
},
|
|
543
631
|
"generate.cloudformation": {
|
|
544
632
|
"effects": {
|
|
545
633
|
"risk_level": "low",
|
|
@@ -851,8 +939,8 @@ function deriveCommandPolicy(command_id, optionValues) {
|
|
|
851
939
|
}
|
|
852
940
|
|
|
853
941
|
// src/generated/contract.ts
|
|
854
|
-
var CONTRACT_YAML = "cli_contracts: 0.1.0\n\ninfo:\n title: GraphDDB CLI\n version: 0.1.0\n description: >-\n Contract for the graphddb code-generation CLI. The CLI reads TypeScript\n GraphDDB model + CQRS contract definitions (the single source of truth)\n and emits Python bindings (manifest.json, operations.json, types.py,\n repositories.py, __init__.py) for the Python bridge runtime.\n license:\n name: MIT\n contact:\n name: foo-log-inc\n url: https://github.com/foo-log-inc/graphddb\n\nartifact_slots:\n ts-definitions:\n description: >-\n TypeScript GraphDDB definition modules (entity models + the CQRS\n publishQuery / publishCommand contracts) used as the single source of truth.\n direction: read\n generated-code:\n description: >-\n Generated Python bindings and JSON specs written to the output directory\n (manifest.json, operations.json, types.py, repositories.py, __init__.py).\n direction: write\n ts-app-sources:\n description: >-\n Application TypeScript sources containing `DDBModel.prepare` call sites.\n Read by the prepared-statement build lint; rewritten in place by\n `transform prepared --write` (hoist normalization, issue #206).\n direction: write\n\ncommand_sets:\n graphddb:\n summary: Graph data modeling on DynamoDB \u2014 code generation CLI.\n x-stdin: >-\n No command reads from stdin. All inputs are provided via file options.\n\n commands:\n # \u2500\u2500 generate python \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.python:\n summary: Generate Python bindings from TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes the Python bridge bindings (manifest.json, operations.json,\n types.py, repositories.py, __init__.py) to the output directory.\n Output is deterministic for a given set of inputs.\n usage:\n - graphddb generate python --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate python --entry definitions.ts --out generated/\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (a map of publishQuery /\n publishCommand results \u2014 the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 a project with no\n contracts omits it, and the output gains no `contracts` content.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership: context name \u2192 the\n Model / Contract names that belong to it). Defaults to the\n contracts module (or the entry module) when omitted. Optional \u2014\n consumed by the boundary lint to tell own from foreign.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: dataclass\n description: >-\n Emit Python result / element types as @dataclass classes instead\n of TypedDict (decimal / Optional / Connection mapped accordingly).\n schema:\n type: boolean\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Python bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n files:\n - path: '{options.out}/manifest.json'\n required: true\n media_type: application/json\n description: Entity / table / key / relation metadata.\n - path: '{options.out}/operations.json'\n required: true\n media_type: application/json\n description: Per-query / per-command execution specs.\n - path: '{options.out}/types.py'\n required: true\n media_type: text/x-python\n description: TypedDict result types derived from query selects.\n - path: '{options.out}/repositories.py'\n required: true\n media_type: text/x-python\n description: Per-entity repository classes (sync methods).\n - path: '{options.out}/__init__.py'\n required: true\n media_type: text/x-python\n description: Package re-exports for the generated bindings.\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate php \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.php:\n summary: >-\n Generate typed PHP bindings (repositories + result DTOs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes typed PHP bindings \u2014 one `<Entity>Repository` per entity plus a\n result DTO (and `<Item>Connection`) per query result shape \u2014 into the\n output directory. Each repository wraps the PHP `GraphDDBRuntime`; query\n methods return a hydrated `?<Result>` typed object, command methods\n return void, both calling the runtime by the original operation id. The\n layout is defined by bundled Handlebars templates users can override\n with --template-dir (per-partial) and extend with --helpers; type\n resolution always lives in code (the templates customize layout, not\n types). Output is deterministic for a given set of inputs. The `--typed`\n flag selects the typed-binding output (the only mode today; reserved for\n a future raw-binding mode).\n usage:\n - graphddb generate php --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate php --typed --entry definitions.ts --out generated/\n - graphddb generate php --typed --entry definitions.ts --out generated/ --template-dir php-templates/ --helpers php-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result DTOs). The only\n output mode today; reserved to distinguish a future raw-binding mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / dto-class / connection-class / repo-class /\n repo-method / tx-class / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated PHP bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate rust \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.rust:\n summary: >-\n Generate typed Rust bindings (repositories + serde result structs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes a single `bindings.rs` module of typed Rust bindings \u2014 a\n serde-`Deserialize` result struct (and `<Item>Connection`) per query\n result shape plus one `<Entity>Repository` per entity \u2014 into the output\n directory. Each repository holds an `Arc<GraphDDBRuntime>`; query methods\n return `Result<Option<T>, GraphDDBError>` (the deserialized typed\n result), command methods return `Result<(), GraphDDBError>`, both calling\n the runtime by the original operation id. The layout is defined by\n bundled Handlebars templates users can override with --template-dir\n (per-partial) and extend with --helpers; type resolution always lives in\n code (the templates customize layout, not types). Output is deterministic\n for a given set of inputs. The `--typed` flag selects the typed-binding\n output (the only mode today; reserved for a future raw-binding mode).\n usage:\n - graphddb generate rust --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate rust --typed --entry definitions.ts --out generated/\n - graphddb generate rust --typed --entry definitions.ts --out generated/ --template-dir rust-templates/ --helpers rust-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result structs). The\n only output mode today; reserved to distinguish a future raw-binding\n mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / result-struct / connection-struct / repo-struct /\n repo-method / tx-struct / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Rust bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate go \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.go:\n summary: >-\n Generate typed Go bindings (repositories + json result structs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes a single `bindings.go` package of typed Go bindings \u2014 a json result\n struct (and `<Item>Connection`) per query result shape plus one\n `<Entity>Repository` per entity \u2014 into the output directory. Each\n repository holds a `*graphddb_runtime.GraphDDBRuntime`; query methods\n return `(*T, error)` (the deserialized typed result; a nil pointer for no\n match), command methods return `error`, both calling the runtime by the\n original operation id. Numbers are precision-strict (`json.Number`), so a\n large integer round-trips losslessly. The layout is defined by bundled\n Handlebars templates users can override with --template-dir (per-partial)\n and extend with --helpers; type resolution always lives in code (the\n templates customize layout, not types). Output is deterministic for a\n given set of inputs and gofmt-normalized. The `--typed` flag selects the\n typed-binding output (the only mode today; reserved for a future\n raw-binding mode).\n usage:\n - graphddb generate go --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate go --typed --entry definitions.ts --out generated/\n - graphddb generate go --typed --entry definitions.ts --out generated/ --template-dir go-templates/ --helpers go-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result structs). The\n only output mode today; reserved to distinguish a future raw-binding\n mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / result-struct / connection-struct / repo-struct /\n repo-method / tx-struct / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Go bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate cloudformation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.cloudformation:\n summary: >-\n Generate an AWS CloudFormation template (DynamoDB table + GSIs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and builds the serializable\n manifest, then emits an AWS CloudFormation template describing the\n DynamoDB table(s) the single-table design maps onto: one\n `AWS::DynamoDB::Table` per physical table, with the base key schema\n (`PK` / `SK`), the unioned Global Secondary Indexes\n (`<indexName>PK` / `<indexName>SK`), `PAY_PER_REQUEST` billing, a\n `TableName` parameter (default = physical name), and Outputs\n (table name + ARN). Output is deterministic and, by default, YAML.\n usage:\n - graphddb generate cloudformation --entry models.ts --out table.yaml\n - graphddb generate cloudformation --entry models.ts --format json\n - graphddb generate cloudformation --entry models.ts --gsi-projection KEYS_ONLY --out table.yaml\n - graphddb generate cloudformation --entry models.ts --stream on --out table.yaml\n - graphddb generate cloudformation --entry models.ts --pitr --sse --table-class STANDARD_INFREQUENT_ACCESS --out table.yaml\n - graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --rcu 10 --wcu 5 --out table.yaml\n - graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --autoscale --autoscale-min 5 --autoscale-max 100 --autoscale-target 70 --out table.yaml\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import).\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: out\n aliases: [o]\n description: >-\n Output file for the generated CloudFormation template. Written to\n stdout when omitted.\n value_name: file\n schema:\n type: string\n\n - name: format\n aliases: [f]\n description: Output serialization format (yaml or json).\n value_name: format\n schema:\n type: string\n enum: [yaml, json]\n default: yaml\n\n - name: gsi-projection\n description: >-\n GSI ProjectionType. ALL (default) projects every attribute;\n KEYS_ONLY projects only the key attributes.\n value_name: projection\n schema:\n type: string\n enum: [ALL, KEYS_ONLY]\n default: ALL\n\n - name: stream\n description: >-\n DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission.\n auto (default) emits a stream only when the model set uses\n stream-based maintenance (updateMode:'stream'); on always emits;\n off never emits. When enabled, a StreamArn Output is added too.\n value_name: mode\n schema:\n type: string\n enum: [auto, on, off]\n default: auto\n\n - name: billing-mode\n description: >-\n DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand\n (no provisioned throughput). PROVISIONED emits BillingMode:\n PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the\n table and every GSI, and unlocks Application Auto Scaling\n (--autoscale).\n value_name: mode\n schema:\n type: string\n enum: [PAY_PER_REQUEST, PROVISIONED]\n default: PAY_PER_REQUEST\n\n - name: rcu\n description: >-\n Provisioned ReadCapacityUnits (a positive integer) applied to the\n table and every GSI. Only valid with --billing-mode PROVISIONED\n (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: wcu\n description: >-\n Provisioned WriteCapacityUnits (a positive integer) applied to the\n table and every GSI. Only valid with --billing-mode PROVISIONED\n (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale\n description: >-\n Enable Application Auto Scaling. Emits an\n AWS::ApplicationAutoScaling::ScalableTarget +\n AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read\n and write capacity AND for each GSI read and write capacity. Only\n valid with --billing-mode PROVISIONED (autoscaling is invalid on\n on-demand and is rejected). Off by default \u2014 no autoscaling\n resources are emitted unless this flag is passed.\n schema:\n type: boolean\n\n - name: autoscale-min\n description: >-\n Auto Scaling minimum capacity (MinCapacity) for every scalable\n target. Must be <= --autoscale-max. Only meaningful with\n --autoscale. Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale-max\n description: >-\n Auto Scaling maximum capacity (MaxCapacity) for every scalable\n target. Must be >= --autoscale-min. Only meaningful with\n --autoscale. Defaults to 100 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale-target\n description: >-\n Auto Scaling target utilization percentage (TargetValue of the\n TargetTrackingScaling policy). Only meaningful with --autoscale.\n Defaults to 70 when omitted.\n value_name: percent\n schema:\n type: integer\n minimum: 1\n maximum: 100\n\n - name: pitr\n description: >-\n Enable point-in-time recovery (PointInTimeRecoverySpecification\n PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is\n omitted entirely unless this flag is passed.\n schema:\n type: boolean\n\n - name: table-class\n description: >-\n DynamoDB table class. Omitted by default (AWS defaults to\n STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit\n TableClass.\n value_name: class\n schema:\n type: string\n enum: [STANDARD, STANDARD_INFREQUENT_ACCESS]\n\n - name: sse\n description: >-\n Enable server-side encryption with the AWS-owned/managed key\n (SSESpecification SSEEnabled:true). Off by default \u2014 the property is\n omitted entirely unless this flag is passed.\n schema:\n type: boolean\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate docs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.docs:\n summary: >-\n Generate model-specification documentation (Markdown + Mermaid) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models (and, optionally, the CQRS contract\n definitions), builds the serializable manifest / operations bundle, then\n renders human-facing model documentation \u2014 Table Overview, Entity\n Relationship Diagram, Physical Key Schema, Property Matrix, Entity\n Details, Access Patterns, Mutation Contracts, Maintained Access Paths,\n CDC, and CloudFormation summary \u2014 as Markdown with Mermaid diagrams. The\n layout is defined by bundled Handlebars templates users can override with\n --template-dir (per-partial) and extend with --helpers. Output is\n deterministic for a given set of inputs.\n usage:\n - graphddb generate docs --entry models.ts --out doc.md\n - graphddb generate docs --entry models.ts --contracts contracts.ts --out doc.md\n - graphddb generate docs --entry models.ts --out docs/\n - graphddb generate docs --entry models.ts --out docs/ --template-dir doc-templates/ --helpers doc-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (a map of publishQuery /\n publishCommand results \u2014 the CQRS Contract layer) used for the\n Access Patterns / Mutation Contracts sections. Defaults to the\n entry module when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: out\n aliases: [o]\n required: true\n description: >-\n Output path for the generated documentation. A file path ending in\n .md writes the single Markdown file at exactly that path (creating\n parent directories); any other value is treated as a directory and\n the file is written as <dir>/index.md.\n value_name: path\n schema:\n type: string\n\n - name: format\n aliases: [f]\n description: Output format. Only markdown is supported today.\n value_name: format\n schema:\n type: string\n enum: [markdown]\n default: markdown\n\n - name: split\n description: >-\n Output granularity. none (default) emits a single index.md; entity\n is reserved for a future per-entity split.\n value_name: mode\n schema:\n type: string\n enum: [none, entity]\n default: none\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (index / table-overview / er-diagram / key-schema /\n property-matrix / entity / access-pattern / maintained / cdc /\n cloudformation) overrides the bundled one; absent partials fall back\n to the bundled default.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of extra\n Handlebars helpers to register alongside the built-in set (eq / join\n / pascal / mermaidId / codeOrEmpty).\n value_name: file\n schema:\n type: string\n\n - name: billing-mode\n description: >-\n DynamoDB billing mode used in the Table Overview (shared with\n generate cloudformation). PAY_PER_REQUEST (default) or PROVISIONED.\n value_name: mode\n schema:\n type: string\n enum: [PAY_PER_REQUEST, PROVISIONED]\n default: PAY_PER_REQUEST\n\n - name: stream\n description: >-\n DynamoDB Streams state used in the Table Overview (shared with\n generate cloudformation). auto (default) detects stream-based\n maintenance (updateMode:'stream'); on always enabled; off never.\n value_name: mode\n schema:\n type: string\n enum: [auto, on, off]\n default: auto\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 transform prepared \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n transform.prepared:\n summary: >-\n Lint and hoist-normalize `DDBModel.prepare` call sites (compile-time\n prepared statements, issue #206).\n description: >-\n A source-to-source build pass over application TypeScript files. It\n statically enforces the prepared-statement no-runtime-capture rule\n (a prepare body may reference only its `$` placeholder and\n module-static bindings; capturing a per-call runtime value \u2014 directly\n or via a helper call \u2014 is a loud error), and normalizes every\n verified INLINE `DDBModel.prepare(fn)` call site into a module-scope\n prepared slot so the plan compiles once per module and each call is\n a plain `.execute` (zero per-op planning / hashing \u2014 placement\n independent). Without --write it is a pure check (the build lint):\n violations exit non-zero and hoistable inline call sites are\n reported as notes. With --write, verified inline call sites are\n rewritten in place; files with violations are never rewritten.\n Idempotent: re-running on transformed output changes nothing.\n With --aot <artifact> (issue #208), the pass additionally compiles\n every verified prepare body at BUILD time into a static prepared-plan\n artifact (a generated TypeScript module): with --write it writes the\n artifact and rewrites each call site to load its static plan\n (`loadPreparedPlan(document, id, body)` \u2014 the body stays in source as\n the plan's compile source and fallback); without --write it is the\n DRIFT CHECK \u2014 it recompiles every plan and exits non-zero when the\n artifact is missing or differs (CI gate: model declarations changed\n without regenerating the artifact).\n usage:\n - graphddb transform prepared --src src/\n - graphddb transform prepared --src src/ --write\n - graphddb transform prepared --src src/app/handlers.ts --write\n - graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts --write\n - graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts\n\n effects:\n risk_level: medium\n reads:\n - ts-app-sources\n writes:\n - ts-app-sources\n\n x-agent:\n recommended_before_use:\n - \"Commit or stash pending changes first when using --write (it rewrites sources in place).\"\n\n options:\n - name: src\n aliases: [s]\n required: true\n description: >-\n A TypeScript source file, or a directory scanned recursively for\n .ts/.tsx/.mts/.cts files (node_modules, dist, hidden directories,\n and .d.ts files are skipped).\n value_name: path\n schema:\n type: string\n file:\n mode: read\n exists: true\n\n - name: write\n aliases: [w]\n description: >-\n Rewrite verified inline call sites in place (hoist\n normalization). Without it the command only checks and reports.\n schema:\n type: boolean\n\n - name: aot\n aliases: [a]\n description: >-\n Static prepared-plan artifact module path (issue #208). Enables\n build-time (AOT) compilation of every verified prepare body:\n with --write the artifact module is (re)generated and call sites\n are rewritten to load their static plan; without --write the\n pass recompiles and compares (drift check \u2014 a missing or\n differing artifact exits 1).\n value_name: artifact\n schema:\n type: string\n\n exits:\n '0':\n description: >-\n Check passed / transform applied. No no-runtime-capture\n violations were found.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/TransformPreparedResult'\n\n '1':\n description: >-\n No-runtime-capture violations found, or --aot drift detected\n (reported in the result on stdout), or an unexpected error\n (reported on stderr).\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/TransformPreparedResult'\n\n '2':\n description: Invalid arguments (missing/unreadable input).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\ncomponents:\n schemas:\n GenerateResult:\n type: object\n required: [status, outDir, files]\n properties:\n status:\n type: string\n enum: [ok]\n outDir:\n type: string\n description: Output directory the files were written to.\n files:\n type: array\n description: Paths of the generated files (relative to outDir).\n items:\n type: string\n Error:\n type: object\n required: [code, message]\n properties:\n code:\n type: string\n message:\n type: string\n TransformPreparedResult:\n type: object\n required: [status, files, hoisted, moduleScope, alreadyHoisted, errors, diagnostics]\n properties:\n status:\n type: string\n enum: [ok, violations, drift]\n files:\n type: array\n description: Source files scanned.\n items:\n type: string\n changedFiles:\n type: array\n description: Files rewritten in place (--write only).\n items:\n type: string\n hoisted:\n type: integer\n description: Inline call sites normalized (or normalizable in check mode).\n moduleScope:\n type: integer\n description: Call sites already evaluated once per module load (left as-is).\n alreadyHoisted:\n type: integer\n description: Call sites already normalized by a previous run.\n errors:\n type: integer\n description: No-runtime-capture violations found.\n artifact:\n type: string\n description: The static prepared-plan artifact path (--aot only).\n plans:\n type: integer\n description: Prepared plans compiled into the artifact (--aot only).\n drift:\n type: object\n description: >-\n Artifact drift detail (--aot check mode only; present when status\n is drift).\n properties:\n missing:\n type: boolean\n description: The artifact module does not exist.\n added:\n type: array\n items:\n type: string\n removed:\n type: array\n items:\n type: string\n changed:\n type: array\n items:\n type: string\n diagnostics:\n type: array\n description: Per-position lint diagnostics (errors and notes).\n items:\n type: object\n required: [code, category, message, file, line, column]\n properties:\n code:\n type: string\n category:\n type: string\n enum: [error, note]\n message:\n type: string\n file:\n type: string\n line:\n type: integer\n column:\n type: integer\n";
|
|
855
|
-
var CONTRACT_JSON_STR = '{\n "cli_contracts": "0.1.0",\n "info": {\n "title": "GraphDDB CLI",\n "version": "0.1.0",\n "description": "Contract for the graphddb code-generation CLI. The CLI reads TypeScript GraphDDB model + CQRS contract definitions (the single source of truth) and emits Python bindings (manifest.json, operations.json, types.py, repositories.py, __init__.py) for the Python bridge runtime.",\n "license": {\n "name": "MIT"\n },\n "contact": {\n "name": "foo-log-inc",\n "url": "https://github.com/foo-log-inc/graphddb"\n }\n },\n "artifact_slots": {\n "ts-definitions": {\n "description": "TypeScript GraphDDB definition modules (entity models + the CQRS publishQuery / publishCommand contracts) used as the single source of truth.",\n "direction": "read"\n },\n "generated-code": {\n "description": "Generated Python bindings and JSON specs written to the output directory (manifest.json, operations.json, types.py, repositories.py, __init__.py).",\n "direction": "write"\n },\n "ts-app-sources": {\n "description": "Application TypeScript sources containing `DDBModel.prepare` call sites. Read by the prepared-statement build lint; rewritten in place by `transform prepared --write` (hoist normalization, issue #206).",\n "direction": "write"\n }\n },\n "command_sets": {\n "graphddb": {\n "summary": "Graph data modeling on DynamoDB \u2014 code generation CLI.",\n "x-stdin": "No command reads from stdin. All inputs are provided via file options.",\n "commands": {\n "generate.python": {\n "summary": "Generate Python bindings from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes the Python bridge bindings (manifest.json, operations.json, types.py, repositories.py, __init__.py) to the output directory. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate python --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate python --entry definitions.ts --out generated/"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (a map of publishQuery / publishCommand results \u2014 the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 a project with no contracts omits it, and the output gains no `contracts` content.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership: context name \u2192 the Model / Contract names that belong to it). Defaults to the contracts module (or the entry module) when omitted. Optional \u2014 consumed by the boundary lint to tell own from foreign.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "dataclass",\n "description": "Emit Python result / element types as @dataclass classes instead of TypedDict (decimal / Optional / Connection mapped accordingly).",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Python bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n },\n "files": [\n {\n "path": "{options.out}/manifest.json",\n "required": true,\n "media_type": "application/json",\n "description": "Entity / table / key / relation metadata."\n },\n {\n "path": "{options.out}/operations.json",\n "required": true,\n "media_type": "application/json",\n "description": "Per-query / per-command execution specs."\n },\n {\n "path": "{options.out}/types.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "TypedDict result types derived from query selects."\n },\n {\n "path": "{options.out}/repositories.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "Per-entity repository classes (sync methods)."\n },\n {\n "path": "{options.out}/__init__.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "Package re-exports for the generated bindings."\n }\n ]\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.php": {\n "summary": "Generate typed PHP bindings (repositories + result DTOs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes typed PHP bindings \u2014 one `<Entity>Repository` per entity plus a result DTO (and `<Item>Connection`) per query result shape \u2014 into the output directory. Each repository wraps the PHP `GraphDDBRuntime`; query methods return a hydrated `?<Result>` typed object, command methods return void, both calling the runtime by the original operation id. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate php --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate php --typed --entry definitions.ts --out generated/",\n "graphddb generate php --typed --entry definitions.ts --out generated/ --template-dir php-templates/ --helpers php-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result DTOs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / dto-class / connection-class / repo-class / repo-method / tx-class / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated PHP bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.rust": {\n "summary": "Generate typed Rust bindings (repositories + serde result structs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes a single `bindings.rs` module of typed Rust bindings \u2014 a serde-`Deserialize` result struct (and `<Item>Connection`) per query result shape plus one `<Entity>Repository` per entity \u2014 into the output directory. Each repository holds an `Arc<GraphDDBRuntime>`; query methods return `Result<Option<T>, GraphDDBError>` (the deserialized typed result), command methods return `Result<(), GraphDDBError>`, both calling the runtime by the original operation id. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate rust --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate rust --typed --entry definitions.ts --out generated/",\n "graphddb generate rust --typed --entry definitions.ts --out generated/ --template-dir rust-templates/ --helpers rust-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result structs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / result-struct / connection-struct / repo-struct / repo-method / tx-struct / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Rust bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.go": {\n "summary": "Generate typed Go bindings (repositories + json result structs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes a single `bindings.go` package of typed Go bindings \u2014 a json result struct (and `<Item>Connection`) per query result shape plus one `<Entity>Repository` per entity \u2014 into the output directory. Each repository holds a `*graphddb_runtime.GraphDDBRuntime`; query methods return `(*T, error)` (the deserialized typed result; a nil pointer for no match), command methods return `error`, both calling the runtime by the original operation id. Numbers are precision-strict (`json.Number`), so a large integer round-trips losslessly. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs and gofmt-normalized. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate go --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate go --typed --entry definitions.ts --out generated/",\n "graphddb generate go --typed --entry definitions.ts --out generated/ --template-dir go-templates/ --helpers go-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result structs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / result-struct / connection-struct / repo-struct / repo-method / tx-struct / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Go bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.cloudformation": {\n "summary": "Generate an AWS CloudFormation template (DynamoDB table + GSIs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and builds the serializable manifest, then emits an AWS CloudFormation template describing the DynamoDB table(s) the single-table design maps onto: one `AWS::DynamoDB::Table` per physical table, with the base key schema (`PK` / `SK`), the unioned Global Secondary Indexes (`<indexName>PK` / `<indexName>SK`), `PAY_PER_REQUEST` billing, a `TableName` parameter (default = physical name), and Outputs (table name + ARN). Output is deterministic and, by default, YAML.",\n "usage": [\n "graphddb generate cloudformation --entry models.ts --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --format json",\n "graphddb generate cloudformation --entry models.ts --gsi-projection KEYS_ONLY --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --stream on --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --pitr --sse --table-class STANDARD_INFREQUENT_ACCESS --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --rcu 10 --wcu 5 --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --autoscale --autoscale-min 5 --autoscale-max 100 --autoscale-target 70 --out table.yaml"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import).",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "description": "Output file for the generated CloudFormation template. Written to stdout when omitted.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "format",\n "aliases": [\n "f"\n ],\n "description": "Output serialization format (yaml or json).",\n "value_name": "format",\n "schema": {\n "type": "string",\n "enum": [\n "yaml",\n "json"\n ],\n "default": "yaml"\n }\n },\n {\n "name": "gsi-projection",\n "description": "GSI ProjectionType. ALL (default) projects every attribute; KEYS_ONLY projects only the key attributes.",\n "value_name": "projection",\n "schema": {\n "type": "string",\n "enum": [\n "ALL",\n "KEYS_ONLY"\n ],\n "default": "ALL"\n }\n },\n {\n "name": "stream",\n "description": "DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission. auto (default) emits a stream only when the model set uses stream-based maintenance (updateMode:\'stream\'); on always emits; off never emits. When enabled, a StreamArn Output is added too.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "auto",\n "on",\n "off"\n ],\n "default": "auto"\n }\n },\n {\n "name": "billing-mode",\n "description": "DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand (no provisioned throughput). PROVISIONED emits BillingMode: PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the table and every GSI, and unlocks Application Auto Scaling (--autoscale).",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "PAY_PER_REQUEST",\n "PROVISIONED"\n ],\n "default": "PAY_PER_REQUEST"\n }\n },\n {\n "name": "rcu",\n "description": "Provisioned ReadCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "wcu",\n "description": "Provisioned WriteCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale",\n "description": "Enable Application Auto Scaling. Emits an AWS::ApplicationAutoScaling::ScalableTarget + AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read and write capacity AND for each GSI read and write capacity. Only valid with --billing-mode PROVISIONED (autoscaling is invalid on on-demand and is rejected). Off by default \u2014 no autoscaling resources are emitted unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "autoscale-min",\n "description": "Auto Scaling minimum capacity (MinCapacity) for every scalable target. Must be <= --autoscale-max. Only meaningful with --autoscale. Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale-max",\n "description": "Auto Scaling maximum capacity (MaxCapacity) for every scalable target. Must be >= --autoscale-min. Only meaningful with --autoscale. Defaults to 100 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale-target",\n "description": "Auto Scaling target utilization percentage (TargetValue of the TargetTrackingScaling policy). Only meaningful with --autoscale. Defaults to 70 when omitted.",\n "value_name": "percent",\n "schema": {\n "type": "integer",\n "minimum": 1,\n "maximum": 100\n }\n },\n {\n "name": "pitr",\n "description": "Enable point-in-time recovery (PointInTimeRecoverySpecification PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "table-class",\n "description": "DynamoDB table class. Omitted by default (AWS defaults to STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit TableClass.",\n "value_name": "class",\n "schema": {\n "type": "string",\n "enum": [\n "STANDARD",\n "STANDARD_INFREQUENT_ACCESS"\n ]\n }\n },\n {\n "name": "sse",\n "description": "Enable server-side encryption with the AWS-owned/managed key (SSESpecification SSEEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.docs": {\n "summary": "Generate model-specification documentation (Markdown + Mermaid) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models (and, optionally, the CQRS contract definitions), builds the serializable manifest / operations bundle, then renders human-facing model documentation \u2014 Table Overview, Entity Relationship Diagram, Physical Key Schema, Property Matrix, Entity Details, Access Patterns, Mutation Contracts, Maintained Access Paths, CDC, and CloudFormation summary \u2014 as Markdown with Mermaid diagrams. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate docs --entry models.ts --out doc.md",\n "graphddb generate docs --entry models.ts --contracts contracts.ts --out doc.md",\n "graphddb generate docs --entry models.ts --out docs/",\n "graphddb generate docs --entry models.ts --out docs/ --template-dir doc-templates/ --helpers doc-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (a map of publishQuery / publishCommand results \u2014 the CQRS Contract layer) used for the Access Patterns / Mutation Contracts sections. Defaults to the entry module when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output path for the generated documentation. A file path ending in .md writes the single Markdown file at exactly that path (creating parent directories); any other value is treated as a directory and the file is written as <dir>/index.md.",\n "value_name": "path",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "format",\n "aliases": [\n "f"\n ],\n "description": "Output format. Only markdown is supported today.",\n "value_name": "format",\n "schema": {\n "type": "string",\n "enum": [\n "markdown"\n ],\n "default": "markdown"\n }\n },\n {\n "name": "split",\n "description": "Output granularity. none (default) emits a single index.md; entity is reserved for a future per-entity split.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "none",\n "entity"\n ],\n "default": "none"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (index / table-overview / er-diagram / key-schema / property-matrix / entity / access-pattern / maintained / cdc / cloudformation) overrides the bundled one; absent partials fall back to the bundled default.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set (eq / join / pascal / mermaidId / codeOrEmpty).",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "billing-mode",\n "description": "DynamoDB billing mode used in the Table Overview (shared with generate cloudformation). PAY_PER_REQUEST (default) or PROVISIONED.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "PAY_PER_REQUEST",\n "PROVISIONED"\n ],\n "default": "PAY_PER_REQUEST"\n }\n },\n {\n "name": "stream",\n "description": "DynamoDB Streams state used in the Table Overview (shared with generate cloudformation). auto (default) detects stream-based maintenance (updateMode:\'stream\'); on always enabled; off never.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "auto",\n "on",\n "off"\n ],\n "default": "auto"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "transform.prepared": {\n "summary": "Lint and hoist-normalize `DDBModel.prepare` call sites (compile-time prepared statements, issue #206).",\n "description": "A source-to-source build pass over application TypeScript files. It statically enforces the prepared-statement no-runtime-capture rule (a prepare body may reference only its `$` placeholder and module-static bindings; capturing a per-call runtime value \u2014 directly or via a helper call \u2014 is a loud error), and normalizes every verified INLINE `DDBModel.prepare(fn)` call site into a module-scope prepared slot so the plan compiles once per module and each call is a plain `.execute` (zero per-op planning / hashing \u2014 placement independent). Without --write it is a pure check (the build lint): violations exit non-zero and hoistable inline call sites are reported as notes. With --write, verified inline call sites are rewritten in place; files with violations are never rewritten. Idempotent: re-running on transformed output changes nothing. With --aot <artifact> (issue #208), the pass additionally compiles every verified prepare body at BUILD time into a static prepared-plan artifact (a generated TypeScript module): with --write it writes the artifact and rewrites each call site to load its static plan (`loadPreparedPlan(document, id, body)` \u2014 the body stays in source as the plan\'s compile source and fallback); without --write it is the DRIFT CHECK \u2014 it recompiles every plan and exits non-zero when the artifact is missing or differs (CI gate: model declarations changed without regenerating the artifact).",\n "usage": [\n "graphddb transform prepared --src src/",\n "graphddb transform prepared --src src/ --write",\n "graphddb transform prepared --src src/app/handlers.ts --write",\n "graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts --write",\n "graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts"\n ],\n "effects": {\n "risk_level": "medium",\n "reads": [\n "ts-app-sources"\n ],\n "writes": [\n "ts-app-sources"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Commit or stash pending changes first when using --write (it rewrites sources in place)."\n ]\n },\n "options": [\n {\n "name": "src",\n "aliases": [\n "s"\n ],\n "required": true,\n "description": "A TypeScript source file, or a directory scanned recursively for .ts/.tsx/.mts/.cts files (node_modules, dist, hidden directories, and .d.ts files are skipped).",\n "value_name": "path",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true\n }\n },\n {\n "name": "write",\n "aliases": [\n "w"\n ],\n "description": "Rewrite verified inline call sites in place (hoist normalization). Without it the command only checks and reports.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "aot",\n "aliases": [\n "a"\n ],\n "description": "Static prepared-plan artifact module path (issue #208). Enables build-time (AOT) compilation of every verified prepare body: with --write the artifact module is (re)generated and call sites are rewritten to load their static plan; without --write the pass recompiles and compares (drift check \u2014 a missing or differing artifact exits 1).",\n "value_name": "artifact",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Check passed / transform applied. No no-runtime-capture violations were found.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/TransformPreparedResult"\n }\n }\n },\n "1": {\n "description": "No-runtime-capture violations found, or --aot drift detected (reported in the result on stdout), or an unexpected error (reported on stderr).",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/TransformPreparedResult"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n }\n }\n }\n },\n "components": {\n "schemas": {\n "GenerateResult": {\n "type": "object",\n "required": [\n "status",\n "outDir",\n "files"\n ],\n "properties": {\n "status": {\n "type": "string",\n "enum": [\n "ok"\n ]\n },\n "outDir": {\n "type": "string",\n "description": "Output directory the files were written to."\n },\n "files": {\n "type": "array",\n "description": "Paths of the generated files (relative to outDir).",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "Error": {\n "type": "object",\n "required": [\n "code",\n "message"\n ],\n "properties": {\n "code": {\n "type": "string"\n },\n "message": {\n "type": "string"\n }\n }\n },\n "TransformPreparedResult": {\n "type": "object",\n "required": [\n "status",\n "files",\n "hoisted",\n "moduleScope",\n "alreadyHoisted",\n "errors",\n "diagnostics"\n ],\n "properties": {\n "status": {\n "type": "string",\n "enum": [\n "ok",\n "violations",\n "drift"\n ]\n },\n "files": {\n "type": "array",\n "description": "Source files scanned.",\n "items": {\n "type": "string"\n }\n },\n "changedFiles": {\n "type": "array",\n "description": "Files rewritten in place (--write only).",\n "items": {\n "type": "string"\n }\n },\n "hoisted": {\n "type": "integer",\n "description": "Inline call sites normalized (or normalizable in check mode)."\n },\n "moduleScope": {\n "type": "integer",\n "description": "Call sites already evaluated once per module load (left as-is)."\n },\n "alreadyHoisted": {\n "type": "integer",\n "description": "Call sites already normalized by a previous run."\n },\n "errors": {\n "type": "integer",\n "description": "No-runtime-capture violations found."\n },\n "artifact": {\n "type": "string",\n "description": "The static prepared-plan artifact path (--aot only)."\n },\n "plans": {\n "type": "integer",\n "description": "Prepared plans compiled into the artifact (--aot only)."\n },\n "drift": {\n "type": "object",\n "description": "Artifact drift detail (--aot check mode only; present when status is drift).",\n "properties": {\n "missing": {\n "type": "boolean",\n "description": "The artifact module does not exist."\n },\n "added": {\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "removed": {\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "changed": {\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "diagnostics": {\n "type": "array",\n "description": "Per-position lint diagnostics (errors and notes).",\n "items": {\n "type": "object",\n "required": [\n "code",\n "category",\n "message",\n "file",\n "line",\n "column"\n ],\n "properties": {\n "code": {\n "type": "string"\n },\n "category": {\n "type": "string",\n "enum": [\n "error",\n "note"\n ]\n },\n "message": {\n "type": "string"\n },\n "file": {\n "type": "string"\n },\n "line": {\n "type": "integer"\n },\n "column": {\n "type": "integer"\n }\n }\n }\n }\n }\n }\n }\n }\n}';
|
|
942
|
+
var CONTRACT_YAML = "cli_contracts: 0.1.0\n\ninfo:\n title: GraphDDB CLI\n version: 0.1.0\n description: >-\n Contract for the graphddb code-generation CLI. The CLI reads TypeScript\n GraphDDB model + CQRS contract definitions (the single source of truth)\n and emits Python bindings (manifest.json, operations.json, types.py,\n repositories.py, __init__.py) for the Python bridge runtime.\n license:\n name: MIT\n contact:\n name: foo-log-inc\n url: https://github.com/foo-log-inc/graphddb\n\nartifact_slots:\n ts-definitions:\n description: >-\n TypeScript GraphDDB definition modules (entity models + the CQRS\n publishQuery / publishCommand contracts) used as the single source of truth.\n direction: read\n generated-code:\n description: >-\n Generated Python bindings and JSON specs written to the output directory\n (manifest.json, operations.json, types.py, repositories.py, __init__.py).\n direction: write\n ts-app-sources:\n description: >-\n Application TypeScript sources containing `DDBModel.prepare` call sites.\n Read by the prepared-statement build lint; rewritten in place by\n `transform prepared --write` (hoist normalization, issue #206).\n direction: write\n\ncommand_sets:\n graphddb:\n summary: Graph data modeling on DynamoDB \u2014 code generation CLI.\n x-stdin: >-\n No command reads from stdin. All inputs are provided via file options.\n\n commands:\n # \u2500\u2500 generate python \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.python:\n summary: Generate Python bindings from TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes the Python bridge bindings (manifest.json, operations.json,\n types.py, repositories.py, __init__.py) to the output directory.\n Output is deterministic for a given set of inputs.\n usage:\n - graphddb generate python --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate python --entry definitions.ts --out generated/\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (a map of publishQuery /\n publishCommand results \u2014 the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 a project with no\n contracts omits it, and the output gains no `contracts` content.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership: context name \u2192 the\n Model / Contract names that belong to it). Defaults to the\n contracts module (or the entry module) when omitted. Optional \u2014\n consumed by the boundary lint to tell own from foreign.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: dataclass\n description: >-\n Emit Python result / element types as @dataclass classes instead\n of TypedDict (decimal / Optional / Connection mapped accordingly).\n schema:\n type: boolean\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Python bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n files:\n - path: '{options.out}/manifest.json'\n required: true\n media_type: application/json\n description: Entity / table / key / relation metadata.\n - path: '{options.out}/operations.json'\n required: true\n media_type: application/json\n description: Per-query / per-command execution specs.\n - path: '{options.out}/types.py'\n required: true\n media_type: text/x-python\n description: TypedDict result types derived from query selects.\n - path: '{options.out}/repositories.py'\n required: true\n media_type: text/x-python\n description: Per-entity repository classes (sync methods).\n - path: '{options.out}/__init__.py'\n required: true\n media_type: text/x-python\n description: Package re-exports for the generated bindings.\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate php \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.php:\n summary: >-\n Generate typed PHP bindings (repositories + result DTOs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes typed PHP bindings \u2014 one `<Entity>Repository` per entity plus a\n result DTO (and `<Item>Connection`) per query result shape \u2014 into the\n output directory. Each repository wraps the PHP `GraphDDBRuntime`; query\n methods return a hydrated `?<Result>` typed object, command methods\n return void, both calling the runtime by the original operation id. The\n layout is defined by bundled Handlebars templates users can override\n with --template-dir (per-partial) and extend with --helpers; type\n resolution always lives in code (the templates customize layout, not\n types). Output is deterministic for a given set of inputs. The `--typed`\n flag selects the typed-binding output (the only mode today; reserved for\n a future raw-binding mode).\n usage:\n - graphddb generate php --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate php --typed --entry definitions.ts --out generated/\n - graphddb generate php --typed --entry definitions.ts --out generated/ --template-dir php-templates/ --helpers php-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result DTOs). The only\n output mode today; reserved to distinguish a future raw-binding mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / dto-class / connection-class / repo-class /\n repo-method / tx-class / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated PHP bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate rust \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.rust:\n summary: >-\n Generate typed Rust bindings (repositories + serde result structs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes a single `bindings.rs` module of typed Rust bindings \u2014 a\n serde-`Deserialize` result struct (and `<Item>Connection`) per query\n result shape plus one `<Entity>Repository` per entity \u2014 into the output\n directory. Each repository holds an `Arc<GraphDDBRuntime>`; query methods\n return `Result<Option<T>, GraphDDBError>` (the deserialized typed\n result), command methods return `Result<(), GraphDDBError>`, both calling\n the runtime by the original operation id. The layout is defined by\n bundled Handlebars templates users can override with --template-dir\n (per-partial) and extend with --helpers; type resolution always lives in\n code (the templates customize layout, not types). Output is deterministic\n for a given set of inputs. The `--typed` flag selects the typed-binding\n output (the only mode today; reserved for a future raw-binding mode).\n usage:\n - graphddb generate rust --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate rust --typed --entry definitions.ts --out generated/\n - graphddb generate rust --typed --entry definitions.ts --out generated/ --template-dir rust-templates/ --helpers rust-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result structs). The\n only output mode today; reserved to distinguish a future raw-binding\n mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / result-struct / connection-struct / repo-struct /\n repo-method / tx-struct / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Rust bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate go \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.go:\n summary: >-\n Generate typed Go bindings (repositories + json result structs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes a single `bindings.go` package of typed Go bindings \u2014 a json result\n struct (and `<Item>Connection`) per query result shape plus one\n `<Entity>Repository` per entity \u2014 into the output directory. Each\n repository holds a `*graphddb_runtime.GraphDDBRuntime`; query methods\n return `(*T, error)` (the deserialized typed result; a nil pointer for no\n match), command methods return `error`, both calling the runtime by the\n original operation id. Numbers are precision-strict (`json.Number`), so a\n large integer round-trips losslessly. The layout is defined by bundled\n Handlebars templates users can override with --template-dir (per-partial)\n and extend with --helpers; type resolution always lives in code (the\n templates customize layout, not types). Output is deterministic for a\n given set of inputs and gofmt-normalized. The `--typed` flag selects the\n typed-binding output (the only mode today; reserved for a future\n raw-binding mode).\n usage:\n - graphddb generate go --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate go --typed --entry definitions.ts --out generated/\n - graphddb generate go --typed --entry definitions.ts --out generated/ --template-dir go-templates/ --helpers go-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result structs). The\n only output mode today; reserved to distinguish a future raw-binding\n mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / result-struct / connection-struct / repo-struct /\n repo-method / tx-struct / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Go bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate behaviors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.behaviors:\n summary: >-\n Generate a native behavior module (the codegen-static endpoint) via the\n upstream behavior-contracts common Generator.\n description: >-\n Loads the TypeScript entity models and CQRS contract definitions,\n builds the serializable operations bundle, wraps its universal\n components[] into the portable component-graph IR envelope\n ({irVersion, exprVersion, components} \u2014 scp-ir-architecture.md \xA75),\n and hands it to behavior-contracts' common Generator\n (`generateModule`, foo-ogawa/behavior-contracts#13) to emit ONE native\n module for the selected language (issue #257). graphddb adds no\n generation logic: envelope + invoke + file write only. The generated\n module embeds the IR as a native literal with the spec versions and\n the IR fingerprint baked in (fail-closed load-time checks, the #208\n prepared-artifact discipline) and exposes a `bind(handlers)` accessor\n that delegates to the runtime core \u2014 handlers are always injected at\n the boundary by the consuming runtime (the graphddb per-language\n behavior-exec seams). This is the OPT-IN static endpoint (\xA77.3\n endpoint 3); the JSON-dynamic operations.json path remains the\n default and is permanently supported. Output is deterministic for a\n given set of inputs.\n usage:\n - graphddb generate behaviors --lang ts --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate behaviors --lang go --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate behaviors --lang python --entry definitions.ts --out generated/\n - graphddb generate behaviors --lang rust --entry definitions.ts --out generated/ --runtime-import behavior_contracts\n - graphddb generate behaviors --lang php --entry definitions.ts --out generated/\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: lang\n aliases: [l]\n required: true\n description: >-\n Target language of the generated behavior module. `ts` emits a\n typed TypeScript module, `python` a dict-literal module, `go` a\n JNode composite-literal package, `rust` a json!-constructor\n module (requires Rust >= 1.80 \u2014 std::sync::LazyLock), `php` a\n require-scoped module value.\n value_name: lang\n schema:\n type: string\n enum: [ts, python, go, rust, php]\n\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults\n to the entry module when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: runtime-import\n description: >-\n Module specifier the generated module imports the\n behavior-contracts runtime core from. Defaults to the emitter's\n published package name per language \u2014 except `php`, which\n defaults to graphddb's vendored namespace\n (GraphDDB\\Runtime\\BehaviorContracts) so the generated module\n resolves against the PHP runtime this package ships.\n value_name: specifier\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated behavior module.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate cloudformation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.cloudformation:\n summary: >-\n Generate an AWS CloudFormation template (DynamoDB table + GSIs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and builds the serializable\n manifest, then emits an AWS CloudFormation template describing the\n DynamoDB table(s) the single-table design maps onto: one\n `AWS::DynamoDB::Table` per physical table, with the base key schema\n (`PK` / `SK`), the unioned Global Secondary Indexes\n (`<indexName>PK` / `<indexName>SK`), `PAY_PER_REQUEST` billing, a\n `TableName` parameter (default = physical name), and Outputs\n (table name + ARN). Output is deterministic and, by default, YAML.\n usage:\n - graphddb generate cloudformation --entry models.ts --out table.yaml\n - graphddb generate cloudformation --entry models.ts --format json\n - graphddb generate cloudformation --entry models.ts --gsi-projection KEYS_ONLY --out table.yaml\n - graphddb generate cloudformation --entry models.ts --stream on --out table.yaml\n - graphddb generate cloudformation --entry models.ts --pitr --sse --table-class STANDARD_INFREQUENT_ACCESS --out table.yaml\n - graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --rcu 10 --wcu 5 --out table.yaml\n - graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --autoscale --autoscale-min 5 --autoscale-max 100 --autoscale-target 70 --out table.yaml\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import).\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: out\n aliases: [o]\n description: >-\n Output file for the generated CloudFormation template. Written to\n stdout when omitted.\n value_name: file\n schema:\n type: string\n\n - name: format\n aliases: [f]\n description: Output serialization format (yaml or json).\n value_name: format\n schema:\n type: string\n enum: [yaml, json]\n default: yaml\n\n - name: gsi-projection\n description: >-\n GSI ProjectionType. ALL (default) projects every attribute;\n KEYS_ONLY projects only the key attributes.\n value_name: projection\n schema:\n type: string\n enum: [ALL, KEYS_ONLY]\n default: ALL\n\n - name: stream\n description: >-\n DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission.\n auto (default) emits a stream only when the model set uses\n stream-based maintenance (updateMode:'stream'); on always emits;\n off never emits. When enabled, a StreamArn Output is added too.\n value_name: mode\n schema:\n type: string\n enum: [auto, on, off]\n default: auto\n\n - name: billing-mode\n description: >-\n DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand\n (no provisioned throughput). PROVISIONED emits BillingMode:\n PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the\n table and every GSI, and unlocks Application Auto Scaling\n (--autoscale).\n value_name: mode\n schema:\n type: string\n enum: [PAY_PER_REQUEST, PROVISIONED]\n default: PAY_PER_REQUEST\n\n - name: rcu\n description: >-\n Provisioned ReadCapacityUnits (a positive integer) applied to the\n table and every GSI. Only valid with --billing-mode PROVISIONED\n (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: wcu\n description: >-\n Provisioned WriteCapacityUnits (a positive integer) applied to the\n table and every GSI. Only valid with --billing-mode PROVISIONED\n (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale\n description: >-\n Enable Application Auto Scaling. Emits an\n AWS::ApplicationAutoScaling::ScalableTarget +\n AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read\n and write capacity AND for each GSI read and write capacity. Only\n valid with --billing-mode PROVISIONED (autoscaling is invalid on\n on-demand and is rejected). Off by default \u2014 no autoscaling\n resources are emitted unless this flag is passed.\n schema:\n type: boolean\n\n - name: autoscale-min\n description: >-\n Auto Scaling minimum capacity (MinCapacity) for every scalable\n target. Must be <= --autoscale-max. Only meaningful with\n --autoscale. Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale-max\n description: >-\n Auto Scaling maximum capacity (MaxCapacity) for every scalable\n target. Must be >= --autoscale-min. Only meaningful with\n --autoscale. Defaults to 100 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale-target\n description: >-\n Auto Scaling target utilization percentage (TargetValue of the\n TargetTrackingScaling policy). Only meaningful with --autoscale.\n Defaults to 70 when omitted.\n value_name: percent\n schema:\n type: integer\n minimum: 1\n maximum: 100\n\n - name: pitr\n description: >-\n Enable point-in-time recovery (PointInTimeRecoverySpecification\n PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is\n omitted entirely unless this flag is passed.\n schema:\n type: boolean\n\n - name: table-class\n description: >-\n DynamoDB table class. Omitted by default (AWS defaults to\n STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit\n TableClass.\n value_name: class\n schema:\n type: string\n enum: [STANDARD, STANDARD_INFREQUENT_ACCESS]\n\n - name: sse\n description: >-\n Enable server-side encryption with the AWS-owned/managed key\n (SSESpecification SSEEnabled:true). Off by default \u2014 the property is\n omitted entirely unless this flag is passed.\n schema:\n type: boolean\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate docs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.docs:\n summary: >-\n Generate model-specification documentation (Markdown + Mermaid) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models (and, optionally, the CQRS contract\n definitions), builds the serializable manifest / operations bundle, then\n renders human-facing model documentation \u2014 Table Overview, Entity\n Relationship Diagram, Physical Key Schema, Property Matrix, Entity\n Details, Access Patterns, Mutation Contracts, Maintained Access Paths,\n CDC, and CloudFormation summary \u2014 as Markdown with Mermaid diagrams. The\n layout is defined by bundled Handlebars templates users can override with\n --template-dir (per-partial) and extend with --helpers. Output is\n deterministic for a given set of inputs.\n usage:\n - graphddb generate docs --entry models.ts --out doc.md\n - graphddb generate docs --entry models.ts --contracts contracts.ts --out doc.md\n - graphddb generate docs --entry models.ts --out docs/\n - graphddb generate docs --entry models.ts --out docs/ --template-dir doc-templates/ --helpers doc-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (a map of publishQuery /\n publishCommand results \u2014 the CQRS Contract layer) used for the\n Access Patterns / Mutation Contracts sections. Defaults to the\n entry module when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: out\n aliases: [o]\n required: true\n description: >-\n Output path for the generated documentation. A file path ending in\n .md writes the single Markdown file at exactly that path (creating\n parent directories); any other value is treated as a directory and\n the file is written as <dir>/index.md.\n value_name: path\n schema:\n type: string\n\n - name: format\n aliases: [f]\n description: Output format. Only markdown is supported today.\n value_name: format\n schema:\n type: string\n enum: [markdown]\n default: markdown\n\n - name: split\n description: >-\n Output granularity. none (default) emits a single index.md; entity\n is reserved for a future per-entity split.\n value_name: mode\n schema:\n type: string\n enum: [none, entity]\n default: none\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (index / table-overview / er-diagram / key-schema /\n property-matrix / entity / access-pattern / maintained / cdc /\n cloudformation) overrides the bundled one; absent partials fall back\n to the bundled default.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of extra\n Handlebars helpers to register alongside the built-in set (eq / join\n / pascal / mermaidId / codeOrEmpty).\n value_name: file\n schema:\n type: string\n\n - name: billing-mode\n description: >-\n DynamoDB billing mode used in the Table Overview (shared with\n generate cloudformation). PAY_PER_REQUEST (default) or PROVISIONED.\n value_name: mode\n schema:\n type: string\n enum: [PAY_PER_REQUEST, PROVISIONED]\n default: PAY_PER_REQUEST\n\n - name: stream\n description: >-\n DynamoDB Streams state used in the Table Overview (shared with\n generate cloudformation). auto (default) detects stream-based\n maintenance (updateMode:'stream'); on always enabled; off never.\n value_name: mode\n schema:\n type: string\n enum: [auto, on, off]\n default: auto\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 transform prepared \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n transform.prepared:\n summary: >-\n Lint and hoist-normalize `DDBModel.prepare` call sites (compile-time\n prepared statements, issue #206).\n description: >-\n A source-to-source build pass over application TypeScript files. It\n statically enforces the prepared-statement no-runtime-capture rule\n (a prepare body may reference only its `$` placeholder and\n module-static bindings; capturing a per-call runtime value \u2014 directly\n or via a helper call \u2014 is a loud error), and normalizes every\n verified INLINE `DDBModel.prepare(fn)` call site into a module-scope\n prepared slot so the plan compiles once per module and each call is\n a plain `.execute` (zero per-op planning / hashing \u2014 placement\n independent). Without --write it is a pure check (the build lint):\n violations exit non-zero and hoistable inline call sites are\n reported as notes. With --write, verified inline call sites are\n rewritten in place; files with violations are never rewritten.\n Idempotent: re-running on transformed output changes nothing.\n With --aot <artifact> (issue #208), the pass additionally compiles\n every verified prepare body at BUILD time into a static prepared-plan\n artifact (a generated TypeScript module): with --write it writes the\n artifact and rewrites each call site to load its static plan\n (`loadPreparedPlan(document, id, body)` \u2014 the body stays in source as\n the plan's compile source and fallback); without --write it is the\n DRIFT CHECK \u2014 it recompiles every plan and exits non-zero when the\n artifact is missing or differs (CI gate: model declarations changed\n without regenerating the artifact).\n usage:\n - graphddb transform prepared --src src/\n - graphddb transform prepared --src src/ --write\n - graphddb transform prepared --src src/app/handlers.ts --write\n - graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts --write\n - graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts\n\n effects:\n risk_level: medium\n reads:\n - ts-app-sources\n writes:\n - ts-app-sources\n\n x-agent:\n recommended_before_use:\n - \"Commit or stash pending changes first when using --write (it rewrites sources in place).\"\n\n options:\n - name: src\n aliases: [s]\n required: true\n description: >-\n A TypeScript source file, or a directory scanned recursively for\n .ts/.tsx/.mts/.cts files (node_modules, dist, hidden directories,\n and .d.ts files are skipped).\n value_name: path\n schema:\n type: string\n file:\n mode: read\n exists: true\n\n - name: write\n aliases: [w]\n description: >-\n Rewrite verified inline call sites in place (hoist\n normalization). Without it the command only checks and reports.\n schema:\n type: boolean\n\n - name: aot\n aliases: [a]\n description: >-\n Static prepared-plan artifact module path (issue #208). Enables\n build-time (AOT) compilation of every verified prepare body:\n with --write the artifact module is (re)generated and call sites\n are rewritten to load their static plan; without --write the\n pass recompiles and compares (drift check \u2014 a missing or\n differing artifact exits 1).\n value_name: artifact\n schema:\n type: string\n\n exits:\n '0':\n description: >-\n Check passed / transform applied. No no-runtime-capture\n violations were found.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/TransformPreparedResult'\n\n '1':\n description: >-\n No-runtime-capture violations found, or --aot drift detected\n (reported in the result on stdout), or an unexpected error\n (reported on stderr).\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/TransformPreparedResult'\n\n '2':\n description: Invalid arguments (missing/unreadable input).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\ncomponents:\n schemas:\n GenerateResult:\n type: object\n required: [status, outDir, files]\n properties:\n status:\n type: string\n enum: [ok]\n outDir:\n type: string\n description: Output directory the files were written to.\n files:\n type: array\n description: Paths of the generated files (relative to outDir).\n items:\n type: string\n Error:\n type: object\n required: [code, message]\n properties:\n code:\n type: string\n message:\n type: string\n TransformPreparedResult:\n type: object\n required: [status, files, hoisted, moduleScope, alreadyHoisted, errors, diagnostics]\n properties:\n status:\n type: string\n enum: [ok, violations, drift]\n files:\n type: array\n description: Source files scanned.\n items:\n type: string\n changedFiles:\n type: array\n description: Files rewritten in place (--write only).\n items:\n type: string\n hoisted:\n type: integer\n description: Inline call sites normalized (or normalizable in check mode).\n moduleScope:\n type: integer\n description: Call sites already evaluated once per module load (left as-is).\n alreadyHoisted:\n type: integer\n description: Call sites already normalized by a previous run.\n errors:\n type: integer\n description: No-runtime-capture violations found.\n artifact:\n type: string\n description: The static prepared-plan artifact path (--aot only).\n plans:\n type: integer\n description: Prepared plans compiled into the artifact (--aot only).\n drift:\n type: object\n description: >-\n Artifact drift detail (--aot check mode only; present when status\n is drift).\n properties:\n missing:\n type: boolean\n description: The artifact module does not exist.\n added:\n type: array\n items:\n type: string\n removed:\n type: array\n items:\n type: string\n changed:\n type: array\n items:\n type: string\n diagnostics:\n type: array\n description: Per-position lint diagnostics (errors and notes).\n items:\n type: object\n required: [code, category, message, file, line, column]\n properties:\n code:\n type: string\n category:\n type: string\n enum: [error, note]\n message:\n type: string\n file:\n type: string\n line:\n type: integer\n column:\n type: integer\n";
|
|
943
|
+
var CONTRACT_JSON_STR = '{\n "cli_contracts": "0.1.0",\n "info": {\n "title": "GraphDDB CLI",\n "version": "0.1.0",\n "description": "Contract for the graphddb code-generation CLI. The CLI reads TypeScript GraphDDB model + CQRS contract definitions (the single source of truth) and emits Python bindings (manifest.json, operations.json, types.py, repositories.py, __init__.py) for the Python bridge runtime.",\n "license": {\n "name": "MIT"\n },\n "contact": {\n "name": "foo-log-inc",\n "url": "https://github.com/foo-log-inc/graphddb"\n }\n },\n "artifact_slots": {\n "ts-definitions": {\n "description": "TypeScript GraphDDB definition modules (entity models + the CQRS publishQuery / publishCommand contracts) used as the single source of truth.",\n "direction": "read"\n },\n "generated-code": {\n "description": "Generated Python bindings and JSON specs written to the output directory (manifest.json, operations.json, types.py, repositories.py, __init__.py).",\n "direction": "write"\n },\n "ts-app-sources": {\n "description": "Application TypeScript sources containing `DDBModel.prepare` call sites. Read by the prepared-statement build lint; rewritten in place by `transform prepared --write` (hoist normalization, issue #206).",\n "direction": "write"\n }\n },\n "command_sets": {\n "graphddb": {\n "summary": "Graph data modeling on DynamoDB \u2014 code generation CLI.",\n "x-stdin": "No command reads from stdin. All inputs are provided via file options.",\n "commands": {\n "generate.python": {\n "summary": "Generate Python bindings from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes the Python bridge bindings (manifest.json, operations.json, types.py, repositories.py, __init__.py) to the output directory. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate python --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate python --entry definitions.ts --out generated/"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (a map of publishQuery / publishCommand results \u2014 the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 a project with no contracts omits it, and the output gains no `contracts` content.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership: context name \u2192 the Model / Contract names that belong to it). Defaults to the contracts module (or the entry module) when omitted. Optional \u2014 consumed by the boundary lint to tell own from foreign.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "dataclass",\n "description": "Emit Python result / element types as @dataclass classes instead of TypedDict (decimal / Optional / Connection mapped accordingly).",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Python bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n },\n "files": [\n {\n "path": "{options.out}/manifest.json",\n "required": true,\n "media_type": "application/json",\n "description": "Entity / table / key / relation metadata."\n },\n {\n "path": "{options.out}/operations.json",\n "required": true,\n "media_type": "application/json",\n "description": "Per-query / per-command execution specs."\n },\n {\n "path": "{options.out}/types.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "TypedDict result types derived from query selects."\n },\n {\n "path": "{options.out}/repositories.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "Per-entity repository classes (sync methods)."\n },\n {\n "path": "{options.out}/__init__.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "Package re-exports for the generated bindings."\n }\n ]\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.php": {\n "summary": "Generate typed PHP bindings (repositories + result DTOs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes typed PHP bindings \u2014 one `<Entity>Repository` per entity plus a result DTO (and `<Item>Connection`) per query result shape \u2014 into the output directory. Each repository wraps the PHP `GraphDDBRuntime`; query methods return a hydrated `?<Result>` typed object, command methods return void, both calling the runtime by the original operation id. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate php --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate php --typed --entry definitions.ts --out generated/",\n "graphddb generate php --typed --entry definitions.ts --out generated/ --template-dir php-templates/ --helpers php-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result DTOs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / dto-class / connection-class / repo-class / repo-method / tx-class / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated PHP bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.rust": {\n "summary": "Generate typed Rust bindings (repositories + serde result structs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes a single `bindings.rs` module of typed Rust bindings \u2014 a serde-`Deserialize` result struct (and `<Item>Connection`) per query result shape plus one `<Entity>Repository` per entity \u2014 into the output directory. Each repository holds an `Arc<GraphDDBRuntime>`; query methods return `Result<Option<T>, GraphDDBError>` (the deserialized typed result), command methods return `Result<(), GraphDDBError>`, both calling the runtime by the original operation id. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate rust --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate rust --typed --entry definitions.ts --out generated/",\n "graphddb generate rust --typed --entry definitions.ts --out generated/ --template-dir rust-templates/ --helpers rust-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result structs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / result-struct / connection-struct / repo-struct / repo-method / tx-struct / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Rust bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.go": {\n "summary": "Generate typed Go bindings (repositories + json result structs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes a single `bindings.go` package of typed Go bindings \u2014 a json result struct (and `<Item>Connection`) per query result shape plus one `<Entity>Repository` per entity \u2014 into the output directory. Each repository holds a `*graphddb_runtime.GraphDDBRuntime`; query methods return `(*T, error)` (the deserialized typed result; a nil pointer for no match), command methods return `error`, both calling the runtime by the original operation id. Numbers are precision-strict (`json.Number`), so a large integer round-trips losslessly. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs and gofmt-normalized. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate go --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate go --typed --entry definitions.ts --out generated/",\n "graphddb generate go --typed --entry definitions.ts --out generated/ --template-dir go-templates/ --helpers go-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result structs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / result-struct / connection-struct / repo-struct / repo-method / tx-struct / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Go bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.behaviors": {\n "summary": "Generate a native behavior module (the codegen-static endpoint) via the upstream behavior-contracts common Generator.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable operations bundle, wraps its universal components[] into the portable component-graph IR envelope ({irVersion, exprVersion, components} \u2014 scp-ir-architecture.md \xA75), and hands it to behavior-contracts\' common Generator (`generateModule`, foo-ogawa/behavior-contracts#13) to emit ONE native module for the selected language (issue #257). graphddb adds no generation logic: envelope + invoke + file write only. The generated module embeds the IR as a native literal with the spec versions and the IR fingerprint baked in (fail-closed load-time checks, the #208 prepared-artifact discipline) and exposes a `bind(handlers)` accessor that delegates to the runtime core \u2014 handlers are always injected at the boundary by the consuming runtime (the graphddb per-language behavior-exec seams). This is the OPT-IN static endpoint (\xA77.3 endpoint 3); the JSON-dynamic operations.json path remains the default and is permanently supported. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate behaviors --lang ts --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate behaviors --lang go --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate behaviors --lang python --entry definitions.ts --out generated/",\n "graphddb generate behaviors --lang rust --entry definitions.ts --out generated/ --runtime-import behavior_contracts",\n "graphddb generate behaviors --lang php --entry definitions.ts --out generated/"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "lang",\n "aliases": [\n "l"\n ],\n "required": true,\n "description": "Target language of the generated behavior module. `ts` emits a typed TypeScript module, `python` a dict-literal module, `go` a JNode composite-literal package, `rust` a json!-constructor module (requires Rust >= 1.80 \u2014 std::sync::LazyLock), `php` a require-scoped module value.",\n "value_name": "lang",\n "schema": {\n "type": "string",\n "enum": [\n "ts",\n "python",\n "go",\n "rust",\n "php"\n ]\n }\n },\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "runtime-import",\n "description": "Module specifier the generated module imports the behavior-contracts runtime core from. Defaults to the emitter\'s published package name per language \u2014 except `php`, which defaults to graphddb\'s vendored namespace (GraphDDB\\\\Runtime\\\\BehaviorContracts) so the generated module resolves against the PHP runtime this package ships.",\n "value_name": "specifier",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated behavior module.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.cloudformation": {\n "summary": "Generate an AWS CloudFormation template (DynamoDB table + GSIs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and builds the serializable manifest, then emits an AWS CloudFormation template describing the DynamoDB table(s) the single-table design maps onto: one `AWS::DynamoDB::Table` per physical table, with the base key schema (`PK` / `SK`), the unioned Global Secondary Indexes (`<indexName>PK` / `<indexName>SK`), `PAY_PER_REQUEST` billing, a `TableName` parameter (default = physical name), and Outputs (table name + ARN). Output is deterministic and, by default, YAML.",\n "usage": [\n "graphddb generate cloudformation --entry models.ts --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --format json",\n "graphddb generate cloudformation --entry models.ts --gsi-projection KEYS_ONLY --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --stream on --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --pitr --sse --table-class STANDARD_INFREQUENT_ACCESS --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --rcu 10 --wcu 5 --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --autoscale --autoscale-min 5 --autoscale-max 100 --autoscale-target 70 --out table.yaml"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import).",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "description": "Output file for the generated CloudFormation template. Written to stdout when omitted.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "format",\n "aliases": [\n "f"\n ],\n "description": "Output serialization format (yaml or json).",\n "value_name": "format",\n "schema": {\n "type": "string",\n "enum": [\n "yaml",\n "json"\n ],\n "default": "yaml"\n }\n },\n {\n "name": "gsi-projection",\n "description": "GSI ProjectionType. ALL (default) projects every attribute; KEYS_ONLY projects only the key attributes.",\n "value_name": "projection",\n "schema": {\n "type": "string",\n "enum": [\n "ALL",\n "KEYS_ONLY"\n ],\n "default": "ALL"\n }\n },\n {\n "name": "stream",\n "description": "DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission. auto (default) emits a stream only when the model set uses stream-based maintenance (updateMode:\'stream\'); on always emits; off never emits. When enabled, a StreamArn Output is added too.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "auto",\n "on",\n "off"\n ],\n "default": "auto"\n }\n },\n {\n "name": "billing-mode",\n "description": "DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand (no provisioned throughput). PROVISIONED emits BillingMode: PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the table and every GSI, and unlocks Application Auto Scaling (--autoscale).",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "PAY_PER_REQUEST",\n "PROVISIONED"\n ],\n "default": "PAY_PER_REQUEST"\n }\n },\n {\n "name": "rcu",\n "description": "Provisioned ReadCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "wcu",\n "description": "Provisioned WriteCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale",\n "description": "Enable Application Auto Scaling. Emits an AWS::ApplicationAutoScaling::ScalableTarget + AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read and write capacity AND for each GSI read and write capacity. Only valid with --billing-mode PROVISIONED (autoscaling is invalid on on-demand and is rejected). Off by default \u2014 no autoscaling resources are emitted unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "autoscale-min",\n "description": "Auto Scaling minimum capacity (MinCapacity) for every scalable target. Must be <= --autoscale-max. Only meaningful with --autoscale. Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale-max",\n "description": "Auto Scaling maximum capacity (MaxCapacity) for every scalable target. Must be >= --autoscale-min. Only meaningful with --autoscale. Defaults to 100 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale-target",\n "description": "Auto Scaling target utilization percentage (TargetValue of the TargetTrackingScaling policy). Only meaningful with --autoscale. Defaults to 70 when omitted.",\n "value_name": "percent",\n "schema": {\n "type": "integer",\n "minimum": 1,\n "maximum": 100\n }\n },\n {\n "name": "pitr",\n "description": "Enable point-in-time recovery (PointInTimeRecoverySpecification PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "table-class",\n "description": "DynamoDB table class. Omitted by default (AWS defaults to STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit TableClass.",\n "value_name": "class",\n "schema": {\n "type": "string",\n "enum": [\n "STANDARD",\n "STANDARD_INFREQUENT_ACCESS"\n ]\n }\n },\n {\n "name": "sse",\n "description": "Enable server-side encryption with the AWS-owned/managed key (SSESpecification SSEEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.docs": {\n "summary": "Generate model-specification documentation (Markdown + Mermaid) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models (and, optionally, the CQRS contract definitions), builds the serializable manifest / operations bundle, then renders human-facing model documentation \u2014 Table Overview, Entity Relationship Diagram, Physical Key Schema, Property Matrix, Entity Details, Access Patterns, Mutation Contracts, Maintained Access Paths, CDC, and CloudFormation summary \u2014 as Markdown with Mermaid diagrams. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate docs --entry models.ts --out doc.md",\n "graphddb generate docs --entry models.ts --contracts contracts.ts --out doc.md",\n "graphddb generate docs --entry models.ts --out docs/",\n "graphddb generate docs --entry models.ts --out docs/ --template-dir doc-templates/ --helpers doc-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (a map of publishQuery / publishCommand results \u2014 the CQRS Contract layer) used for the Access Patterns / Mutation Contracts sections. Defaults to the entry module when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output path for the generated documentation. A file path ending in .md writes the single Markdown file at exactly that path (creating parent directories); any other value is treated as a directory and the file is written as <dir>/index.md.",\n "value_name": "path",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "format",\n "aliases": [\n "f"\n ],\n "description": "Output format. Only markdown is supported today.",\n "value_name": "format",\n "schema": {\n "type": "string",\n "enum": [\n "markdown"\n ],\n "default": "markdown"\n }\n },\n {\n "name": "split",\n "description": "Output granularity. none (default) emits a single index.md; entity is reserved for a future per-entity split.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "none",\n "entity"\n ],\n "default": "none"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (index / table-overview / er-diagram / key-schema / property-matrix / entity / access-pattern / maintained / cdc / cloudformation) overrides the bundled one; absent partials fall back to the bundled default.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set (eq / join / pascal / mermaidId / codeOrEmpty).",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "billing-mode",\n "description": "DynamoDB billing mode used in the Table Overview (shared with generate cloudformation). PAY_PER_REQUEST (default) or PROVISIONED.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "PAY_PER_REQUEST",\n "PROVISIONED"\n ],\n "default": "PAY_PER_REQUEST"\n }\n },\n {\n "name": "stream",\n "description": "DynamoDB Streams state used in the Table Overview (shared with generate cloudformation). auto (default) detects stream-based maintenance (updateMode:\'stream\'); on always enabled; off never.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "auto",\n "on",\n "off"\n ],\n "default": "auto"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "transform.prepared": {\n "summary": "Lint and hoist-normalize `DDBModel.prepare` call sites (compile-time prepared statements, issue #206).",\n "description": "A source-to-source build pass over application TypeScript files. It statically enforces the prepared-statement no-runtime-capture rule (a prepare body may reference only its `$` placeholder and module-static bindings; capturing a per-call runtime value \u2014 directly or via a helper call \u2014 is a loud error), and normalizes every verified INLINE `DDBModel.prepare(fn)` call site into a module-scope prepared slot so the plan compiles once per module and each call is a plain `.execute` (zero per-op planning / hashing \u2014 placement independent). Without --write it is a pure check (the build lint): violations exit non-zero and hoistable inline call sites are reported as notes. With --write, verified inline call sites are rewritten in place; files with violations are never rewritten. Idempotent: re-running on transformed output changes nothing. With --aot <artifact> (issue #208), the pass additionally compiles every verified prepare body at BUILD time into a static prepared-plan artifact (a generated TypeScript module): with --write it writes the artifact and rewrites each call site to load its static plan (`loadPreparedPlan(document, id, body)` \u2014 the body stays in source as the plan\'s compile source and fallback); without --write it is the DRIFT CHECK \u2014 it recompiles every plan and exits non-zero when the artifact is missing or differs (CI gate: model declarations changed without regenerating the artifact).",\n "usage": [\n "graphddb transform prepared --src src/",\n "graphddb transform prepared --src src/ --write",\n "graphddb transform prepared --src src/app/handlers.ts --write",\n "graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts --write",\n "graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts"\n ],\n "effects": {\n "risk_level": "medium",\n "reads": [\n "ts-app-sources"\n ],\n "writes": [\n "ts-app-sources"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Commit or stash pending changes first when using --write (it rewrites sources in place)."\n ]\n },\n "options": [\n {\n "name": "src",\n "aliases": [\n "s"\n ],\n "required": true,\n "description": "A TypeScript source file, or a directory scanned recursively for .ts/.tsx/.mts/.cts files (node_modules, dist, hidden directories, and .d.ts files are skipped).",\n "value_name": "path",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true\n }\n },\n {\n "name": "write",\n "aliases": [\n "w"\n ],\n "description": "Rewrite verified inline call sites in place (hoist normalization). Without it the command only checks and reports.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "aot",\n "aliases": [\n "a"\n ],\n "description": "Static prepared-plan artifact module path (issue #208). Enables build-time (AOT) compilation of every verified prepare body: with --write the artifact module is (re)generated and call sites are rewritten to load their static plan; without --write the pass recompiles and compares (drift check \u2014 a missing or differing artifact exits 1).",\n "value_name": "artifact",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Check passed / transform applied. No no-runtime-capture violations were found.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/TransformPreparedResult"\n }\n }\n },\n "1": {\n "description": "No-runtime-capture violations found, or --aot drift detected (reported in the result on stdout), or an unexpected error (reported on stderr).",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/TransformPreparedResult"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n }\n }\n }\n },\n "components": {\n "schemas": {\n "GenerateResult": {\n "type": "object",\n "required": [\n "status",\n "outDir",\n "files"\n ],\n "properties": {\n "status": {\n "type": "string",\n "enum": [\n "ok"\n ]\n },\n "outDir": {\n "type": "string",\n "description": "Output directory the files were written to."\n },\n "files": {\n "type": "array",\n "description": "Paths of the generated files (relative to outDir).",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "Error": {\n "type": "object",\n "required": [\n "code",\n "message"\n ],\n "properties": {\n "code": {\n "type": "string"\n },\n "message": {\n "type": "string"\n }\n }\n },\n "TransformPreparedResult": {\n "type": "object",\n "required": [\n "status",\n "files",\n "hoisted",\n "moduleScope",\n "alreadyHoisted",\n "errors",\n "diagnostics"\n ],\n "properties": {\n "status": {\n "type": "string",\n "enum": [\n "ok",\n "violations",\n "drift"\n ]\n },\n "files": {\n "type": "array",\n "description": "Source files scanned.",\n "items": {\n "type": "string"\n }\n },\n "changedFiles": {\n "type": "array",\n "description": "Files rewritten in place (--write only).",\n "items": {\n "type": "string"\n }\n },\n "hoisted": {\n "type": "integer",\n "description": "Inline call sites normalized (or normalizable in check mode)."\n },\n "moduleScope": {\n "type": "integer",\n "description": "Call sites already evaluated once per module load (left as-is)."\n },\n "alreadyHoisted": {\n "type": "integer",\n "description": "Call sites already normalized by a previous run."\n },\n "errors": {\n "type": "integer",\n "description": "No-runtime-capture violations found."\n },\n "artifact": {\n "type": "string",\n "description": "The static prepared-plan artifact path (--aot only)."\n },\n "plans": {\n "type": "integer",\n "description": "Prepared plans compiled into the artifact (--aot only)."\n },\n "drift": {\n "type": "object",\n "description": "Artifact drift detail (--aot check mode only; present when status is drift).",\n "properties": {\n "missing": {\n "type": "boolean",\n "description": "The artifact module does not exist."\n },\n "added": {\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "removed": {\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "changed": {\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "diagnostics": {\n "type": "array",\n "description": "Per-position lint diagnostics (errors and notes).",\n "items": {\n "type": "object",\n "required": [\n "code",\n "category",\n "message",\n "file",\n "line",\n "column"\n ],\n "properties": {\n "code": {\n "type": "string"\n },\n "category": {\n "type": "string",\n "enum": [\n "error",\n "note"\n ]\n },\n "message": {\n "type": "string"\n },\n "file": {\n "type": "string"\n },\n "line": {\n "type": "integer"\n },\n "column": {\n "type": "integer"\n }\n }\n }\n }\n }\n }\n }\n }\n}';
|
|
856
944
|
|
|
857
945
|
// src/generated/program.ts
|
|
858
946
|
function createProgram(handlers2, version) {
|
|
@@ -896,6 +984,15 @@ function createProgram(handlers2, version) {
|
|
|
896
984
|
}
|
|
897
985
|
await handlers2.generateGo(opts, globalOpts);
|
|
898
986
|
});
|
|
987
|
+
__cmd_generate.command("behaviors").description("Generate a native behavior module (the codegen-static endpoint) via the upstream behavior-contracts common Generator.").option("-l, --lang <lang>", "Target language of the generated behavior module. `ts` emits a typed TypeScript module, `python` a dict-literal module, `go` a JNode composite-literal package, `rust` a json!-constructor module (requires Rust >= 1.80 \u2014 std::sync::LazyLock), `php` a require-scoped module value.").option("-e, --entry <file>", "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.").option("-t, --transactions <file>", "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional.").option("--contracts <file>", "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional.").option("--contexts <file>", "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.").option("--runtime-import <specifier>", "Module specifier the generated module imports the behavior-contracts runtime core from. Defaults to the emitter's published package name per language \u2014 except `php`, which defaults to graphddb's vendored namespace (GraphDDB\\Runtime\\BehaviorContracts) so the generated module resolves against the PHP runtime this package ships.").option("-o, --out <dir>", "Output directory for the generated behavior module.").action(async (opts, cmd) => {
|
|
988
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
989
|
+
if (globalOpts.introspect) {
|
|
990
|
+
const policy = deriveCommandPolicy("generate.behaviors", opts);
|
|
991
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
await handlers2.generateBehaviors(opts, globalOpts);
|
|
995
|
+
});
|
|
899
996
|
__cmd_generate.command("cloudformation").description("Generate an AWS CloudFormation template (DynamoDB table + GSIs) from TypeScript GraphDDB definitions.").option("-e, --entry <file>", "Entry module that registers the entity models (side-effecting import).").option("-o, --out <file>", "Output file for the generated CloudFormation template. Written to stdout when omitted.").option("-f, --format <format>", "Output serialization format (yaml or json).", "yaml").option("--gsi-projection <projection>", "GSI ProjectionType. ALL (default) projects every attribute; KEYS_ONLY projects only the key attributes.", "ALL").option("--stream <mode>", "DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission. auto (default) emits a stream only when the model set uses stream-based maintenance (updateMode:'stream'); on always emits; off never emits. When enabled, a StreamArn Output is added too.", "auto").option("--billing-mode <mode>", "DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand (no provisioned throughput). PROVISIONED emits BillingMode: PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the table and every GSI, and unlocks Application Auto Scaling (--autoscale).", "PAY_PER_REQUEST").option("--rcu <units>", "Provisioned ReadCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.").option("--wcu <units>", "Provisioned WriteCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.").option("--autoscale", "Enable Application Auto Scaling. Emits an AWS::ApplicationAutoScaling::ScalableTarget + AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read and write capacity AND for each GSI read and write capacity. Only valid with --billing-mode PROVISIONED (autoscaling is invalid on on-demand and is rejected). Off by default \u2014 no autoscaling resources are emitted unless this flag is passed.").option("--autoscale-min <units>", "Auto Scaling minimum capacity (MinCapacity) for every scalable target. Must be <= --autoscale-max. Only meaningful with --autoscale. Defaults to 5 when omitted.").option("--autoscale-max <units>", "Auto Scaling maximum capacity (MaxCapacity) for every scalable target. Must be >= --autoscale-min. Only meaningful with --autoscale. Defaults to 100 when omitted.").option("--autoscale-target <percent>", "Auto Scaling target utilization percentage (TargetValue of the TargetTrackingScaling policy). Only meaningful with --autoscale. Defaults to 70 when omitted.").option("--pitr", "Enable point-in-time recovery (PointInTimeRecoverySpecification PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.").option("--table-class <class>", "DynamoDB table class. Omitted by default (AWS defaults to STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit TableClass.").option("--sse", "Enable server-side encryption with the AWS-owned/managed key (SSESpecification SSEEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.").action(async (opts, cmd) => {
|
|
900
997
|
const globalOpts = cmd.optsWithGlobals();
|
|
901
998
|
if (globalOpts.introspect) {
|
|
@@ -941,7 +1038,7 @@ function createProgram(handlers2, version) {
|
|
|
941
1038
|
type: "cli-contracts/extract",
|
|
942
1039
|
extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
943
1040
|
specVersion: doc.cli_contracts ?? "0.1.0",
|
|
944
|
-
commands: ["graphddb.generate.python", "graphddb.generate.php", "graphddb.generate.rust", "graphddb.generate.go", "graphddb.generate.cloudformation", "graphddb.generate.docs", "graphddb.transform.prepared"]
|
|
1041
|
+
commands: ["graphddb.generate.python", "graphddb.generate.php", "graphddb.generate.rust", "graphddb.generate.go", "graphddb.generate.behaviors", "graphddb.generate.cloudformation", "graphddb.generate.docs", "graphddb.transform.prepared"]
|
|
945
1042
|
};
|
|
946
1043
|
}
|
|
947
1044
|
Object.assign(out, doc);
|
|
@@ -958,7 +1055,7 @@ function createProgram(handlers2, version) {
|
|
|
958
1055
|
yamlLines.push("extractedAt: " + (/* @__PURE__ */ new Date()).toISOString());
|
|
959
1056
|
yamlLines.push("spec_version: " + (doc.cli_contracts ?? "0.1.0"));
|
|
960
1057
|
yamlLines.push("commands:");
|
|
961
|
-
for (const id of ["graphddb.generate.python", "graphddb.generate.php", "graphddb.generate.rust", "graphddb.generate.go", "graphddb.generate.cloudformation", "graphddb.generate.docs", "graphddb.transform.prepared"]) {
|
|
1058
|
+
for (const id of ["graphddb.generate.python", "graphddb.generate.php", "graphddb.generate.rust", "graphddb.generate.go", "graphddb.generate.behaviors", "graphddb.generate.cloudformation", "graphddb.generate.docs", "graphddb.transform.prepared"]) {
|
|
962
1059
|
yamlLines.push(" - " + id);
|
|
963
1060
|
}
|
|
964
1061
|
}
|
|
@@ -1014,27 +1111,37 @@ function entityBaseName(entity) {
|
|
|
1014
1111
|
function queryResultTypeName(queryName) {
|
|
1015
1112
|
return `${toPascalCase(queryName)}Result`;
|
|
1016
1113
|
}
|
|
1017
|
-
function txElementTypeName(txName, paramName) {
|
|
1114
|
+
function txElementTypeName(txName, paramName, batchWrite = false) {
|
|
1115
|
+
if (batchWrite && paramName === "items") return `${toPascalCase(txName)}Item`;
|
|
1018
1116
|
return `${toPascalCase(txName)}${toPascalCase(paramName)}Item`;
|
|
1019
1117
|
}
|
|
1020
1118
|
function contractOperationId(contract, method) {
|
|
1021
1119
|
return `${contract}__${method}`;
|
|
1022
1120
|
}
|
|
1023
|
-
function relationSegments(
|
|
1024
|
-
|
|
1025
|
-
const parts = resultPath.replace(/^\$\.?/, "").split(".");
|
|
1026
|
-
return parts.filter((p) => p !== "items");
|
|
1121
|
+
function relationSegments(nodeId) {
|
|
1122
|
+
return nodeId.split(".").filter((p) => p !== "items");
|
|
1027
1123
|
}
|
|
1028
|
-
function
|
|
1029
|
-
|
|
1030
|
-
|
|
1124
|
+
function nodePorts(node) {
|
|
1125
|
+
if ("map" in node) return node.map.ports;
|
|
1126
|
+
if ("cond" in node) return void 0;
|
|
1127
|
+
return node.ports;
|
|
1128
|
+
}
|
|
1129
|
+
function nodeProjection(ports) {
|
|
1130
|
+
const port = ports.projection;
|
|
1131
|
+
return (port?.arr ?? []).filter((f) => typeof f === "string");
|
|
1132
|
+
}
|
|
1133
|
+
function insertComponentNode(root, node, manifest) {
|
|
1134
|
+
const ports = nodePorts(node);
|
|
1135
|
+
if (ports === void 0) return;
|
|
1136
|
+
const segments = relationSegments(node.id);
|
|
1137
|
+
let tree = root;
|
|
1031
1138
|
let parent = root;
|
|
1032
1139
|
let entity = root.entity;
|
|
1033
1140
|
for (const prop of segments) {
|
|
1034
|
-
parent =
|
|
1141
|
+
parent = tree;
|
|
1035
1142
|
const relation = manifest.entities[entity]?.relations[prop];
|
|
1036
1143
|
const target = relation?.target ?? entity;
|
|
1037
|
-
let child =
|
|
1144
|
+
let child = tree.children.get(prop);
|
|
1038
1145
|
if (!child) {
|
|
1039
1146
|
child = {
|
|
1040
1147
|
entity: target,
|
|
@@ -1042,14 +1149,21 @@ function insertOperation(root, op, manifest) {
|
|
|
1042
1149
|
children: /* @__PURE__ */ new Map(),
|
|
1043
1150
|
implicitFields: /* @__PURE__ */ new Set()
|
|
1044
1151
|
};
|
|
1045
|
-
|
|
1152
|
+
tree.children.set(prop, child);
|
|
1046
1153
|
}
|
|
1047
|
-
|
|
1154
|
+
tree = child;
|
|
1048
1155
|
entity = target;
|
|
1049
1156
|
}
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1157
|
+
tree.projection = nodeProjection(ports);
|
|
1158
|
+
const implicit = ports.implicitSourceField;
|
|
1159
|
+
if (typeof implicit === "string") parent.implicitFields.add(implicit);
|
|
1160
|
+
}
|
|
1161
|
+
function populateResultTree(root, spec, component, manifest) {
|
|
1162
|
+
root.projection = spec.operations[0]?.projection ?? [];
|
|
1163
|
+
if (component === void 0) return;
|
|
1164
|
+
for (const node of component.body) {
|
|
1165
|
+
if (node.id === "root") continue;
|
|
1166
|
+
insertComponentNode(root, node, manifest);
|
|
1053
1167
|
}
|
|
1054
1168
|
}
|
|
1055
1169
|
function emitResultClasses(node, typeName, manifest, out, seen) {
|
|
@@ -1139,7 +1253,7 @@ function emitTransactionElementTypes(transactions, out, seen) {
|
|
|
1139
1253
|
for (const paramName of Object.keys(spec.params).sort()) {
|
|
1140
1254
|
const p = spec.params[paramName];
|
|
1141
1255
|
if (p.type !== "array" || !p.element) continue;
|
|
1142
|
-
const name = txElementTypeName(txName, paramName);
|
|
1256
|
+
const name = txElementTypeName(txName, paramName, spec.batchWrite === true);
|
|
1143
1257
|
if (seen.has(name)) continue;
|
|
1144
1258
|
seen.add(name);
|
|
1145
1259
|
const element = p.element;
|
|
@@ -1152,7 +1266,7 @@ function emitTransactionElementTypes(transactions, out, seen) {
|
|
|
1152
1266
|
}
|
|
1153
1267
|
}
|
|
1154
1268
|
function elementParamField(name, p) {
|
|
1155
|
-
const scalarType = p.type === "number" ? "number" : "string";
|
|
1269
|
+
const scalarType = p.type === "number" ? "number" : p.type === "map" ? "map" : "string";
|
|
1156
1270
|
return {
|
|
1157
1271
|
name,
|
|
1158
1272
|
shape: "scalar",
|
|
@@ -1211,9 +1325,9 @@ function contractCommandMethodSpec(operations, binding) {
|
|
|
1211
1325
|
}
|
|
1212
1326
|
function contractCommandParams(operations, binding, spec) {
|
|
1213
1327
|
const single = spec.single;
|
|
1214
|
-
const params = single.mode === "transaction" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
|
|
1328
|
+
const params = single.mode === "transaction" || single.mode === "batchWrite" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
|
|
1215
1329
|
if (!params) {
|
|
1216
|
-
const ref = single.mode === "transaction" ? `transaction '${single.transaction}'` : `command '${single.operation}'`;
|
|
1330
|
+
const ref = single.mode === "transaction" || single.mode === "batchWrite" ? `transaction '${single.transaction}'` : `command '${single.operation}'`;
|
|
1217
1331
|
throw new Error(
|
|
1218
1332
|
`Contract '${binding.contract}.${binding.method}': its single resolution target (${ref}) is not present in the operations document.`
|
|
1219
1333
|
);
|
|
@@ -1237,6 +1351,9 @@ function buildBindingModel(manifest, operations, options) {
|
|
|
1237
1351
|
...meta.description !== void 0 ? { description: meta.description } : {}
|
|
1238
1352
|
};
|
|
1239
1353
|
});
|
|
1354
|
+
const componentByName = new Map(
|
|
1355
|
+
(operations.components ?? []).map((c) => [c.name, c])
|
|
1356
|
+
);
|
|
1240
1357
|
const resultClasses = [];
|
|
1241
1358
|
const seen = /* @__PURE__ */ new Set();
|
|
1242
1359
|
for (const queryName of queryNames) {
|
|
@@ -1249,7 +1366,7 @@ function buildBindingModel(manifest, operations, options) {
|
|
|
1249
1366
|
children: /* @__PURE__ */ new Map(),
|
|
1250
1367
|
implicitFields: /* @__PURE__ */ new Set()
|
|
1251
1368
|
};
|
|
1252
|
-
|
|
1369
|
+
populateResultTree(root, spec, componentByName.get(queryName), manifest);
|
|
1253
1370
|
emitResultClasses(root, queryResultTypeName(queryName), manifest, resultClasses, seen);
|
|
1254
1371
|
}
|
|
1255
1372
|
for (const q of contractQueries) {
|
|
@@ -1272,7 +1389,7 @@ function buildBindingModel(manifest, operations, options) {
|
|
|
1272
1389
|
children: /* @__PURE__ */ new Map(),
|
|
1273
1390
|
implicitFields: /* @__PURE__ */ new Set()
|
|
1274
1391
|
};
|
|
1275
|
-
|
|
1392
|
+
populateResultTree(root, spec, componentByName.get(q.operation), manifest);
|
|
1276
1393
|
emitResultClasses(root, recordName, manifest, resultClasses, seen);
|
|
1277
1394
|
appendFieldsToClass(resultClasses, recordName, composeFields(methodSpec.compose ?? []));
|
|
1278
1395
|
if (cardinality === "many") {
|
|
@@ -1364,8 +1481,10 @@ function buildBindingModel(manifest, operations, options) {
|
|
|
1364
1481
|
transactionId: txName,
|
|
1365
1482
|
params: buildParams(
|
|
1366
1483
|
transactions[txName].params,
|
|
1367
|
-
(p) => txElementTypeName(txName, p)
|
|
1368
|
-
)
|
|
1484
|
+
(p) => txElementTypeName(txName, p, transactions[txName].batchWrite === true)
|
|
1485
|
+
),
|
|
1486
|
+
// #298: a `batchWrite` bulk form dispatches to `executeBatchWrite`.
|
|
1487
|
+
...transactions[txName].batchWrite === true ? { batchWrite: true } : {}
|
|
1369
1488
|
}));
|
|
1370
1489
|
return {
|
|
1371
1490
|
entities,
|
|
@@ -1466,7 +1585,7 @@ function resolveField(field, mapper) {
|
|
|
1466
1585
|
case "scalar":
|
|
1467
1586
|
default:
|
|
1468
1587
|
type = field.isParamScalar ? mapper.paramScalar(
|
|
1469
|
-
field.scalarType === "number" ? "number" : field.literals ? "literal" : "string",
|
|
1588
|
+
field.scalarType === "number" ? "number" : field.scalarType === "map" ? "map" : field.literals ? "literal" : "string",
|
|
1470
1589
|
field.literals
|
|
1471
1590
|
) : mapper.scalar(field.scalarType ?? "string", field.scalarFormat);
|
|
1472
1591
|
break;
|
|
@@ -1565,7 +1684,8 @@ function resolveBindingView(model, mapper, options = {}) {
|
|
|
1565
1684
|
})),
|
|
1566
1685
|
transactions: model.transactions.map((tx) => ({
|
|
1567
1686
|
transactionId: tx.transactionId,
|
|
1568
|
-
params: tx.params.map((p) => resolveParam(p, mapper))
|
|
1687
|
+
params: tx.params.map((p) => resolveParam(p, mapper)),
|
|
1688
|
+
...tx.batchWrite === true ? { batchWrite: true } : {}
|
|
1569
1689
|
}))
|
|
1570
1690
|
};
|
|
1571
1691
|
}
|
|
@@ -1573,7 +1693,8 @@ function resolveBindingView(model, mapper, options = {}) {
|
|
|
1573
1693
|
// src/codegen/python-mapper.ts
|
|
1574
1694
|
var PythonTypeMapper = {
|
|
1575
1695
|
language: "python",
|
|
1576
|
-
scalar(type) {
|
|
1696
|
+
scalar(type, format) {
|
|
1697
|
+
if (format === "datetime" || format === "date") return "datetime";
|
|
1577
1698
|
switch (type) {
|
|
1578
1699
|
case "number":
|
|
1579
1700
|
case "numberSet":
|
|
@@ -1597,6 +1718,7 @@ var PythonTypeMapper = {
|
|
|
1597
1718
|
const lits = literals.map((l) => typeof l === "string" ? JSON.stringify(l) : String(l)).join(", ");
|
|
1598
1719
|
return `Literal[${lits}]`;
|
|
1599
1720
|
}
|
|
1721
|
+
if (kind === "map") return "dict";
|
|
1600
1722
|
return kind === "number" ? "float" : "str";
|
|
1601
1723
|
},
|
|
1602
1724
|
connection(itemType) {
|
|
@@ -1621,8 +1743,10 @@ var TYPES = `{{header}}
|
|
|
1621
1743
|
from __future__ import annotations
|
|
1622
1744
|
|
|
1623
1745
|
{{#if isDataclass}}from dataclasses import dataclass
|
|
1624
|
-
{{#if
|
|
1625
|
-
{{/if}}{{
|
|
1746
|
+
{{#if datetimeImport}}{{datetimeImport}}
|
|
1747
|
+
{{/if}}{{#if usesLiteral}}from typing import Literal
|
|
1748
|
+
{{/if}}{{else}}{{#if datetimeImport}}{{datetimeImport}}
|
|
1749
|
+
{{/if}}{{#if usesLiteral}}from typing import Literal, TypedDict
|
|
1626
1750
|
{{else}}from typing import TypedDict
|
|
1627
1751
|
{{/if}}{{/if}}
|
|
1628
1752
|
|
|
@@ -1650,7 +1774,7 @@ var REPO_CLASS = `class {{name}}:
|
|
|
1650
1774
|
|
|
1651
1775
|
{{/unless}}{{/each}}{{else}} pass{{/if}}`;
|
|
1652
1776
|
var TX_METHOD = ` def {{methodName}}(self{{#if signature}}, {{signature}}{{/if}}) -> None:
|
|
1653
|
-
self._runtime.
|
|
1777
|
+
self._runtime.{{runtimeCall}}(
|
|
1654
1778
|
transaction_id="{{transactionId}}",
|
|
1655
1779
|
params={{paramsDict}},
|
|
1656
1780
|
)`;
|
|
@@ -1755,12 +1879,17 @@ function txMethodContext(m) {
|
|
|
1755
1879
|
methodName: toSnakeCase(m.transactionId),
|
|
1756
1880
|
signature: signatureOf(m.params),
|
|
1757
1881
|
transactionId: m.transactionId,
|
|
1758
|
-
paramsDict: paramsDictOf(m.params)
|
|
1882
|
+
paramsDict: paramsDictOf(m.params),
|
|
1883
|
+
runtimeCall: m.batchWrite === true ? "execute_batch_write" : "execute_transaction"
|
|
1759
1884
|
};
|
|
1760
1885
|
}
|
|
1761
1886
|
function classesUseLiteral(classes) {
|
|
1762
1887
|
return classes.some((c) => c.fields.some((f) => f.type.includes("Literal[")));
|
|
1763
1888
|
}
|
|
1889
|
+
function datetimeImportOf(classes) {
|
|
1890
|
+
const usesDatetime = classes.some((c) => c.fields.some((f) => /\bdatetime\b/.test(f.type)));
|
|
1891
|
+
return usesDatetime ? "from datetime import datetime" : void 0;
|
|
1892
|
+
}
|
|
1764
1893
|
function methodsUseLiteral(view) {
|
|
1765
1894
|
const paramLiteral = (p) => p.type.startsWith("Literal[");
|
|
1766
1895
|
return view.repositories.some((r) => r.methods.some((m) => m.params.some(paramLiteral))) || view.transactions.some((t) => t.params.some(paramLiteral));
|
|
@@ -1798,10 +1927,12 @@ function renderTypesFile(view, options) {
|
|
|
1798
1927
|
(c) => render("type-class", classContext(c, isDataclass), engine)
|
|
1799
1928
|
);
|
|
1800
1929
|
const body = blocks.length === 0 ? "# (no query result types)" : blocks.join("\n\n\n");
|
|
1930
|
+
const datetimeImport = datetimeImportOf(view.resultClasses);
|
|
1801
1931
|
const context = {
|
|
1802
1932
|
header: PY_HEADER,
|
|
1803
1933
|
isDataclass,
|
|
1804
1934
|
usesLiteral: classesUseLiteral(view.resultClasses),
|
|
1935
|
+
...datetimeImport !== void 0 ? { datetimeImport } : {},
|
|
1805
1936
|
body
|
|
1806
1937
|
};
|
|
1807
1938
|
return render("types", context, engine);
|
|
@@ -1950,6 +2081,7 @@ var PhpTypeMapper = {
|
|
|
1950
2081
|
}
|
|
1951
2082
|
},
|
|
1952
2083
|
paramScalar(kind) {
|
|
2084
|
+
if (kind === "map") return "array|\\stdClass";
|
|
1953
2085
|
return kind === "number" ? PHP_NUMBER : "string";
|
|
1954
2086
|
},
|
|
1955
2087
|
connection(itemType) {
|
|
@@ -2052,7 +2184,7 @@ final class {{name}}
|
|
|
2052
2184
|
}`;
|
|
2053
2185
|
var TX_METHOD2 = `{{docblock}} public function {{methodName}}({{signature}}): void
|
|
2054
2186
|
{
|
|
2055
|
-
$this->runtime->
|
|
2187
|
+
$this->runtime->{{runtimeCall}}('{{transactionId}}', {{paramsArray}});
|
|
2056
2188
|
}`;
|
|
2057
2189
|
var TX_CLASS2 = `/**
|
|
2058
2190
|
* Typed repository for declarative transactions, wrapping a {@see GraphDDBRuntime}.
|
|
@@ -2220,7 +2352,8 @@ function txMethodContext2(method, metas) {
|
|
|
2220
2352
|
signature: signatureOf2(method.params),
|
|
2221
2353
|
transactionId: method.transactionId,
|
|
2222
2354
|
paramsArray: paramsArrayOf(method.params),
|
|
2223
|
-
docblock: txDocblockOf(method, metas)
|
|
2355
|
+
docblock: txDocblockOf(method, metas),
|
|
2356
|
+
runtimeCall: method.batchWrite === true ? "executeBatchWrite" : "executeTransaction"
|
|
2224
2357
|
};
|
|
2225
2358
|
}
|
|
2226
2359
|
function engineOptions2(options) {
|
|
@@ -2246,12 +2379,16 @@ function renderFile(body, uses, options) {
|
|
|
2246
2379
|
}
|
|
2247
2380
|
function buildParamMetaIndex(operations, surface) {
|
|
2248
2381
|
const index = /* @__PURE__ */ new Map();
|
|
2249
|
-
const record = (opId, params) => {
|
|
2382
|
+
const record = (opId, params, batchWrite = false) => {
|
|
2250
2383
|
const inner = /* @__PURE__ */ new Map();
|
|
2251
2384
|
for (const [name, p] of Object.entries(params)) {
|
|
2252
2385
|
inner.set(name, {
|
|
2253
2386
|
...p.literals !== void 0 ? { literals: p.literals } : {},
|
|
2254
|
-
|
|
2387
|
+
// #298: a batchWrite form's `items` element is `<TxName>Item` (matching
|
|
2388
|
+
// `txElementTypeName` — the generic rule would double the word).
|
|
2389
|
+
...p.type === "array" ? {
|
|
2390
|
+
elementType: batchWrite && name === "items" ? `${pascal(opId)}Item` : `${pascal(opId)}${pascal(name)}Item`
|
|
2391
|
+
} : {}
|
|
2255
2392
|
});
|
|
2256
2393
|
}
|
|
2257
2394
|
index.set(opId, inner);
|
|
@@ -2265,7 +2402,7 @@ function buildParamMetaIndex(operations, surface) {
|
|
|
2265
2402
|
if (commandSet.has(name)) record(name, spec.params ?? {});
|
|
2266
2403
|
}
|
|
2267
2404
|
for (const [name, spec] of Object.entries(operations.transactions ?? {})) {
|
|
2268
|
-
record(name, spec.params ?? {});
|
|
2405
|
+
record(name, spec.params ?? {}, spec.batchWrite === true);
|
|
2269
2406
|
}
|
|
2270
2407
|
recordContractMetas(index, operations, surface, record);
|
|
2271
2408
|
return index;
|
|
@@ -2278,7 +2415,7 @@ function recordContractMetas(index, operations, surface, record) {
|
|
|
2278
2415
|
for (const c of surface.contractCommands ?? []) {
|
|
2279
2416
|
const methodSpec = operations.contracts?.[c.contract]?.methods?.[c.method];
|
|
2280
2417
|
const single = methodSpec && "single" in methodSpec ? methodSpec.single : void 0;
|
|
2281
|
-
const params = single === void 0 ? void 0 : single.mode === "transaction" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
|
|
2418
|
+
const params = single === void 0 ? void 0 : single.mode === "transaction" || single.mode === "batchWrite" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
|
|
2282
2419
|
if (params) record(contractOperationId(c.contract, c.method), params);
|
|
2283
2420
|
}
|
|
2284
2421
|
}
|
|
@@ -2397,6 +2534,7 @@ var RustTypeMapper = {
|
|
|
2397
2534
|
}
|
|
2398
2535
|
},
|
|
2399
2536
|
paramScalar(kind) {
|
|
2537
|
+
if (kind === "map") return "serde_json::Value";
|
|
2400
2538
|
return kind === "number" ? RUST_NUMBER : "String";
|
|
2401
2539
|
},
|
|
2402
2540
|
connection(itemType) {
|
|
@@ -2461,6 +2599,9 @@ pub struct {{name}} {
|
|
|
2461
2599
|
runtime: Arc<GraphDDBRuntime>,
|
|
2462
2600
|
}
|
|
2463
2601
|
|
|
2602
|
+
// Generated methods use cross-language-stable \`contract__method\` names and
|
|
2603
|
+
// take one typed argument per contract key/shared field.
|
|
2604
|
+
#[allow(non_snake_case, clippy::too_many_arguments)]
|
|
2464
2605
|
impl {{name}} {
|
|
2465
2606
|
/// Construct the repository over a shared runtime.
|
|
2466
2607
|
pub fn new(runtime: Arc<GraphDDBRuntime>) -> Self {
|
|
@@ -2472,7 +2613,7 @@ impl {{name}} {
|
|
|
2472
2613
|
{{/if~}}
|
|
2473
2614
|
}`;
|
|
2474
2615
|
var TX_METHOD3 = `{{docComment}} pub async fn {{methodName}}(&self{{#if signature}}, {{signature}}{{/if}}) -> Result<(), GraphDDBError> {
|
|
2475
|
-
{{paramsStmts}} self.runtime.
|
|
2616
|
+
{{paramsStmts}} self.runtime.{{runtimeCall}}("{{transactionId}}", ¶ms).await?;
|
|
2476
2617
|
Ok(())
|
|
2477
2618
|
}`;
|
|
2478
2619
|
var TX_STRUCT = `/// Typed repository for declarative transactions, wrapping a \`GraphDDBRuntime\`.
|
|
@@ -2481,6 +2622,9 @@ pub struct {{name}} {
|
|
|
2481
2622
|
runtime: Arc<GraphDDBRuntime>,
|
|
2482
2623
|
}
|
|
2483
2624
|
|
|
2625
|
+
// Generated methods use cross-language-stable \`contract__method\` names and
|
|
2626
|
+
// take one typed argument per contract key/shared field.
|
|
2627
|
+
#[allow(non_snake_case, clippy::too_many_arguments)]
|
|
2484
2628
|
impl {{name}} {
|
|
2485
2629
|
/// Construct the repository over a shared runtime.
|
|
2486
2630
|
pub fn new(runtime: Arc<GraphDDBRuntime>) -> Self {
|
|
@@ -2534,12 +2678,16 @@ function pascal2(name) {
|
|
|
2534
2678
|
}
|
|
2535
2679
|
function buildParamMetaIndex2(operations, surface) {
|
|
2536
2680
|
const index = /* @__PURE__ */ new Map();
|
|
2537
|
-
const record = (opId, params) => {
|
|
2681
|
+
const record = (opId, params, batchWrite = false) => {
|
|
2538
2682
|
const inner = /* @__PURE__ */ new Map();
|
|
2539
2683
|
for (const [name, p] of Object.entries(params)) {
|
|
2540
2684
|
inner.set(name, {
|
|
2541
2685
|
...p.literals !== void 0 ? { literals: p.literals } : {},
|
|
2542
|
-
|
|
2686
|
+
// #298: a batchWrite form's `items` element is `<TxName>Item` (matching
|
|
2687
|
+
// `txElementTypeName` — the generic rule would double the word).
|
|
2688
|
+
...p.type === "array" ? {
|
|
2689
|
+
elementType: batchWrite && name === "items" ? `${pascal2(opId)}Item` : `${pascal2(opId)}${pascal2(name)}Item`
|
|
2690
|
+
} : {}
|
|
2543
2691
|
});
|
|
2544
2692
|
}
|
|
2545
2693
|
index.set(opId, inner);
|
|
@@ -2553,7 +2701,7 @@ function buildParamMetaIndex2(operations, surface) {
|
|
|
2553
2701
|
if (commandSet.has(name)) record(name, spec.params ?? {});
|
|
2554
2702
|
}
|
|
2555
2703
|
for (const [name, spec] of Object.entries(operations.transactions ?? {})) {
|
|
2556
|
-
record(name, spec.params ?? {});
|
|
2704
|
+
record(name, spec.params ?? {}, spec.batchWrite === true);
|
|
2557
2705
|
}
|
|
2558
2706
|
for (const q of surface.contractQueries ?? []) {
|
|
2559
2707
|
const spec = operations.queries[q.operation];
|
|
@@ -2562,7 +2710,7 @@ function buildParamMetaIndex2(operations, surface) {
|
|
|
2562
2710
|
for (const c of surface.contractCommands ?? []) {
|
|
2563
2711
|
const methodSpec = operations.contracts?.[c.contract]?.methods?.[c.method];
|
|
2564
2712
|
const single = methodSpec && "single" in methodSpec ? methodSpec.single : void 0;
|
|
2565
|
-
const params = single === void 0 ? void 0 : single.mode === "transaction" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
|
|
2713
|
+
const params = single === void 0 ? void 0 : single.mode === "transaction" || single.mode === "batchWrite" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
|
|
2566
2714
|
if (params) record(contractOperationId(c.contract, c.method), params);
|
|
2567
2715
|
}
|
|
2568
2716
|
return index;
|
|
@@ -2676,7 +2824,8 @@ function txMethodContext3(method, metas) {
|
|
|
2676
2824
|
signature: signatureOf3(method.params),
|
|
2677
2825
|
transactionId: method.transactionId,
|
|
2678
2826
|
paramsStmts: paramsStmtsOf(method.params),
|
|
2679
|
-
docComment: txMethodDocComment(method, metas)
|
|
2827
|
+
docComment: txMethodDocComment(method, metas),
|
|
2828
|
+
runtimeCall: method.batchWrite === true ? "execute_batch_write" : "execute_transaction"
|
|
2680
2829
|
};
|
|
2681
2830
|
}
|
|
2682
2831
|
function engineOptions3(options) {
|
|
@@ -2782,6 +2931,7 @@ var GoTypeMapper = {
|
|
|
2782
2931
|
}
|
|
2783
2932
|
},
|
|
2784
2933
|
paramScalar(kind) {
|
|
2934
|
+
if (kind === "map") return "map[string]any";
|
|
2785
2935
|
return kind === "number" ? GO_NUMBER : "string";
|
|
2786
2936
|
},
|
|
2787
2937
|
connection(itemType) {
|
|
@@ -2868,7 +3018,7 @@ func New{{name}}(runtime *graphddb_runtime.GraphDDBRuntime) *{{name}} {
|
|
|
2868
3018
|
|
|
2869
3019
|
{{body}}{{/if}}`;
|
|
2870
3020
|
var TX_METHOD4 = `{{docComment}}func (r *{{repoName}}) {{methodName}}(ctx context.Context{{#if signature}}, {{signature}}{{/if}}) error {
|
|
2871
|
-
{{paramsStmts}} return r.runtime.
|
|
3021
|
+
{{paramsStmts}} return r.runtime.{{runtimeCall}}(ctx, "{{transactionId}}", params, nil)
|
|
2872
3022
|
}`;
|
|
2873
3023
|
var TX_STRUCT2 = `// {{name}} is a typed repository for declarative transactions, wrapping a *graphddb_runtime.GraphDDBRuntime.
|
|
2874
3024
|
type {{name}} struct {
|
|
@@ -2969,12 +3119,16 @@ function pascal3(name) {
|
|
|
2969
3119
|
}
|
|
2970
3120
|
function buildParamMetaIndex3(operations, surface) {
|
|
2971
3121
|
const index = /* @__PURE__ */ new Map();
|
|
2972
|
-
const record = (opId, params) => {
|
|
3122
|
+
const record = (opId, params, batchWrite = false) => {
|
|
2973
3123
|
const inner = /* @__PURE__ */ new Map();
|
|
2974
3124
|
for (const [name, p] of Object.entries(params)) {
|
|
2975
3125
|
inner.set(name, {
|
|
2976
3126
|
...p.literals !== void 0 ? { literals: p.literals } : {},
|
|
2977
|
-
|
|
3127
|
+
// #298: a batchWrite form's `items` element is `<TxName>Item` (matching
|
|
3128
|
+
// `txElementTypeName` — the generic rule would double the word).
|
|
3129
|
+
...p.type === "array" ? {
|
|
3130
|
+
elementType: batchWrite && name === "items" ? `${pascal3(opId)}Item` : `${pascal3(opId)}${pascal3(name)}Item`
|
|
3131
|
+
} : {}
|
|
2978
3132
|
});
|
|
2979
3133
|
}
|
|
2980
3134
|
index.set(opId, inner);
|
|
@@ -2988,7 +3142,7 @@ function buildParamMetaIndex3(operations, surface) {
|
|
|
2988
3142
|
if (commandSet.has(name)) record(name, spec.params ?? {});
|
|
2989
3143
|
}
|
|
2990
3144
|
for (const [name, spec] of Object.entries(operations.transactions ?? {})) {
|
|
2991
|
-
record(name, spec.params ?? {});
|
|
3145
|
+
record(name, spec.params ?? {}, spec.batchWrite === true);
|
|
2992
3146
|
}
|
|
2993
3147
|
for (const q of surface.contractQueries ?? []) {
|
|
2994
3148
|
const spec = operations.queries[q.operation];
|
|
@@ -2997,7 +3151,7 @@ function buildParamMetaIndex3(operations, surface) {
|
|
|
2997
3151
|
for (const c of surface.contractCommands ?? []) {
|
|
2998
3152
|
const methodSpec = operations.contracts?.[c.contract]?.methods?.[c.method];
|
|
2999
3153
|
const single = methodSpec && "single" in methodSpec ? methodSpec.single : void 0;
|
|
3000
|
-
const params = single === void 0 ? void 0 : single.mode === "transaction" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
|
|
3154
|
+
const params = single === void 0 ? void 0 : single.mode === "transaction" || single.mode === "batchWrite" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
|
|
3001
3155
|
if (params) record(contractOperationId(c.contract, c.method), params);
|
|
3002
3156
|
}
|
|
3003
3157
|
return index;
|
|
@@ -3099,7 +3253,8 @@ function txMethodContext4(repoName, method, metas) {
|
|
|
3099
3253
|
signature: signatureOf4(method.params),
|
|
3100
3254
|
transactionId: method.transactionId,
|
|
3101
3255
|
paramsStmts: paramsStmtsOf2(method.params),
|
|
3102
|
-
docComment: methodDocComment2(methodName, void 0, method.params, metas)
|
|
3256
|
+
docComment: methodDocComment2(methodName, void 0, method.params, metas),
|
|
3257
|
+
runtimeCall: method.batchWrite === true ? "ExecuteBatchWrite" : "ExecuteTransaction"
|
|
3103
3258
|
};
|
|
3104
3259
|
}
|
|
3105
3260
|
function engineOptions4(options) {
|
|
@@ -3670,6 +3825,14 @@ function generateCdcRegistry(options = {}) {
|
|
|
3670
3825
|
}
|
|
3671
3826
|
|
|
3672
3827
|
// src/codegen/docs-model.ts
|
|
3828
|
+
function keyConditionTemplates(op) {
|
|
3829
|
+
if (op.keyCondition) return { ...op.keyCondition };
|
|
3830
|
+
const out = {};
|
|
3831
|
+
for (const [attr, node] of Object.entries(op.keyExpr ?? {})) {
|
|
3832
|
+
out[attr] = renderKeyExprToTemplate(node);
|
|
3833
|
+
}
|
|
3834
|
+
return out;
|
|
3835
|
+
}
|
|
3673
3836
|
var AS_CONFIGURED = "as configured at deployment";
|
|
3674
3837
|
function fieldTypeLabel(entity, field) {
|
|
3675
3838
|
const f = entity.fields[field];
|
|
@@ -3709,17 +3872,37 @@ function referencesField(template, field) {
|
|
|
3709
3872
|
function keyLabel(prefix, template) {
|
|
3710
3873
|
return template ? `${prefix} = ${template}` : "";
|
|
3711
3874
|
}
|
|
3875
|
+
function exprLiteralPrefix(node) {
|
|
3876
|
+
if (typeof node === "string") return node;
|
|
3877
|
+
if (node !== null && typeof node === "object" && "concat" in node) {
|
|
3878
|
+
const first = node.concat[0];
|
|
3879
|
+
if (typeof first === "string") return first;
|
|
3880
|
+
}
|
|
3881
|
+
return "";
|
|
3882
|
+
}
|
|
3883
|
+
function relationHops(component) {
|
|
3884
|
+
const hops = [];
|
|
3885
|
+
for (const node of component?.body ?? []) {
|
|
3886
|
+
if (node.id === "root" || "cond" in node) continue;
|
|
3887
|
+
const kind = "map" in node ? node.map.component : node.component;
|
|
3888
|
+
const ports = "map" in node ? node.map.ports : node.ports;
|
|
3889
|
+
const indexName = typeof ports.indexName === "string" ? ports.indexName : void 0;
|
|
3890
|
+
const table = typeof ports.table === "string" ? ports.table : "";
|
|
3891
|
+
const pkNode = (indexName ? ports[`${indexName}PK`] : void 0) ?? ports.PK ?? ports.pk;
|
|
3892
|
+
hops.push({
|
|
3893
|
+
type: kind,
|
|
3894
|
+
tableName: table,
|
|
3895
|
+
...indexName !== void 0 ? { indexName } : {},
|
|
3896
|
+
pkTemplate: exprLiteralPrefix(pkNode)
|
|
3897
|
+
});
|
|
3898
|
+
}
|
|
3899
|
+
return hops;
|
|
3900
|
+
}
|
|
3712
3901
|
function rootIndex(spec) {
|
|
3713
3902
|
const root = spec.operations[0];
|
|
3714
3903
|
if (!root) return "";
|
|
3715
3904
|
return root.indexName ?? "PK";
|
|
3716
3905
|
}
|
|
3717
|
-
function isRelation(spec) {
|
|
3718
|
-
return spec.operations.length > 1;
|
|
3719
|
-
}
|
|
3720
|
-
function usesBatchGet(spec) {
|
|
3721
|
-
return spec.operations.some((op) => op.type === "BatchGetItem");
|
|
3722
|
-
}
|
|
3723
3906
|
function usesCursor(spec) {
|
|
3724
3907
|
return (spec.cardinality ?? "many") === "many";
|
|
3725
3908
|
}
|
|
@@ -3736,10 +3919,11 @@ function inputShape(spec) {
|
|
|
3736
3919
|
return `{ ${parts.join(", ")} }`;
|
|
3737
3920
|
}
|
|
3738
3921
|
function opPkTemplate(op) {
|
|
3922
|
+
const kc = keyConditionTemplates(op);
|
|
3739
3923
|
if (op.indexName) {
|
|
3740
|
-
return
|
|
3924
|
+
return kc[`${op.indexName}PK`] ?? kc["PK"] ?? kc["pk"] ?? "";
|
|
3741
3925
|
}
|
|
3742
|
-
return
|
|
3926
|
+
return kc["PK"] ?? kc["pk"] ?? "";
|
|
3743
3927
|
}
|
|
3744
3928
|
function rootEntityName(spec, manifest) {
|
|
3745
3929
|
const root = spec.operations[0];
|
|
@@ -3756,10 +3940,10 @@ function outputShape(spec, entityName) {
|
|
|
3756
3940
|
const base = entityName || "Result";
|
|
3757
3941
|
return many ? `Page<${base}>` : base;
|
|
3758
3942
|
}
|
|
3759
|
-
function buildResolution(spec, manifest) {
|
|
3943
|
+
function buildResolution(spec, relHops, manifest) {
|
|
3760
3944
|
const root = spec.operations[0];
|
|
3761
3945
|
if (!root) return { resolve: "", diagram: [] };
|
|
3762
|
-
if (
|
|
3946
|
+
if (relHops.length === 0) {
|
|
3763
3947
|
const keyLabelStr = rootKeyLabel(root);
|
|
3764
3948
|
const proj = root.projection.length > 0 ? `Projection(${root.projection.slice(0, 4).join(", ")})` : "Projection";
|
|
3765
3949
|
const resolve4 = `${keyLabelStr} \u2192 ${root.type} \u2192 ${proj}`;
|
|
@@ -3773,13 +3957,22 @@ function buildResolution(spec, manifest) {
|
|
|
3773
3957
|
];
|
|
3774
3958
|
return { resolve: resolve4, diagram: diagram2 };
|
|
3775
3959
|
}
|
|
3960
|
+
const hops = [
|
|
3961
|
+
{
|
|
3962
|
+
type: root.type,
|
|
3963
|
+
tableName: root.tableName,
|
|
3964
|
+
...root.indexName !== void 0 ? { indexName: root.indexName } : {},
|
|
3965
|
+
pkTemplate: opPkTemplate(root)
|
|
3966
|
+
},
|
|
3967
|
+
...relHops
|
|
3968
|
+
];
|
|
3776
3969
|
const entityHops = [];
|
|
3777
3970
|
const diagram = [];
|
|
3778
|
-
for (let i = 0; i <
|
|
3779
|
-
const
|
|
3780
|
-
const entity =
|
|
3781
|
-
entityHops.push(`${
|
|
3782
|
-
const edge = i <
|
|
3971
|
+
for (let i = 0; i < hops.length; i++) {
|
|
3972
|
+
const hop = hops[i];
|
|
3973
|
+
const entity = hopEntityName(hop, manifest) || hop.tableName;
|
|
3974
|
+
entityHops.push(`${hop.type}(${entity}${hop.indexName ? ` by ${hop.indexName}` : ""})`);
|
|
3975
|
+
const edge = i < hops.length - 1 ? hops[i + 1].type === "BatchGetItem" ? "BatchGet" : hop.indexName ?? "PK" : "";
|
|
3783
3976
|
diagram.push({ label: entity, edge });
|
|
3784
3977
|
}
|
|
3785
3978
|
return { resolve: entityHops.join(" \u2192 "), diagram };
|
|
@@ -3789,10 +3982,10 @@ function rootKeyLabel(op) {
|
|
|
3789
3982
|
const prefix = op.indexName ? `${op.indexName} PK` : "PK";
|
|
3790
3983
|
return `${prefix} = ${pk}`;
|
|
3791
3984
|
}
|
|
3792
|
-
function
|
|
3793
|
-
const pk =
|
|
3985
|
+
function hopEntityName(hop, manifest) {
|
|
3986
|
+
const pk = hop.pkTemplate;
|
|
3794
3987
|
for (const [name, entity] of Object.entries(manifest.entities)) {
|
|
3795
|
-
const cand =
|
|
3988
|
+
const cand = hop.indexName ? gsiByName(entity, hop.indexName)?.pkTemplate : entity.key?.pkTemplate;
|
|
3796
3989
|
if (cand && pk) {
|
|
3797
3990
|
if (literalPrefix(cand) === literalPrefix(pk)) return name;
|
|
3798
3991
|
}
|
|
@@ -3998,14 +4191,18 @@ function buildDocModel(manifest, operations, registry = MetadataRegistry, option
|
|
|
3998
4191
|
)
|
|
3999
4192
|
};
|
|
4000
4193
|
});
|
|
4194
|
+
const componentByName = new Map(
|
|
4195
|
+
(operations.components ?? []).map((c) => [c.name, c])
|
|
4196
|
+
);
|
|
4001
4197
|
const accessPatterns = [];
|
|
4002
4198
|
const accessMatrix = [];
|
|
4003
4199
|
for (const name of Object.keys(operations.queries).sort()) {
|
|
4004
4200
|
const spec = operations.queries[name];
|
|
4005
4201
|
const entityName = rootEntityName(spec, manifest);
|
|
4006
|
-
const
|
|
4007
|
-
const
|
|
4008
|
-
const
|
|
4202
|
+
const relHops = relationHops(componentByName.get(name));
|
|
4203
|
+
const { resolve: resolve4, diagram } = buildResolution(spec, relHops, manifest);
|
|
4204
|
+
const relation = relHops.length > 0;
|
|
4205
|
+
const batchGet = spec.operations[0]?.type === "BatchGetItem" || relHops.some((h) => h.type === "BatchGetItem");
|
|
4009
4206
|
const cursor = usesCursor(spec);
|
|
4010
4207
|
const index = rootIndex(spec);
|
|
4011
4208
|
const methodName = name.includes("__") ? name.slice(name.lastIndexOf("__") + 2) : name;
|
|
@@ -4366,6 +4563,9 @@ function renderBundle(queries = {}, commands = {}, registry = MetadataRegistry,
|
|
|
4366
4563
|
};
|
|
4367
4564
|
}
|
|
4368
4565
|
|
|
4566
|
+
// src/cli/handlers.ts
|
|
4567
|
+
import { generateModule, GeneratorFailure } from "behavior-contracts";
|
|
4568
|
+
|
|
4369
4569
|
// src/codegen/jsdoc.ts
|
|
4370
4570
|
async function loadTypescript() {
|
|
4371
4571
|
try {
|
|
@@ -4817,6 +5017,92 @@ var handlers = {
|
|
|
4817
5017
|
fail("GENERATION_FAILED", message, 1);
|
|
4818
5018
|
}
|
|
4819
5019
|
},
|
|
5020
|
+
/**
|
|
5021
|
+
* `generate behaviors --lang <ts|python|go|rust|php>` (issue #257 — the
|
|
5022
|
+
* codegen-static endpoint, §7.3 endpoint 3).
|
|
5023
|
+
*
|
|
5024
|
+
* Loads the TypeScript definitions exactly like `generate python`, builds the
|
|
5025
|
+
* SAME operations bundle (so the components[] are byte-identical to the ones
|
|
5026
|
+
* a `generate python` run serializes into operations.json — the fingerprint
|
|
5027
|
+
* skew check in the consuming runtimes depends on this), wraps the universal
|
|
5028
|
+
* `components[]` into the portable IR envelope, and invokes behavior-contracts'
|
|
5029
|
+
* common Generator (`generateModule`, bc#13). graphddb adds NO generation
|
|
5030
|
+
* logic: envelope + invoke + file write only. The dynamic JSON path stays the
|
|
5031
|
+
* default; the generated module is the opt-in static endpoint.
|
|
5032
|
+
*/
|
|
5033
|
+
async generateBehaviors(options) {
|
|
5034
|
+
const {
|
|
5035
|
+
lang,
|
|
5036
|
+
entry,
|
|
5037
|
+
transactions: transactionsPath,
|
|
5038
|
+
contracts: contractsPath,
|
|
5039
|
+
contexts: contextsPath,
|
|
5040
|
+
runtimeImport,
|
|
5041
|
+
out
|
|
5042
|
+
} = options;
|
|
5043
|
+
if (!lang) fail("INVALID_ARGS", "Missing required option --lang.", 2);
|
|
5044
|
+
if (!entry) fail("INVALID_ARGS", "Missing required option --entry.", 2);
|
|
5045
|
+
if (!out) fail("INVALID_ARGS", "Missing required option --out.", 2);
|
|
5046
|
+
const LANGUAGES = {
|
|
5047
|
+
ts: { language: "typescript" },
|
|
5048
|
+
python: { language: "python" },
|
|
5049
|
+
go: { language: "go" },
|
|
5050
|
+
rust: { language: "rust" },
|
|
5051
|
+
php: { language: "php", runtimeImport: "GraphDDB\\Runtime\\BehaviorContracts" }
|
|
5052
|
+
};
|
|
5053
|
+
const target = LANGUAGES[lang];
|
|
5054
|
+
if (target === void 0) {
|
|
5055
|
+
fail(
|
|
5056
|
+
"INVALID_ARGS",
|
|
5057
|
+
`Unknown --lang '${lang}' (supported: ${Object.keys(LANGUAGES).join(", ")}).`,
|
|
5058
|
+
2
|
|
5059
|
+
);
|
|
5060
|
+
}
|
|
5061
|
+
try {
|
|
5062
|
+
await importModelEntry(entry);
|
|
5063
|
+
const queries = {};
|
|
5064
|
+
const commands = {};
|
|
5065
|
+
const transactions = await loadOptionalMap(
|
|
5066
|
+
transactionsPath ?? entry,
|
|
5067
|
+
"transactions"
|
|
5068
|
+
);
|
|
5069
|
+
const contracts = await loadOptionalMap(
|
|
5070
|
+
contractsPath ?? entry,
|
|
5071
|
+
"contracts"
|
|
5072
|
+
);
|
|
5073
|
+
const contexts = await loadOptionalMap(
|
|
5074
|
+
contextsPath ?? contractsPath ?? entry,
|
|
5075
|
+
"contexts"
|
|
5076
|
+
);
|
|
5077
|
+
const abs = (p) => isAbsolute(p) ? p : resolve3(process.cwd(), p);
|
|
5078
|
+
await applyJsDocDescriptions({ entry: abs(entry) });
|
|
5079
|
+
const doc = buildOperations(queries, commands, transactions, { contracts, contexts });
|
|
5080
|
+
const components = doc.components ?? [];
|
|
5081
|
+
const generated = generateModule(
|
|
5082
|
+
portableIrDocument(components),
|
|
5083
|
+
{
|
|
5084
|
+
language: target.language,
|
|
5085
|
+
...runtimeImport !== void 0 ? { runtimeImport } : target.runtimeImport !== void 0 ? { runtimeImport: target.runtimeImport } : {}
|
|
5086
|
+
}
|
|
5087
|
+
);
|
|
5088
|
+
const outDir = isAbsolute(out) ? out : resolve3(process.cwd(), out);
|
|
5089
|
+
mkdirSync(outDir, { recursive: true });
|
|
5090
|
+
writeFileSync(resolve3(outDir, generated.filenameHint), generated.code, "utf8");
|
|
5091
|
+
process.stdout.write(
|
|
5092
|
+
JSON.stringify({
|
|
5093
|
+
status: "ok",
|
|
5094
|
+
outDir: out,
|
|
5095
|
+
files: [generated.filenameHint]
|
|
5096
|
+
}) + "\n"
|
|
5097
|
+
);
|
|
5098
|
+
} catch (err) {
|
|
5099
|
+
if (err instanceof GeneratorFailure) {
|
|
5100
|
+
fail(`GENERATOR_${err.code}`, err.message, 1);
|
|
5101
|
+
}
|
|
5102
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
5103
|
+
fail("GENERATION_FAILED", message, 1);
|
|
5104
|
+
}
|
|
5105
|
+
},
|
|
4820
5106
|
/**
|
|
4821
5107
|
* `generate php --typed` (issue #219, Epic #216 — typed-binding codegen).
|
|
4822
5108
|
*
|