domainforge 0.13.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.
Files changed (481) hide show
  1. package/.cargo/config.toml +6 -0
  2. package/.claude/settings.local.json +18 -0
  3. package/.coderabbit.yml +43 -0
  4. package/.codex/skills/release-management/SKILL.md +151 -0
  5. package/.codex/skills/release-management/agents/openai.yaml +4 -0
  6. package/.github/actions/decrypt-secrets/action.yml +121 -0
  7. package/.github/agents/Coder.agent.md +97 -0
  8. package/.github/agents/DeepResearch.agent.md +61 -0
  9. package/.github/chatmodes/tdd.vibepro.chatmode.md +1183 -0
  10. package/.github/copilot-instructions.md +13 -0
  11. package/.github/dependabot.yml +68 -0
  12. package/.github/workflows/README.md +165 -0
  13. package/.github/workflows/ci.yml +335 -0
  14. package/.github/workflows/dependabot-automerge.yml +114 -0
  15. package/.github/workflows/dependency-review.yml +27 -0
  16. package/.github/workflows/deploy.yml +87 -0
  17. package/.github/workflows/prepare-release.yml +168 -0
  18. package/.github/workflows/release-crates.yml +42 -0
  19. package/.github/workflows/release-npm.yml +137 -0
  20. package/.github/workflows/release-please.yml +29 -0
  21. package/.github/workflows/release-pypi.yml +96 -0
  22. package/.gitkeep +1 -0
  23. package/.release-please-manifest.json +5 -0
  24. package/.sea-registry.toml +10 -0
  25. package/.serena/project.yml +133 -0
  26. package/.sops.yaml +10 -0
  27. package/AGENTS.md +216 -0
  28. package/CHANGELOG.md +400 -0
  29. package/CLAUDE.md +62 -0
  30. package/CONTRIBUTING.md +323 -0
  31. package/Cargo.lock +3612 -0
  32. package/Cargo.toml +12 -0
  33. package/LICENSE +201 -0
  34. package/README.md +660 -0
  35. package/README_PYTHON.md +256 -0
  36. package/README_TYPESCRIPT.md +305 -0
  37. package/README_WASM.md +329 -0
  38. package/RELEASE_NOTES.md +41 -0
  39. package/bun.lock +378 -0
  40. package/bunfig.toml +11 -0
  41. package/check_output.txt +83 -0
  42. package/clippy_output.txt +80 -0
  43. package/commitlint.config.cjs +8 -0
  44. package/deny.toml +42 -0
  45. package/devbox.json +14 -0
  46. package/devbox.lock +76 -0
  47. package/docs/RELEASE_PROCESS.md +360 -0
  48. package/docs/diagnostics.md +161 -0
  49. package/docs/doc_guidelines.md +53 -0
  50. package/docs/explanations/README.md +21 -0
  51. package/docs/explanations/architecture-overview.md +109 -0
  52. package/docs/explanations/cross-language-binding-strategy.md +68 -0
  53. package/docs/explanations/graph-store-design.md +47 -0
  54. package/docs/explanations/performance-benchmarks.md +63 -0
  55. package/docs/explanations/policy-evaluation-logic.md +106 -0
  56. package/docs/explanations/semantic-modeling-concepts.md +109 -0
  57. package/docs/explanations/three-valued-logic.md +66 -0
  58. package/docs/explanations/versioning-strategy.md +45 -0
  59. package/docs/governance.md +168 -0
  60. package/docs/how-tos/README.md +46 -0
  61. package/docs/how-tos/ci-cd-validation.md +93 -0
  62. package/docs/how-tos/create-custom-units.md +125 -0
  63. package/docs/how-tos/define-policies.md +119 -0
  64. package/docs/how-tos/export-to-calm.md +110 -0
  65. package/docs/how-tos/export-to-protobuf.md +312 -0
  66. package/docs/how-tos/extend-grammar.md +133 -0
  67. package/docs/how-tos/generate-rdf-turtle.md +106 -0
  68. package/docs/how-tos/import-from-calm.md +114 -0
  69. package/docs/how-tos/import-from-sbvr.md +249 -0
  70. package/docs/how-tos/install-cli.md +126 -0
  71. package/docs/how-tos/parse-sea-files.md +132 -0
  72. package/docs/how-tos/policy-evaluation-modes.md +30 -0
  73. package/docs/how-tos/run-cross-language-tests.md +115 -0
  74. package/docs/how-tos/troubleshoot-napi-builds.md +55 -0
  75. package/docs/how-tos/use-modules-imports.md +285 -0
  76. package/docs/index.md +13 -0
  77. package/docs/plans/canonical-normalizer.md +121 -0
  78. package/docs/plans/cd_improvement.md +112 -0
  79. package/docs/plans/cli-ast.md +29 -0
  80. package/docs/plans/expression-bindings-and-normalizer-integration.md +174 -0
  81. package/docs/plans/protobuf_advanced_features_plan.md +597 -0
  82. package/docs/plans/protobuf_plan.yml +525 -0
  83. package/docs/plans/refactor_dsl_architecture.md +131 -0
  84. package/docs/plans/release-plan.md +163 -0
  85. package/docs/plans/sea_fmt_implementation_plan.md +516 -0
  86. package/docs/playbooks/README.md +18 -0
  87. package/docs/playbooks/adding-new-primitive.md +68 -0
  88. package/docs/playbooks/debugging-parser-failures.md +42 -0
  89. package/docs/playbooks/local-release-preparation.md +139 -0
  90. package/docs/playbooks/migrating-schema-versions.md +43 -0
  91. package/docs/playbooks/onboarding-contributors.md +64 -0
  92. package/docs/playbooks/releasing-beta.md +86 -0
  93. package/docs/playbooks/secret-management.md +64 -0
  94. package/docs/reference/README.md +199 -0
  95. package/docs/reference/ast-json-api.md +427 -0
  96. package/docs/reference/calm-mapping.md +519 -0
  97. package/docs/reference/cli-commands.md +588 -0
  98. package/docs/reference/configuration.md +202 -0
  99. package/docs/reference/error-codes.md +664 -0
  100. package/docs/reference/generated-artifacts-policy.md +53 -0
  101. package/docs/reference/grammar-spec.md +255 -0
  102. package/docs/reference/primitives-api.md +317 -0
  103. package/docs/reference/protobuf-api.md +426 -0
  104. package/docs/reference/python-api.md +485 -0
  105. package/docs/reference/registry.md +50 -0
  106. package/docs/reference/sea-dsl-ai-cheatsheet.yaml +913 -0
  107. package/docs/reference/security-model.md +74 -0
  108. package/docs/reference/typescript-api.md +508 -0
  109. package/docs/reference/wasm-api.md +420 -0
  110. package/docs/semantic-pack-review.md +144 -0
  111. package/docs/semantic-pack-signing.md +234 -0
  112. package/docs/semantic-packs.md +284 -0
  113. package/docs/specs/ADR-001-sea-dsl-semantic-source-of-truth.md +33 -0
  114. package/docs/specs/ADR-002-projection-first-class-construct.md +50 -0
  115. package/docs/specs/ADR-003-protobuf-projection-target.md +51 -0
  116. package/docs/specs/ADR-004-projection-compatibility-semantics.md +57 -0
  117. package/docs/specs/ADR-005-multi-language-support-strategy.md +112 -0
  118. package/docs/specs/ADR-006-error-handling-strategy.md +115 -0
  119. package/docs/specs/ADR-007-policy-evaluation-engine.md +95 -0
  120. package/docs/specs/ADR-008-knowledge-graph-integration.md +90 -0
  121. package/docs/specs/ADR-009-module-resolution-strategy.md +115 -0
  122. package/docs/specs/ADR-010-unit-system.md +106 -0
  123. package/docs/specs/PRD-001-sea-projection-framework.md +155 -0
  124. package/docs/specs/PRD-002-sea-cli-tooling.md +169 -0
  125. package/docs/specs/PRD-003-dsl-core-capabilities.md +275 -0
  126. package/docs/specs/README.md +62 -0
  127. package/docs/specs/SDS-001-protobuf-projection-engine.md +451 -0
  128. package/docs/specs/SDS-002-sea-core-architecture.md +268 -0
  129. package/docs/specs/SDS-003-parser-semantic-graph.md +377 -0
  130. package/docs/specs/SDS-004-policy-engine-design.md +362 -0
  131. package/docs/specs/SDS-005-knowledge-graph-module.md +364 -0
  132. package/docs/specs/SDS-006-calm-integration.md +367 -0
  133. package/docs/specs/SDS-007-sbvr-import.md +347 -0
  134. package/docs/templates/template_explanation.md +14 -0
  135. package/docs/templates/template_howto.md +21 -0
  136. package/docs/templates/template_playbook.md +21 -0
  137. package/docs/templates/template_reference.md +17 -0
  138. package/docs/templates/template_tutorial.md +24 -0
  139. package/docs/tutorials/README.md +12 -0
  140. package/docs/tutorials/first-sea-model.md +85 -0
  141. package/docs/tutorials/getting-started.md +98 -0
  142. package/docs/tutorials/python-binding-quickstart.md +107 -0
  143. package/docs/tutorials/typescript-binding-quickstart.md +91 -0
  144. package/docs/tutorials/wasm-in-browser.md +75 -0
  145. package/domainforge-core/CHANGELOG.md +138 -0
  146. package/domainforge-core/Cargo.toml +101 -0
  147. package/domainforge-core/MIGRATING.md +32 -0
  148. package/domainforge-core/README.md +197 -0
  149. package/domainforge-core/benchmark_results.txt +51 -0
  150. package/domainforge-core/build.rs +6 -0
  151. package/domainforge-core/deny.toml +31 -0
  152. package/domainforge-core/docs/specs/projections/sbvr_kg_mapping.md +43 -0
  153. package/domainforge-core/examples/basic.sea +7 -0
  154. package/domainforge-core/examples/cli/import_export_workflow.sh +38 -0
  155. package/domainforge-core/examples/cli/validate_example.sh +30 -0
  156. package/domainforge-core/examples/evolution_semantics.sea +31 -0
  157. package/domainforge-core/examples/parser_demo.rs +203 -0
  158. package/domainforge-core/grammar/sea.pest +408 -0
  159. package/domainforge-core/schemas/calm-v1.schema.json +170 -0
  160. package/domainforge-core/schemas/shacl/sea_shapes.ttl +19 -0
  161. package/domainforge-core/src/authority/compiler.rs +309 -0
  162. package/domainforge-core/src/authority/environment.rs +203 -0
  163. package/domainforge-core/src/authority/error.rs +164 -0
  164. package/domainforge-core/src/authority/fact_resolver.rs +224 -0
  165. package/domainforge-core/src/authority/mod.rs +25 -0
  166. package/domainforge-core/src/authority/pack.rs +133 -0
  167. package/domainforge-core/src/authority/policy.rs +224 -0
  168. package/domainforge-core/src/authority/resolver.rs +446 -0
  169. package/domainforge-core/src/authority/trace.rs +217 -0
  170. package/domainforge-core/src/authority/transform.rs +168 -0
  171. package/domainforge-core/src/authority/types.rs +617 -0
  172. package/domainforge-core/src/bin/domainforge.rs +25 -0
  173. package/domainforge-core/src/calm/export.rs +538 -0
  174. package/domainforge-core/src/calm/import.rs +1220 -0
  175. package/domainforge-core/src/calm/mod.rs +9 -0
  176. package/domainforge-core/src/calm/models.rs +108 -0
  177. package/domainforge-core/src/calm/sbvr_import.rs +9 -0
  178. package/domainforge-core/src/cli/authority.rs +149 -0
  179. package/domainforge-core/src/cli/format.rs +85 -0
  180. package/domainforge-core/src/cli/import.rs +133 -0
  181. package/domainforge-core/src/cli/mod.rs +64 -0
  182. package/domainforge-core/src/cli/normalize.rs +180 -0
  183. package/domainforge-core/src/cli/pack.rs +904 -0
  184. package/domainforge-core/src/cli/parse.rs +112 -0
  185. package/domainforge-core/src/cli/project.rs +294 -0
  186. package/domainforge-core/src/cli/registry.rs +41 -0
  187. package/domainforge-core/src/cli/test.rs +12 -0
  188. package/domainforge-core/src/cli/validate.rs +195 -0
  189. package/domainforge-core/src/cli/validate_kg.rs +80 -0
  190. package/domainforge-core/src/concept_id.rs +89 -0
  191. package/domainforge-core/src/error/diagnostics.rs +426 -0
  192. package/domainforge-core/src/error/fuzzy.rs +253 -0
  193. package/domainforge-core/src/error/mod.rs +13 -0
  194. package/domainforge-core/src/formatter/comments.rs +223 -0
  195. package/domainforge-core/src/formatter/config.rs +114 -0
  196. package/domainforge-core/src/formatter/mod.rs +22 -0
  197. package/domainforge-core/src/formatter/printer.rs +906 -0
  198. package/domainforge-core/src/graph/mod.rs +858 -0
  199. package/domainforge-core/src/graph/to_ast.rs +66 -0
  200. package/domainforge-core/src/kg.rs +1476 -0
  201. package/domainforge-core/src/kg_import.rs +251 -0
  202. package/domainforge-core/src/lib.rs +203 -0
  203. package/domainforge-core/src/module/mod.rs +1 -0
  204. package/domainforge-core/src/module/resolver.rs +260 -0
  205. package/domainforge-core/src/parser/ast.rs +2919 -0
  206. package/domainforge-core/src/parser/ast_convert.rs +494 -0
  207. package/domainforge-core/src/parser/ast_schema.rs +491 -0
  208. package/domainforge-core/src/parser/error.rs +291 -0
  209. package/domainforge-core/src/parser/lint.rs +39 -0
  210. package/domainforge-core/src/parser/mod.rs +193 -0
  211. package/domainforge-core/src/parser/printer.rs +702 -0
  212. package/domainforge-core/src/parser/profiles.rs +71 -0
  213. package/domainforge-core/src/parser/string_utils.rs +138 -0
  214. package/domainforge-core/src/patterns.rs +68 -0
  215. package/domainforge-core/src/policy/core.rs +1148 -0
  216. package/domainforge-core/src/policy/expression.rs +399 -0
  217. package/domainforge-core/src/policy/mod.rs +18 -0
  218. package/domainforge-core/src/policy/normalize.rs +1028 -0
  219. package/domainforge-core/src/policy/quantifier.rs +940 -0
  220. package/domainforge-core/src/policy/three_valued.rs +140 -0
  221. package/domainforge-core/src/policy/three_valued_microbench.rs +104 -0
  222. package/domainforge-core/src/policy/type_inference.rs +67 -0
  223. package/domainforge-core/src/policy/violation.rs +36 -0
  224. package/domainforge-core/src/primitives/concept_change.rs +61 -0
  225. package/domainforge-core/src/primitives/entity.rs +224 -0
  226. package/domainforge-core/src/primitives/flow.rs +111 -0
  227. package/domainforge-core/src/primitives/instance.rs +93 -0
  228. package/domainforge-core/src/primitives/mapping_contract.rs +50 -0
  229. package/domainforge-core/src/primitives/metric.rs +79 -0
  230. package/domainforge-core/src/primitives/mod.rs +25 -0
  231. package/domainforge-core/src/primitives/projection_contract.rs +50 -0
  232. package/domainforge-core/src/primitives/quantity.rs +56 -0
  233. package/domainforge-core/src/primitives/relation.rs +68 -0
  234. package/domainforge-core/src/primitives/resource.rs +237 -0
  235. package/domainforge-core/src/primitives/resource_instance.rs +88 -0
  236. package/domainforge-core/src/primitives/role.rs +49 -0
  237. package/domainforge-core/src/projection/buf.rs +404 -0
  238. package/domainforge-core/src/projection/contracts.rs +22 -0
  239. package/domainforge-core/src/projection/engine.rs +19 -0
  240. package/domainforge-core/src/projection/mod.rs +16 -0
  241. package/domainforge-core/src/projection/protobuf.rs +3331 -0
  242. package/domainforge-core/src/projection/registry.rs +43 -0
  243. package/domainforge-core/src/python/authority.rs +253 -0
  244. package/domainforge-core/src/python/error.rs +227 -0
  245. package/domainforge-core/src/python/formatter.rs +86 -0
  246. package/domainforge-core/src/python/graph.rs +366 -0
  247. package/domainforge-core/src/python/mod.rs +9 -0
  248. package/domainforge-core/src/python/policy.rs +651 -0
  249. package/domainforge-core/src/python/primitives.rs +796 -0
  250. package/domainforge-core/src/python/registry.rs +98 -0
  251. package/domainforge-core/src/python/semantic_pack.rs +619 -0
  252. package/domainforge-core/src/python/units.rs +96 -0
  253. package/domainforge-core/src/registry/mod.rs +432 -0
  254. package/domainforge-core/src/registry/tests.rs +210 -0
  255. package/domainforge-core/src/sbvr.rs +744 -0
  256. package/domainforge-core/src/semantic_pack/builder.rs +470 -0
  257. package/domainforge-core/src/semantic_pack/canonical_json.rs +184 -0
  258. package/domainforge-core/src/semantic_pack/diagnostics.rs +214 -0
  259. package/domainforge-core/src/semantic_pack/diff.rs +216 -0
  260. package/domainforge-core/src/semantic_pack/mod.rs +31 -0
  261. package/domainforge-core/src/semantic_pack/pack_set.rs +240 -0
  262. package/domainforge-core/src/semantic_pack/resolver.rs +437 -0
  263. package/domainforge-core/src/semantic_pack/review.rs +125 -0
  264. package/domainforge-core/src/semantic_pack/schema.rs +342 -0
  265. package/domainforge-core/src/semantic_pack/signing.rs +105 -0
  266. package/domainforge-core/src/semantic_pack/validator.rs +368 -0
  267. package/domainforge-core/src/semantic_version.rs +140 -0
  268. package/domainforge-core/src/test_utils.rs +12 -0
  269. package/domainforge-core/src/typescript/authority.rs +184 -0
  270. package/domainforge-core/src/typescript/error.rs +146 -0
  271. package/domainforge-core/src/typescript/formatter.rs +76 -0
  272. package/domainforge-core/src/typescript/graph.rs +391 -0
  273. package/domainforge-core/src/typescript/mod.rs +9 -0
  274. package/domainforge-core/src/typescript/policy.rs +564 -0
  275. package/domainforge-core/src/typescript/primitives.rs +784 -0
  276. package/domainforge-core/src/typescript/registry.rs +88 -0
  277. package/domainforge-core/src/typescript/semantic_pack.rs +470 -0
  278. package/domainforge-core/src/typescript/units.rs +76 -0
  279. package/domainforge-core/src/units/mod.rs +462 -0
  280. package/domainforge-core/src/uuid_module.rs +42 -0
  281. package/domainforge-core/src/validation_error.rs +818 -0
  282. package/domainforge-core/src/validation_result.rs +30 -0
  283. package/domainforge-core/src/wasm/authority.rs +192 -0
  284. package/domainforge-core/src/wasm/error.rs +145 -0
  285. package/domainforge-core/src/wasm/formatter.rs +69 -0
  286. package/domainforge-core/src/wasm/graph.rs +471 -0
  287. package/domainforge-core/src/wasm/mod.rs +16 -0
  288. package/domainforge-core/src/wasm/policy.rs +607 -0
  289. package/domainforge-core/src/wasm/primitives.rs +295 -0
  290. package/domainforge-core/src/wasm/semantic_pack.rs +471 -0
  291. package/domainforge-core/src/wasm/units.rs +62 -0
  292. package/domainforge-core/std/aws.sea +6 -0
  293. package/domainforge-core/std/core.sea +6 -0
  294. package/domainforge-core/std/http.sea +27 -0
  295. package/domainforge-core/tests/aggregation_enhanced_tests.rs +162 -0
  296. package/domainforge-core/tests/aggregation_eval_tests.rs +248 -0
  297. package/domainforge-core/tests/aggregation_integration_tests.rs +379 -0
  298. package/domainforge-core/tests/aggregation_parser_tests.rs +92 -0
  299. package/domainforge-core/tests/aggregation_tests.rs +102 -0
  300. package/domainforge-core/tests/authority_conformance_tests.rs +1173 -0
  301. package/domainforge-core/tests/calm_round_trip_tests.rs +283 -0
  302. package/domainforge-core/tests/calm_schema_validation_tests.rs +137 -0
  303. package/domainforge-core/tests/cast_operator_tests.rs +85 -0
  304. package/domainforge-core/tests/cli_binary_check.rs +37 -0
  305. package/domainforge-core/tests/cli_import_tests.rs +291 -0
  306. package/domainforge-core/tests/cli_path_traversal_tests.rs +124 -0
  307. package/domainforge-core/tests/cli_tests.rs +63 -0
  308. package/domainforge-core/tests/diagnostics_tests.rs +203 -0
  309. package/domainforge-core/tests/dimension_unit_tests.rs +80 -0
  310. package/domainforge-core/tests/entity_tests.rs +69 -0
  311. package/domainforge-core/tests/evolution_semantics_tests.rs +157 -0
  312. package/domainforge-core/tests/flow_tests.rs +78 -0
  313. package/domainforge-core/tests/flow_unit_validation_tests.rs +31 -0
  314. package/domainforge-core/tests/graph_integration_tests.rs +218 -0
  315. package/domainforge-core/tests/graph_tests.rs +626 -0
  316. package/domainforge-core/tests/import_parsing_tests.rs +23 -0
  317. package/domainforge-core/tests/instance_integration_tests.rs +98 -0
  318. package/domainforge-core/tests/instance_parsing_tests.rs +58 -0
  319. package/domainforge-core/tests/instance_tests.rs +61 -0
  320. package/domainforge-core/tests/kg_uri_encoding_tests.rs +53 -0
  321. package/domainforge-core/tests/lint_tests.rs +19 -0
  322. package/domainforge-core/tests/metric_tests.rs +143 -0
  323. package/domainforge-core/tests/module_resolution_tests.rs +100 -0
  324. package/domainforge-core/tests/namespace_registry_tests.rs +247 -0
  325. package/domainforge-core/tests/null_handling_tests.rs +26 -0
  326. package/domainforge-core/tests/parser_ast_v3.rs +53 -0
  327. package/domainforge-core/tests/parser_dimension_registry_tests.rs +20 -0
  328. package/domainforge-core/tests/parser_integration_tests.rs +294 -0
  329. package/domainforge-core/tests/parser_metadata_tests.rs +97 -0
  330. package/domainforge-core/tests/parser_resource_domain_only_graph_test.rs +21 -0
  331. package/domainforge-core/tests/parser_resource_limits_tests.rs +122 -0
  332. package/domainforge-core/tests/parser_tests.rs +512 -0
  333. package/domainforge-core/tests/pattern_semantics_tests.rs +87 -0
  334. package/domainforge-core/tests/phase_14_determinism_tests.rs +166 -0
  335. package/domainforge-core/tests/phase_15_validation_error_tests.rs +136 -0
  336. package/domainforge-core/tests/phase_16_unicode_tests.rs +248 -0
  337. package/domainforge-core/tests/phase_17_export_tests.rs +285 -0
  338. package/domainforge-core/tests/phase_17_round_trip_tests.rs +264 -0
  339. package/domainforge-core/tests/policy_tests.rs +635 -0
  340. package/domainforge-core/tests/primitives_integration_tests.rs +151 -0
  341. package/domainforge-core/tests/print_rdf_xml.rs +14 -0
  342. package/domainforge-core/tests/printer_tests.rs +204 -0
  343. package/domainforge-core/tests/profile_tests.rs +35 -0
  344. package/domainforge-core/tests/projection_contracts_tests.rs +154 -0
  345. package/domainforge-core/tests/protobuf_projection_tests.rs +199 -0
  346. package/domainforge-core/tests/quantity_tests.rs +41 -0
  347. package/domainforge-core/tests/rdf_xml_typed_literal_tests.rs +105 -0
  348. package/domainforge-core/tests/registry_schema_tests.rs +33 -0
  349. package/domainforge-core/tests/resource_tests.rs +50 -0
  350. package/domainforge-core/tests/resource_unit_tests.rs +24 -0
  351. package/domainforge-core/tests/roles_relations_tests.rs +61 -0
  352. package/domainforge-core/tests/round_trip_tests.rs +34 -0
  353. package/domainforge-core/tests/runtime_toggle_tests.rs +70 -0
  354. package/domainforge-core/tests/sbvr_fact_schema_tests.rs +60 -0
  355. package/domainforge-core/tests/sbvr_flow_facts_tests.rs +55 -0
  356. package/domainforge-core/tests/sbvr_parsing_tests.rs +53 -0
  357. package/domainforge-core/tests/semantic_pack_alias_resolution.rs +197 -0
  358. package/domainforge-core/tests/semantic_pack_build.rs +302 -0
  359. package/domainforge-core/tests/semantic_pack_consumer_smoke.rs +150 -0
  360. package/domainforge-core/tests/semantic_pack_pack_set.rs +160 -0
  361. package/domainforge-core/tests/semantic_pack_signing.rs +157 -0
  362. package/domainforge-core/tests/semantic_pack_three_valued.rs +250 -0
  363. package/domainforge-core/tests/semantic_pack_validate.rs +196 -0
  364. package/domainforge-core/tests/std_lib_tests.rs +37 -0
  365. package/domainforge-core/tests/temporal_evaluation_tests.rs +159 -0
  366. package/domainforge-core/tests/temporal_semantics_tests.rs +214 -0
  367. package/domainforge-core/tests/three_valued_quantifiers_tests.rs +164 -0
  368. package/domainforge-core/tests/turtle_entity_export_tests.rs +38 -0
  369. package/domainforge-core/tests/turtle_escaping_tests.rs +53 -0
  370. package/domainforge-core/tests/turtle_resource_export_tests.rs +34 -0
  371. package/domainforge-core/tests/type_inference_tests.rs +40 -0
  372. package/domainforge-core/tests/unicode_validation_tests.rs +169 -0
  373. package/domainforge-core/tests/unit_tests.rs +81 -0
  374. package/domainforge-core/tests/validate_tests.rs +38 -0
  375. package/domainforge-core/tests/validation_unit_mismatch_tests.rs +83 -0
  376. package/domainforge-core/tests/wasm_tests.rs +229 -0
  377. package/domainforge-python/CHANGELOG-python.md +12 -0
  378. package/domainforge-python/MIGRATING.md +24 -0
  379. package/domainforge-python/README.md +256 -0
  380. package/domainforge-python/domainforge/__init__.py +95 -0
  381. package/domainforge-python/domainforge/domainforge.pyi +519 -0
  382. package/domainforge-python/pyproject.toml +36 -0
  383. package/domainforge-typescript/CHANGELOG-typescript.md +12 -0
  384. package/domainforge-typescript/LICENSE +201 -0
  385. package/domainforge-typescript/MIGRATING.md +24 -0
  386. package/domainforge-typescript/README.md +305 -0
  387. package/domainforge-typescript/index.d.ts +452 -0
  388. package/domainforge-typescript/index.js +361 -0
  389. package/domainforge-typescript/package.json +60 -0
  390. package/example.js +61 -0
  391. package/examples/browser.html +366 -0
  392. package/examples/namespaces/finance/cashflow.sea +5 -0
  393. package/examples/namespaces/logistics/core.sea +7 -0
  394. package/examples/observability_metrics.sea +38 -0
  395. package/fixtures/semantic_packs/acme_procurement/domain/entities.sea +39 -0
  396. package/fixtures/semantic_packs/acme_procurement/domain/metrics.sea +11 -0
  397. package/fixtures/semantic_packs/acme_procurement/domain/relations.sea +7 -0
  398. package/fixtures/semantic_packs/acme_procurement/domain/resources.sea +9 -0
  399. package/fixtures/semantic_packs/acme_procurement/review/acme.procurement.semantic-review.jsonl +7 -0
  400. package/fixtures/semantic_packs/acme_procurement/tests/ambiguous_vendor_alias.sea +8 -0
  401. package/fixtures/semantic_packs/acme_procurement/tests/deprecated_vendor_alias.sea +8 -0
  402. package/fixtures/semantic_packs/acme_procurement/tests/invalid_relation.sea +3 -0
  403. package/fixtures/semantic_packs/acme_procurement/tests/proposed_concept.sea +8 -0
  404. package/fixtures/semantic_packs/acme_procurement/tests/rejected_concept.sea +8 -0
  405. package/fixtures/semantic_packs/acme_procurement/tests/unit_mismatch.sea +7 -0
  406. package/fixtures/semantic_packs/acme_procurement/tests/unknown_vendor_policy.sea +8 -0
  407. package/fixtures/semantic_packs/acme_procurement/tests/valid_purchase_policy.sea +8 -0
  408. package/index.d.ts +2 -0
  409. package/index.js +8 -0
  410. package/justfile +200 -0
  411. package/lefthook.yml +13 -0
  412. package/lib/validate_native_exports.d.ts +4 -0
  413. package/lib/validate_native_exports.js +12 -0
  414. package/package.json +22 -0
  415. package/pytest.ini +5 -0
  416. package/python/tests/test_registry.py +75 -0
  417. package/python/tests/test_units.py +18 -0
  418. package/release-please-config.json +49 -0
  419. package/requirements-dev.txt +3 -0
  420. package/requirements.txt +3 -0
  421. package/rust-toolchain.toml +3 -0
  422. package/schemas/ast-v1.schema.json +72 -0
  423. package/schemas/ast-v2.schema.json +1200 -0
  424. package/schemas/ast-v3.schema.json +1200 -0
  425. package/schemas/sea-registry.schema.json +45 -0
  426. package/scripts/build-python.sh +37 -0
  427. package/scripts/build-release.sh +279 -0
  428. package/scripts/build-typescript.sh +13 -0
  429. package/scripts/build-wasm.sh +113 -0
  430. package/scripts/bump-version.sh +245 -0
  431. package/scripts/check_unused_test_imports.py +85 -0
  432. package/scripts/ci_tasks.py +379 -0
  433. package/scripts/clear_debug_test.sh +10 -0
  434. package/scripts/create-github-release.sh +262 -0
  435. package/scripts/create-tag.sh +203 -0
  436. package/scripts/find_and_link_test_binary.sh +70 -0
  437. package/scripts/generate-changelog.sh +271 -0
  438. package/scripts/generate-release-notes.sh +205 -0
  439. package/scripts/lint_release_security.py +96 -0
  440. package/scripts/lint_release_workflows.py +82 -0
  441. package/scripts/lint_workflow_gates.py +113 -0
  442. package/scripts/optimized-wasm-build.sh +61 -0
  443. package/scripts/patch_napi_types.py +62 -0
  444. package/scripts/pre-release-check.sh +289 -0
  445. package/scripts/prepare_rust_debug.sh +52 -0
  446. package/scripts/release.sh +373 -0
  447. package/scripts/resolve_rust_binary.py +230 -0
  448. package/scripts/run_commitlint.sh +29 -0
  449. package/scripts/test-all.sh +77 -0
  450. package/scripts/update_launch_program.py +93 -0
  451. package/secrets/README.md +27 -0
  452. package/secrets/secrets.yaml +21 -0
  453. package/test_integration.py +67 -0
  454. package/tests/test_authority.py +328 -0
  455. package/tests/test_ci_tasks.py +143 -0
  456. package/tests/test_expression.py +256 -0
  457. package/tests/test_golden_payment_flow.py +42 -0
  458. package/tests/test_graph.py +127 -0
  459. package/tests/test_instance.py +136 -0
  460. package/tests/test_parser.py +82 -0
  461. package/tests/test_primitives.py +68 -0
  462. package/tests/test_role_relation_parity.py +56 -0
  463. package/tests/test_runtime_toggle.py +156 -0
  464. package/tests/test_semantic_pack.py +639 -0
  465. package/tests/test_three_valued_eval.py +159 -0
  466. package/tsconfig.json +30 -0
  467. package/typescript-tests/advanced.test.ts +165 -0
  468. package/typescript-tests/authority.test.ts +216 -0
  469. package/typescript-tests/expression.test.ts +228 -0
  470. package/typescript-tests/golden-payment-flow.test.ts +51 -0
  471. package/typescript-tests/graph.test.ts +142 -0
  472. package/typescript-tests/native-binding.test.ts +20 -0
  473. package/typescript-tests/primitives.test.ts +88 -0
  474. package/typescript-tests/registry.test.ts +122 -0
  475. package/typescript-tests/role_relation.test.ts +63 -0
  476. package/typescript-tests/runtime_toggle.test.ts +141 -0
  477. package/typescript-tests/semantic-pack.test.ts +556 -0
  478. package/typescript-tests/three_valued_eval.test.ts +135 -0
  479. package/typescript-tests/units.test.ts +36 -0
  480. package/vitest.config.ts +13 -0
  481. package/wasm_demo.html +225 -0
@@ -0,0 +1,228 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ Expression,
4
+ NormalizedExpression,
5
+ BinaryOp,
6
+ UnaryOp,
7
+ Quantifier,
8
+ AggregateFunction,
9
+ WindowSpec,
10
+ } from '..';
11
+
12
+ describe('Expression Factory Methods', () => {
13
+ it('creates boolean literal expressions', () => {
14
+ const exprTrue = Expression.literalBool(true);
15
+ expect(exprTrue.toStringRepr()).toBe('true');
16
+
17
+ const exprFalse = Expression.literalBool(false);
18
+ expect(exprFalse.toStringRepr()).toBe('false');
19
+ });
20
+
21
+ it('creates number literal expressions', () => {
22
+ const expr = Expression.literalNumber(42);
23
+ expect(expr.toStringRepr()).toContain('42');
24
+ });
25
+
26
+ it('creates string literal expressions', () => {
27
+ const expr = Expression.literalString('hello');
28
+ expect(expr.toStringRepr()).toContain('hello');
29
+ });
30
+
31
+ it('creates variable expressions', () => {
32
+ const expr = Expression.variable('x');
33
+ expect(expr.toStringRepr()).toBe('x');
34
+ });
35
+
36
+ it('creates quantity expressions', () => {
37
+ const expr = Expression.quantity('100', 'USD');
38
+ const str = expr.toStringRepr();
39
+ expect(str).toContain('100');
40
+ expect(str).toContain('USD');
41
+ });
42
+
43
+ it('creates time expressions', () => {
44
+ const expr = Expression.time('2025-01-01T00:00:00Z');
45
+ expect(expr.toStringRepr()).toContain('2025-01-01');
46
+ });
47
+
48
+ it('creates interval expressions', () => {
49
+ const expr = Expression.interval('2025-01-01T09:00:00Z', '2025-01-01T17:00:00Z');
50
+ const str = expr.toStringRepr();
51
+ expect(str).toContain('09:00:00');
52
+ expect(str).toContain('17:00:00');
53
+ });
54
+
55
+ it('creates binary expressions', () => {
56
+ const left = Expression.variable('a');
57
+ const right = Expression.variable('b');
58
+ const expr = Expression.binary(BinaryOp.And, left, right);
59
+ const str = expr.toStringRepr();
60
+ expect(str).toContain('AND');
61
+ expect(str).toContain('a');
62
+ expect(str).toContain('b');
63
+ });
64
+
65
+ it('creates unary NOT expressions', () => {
66
+ const operand = Expression.variable('x');
67
+ const expr = Expression.unary(UnaryOp.Not, operand);
68
+ const str = expr.toStringRepr();
69
+ expect(str).toContain('NOT');
70
+ expect(str).toContain('x');
71
+ });
72
+
73
+ it('creates member access expressions', () => {
74
+ const expr = Expression.memberAccess('user', 'name');
75
+ const str = expr.toStringRepr();
76
+ expect(str).toContain('user');
77
+ expect(str).toContain('name');
78
+ });
79
+
80
+ it('creates cast expressions', () => {
81
+ const operand = Expression.variable('x');
82
+ const expr = Expression.cast(operand, 'Money');
83
+ const str = expr.toStringRepr();
84
+ expect(str).toContain('x');
85
+ expect(str).toContain('Money');
86
+ });
87
+
88
+ it('creates quantifier expressions', () => {
89
+ const collection = Expression.variable('items');
90
+ const condition = Expression.variable('valid');
91
+ const expr = Expression.quantifier(Quantifier.ForAll, 'x', collection, condition);
92
+ const str = expr.toStringRepr().toLowerCase();
93
+ expect(str).toContain('forall');
94
+ });
95
+
96
+ it('creates aggregation expressions', () => {
97
+ const collection = Expression.variable('items');
98
+ const expr = Expression.aggregation(AggregateFunction.Count, collection, null, null);
99
+ const str = expr.toStringRepr().toLowerCase();
100
+ expect(str).toContain('count');
101
+ });
102
+ });
103
+
104
+ describe('Normalization', () => {
105
+ it('returns a NormalizedExpression', () => {
106
+ const expr = Expression.variable('x');
107
+ const normalized = expr.normalize();
108
+ expect(normalized).toBeDefined();
109
+ expect(typeof normalized.stableHash).toBe('function');
110
+ });
111
+
112
+ it('eliminates identity (true AND x → x)', () => {
113
+ const trueExpr = Expression.literalBool(true);
114
+ const xExpr = Expression.variable('x');
115
+ const expr = Expression.binary(BinaryOp.And, trueExpr, xExpr);
116
+ const normalized = expr.normalize();
117
+ expect(normalized.toStringRepr()).toBe('x');
118
+ });
119
+
120
+ it('eliminates identity (false OR x → x)', () => {
121
+ const falseExpr = Expression.literalBool(false);
122
+ const xExpr = Expression.variable('x');
123
+ const expr = Expression.binary(BinaryOp.Or, falseExpr, xExpr);
124
+ const normalized = expr.normalize();
125
+ expect(normalized.toStringRepr()).toBe('x');
126
+ });
127
+
128
+ it('sorts commutative operands', () => {
129
+ const b = Expression.variable('b');
130
+ const a = Expression.variable('a');
131
+ const expr = Expression.binary(BinaryOp.And, b, a);
132
+ const normalized = expr.normalize();
133
+ expect(normalized.toStringRepr()).toBe('(a AND b)');
134
+ });
135
+
136
+ it('applies idempotence (a AND a → a)', () => {
137
+ const a = Expression.variable('a');
138
+ const expr = Expression.binary(BinaryOp.And, a, a);
139
+ const normalized = expr.normalize();
140
+ expect(normalized.toStringRepr()).toBe('a');
141
+ });
142
+
143
+ it('eliminates double negation (NOT NOT x → x)', () => {
144
+ const x = Expression.variable('x');
145
+ const notX = Expression.unary(UnaryOp.Not, x);
146
+ const notNotX = Expression.unary(UnaryOp.Not, notX);
147
+ const normalized = notNotX.normalize();
148
+ expect(normalized.toStringRepr()).toBe('x');
149
+ });
150
+ });
151
+
152
+ describe('Equivalence', () => {
153
+ it('recognizes equivalent expressions', () => {
154
+ const a1 = Expression.variable('a');
155
+ const b1 = Expression.variable('b');
156
+ const expr1 = Expression.binary(BinaryOp.And, a1, b1);
157
+
158
+ const a2 = Expression.variable('a');
159
+ const b2 = Expression.variable('b');
160
+ const expr2 = Expression.binary(BinaryOp.And, b2, a2);
161
+
162
+ expect(expr1.isEquivalent(expr2)).toBe(true);
163
+ });
164
+
165
+ it('recognizes non-equivalent expressions', () => {
166
+ const a = Expression.variable('a');
167
+ const b = Expression.variable('b');
168
+ const c = Expression.variable('c');
169
+
170
+ const expr1 = Expression.binary(BinaryOp.And, a, b);
171
+ const expr2 = Expression.binary(BinaryOp.And, a, c);
172
+
173
+ expect(expr1.isEquivalent(expr2)).toBe(false);
174
+ });
175
+ });
176
+
177
+ describe('Stable Hash', () => {
178
+ it('is deterministic', () => {
179
+ const expr = Expression.variable('x');
180
+ const hash1 = expr.normalize().stableHash();
181
+ const hash2 = expr.normalize().stableHash();
182
+ expect(hash1).toBe(hash2);
183
+ });
184
+
185
+ it('is the same for equivalent expressions', () => {
186
+ const a1 = Expression.variable('a');
187
+ const b1 = Expression.variable('b');
188
+ const expr1 = Expression.binary(BinaryOp.And, a1, b1);
189
+
190
+ const a2 = Expression.variable('a');
191
+ const b2 = Expression.variable('b');
192
+ const expr2 = Expression.binary(BinaryOp.And, b2, a2);
193
+
194
+ expect(expr1.normalize().stableHash()).toBe(expr2.normalize().stableHash());
195
+ });
196
+
197
+ it('has hex representation', () => {
198
+ const expr = Expression.variable('x');
199
+ const hashHex = expr.normalize().stableHashHex();
200
+ expect(hashHex).toMatch(/^0x[0-9a-f]+$/);
201
+ });
202
+ });
203
+
204
+ describe('NormalizedExpression Methods', () => {
205
+ it('returns inner expression', () => {
206
+ const expr = Expression.variable('x');
207
+ const normalized = expr.normalize();
208
+ const inner = normalized.innerExpression();
209
+ expect(inner.toStringRepr()).toBe('x');
210
+ });
211
+
212
+ it('has string representation', () => {
213
+ const expr = Expression.variable('x');
214
+ const normalized = expr.normalize();
215
+ expect(normalized.toStringRepr()).toBe('x');
216
+ });
217
+
218
+ it('supports equality check', () => {
219
+ const a = Expression.variable('a');
220
+ const b = Expression.variable('b');
221
+ const expr1 = Expression.binary(BinaryOp.And, a, b);
222
+ const expr2 = Expression.binary(BinaryOp.And, b, a);
223
+
224
+ const norm1 = expr1.normalize();
225
+ const norm2 = expr2.normalize();
226
+ expect(norm1.equals(norm2)).toBe(true);
227
+ });
228
+ });
@@ -0,0 +1,51 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { Graph } from '../index';
3
+
4
+ const PAYMENT_DSL = `
5
+ Role "Payer"
6
+ Role "Payee"
7
+
8
+ Resource "Money" units
9
+
10
+ Entity "Alice"
11
+ Entity "Bob"
12
+
13
+ Flow "Money" from "Alice" to "Bob" quantity 10
14
+
15
+ Relation "Payment"
16
+ subject: "Payer"
17
+ predicate: "pays"
18
+ object: "Payee"
19
+ via: flow "Money"
20
+ `;
21
+
22
+ describe('Payment role flow golden path', () => {
23
+ it('parses roles, relations, and flows consistently', () => {
24
+ const graph = Graph.parse(PAYMENT_DSL);
25
+
26
+ expect(graph.entityCount()).toBe(2);
27
+ expect(graph.resourceCount()).toBe(1);
28
+ expect(graph.flowCount()).toBe(1);
29
+ expect(graph.roleCount()).toBe(2);
30
+ expect(graph.relationCount()).toBe(1);
31
+
32
+ const roles = Object.fromEntries(
33
+ graph.allRoles().map((role) => [role.name, role.id])
34
+ );
35
+ expect(roles).toHaveProperty('Payer');
36
+ expect(roles).toHaveProperty('Payee');
37
+
38
+ const relations = graph.allRelations();
39
+ expect(relations).toHaveLength(1);
40
+ expect(relations[0].name).toBe('Payment');
41
+ expect(relations[0].predicate).toBe('pays');
42
+ expect(relations[0].subjectRoleId).toBe(roles.Payer);
43
+ expect(relations[0].objectRoleId).toBe(roles.Payee);
44
+ const flows = graph.allFlows();
45
+ expect(flows).toHaveLength(1);
46
+ const flowResource = flows[0].resourceId ? graph.getResource(flows[0].resourceId) : null;
47
+ expect(flowResource).not.toBeNull();
48
+ expect(flowResource?.name).toBe('Money');
49
+ expect(flows[0].quantity).toBe(10);
50
+ });
51
+ });
@@ -0,0 +1,142 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Graph, Entity, Resource, Flow } from '../index';
3
+
4
+ describe('Graph', () => {
5
+ it('creates empty graph', () => {
6
+ const graph = new Graph();
7
+ expect(graph.entityCount()).toBe(0);
8
+ expect(graph.resourceCount()).toBe(0);
9
+ expect(graph.flowCount()).toBe(0);
10
+ });
11
+
12
+ it('adds entities', () => {
13
+ const graph = new Graph();
14
+ const entity = new Entity('Warehouse');
15
+
16
+ graph.addEntity(entity);
17
+ expect(graph.entityCount()).toBe(1);
18
+ expect(graph.hasEntity(entity.id)).toBe(true);
19
+ });
20
+
21
+ it('adds resources', () => {
22
+ const graph = new Graph();
23
+ const resource = new Resource('Cameras', 'units');
24
+
25
+ graph.addResource(resource);
26
+ expect(graph.resourceCount()).toBe(1);
27
+ expect(graph.hasResource(resource.id)).toBe(true);
28
+ });
29
+
30
+ it('adds flows', () => {
31
+ const graph = new Graph();
32
+ const entity1 = new Entity('Warehouse');
33
+ const entity2 = new Entity('Factory');
34
+ const resource = new Resource('Cameras', 'units');
35
+
36
+ graph.addEntity(entity1);
37
+ graph.addEntity(entity2);
38
+ graph.addResource(resource);
39
+
40
+ const flow = new Flow(resource.id, entity1.id, entity2.id, 100);
41
+ graph.addFlow(flow);
42
+
43
+ expect(graph.flowCount()).toBe(1);
44
+ });
45
+
46
+ it('retrieves entities by ID', () => {
47
+ const graph = new Graph();
48
+ const entity = new Entity('Warehouse');
49
+
50
+ graph.addEntity(entity);
51
+ const retrieved = graph.getEntity(entity.id);
52
+
53
+ expect(retrieved).not.toBeNull();
54
+ expect(retrieved!.name).toBe('Warehouse');
55
+ });
56
+
57
+ it('finds entities by name', () => {
58
+ const graph = new Graph();
59
+ const entity = new Entity('Warehouse');
60
+
61
+ graph.addEntity(entity);
62
+ const foundId = graph.findEntityByName('Warehouse');
63
+
64
+ expect(foundId).toBe(entity.id);
65
+ });
66
+
67
+ it('queries flows from entity', () => {
68
+ const graph = new Graph();
69
+ const entity1 = new Entity('Warehouse');
70
+ const entity2 = new Entity('Factory');
71
+ const resource = new Resource('Cameras', 'units');
72
+
73
+ graph.addEntity(entity1);
74
+ graph.addEntity(entity2);
75
+ graph.addResource(resource);
76
+
77
+ const flow = new Flow(resource.id, entity1.id, entity2.id, 100);
78
+ graph.addFlow(flow);
79
+
80
+ const flows = graph.flowsFrom(entity1.id);
81
+ expect(flows.length).toBe(1);
82
+ expect(flows[0].quantity).toBe(100);
83
+ });
84
+
85
+ it('queries flows to entity', () => {
86
+ const graph = new Graph();
87
+ const entity1 = new Entity('Warehouse');
88
+ const entity2 = new Entity('Factory');
89
+ const resource = new Resource('Cameras', 'units');
90
+
91
+ graph.addEntity(entity1);
92
+ graph.addEntity(entity2);
93
+ graph.addResource(resource);
94
+
95
+ const flow = new Flow(resource.id, entity1.id, entity2.id, 100);
96
+ graph.addFlow(flow);
97
+
98
+ const flows = graph.flowsTo(entity2.id);
99
+ expect(flows.length).toBe(1);
100
+ expect(flows[0].quantity).toBe(100);
101
+ });
102
+
103
+ it('lists all entities', () => {
104
+ const graph = new Graph();
105
+ graph.addEntity(new Entity('Warehouse'));
106
+ graph.addEntity(new Entity('Factory'));
107
+
108
+ const entities = graph.allEntities();
109
+ expect(entities.length).toBe(2);
110
+ });
111
+
112
+ it('parses SEA DSL', () => {
113
+ const source = `
114
+ Entity "Warehouse" in logistics
115
+ Entity "Factory" in manufacturing
116
+ Resource "Cameras" units
117
+ Flow "Cameras" from "Warehouse" to "Factory" quantity 100
118
+ `;
119
+
120
+ const graph = Graph.parse(source);
121
+ expect(graph.entityCount()).toBe(2);
122
+ expect(graph.resourceCount()).toBe(1);
123
+ expect(graph.flowCount()).toBe(1);
124
+ });
125
+
126
+ it('parses complex DSL with namespaces', () => {
127
+ const source = `
128
+ Entity "Main Warehouse" in logistics
129
+ Entity "Assembly Line" in manufacturing
130
+ Resource "Electronic Components" units in electronics
131
+ Flow "Electronic Components" from "Main Warehouse" to "Assembly Line" quantity 500
132
+ `;
133
+
134
+ const graph = Graph.parse(source);
135
+ const entities = graph.allEntities();
136
+ const resources = graph.allResources();
137
+
138
+ expect(entities.some(e => e.namespace === 'logistics')).toBe(true);
139
+ expect(entities.some(e => e.namespace === 'manufacturing')).toBe(true);
140
+ expect(resources.some(r => r.namespace === 'electronics')).toBe(true);
141
+ });
142
+ });
@@ -0,0 +1,20 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { validateNativeExports } from '../lib/validate_native_exports';
3
+
4
+ describe('validateNativeExports helper', () => {
5
+ it('throws a helpful error when required exports are missing', () => {
6
+ const fakeBinding = { Graph: {} }; // minimal missing many required symbols
7
+ const required = ['Graph', 'Entity', 'Resource'];
8
+ expect(() => validateNativeExports(fakeBinding, required)).toThrowError(/Missing required export\(s\): Entity, Resource|missing required export/i);
9
+ });
10
+
11
+ it('does not throw when required exports are present', () => {
12
+ const fakeBinding = {
13
+ Graph: {},
14
+ Entity: {},
15
+ Resource: {},
16
+ };
17
+ const required = ['Graph', 'Entity', 'Resource'];
18
+ expect(() => validateNativeExports(fakeBinding, required)).not.toThrow();
19
+ });
20
+ });
@@ -0,0 +1,88 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Entity, Resource, Flow, ResourceInstance } from '../index';
3
+
4
+ describe('Entity', () => {
5
+ it('creates entity with name', () => {
6
+ const entity = new Entity('Warehouse A');
7
+ expect(entity.name).toBe('Warehouse A');
8
+ expect(entity.id).toHaveLength(36);
9
+ });
10
+
11
+ it('supports namespaces', () => {
12
+ const entity = new Entity('Factory', 'manufacturing');
13
+ expect(entity.namespace).toBe('manufacturing');
14
+ });
15
+
16
+ it('manages attributes', () => {
17
+ const entity = new Entity('Warehouse');
18
+ entity.setAttribute('capacity', JSON.stringify(10000));
19
+ expect(JSON.parse(entity.getAttribute('capacity')!)).toBe(10000);
20
+ });
21
+
22
+ it('handles complex attributes', () => {
23
+ const entity = new Entity('Warehouse');
24
+ entity.setAttribute('location', JSON.stringify({ lat: 40.7128, lng: -74.0060 }));
25
+ const location = JSON.parse(entity.getAttribute('location')!);
26
+ expect(location.lat).toBe(40.7128);
27
+ expect(location.lng).toBe(-74.0060);
28
+ });
29
+ });
30
+
31
+ describe('Resource', () => {
32
+ it('creates resource with unit', () => {
33
+ const resource = new Resource('Cameras', 'units');
34
+ expect(resource.name).toBe('Cameras');
35
+ expect(resource.unit).toBe('units');
36
+ expect(resource.id).toHaveLength(36);
37
+ });
38
+
39
+ it('supports namespaces', () => {
40
+ const resource = new Resource('Steel', 'kg', 'materials');
41
+ expect(resource.namespace).toBe('materials');
42
+ });
43
+
44
+ it('manages attributes', () => {
45
+ const resource = new Resource('Cameras', 'units');
46
+ resource.setAttribute('model', JSON.stringify('HD-2000'));
47
+ expect(JSON.parse(resource.getAttribute('model')!)).toBe('HD-2000');
48
+ });
49
+ });
50
+
51
+ describe('Flow', () => {
52
+ it('creates flow between entities', () => {
53
+ const entity1 = new Entity('Warehouse');
54
+ const entity2 = new Entity('Factory');
55
+ const resource = new Resource('Cameras', 'units');
56
+
57
+ const flow = new Flow(resource.id, entity1.id, entity2.id, 100);
58
+ expect(flow.resourceId).toBe(resource.id);
59
+ expect(flow.fromId).toBe(entity1.id);
60
+ expect(flow.toId).toBe(entity2.id);
61
+ expect(flow.quantity).toBe(100);
62
+ });
63
+
64
+ it('throws on invalid UUID', () => {
65
+ expect(() => {
66
+ new Flow('invalid-uuid', 'also-invalid', 'still-invalid', 100);
67
+ }).toThrow();
68
+ });
69
+ });
70
+
71
+ describe('ResourceInstance', () => {
72
+ it('creates instance', () => {
73
+ const entity = new Entity('Warehouse');
74
+ const resource = new Resource('Cameras', 'units');
75
+
76
+ const instance = new ResourceInstance(resource.id, entity.id);
77
+ expect(instance.resourceId).toBe(resource.id);
78
+ expect(instance.entityId).toBe(entity.id);
79
+ });
80
+
81
+ it('supports namespaces', () => {
82
+ const entity = new Entity('Warehouse');
83
+ const resource = new Resource('Cameras', 'units');
84
+
85
+ const instance = new ResourceInstance(resource.id, entity.id, 'inventory');
86
+ expect(instance.namespace).toBe('inventory');
87
+ });
88
+ });
@@ -0,0 +1,122 @@
1
+ import * as fs from 'fs';
2
+ import { tmpdir } from 'os';
3
+ import * as path from 'path';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { NamespaceRegistry } from '../index';
6
+
7
+ describe('NamespaceRegistry (TS)', () => {
8
+ it('discovers and resolves files', () => {
9
+ // Skip test if addon does not expose namespace registry (prebuilt binaries)
10
+ if ((global as any).NamespaceRegistry === undefined) {
11
+ // Access via require('./index') module import
12
+ const index = require('../index');
13
+ if (!index.NamespaceRegistry) {
14
+ // Skip runtime assertion rather than failing the build
15
+ return;
16
+ }
17
+ }
18
+ const base = fs.mkdtempSync(path.join(tmpdir(), 'sea-test-'));
19
+ const dir = path.join(base, 'domains', 'logistics');
20
+ fs.mkdirSync(dir, { recursive: true });
21
+ const filePath = path.join(dir, 'warehouse.sea');
22
+ fs.writeFileSync(filePath, 'Entity "Warehouse"');
23
+
24
+ const registryPath = path.join(base, '.sea-registry.toml');
25
+ const content = `version = 1\ndefault_namespace = "default"\n\n[[namespaces]]\nnamespace = "logistics"\npatterns = ["domains/logistics/**/*.sea"]\n`;
26
+ fs.writeFileSync(registryPath, content);
27
+
28
+ const reg = NamespaceRegistry.fromFile(registryPath);
29
+ expect(reg).toBeDefined();
30
+ const files = reg.resolveFiles();
31
+ expect(files.length).toBe(1);
32
+ expect(files[0].path).toBe(filePath);
33
+ expect(files[0].namespace).toBe('logistics');
34
+
35
+ const ns = reg.namespaceFor(filePath);
36
+ expect(ns).toBe('logistics');
37
+ });
38
+
39
+ it('enforces precedence longest prefix', () => {
40
+ if ((global as any).NamespaceRegistry === undefined) {
41
+ const index = require('../index');
42
+ if (!index.NamespaceRegistry) {
43
+ return;
44
+ }
45
+ }
46
+ const base = fs.mkdtempSync(path.join(tmpdir(), 'sea-test-'));
47
+ const dir = path.join(base, 'domains', 'logistics');
48
+ fs.mkdirSync(dir, { recursive: true });
49
+ const filePath = path.join(dir, 'warehouse.sea');
50
+ fs.writeFileSync(filePath, 'Entity "Warehouse"');
51
+
52
+ const registryPath = path.join(base, '.sea-registry.toml');
53
+ const content = `version = 1\ndefault_namespace = "default"\n\n[[namespaces]]\nnamespace = "short"\npatterns = ["domains/**/*.sea"]\n\n[[namespaces]]\nnamespace = "long"\npatterns = ["domains/logistics/**/*.sea"]\n`;
54
+ fs.writeFileSync(registryPath, content);
55
+
56
+ const reg = NamespaceRegistry.fromFile(registryPath);
57
+ expect(reg).toBeDefined();
58
+ const ns = reg.namespaceFor(filePath);
59
+ expect(ns).toBe('long');
60
+ });
61
+
62
+ it('enforces alphabetical tie-breaker', () => {
63
+ if ((global as any).NamespaceRegistry === undefined) {
64
+ const index = require('../index');
65
+ if (!index.NamespaceRegistry) {
66
+ return;
67
+ }
68
+ }
69
+ const base = fs.mkdtempSync(path.join(tmpdir(), 'sea-test-'));
70
+ const dir = path.join(base, 'domains', 'logistics');
71
+ fs.mkdirSync(dir, { recursive: true });
72
+ const filePath = path.join(dir, 'warehouse.sea');
73
+ fs.writeFileSync(filePath, 'Entity "Warehouse"');
74
+
75
+ const registryPath = path.join(base, '.sea-registry.toml');
76
+ const content = `version = 1\ndefault_namespace = "default"\n\n[[namespaces]]\nnamespace = "logistics"\npatterns = ["domains/*/warehouse.sea"]\n\n[[namespaces]]\nnamespace = "finance"\npatterns = ["domains/*/warehouse.sea"]\n`;
77
+ fs.writeFileSync(registryPath, content);
78
+
79
+ const reg = NamespaceRegistry.fromFile(registryPath);
80
+ expect(reg).toBeDefined();
81
+ const ns = reg.namespaceFor(filePath);
82
+ expect(ns).toBe('finance');
83
+ });
84
+
85
+ it('errors on ambiguous match when fail flag set', () => {
86
+ if ((global as any).NamespaceRegistry === undefined) {
87
+ const index = require('../index');
88
+ if (!index.NamespaceRegistry) {
89
+ return;
90
+ }
91
+ }
92
+ const base = fs.mkdtempSync(path.join(tmpdir(), 'sea-test-'));
93
+ const dir = path.join(base, 'domains', 'logistics');
94
+ fs.mkdirSync(dir, { recursive: true });
95
+ const filePath = path.join(dir, 'warehouse.sea');
96
+ fs.writeFileSync(filePath, 'Entity "Warehouse"');
97
+
98
+ const registryPath = path.join(base, '.sea-registry.toml');
99
+ const content = `version = 1\ndefault_namespace = "default"\n\n[[namespaces]]\nnamespace = "logistics"\npatterns = ["domains/*/warehouse.sea"]\n\n[[namespaces]]\nnamespace = "finance"\npatterns = ["domains/*/warehouse.sea"]\n`;
100
+ fs.writeFileSync(registryPath, content);
101
+
102
+ const reg = NamespaceRegistry.fromFile(registryPath);
103
+ expect(reg).toBeDefined();
104
+ let threw = false;
105
+ try {
106
+ // pass true to indicate failing on ambiguity
107
+ reg.namespaceFor(filePath, true);
108
+ } catch (err) {
109
+ threw = true;
110
+ }
111
+ expect(threw).toBe(true);
112
+
113
+ // resolveFiles should error as well
114
+ threw = false;
115
+ try {
116
+ reg.resolveFiles(true);
117
+ } catch (err) {
118
+ threw = true;
119
+ }
120
+ expect(threw).toBe(true);
121
+ });
122
+ });