@lssm/lib.contracts 1.41.1 → 1.42.2

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 (499) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -4
  3. package/dist/_virtual/rolldown_runtime.js +37 -1
  4. package/dist/app-config/app-config.feature.d.ts +11 -0
  5. package/dist/app-config/app-config.feature.js +54 -1
  6. package/dist/app-config/branding.d.ts +55 -0
  7. package/dist/app-config/contracts.d.ts +245 -0
  8. package/dist/app-config/contracts.js +395 -1
  9. package/dist/app-config/docs/app-config.docblock.d.ts +6 -0
  10. package/dist/app-config/docs/app-config.docblock.js +21 -220
  11. package/dist/app-config/events.d.ts +122 -0
  12. package/dist/app-config/events.js +174 -1
  13. package/dist/app-config/index.d.ts +9 -0
  14. package/dist/app-config/index.js +8 -1
  15. package/dist/app-config/lifecycle-contracts.d.ts +273 -0
  16. package/dist/app-config/lifecycle-contracts.js +440 -1
  17. package/dist/app-config/lifecycle.d.ts +27 -0
  18. package/dist/app-config/runtime.d.ts +117 -0
  19. package/dist/app-config/runtime.js +617 -1
  20. package/dist/app-config/spec.d.ts +172 -0
  21. package/dist/app-config/spec.js +36 -1
  22. package/dist/app-config/validation.d.ts +49 -0
  23. package/dist/app-config/validation.js +538 -1
  24. package/dist/capabilities/capabilities.d.ts +48 -0
  25. package/dist/capabilities/capabilities.js +50 -0
  26. package/dist/capabilities/docs/capabilities.docblock.d.ts +6 -0
  27. package/dist/capabilities/docs/capabilities.docblock.js +21 -1
  28. package/dist/capabilities/index.d.ts +3 -0
  29. package/dist/capabilities/index.js +4 -0
  30. package/dist/capabilities/openbanking.d.ts +10 -0
  31. package/dist/capabilities/openbanking.js +92 -1
  32. package/dist/client/index.d.ts +6 -0
  33. package/dist/client/index.js +9 -1
  34. package/dist/client/react/drivers/rn-reusables.d.ts +22 -0
  35. package/dist/client/react/drivers/rn-reusables.js +21 -1
  36. package/dist/client/react/drivers/shadcn.d.ts +12 -0
  37. package/dist/client/react/drivers/shadcn.js +11 -1
  38. package/dist/client/react/feature-render.d.ts +21 -0
  39. package/dist/client/react/feature-render.js +44 -1
  40. package/dist/client/react/form-render.d.ts +92 -0
  41. package/dist/client/react/form-render.js +298 -1
  42. package/dist/client/react/index.d.ts +5 -0
  43. package/dist/client/react/index.js +8 -1
  44. package/dist/contract-registry/index.d.ts +3 -0
  45. package/dist/contract-registry/index.js +3 -1
  46. package/dist/contract-registry/schemas.d.ts +124 -0
  47. package/dist/contract-registry/schemas.js +61 -1
  48. package/dist/contract-registry/types.d.ts +46 -0
  49. package/dist/data-views/data-views.d.ts +138 -0
  50. package/dist/data-views/data-views.js +58 -0
  51. package/dist/data-views/docs/data-views.docblock.d.ts +6 -0
  52. package/dist/data-views/docs/data-views.docblock.js +21 -1
  53. package/dist/data-views/index.d.ts +4 -0
  54. package/dist/data-views/index.js +5 -0
  55. package/dist/data-views/query-generator.d.ts +40 -0
  56. package/dist/data-views/query-generator.js +48 -1
  57. package/dist/data-views/runtime.d.ts +27 -0
  58. package/dist/data-views/runtime.js +39 -1
  59. package/dist/docs/accessibility_wcag_compliance_specs.docblock.d.ts +6 -0
  60. package/dist/docs/accessibility_wcag_compliance_specs.docblock.js +17 -350
  61. package/dist/docs/index.d.ts +6 -0
  62. package/dist/docs/index.js +27 -1
  63. package/dist/docs/meta.docs.d.ts +6 -0
  64. package/dist/docs/meta.docs.js +18 -2
  65. package/dist/docs/presentations.d.ts +33 -0
  66. package/dist/docs/presentations.js +64 -1
  67. package/dist/docs/registry.d.ts +23 -0
  68. package/dist/docs/registry.js +51 -1
  69. package/dist/docs/tech/auth/better-auth-nextjs.docblock.d.ts +6 -0
  70. package/dist/docs/tech/auth/better-auth-nextjs.docblock.js +25 -2
  71. package/dist/docs/tech/contracts/README.docblock.d.ts +6 -0
  72. package/dist/docs/tech/contracts/README.docblock.js +21 -1
  73. package/dist/docs/tech/contracts/create-subscription.docblock.d.ts +6 -0
  74. package/dist/docs/tech/contracts/create-subscription.docblock.js +21 -1
  75. package/dist/docs/tech/contracts/graphql-typed-outputs.docblock.d.ts +6 -0
  76. package/dist/docs/tech/contracts/graphql-typed-outputs.docblock.js +21 -180
  77. package/dist/docs/tech/contracts/migrations.docblock.d.ts +6 -0
  78. package/dist/docs/tech/contracts/migrations.docblock.js +21 -1
  79. package/dist/docs/tech/contracts/openapi-export.docblock.d.ts +6 -0
  80. package/dist/docs/tech/contracts/openapi-export.docblock.js +25 -5
  81. package/dist/docs/tech/contracts/ops-to-presentation-linking.docblock.d.ts +6 -0
  82. package/dist/docs/tech/contracts/ops-to-presentation-linking.docblock.js +19 -60
  83. package/dist/docs/tech/contracts/overlays.docblock.d.ts +6 -0
  84. package/dist/docs/tech/contracts/overlays.docblock.js +21 -68
  85. package/dist/docs/tech/contracts/tests.docblock.d.ts +6 -0
  86. package/dist/docs/tech/contracts/tests.docblock.js +21 -132
  87. package/dist/docs/tech/contracts/themes.docblock.d.ts +6 -0
  88. package/dist/docs/tech/contracts/themes.docblock.js +21 -1
  89. package/dist/docs/tech/contracts/vertical-pocket-family-office.docblock.d.ts +6 -0
  90. package/dist/docs/tech/contracts/vertical-pocket-family-office.docblock.js +21 -106
  91. package/dist/docs/tech/lifecycle-stage-system.docblock.d.ts +6 -0
  92. package/dist/docs/tech/lifecycle-stage-system.docblock.js +17 -213
  93. package/dist/docs/tech/llm/llm-integration.docblock.d.ts +7 -0
  94. package/dist/docs/tech/llm/llm-integration.docblock.js +76 -7
  95. package/dist/docs/tech/mcp-endpoints.docblock.d.ts +6 -0
  96. package/dist/docs/tech/mcp-endpoints.docblock.js +38 -1
  97. package/dist/docs/tech/presentation-runtime.docblock.d.ts +6 -0
  98. package/dist/docs/tech/presentation-runtime.docblock.js +17 -1
  99. package/dist/docs/tech/schema/README.docblock.d.ts +6 -0
  100. package/dist/docs/tech/schema/README.docblock.js +21 -262
  101. package/dist/docs/tech/studio/learning-events.docblock.d.ts +6 -0
  102. package/dist/docs/tech/studio/learning-events.docblock.js +49 -1
  103. package/dist/docs/tech/studio/learning-journeys.docblock.d.ts +6 -0
  104. package/dist/docs/tech/studio/learning-journeys.docblock.js +25 -2
  105. package/dist/docs/tech/studio/platform-admin-panel.docblock.d.ts +6 -0
  106. package/dist/docs/tech/studio/platform-admin-panel.docblock.js +24 -2
  107. package/dist/docs/tech/studio/project-access-teams.docblock.d.ts +6 -0
  108. package/dist/docs/tech/studio/project-access-teams.docblock.js +26 -16
  109. package/dist/docs/tech/studio/project-routing.docblock.d.ts +6 -0
  110. package/dist/docs/tech/studio/project-routing.docblock.js +68 -1
  111. package/dist/docs/tech/studio/sandbox-unlogged.docblock.d.ts +6 -0
  112. package/dist/docs/tech/studio/sandbox-unlogged.docblock.js +23 -2
  113. package/dist/docs/tech/studio/team-invitations.docblock.d.ts +6 -0
  114. package/dist/docs/tech/studio/team-invitations.docblock.js +41 -36
  115. package/dist/docs/tech/studio/workspace-ops.docblock.d.ts +6 -0
  116. package/dist/docs/tech/studio/workspace-ops.docblock.js +48 -1
  117. package/dist/docs/tech/studio/workspaces.docblock.d.ts +6 -0
  118. package/dist/docs/tech/studio/workspaces.docblock.js +24 -2
  119. package/dist/docs/tech/telemetry-ingest.docblock.d.ts +6 -0
  120. package/dist/docs/tech/telemetry-ingest.docblock.js +37 -3
  121. package/dist/docs/tech/templates/runtime.docblock.d.ts +6 -0
  122. package/dist/docs/tech/templates/runtime.docblock.js +21 -1
  123. package/dist/docs/tech/vscode-extension.docblock.d.ts +6 -0
  124. package/dist/docs/tech/vscode-extension.docblock.js +37 -3
  125. package/dist/docs/tech/workflows/overview.docblock.d.ts +6 -0
  126. package/dist/docs/tech/workflows/overview.docblock.js +21 -1
  127. package/dist/docs/tech-contracts.docs.d.ts +6 -0
  128. package/dist/docs/tech-contracts.docs.js +27 -7
  129. package/dist/docs/types.d.ts +41 -0
  130. package/dist/events.d.ts +47 -0
  131. package/dist/events.js +19 -1
  132. package/dist/experiments/docs/experiments.docblock.d.ts +6 -0
  133. package/dist/experiments/docs/experiments.docblock.js +21 -128
  134. package/dist/experiments/evaluator.d.ts +37 -0
  135. package/dist/experiments/evaluator.js +101 -1
  136. package/dist/experiments/spec-resolver.d.ts +17 -0
  137. package/dist/experiments/spec.d.ts +82 -0
  138. package/dist/experiments/spec.js +33 -1
  139. package/dist/features.d.ts +104 -0
  140. package/dist/features.js +91 -1
  141. package/dist/forms/docs/forms.docblock.d.ts +6 -0
  142. package/dist/forms/docs/forms.docblock.js +21 -1
  143. package/dist/forms/forms.d.ts +266 -0
  144. package/dist/forms/forms.js +146 -0
  145. package/dist/forms/index.d.ts +2 -0
  146. package/dist/forms/index.js +3 -0
  147. package/dist/index.d.ts +142 -0
  148. package/dist/index.js +119 -1
  149. package/dist/install.d.ts +77 -0
  150. package/dist/install.js +40 -1
  151. package/dist/integrations/binding.d.ts +17 -0
  152. package/dist/integrations/connection.d.ts +51 -0
  153. package/dist/integrations/docs/integrations.docblock.d.ts +6 -0
  154. package/dist/integrations/docs/integrations.docblock.js +94 -1
  155. package/dist/integrations/health.d.ts +21 -0
  156. package/dist/integrations/health.js +69 -1
  157. package/dist/integrations/index.d.ts +34 -0
  158. package/dist/integrations/index.js +23 -1
  159. package/dist/integrations/integrations.feature.d.ts +11 -0
  160. package/dist/integrations/integrations.feature.js +60 -0
  161. package/dist/integrations/openbanking/contracts/accounts.d.ts +289 -0
  162. package/dist/integrations/openbanking/contracts/accounts.js +236 -1
  163. package/dist/integrations/openbanking/contracts/balances.d.ts +165 -0
  164. package/dist/integrations/openbanking/contracts/balances.js +166 -1
  165. package/dist/integrations/openbanking/contracts/index.d.ts +10 -0
  166. package/dist/integrations/openbanking/contracts/index.js +12 -1
  167. package/dist/integrations/openbanking/contracts/transactions.d.ts +213 -0
  168. package/dist/integrations/openbanking/contracts/transactions.js +217 -1
  169. package/dist/integrations/openbanking/guards.d.ts +12 -0
  170. package/dist/integrations/openbanking/guards.js +33 -1
  171. package/dist/integrations/openbanking/models.d.ts +228 -0
  172. package/dist/integrations/openbanking/models.js +240 -1
  173. package/dist/integrations/openbanking/openbanking.feature.d.ts +11 -0
  174. package/dist/integrations/openbanking/openbanking.feature.js +69 -1
  175. package/dist/integrations/openbanking/telemetry.d.ts +15 -0
  176. package/dist/integrations/openbanking/telemetry.js +39 -1
  177. package/dist/integrations/operations.d.ts +437 -0
  178. package/dist/integrations/operations.js +392 -0
  179. package/dist/integrations/providers/calendar.d.ts +78 -0
  180. package/dist/integrations/providers/elevenlabs.d.ts +7 -0
  181. package/dist/integrations/providers/elevenlabs.js +55 -1
  182. package/dist/integrations/providers/email.d.ts +86 -0
  183. package/dist/integrations/providers/embedding.d.ts +24 -0
  184. package/dist/integrations/providers/gcs-storage.d.ts +7 -0
  185. package/dist/integrations/providers/gcs-storage.js +78 -1
  186. package/dist/integrations/providers/gmail.d.ts +7 -0
  187. package/dist/integrations/providers/gmail.js +90 -1
  188. package/dist/integrations/providers/google-calendar.d.ts +7 -0
  189. package/dist/integrations/providers/google-calendar.js +69 -1
  190. package/dist/integrations/providers/impls/elevenlabs-voice.d.ts +20 -0
  191. package/dist/integrations/providers/impls/elevenlabs-voice.js +95 -1
  192. package/dist/integrations/providers/impls/gcs-storage.d.ts +24 -0
  193. package/dist/integrations/providers/impls/gcs-storage.js +88 -1
  194. package/dist/integrations/providers/impls/gmail-inbound.d.ts +26 -0
  195. package/dist/integrations/providers/impls/gmail-inbound.js +200 -1
  196. package/dist/integrations/providers/impls/gmail-outbound.d.ts +18 -0
  197. package/dist/integrations/providers/impls/gmail-outbound.js +104 -5
  198. package/dist/integrations/providers/impls/google-calendar.d.ts +23 -0
  199. package/dist/integrations/providers/impls/google-calendar.js +154 -1
  200. package/dist/integrations/providers/impls/index.d.ts +15 -0
  201. package/dist/integrations/providers/impls/index.js +16 -1
  202. package/dist/integrations/providers/impls/mistral-embedding.d.ts +23 -0
  203. package/dist/integrations/providers/impls/mistral-embedding.js +41 -1
  204. package/dist/integrations/providers/impls/mistral-llm.d.ts +31 -0
  205. package/dist/integrations/providers/impls/mistral-llm.js +247 -1
  206. package/dist/integrations/providers/impls/postmark-email.d.ts +19 -0
  207. package/dist/integrations/providers/impls/postmark-email.js +55 -1
  208. package/dist/integrations/providers/impls/powens-client.d.ts +124 -0
  209. package/dist/integrations/providers/impls/powens-client.js +171 -1
  210. package/dist/integrations/providers/impls/powens-openbanking.d.ts +27 -0
  211. package/dist/integrations/providers/impls/powens-openbanking.js +218 -1
  212. package/dist/integrations/providers/impls/provider-factory.d.ts +26 -0
  213. package/dist/integrations/providers/impls/provider-factory.js +145 -1
  214. package/dist/integrations/providers/impls/qdrant-vector.d.ts +24 -0
  215. package/dist/integrations/providers/impls/qdrant-vector.js +69 -1
  216. package/dist/integrations/providers/impls/stripe-payments.d.ts +28 -0
  217. package/dist/integrations/providers/impls/stripe-payments.js +202 -1
  218. package/dist/integrations/providers/impls/twilio-sms.d.ts +20 -0
  219. package/dist/integrations/providers/impls/twilio-sms.js +58 -1
  220. package/dist/integrations/providers/index.d.ts +22 -0
  221. package/dist/integrations/providers/index.js +13 -1
  222. package/dist/integrations/providers/llm.d.ts +82 -0
  223. package/dist/integrations/providers/mistral.d.ts +7 -0
  224. package/dist/integrations/providers/mistral.js +71 -1
  225. package/dist/integrations/providers/openbanking.d.ts +128 -0
  226. package/dist/integrations/providers/payments.d.ts +109 -0
  227. package/dist/integrations/providers/postmark.d.ts +7 -0
  228. package/dist/integrations/providers/postmark.js +71 -1
  229. package/dist/integrations/providers/powens.d.ts +7 -0
  230. package/dist/integrations/providers/powens.js +119 -1
  231. package/dist/integrations/providers/qdrant.d.ts +7 -0
  232. package/dist/integrations/providers/qdrant.js +76 -1
  233. package/dist/integrations/providers/registry.d.ts +11 -0
  234. package/dist/integrations/providers/registry.js +34 -1
  235. package/dist/integrations/providers/sms.d.ts +34 -0
  236. package/dist/integrations/providers/storage.d.ts +60 -0
  237. package/dist/integrations/providers/stripe.d.ts +7 -0
  238. package/dist/integrations/providers/stripe.js +86 -1
  239. package/dist/integrations/providers/twilio-sms.d.ts +7 -0
  240. package/dist/integrations/providers/twilio-sms.js +64 -1
  241. package/dist/integrations/providers/vector-store.d.ts +43 -0
  242. package/dist/integrations/providers/voice.d.ts +34 -0
  243. package/dist/integrations/runtime.d.ts +99 -0
  244. package/dist/integrations/runtime.js +186 -1
  245. package/dist/integrations/secrets/aws-secret-manager.d.ts +31 -0
  246. package/dist/integrations/secrets/aws-secret-manager.js +231 -1
  247. package/dist/integrations/secrets/env-secret-provider.d.ts +31 -0
  248. package/dist/integrations/secrets/env-secret-provider.js +81 -1
  249. package/dist/integrations/secrets/gcp-secret-manager.d.ts +32 -0
  250. package/dist/integrations/secrets/gcp-secret-manager.js +229 -1
  251. package/dist/integrations/secrets/index.d.ts +7 -0
  252. package/dist/integrations/secrets/index.js +8 -1
  253. package/dist/integrations/secrets/manager.d.ts +47 -0
  254. package/dist/integrations/secrets/manager.js +103 -1
  255. package/dist/integrations/secrets/provider.d.ts +52 -0
  256. package/dist/integrations/secrets/provider.js +58 -1
  257. package/dist/integrations/secrets/scaleway-secret-manager.d.ts +38 -0
  258. package/dist/integrations/secrets/scaleway-secret-manager.js +247 -1
  259. package/dist/integrations/secrets-types.d.ts +17 -0
  260. package/dist/integrations/spec.d.ts +75 -0
  261. package/dist/integrations/spec.js +39 -1
  262. package/dist/jobs/define-job.d.ts +18 -0
  263. package/dist/jobs/define-job.js +16 -1
  264. package/dist/jobs/gcp-cloud-tasks.d.ts +41 -0
  265. package/dist/jobs/gcp-cloud-tasks.js +53 -1
  266. package/dist/jobs/gcp-pubsub.d.ts +25 -0
  267. package/dist/jobs/gcp-pubsub.js +39 -1
  268. package/dist/jobs/handlers/gmail-sync-handler.d.ts +9 -0
  269. package/dist/jobs/handlers/gmail-sync-handler.js +9 -1
  270. package/dist/jobs/handlers/index.d.ts +9 -0
  271. package/dist/jobs/handlers/index.js +12 -1
  272. package/dist/jobs/handlers/ping-handler.d.ts +10 -0
  273. package/dist/jobs/handlers/ping-handler.js +15 -1
  274. package/dist/jobs/handlers/storage-document-handler.d.ts +12 -0
  275. package/dist/jobs/handlers/storage-document-handler.js +14 -1
  276. package/dist/jobs/index.d.ts +3 -0
  277. package/dist/jobs/index.js +4 -1
  278. package/dist/jobs/memory-queue.d.ts +18 -0
  279. package/dist/jobs/memory-queue.js +71 -1
  280. package/dist/jobs/queue.d.ts +131 -0
  281. package/dist/jobs/queue.js +33 -1
  282. package/dist/jobs/scaleway-sqs-queue.d.ts +30 -0
  283. package/dist/jobs/scaleway-sqs-queue.js +153 -1
  284. package/dist/jsonschema.d.ts +28 -0
  285. package/dist/jsonschema.js +32 -1
  286. package/dist/knowledge/binding.d.ts +25 -0
  287. package/dist/knowledge/docs/knowledge.docblock.d.ts +6 -0
  288. package/dist/knowledge/docs/knowledge.docblock.js +21 -138
  289. package/dist/knowledge/index.d.ts +11 -0
  290. package/dist/knowledge/index.js +10 -1
  291. package/dist/knowledge/ingestion/document-processor.d.ts +24 -0
  292. package/dist/knowledge/ingestion/document-processor.js +54 -1
  293. package/dist/knowledge/ingestion/embedding-service.d.ts +12 -0
  294. package/dist/knowledge/ingestion/embedding-service.js +25 -1
  295. package/dist/knowledge/ingestion/gmail-adapter.d.ts +18 -0
  296. package/dist/knowledge/ingestion/gmail-adapter.js +50 -5
  297. package/dist/knowledge/ingestion/index.d.ts +6 -0
  298. package/dist/knowledge/ingestion/index.js +7 -1
  299. package/dist/knowledge/ingestion/storage-adapter.d.ts +15 -0
  300. package/dist/knowledge/ingestion/storage-adapter.js +26 -1
  301. package/dist/knowledge/ingestion/vector-indexer.d.ts +18 -0
  302. package/dist/knowledge/ingestion/vector-indexer.js +32 -1
  303. package/dist/knowledge/knowledge.feature.d.ts +11 -0
  304. package/dist/knowledge/knowledge.feature.js +61 -0
  305. package/dist/knowledge/operations.d.ts +318 -0
  306. package/dist/knowledge/operations.js +321 -0
  307. package/dist/knowledge/query/index.d.ts +2 -0
  308. package/dist/knowledge/query/index.js +3 -1
  309. package/dist/knowledge/query/service.d.ts +29 -0
  310. package/dist/knowledge/query/service.js +64 -2
  311. package/dist/knowledge/runtime.d.ts +32 -0
  312. package/dist/knowledge/runtime.js +49 -1
  313. package/dist/knowledge/source.d.ts +32 -0
  314. package/dist/knowledge/spaces/email-threads.d.ts +7 -0
  315. package/dist/knowledge/spaces/email-threads.js +37 -1
  316. package/dist/knowledge/spaces/financial-docs.d.ts +7 -0
  317. package/dist/knowledge/spaces/financial-docs.js +37 -1
  318. package/dist/knowledge/spaces/financial-overview.d.ts +7 -0
  319. package/dist/knowledge/spaces/financial-overview.js +41 -1
  320. package/dist/knowledge/spaces/index.d.ts +7 -0
  321. package/dist/knowledge/spaces/index.js +8 -1
  322. package/dist/knowledge/spaces/product-canon.d.ts +7 -0
  323. package/dist/knowledge/spaces/product-canon.js +37 -1
  324. package/dist/knowledge/spaces/support-faq.d.ts +7 -0
  325. package/dist/knowledge/spaces/support-faq.js +40 -1
  326. package/dist/knowledge/spaces/uploaded-docs.d.ts +7 -0
  327. package/dist/knowledge/spaces/uploaded-docs.js +37 -1
  328. package/dist/knowledge/spec.d.ts +48 -0
  329. package/dist/knowledge/spec.js +39 -1
  330. package/dist/llm/exporters.d.ts +69 -0
  331. package/dist/llm/exporters.js +542 -8
  332. package/dist/llm/index.d.ts +4 -0
  333. package/dist/llm/index.js +4 -1
  334. package/dist/llm/prompts.d.ts +52 -0
  335. package/dist/llm/prompts.js +246 -56
  336. package/dist/llm/types.d.ts +214 -0
  337. package/dist/markdown.d.ts +22 -0
  338. package/dist/markdown.js +119 -3
  339. package/dist/migrations.d.ts +52 -0
  340. package/dist/migrations.js +33 -1
  341. package/dist/onboarding-base.d.ts +138 -0
  342. package/dist/onboarding-base.js +195 -1
  343. package/dist/openapi.d.ts +31 -0
  344. package/dist/openapi.js +75 -1
  345. package/dist/operations/index.d.ts +3 -0
  346. package/dist/operations/index.js +4 -0
  347. package/dist/operations/operation.d.ts +180 -0
  348. package/dist/operations/operation.js +35 -0
  349. package/dist/operations/registry.d.ts +103 -0
  350. package/dist/operations/registry.js +252 -0
  351. package/dist/ownership.d.ts +84 -0
  352. package/dist/ownership.js +38 -1
  353. package/dist/policy/docs/policy.docblock.d.ts +6 -0
  354. package/dist/policy/docs/policy.docblock.js +21 -1
  355. package/dist/policy/engine.d.ts +40 -0
  356. package/dist/policy/engine.js +223 -1
  357. package/dist/policy/index.d.ts +5 -0
  358. package/dist/policy/index.js +5 -0
  359. package/dist/policy/opa-adapter.d.ts +45 -0
  360. package/dist/policy/opa-adapter.js +71 -1
  361. package/dist/policy/registry.d.ts +9 -0
  362. package/dist/policy/registry.js +11 -0
  363. package/dist/policy/spec.d.ts +103 -0
  364. package/dist/policy/spec.js +0 -1
  365. package/dist/presentations/docs/presentations-conventions.docblock.d.ts +6 -0
  366. package/dist/presentations/docs/presentations-conventions.docblock.js +20 -7
  367. package/dist/presentations/index.d.ts +4 -0
  368. package/dist/presentations/index.js +5 -0
  369. package/dist/presentations/presentations.d.ts +50 -0
  370. package/dist/presentations/presentations.js +7 -0
  371. package/dist/presentations/registry.d.ts +10 -0
  372. package/dist/presentations/registry.js +12 -0
  373. package/dist/presentations/transform-engine.d.ts +66 -0
  374. package/dist/presentations/transform-engine.js +282 -0
  375. package/dist/prompt.d.ts +60 -0
  376. package/dist/prompt.js +10 -1
  377. package/dist/promptRegistry.d.ts +15 -0
  378. package/dist/promptRegistry.js +34 -1
  379. package/dist/regenerator/adapters.d.ts +19 -0
  380. package/dist/regenerator/docs/regenerator.docblock.d.ts +6 -0
  381. package/dist/regenerator/docs/regenerator.docblock.js +21 -184
  382. package/dist/regenerator/executor.d.ts +70 -0
  383. package/dist/regenerator/executor.js +86 -1
  384. package/dist/regenerator/index.d.ts +7 -0
  385. package/dist/regenerator/index.js +6 -1
  386. package/dist/regenerator/service.d.ts +33 -0
  387. package/dist/regenerator/service.js +92 -1
  388. package/dist/regenerator/sinks.d.ts +26 -0
  389. package/dist/regenerator/sinks.js +32 -1
  390. package/dist/regenerator/types.d.ts +107 -0
  391. package/dist/regenerator/utils.d.ts +9 -0
  392. package/dist/regenerator/utils.js +51 -1
  393. package/dist/registry-utils.d.ts +106 -0
  394. package/dist/registry-utils.js +122 -0
  395. package/dist/registry.d.ts +30 -0
  396. package/dist/registry.js +58 -1
  397. package/dist/resources.d.ts +64 -0
  398. package/dist/resources.js +50 -1
  399. package/dist/schema-to-markdown.d.ts +54 -0
  400. package/dist/schema-to-markdown.js +214 -10
  401. package/dist/server/contracts-adapter-hydration.d.ts +15 -0
  402. package/dist/server/contracts-adapter-hydration.js +41 -0
  403. package/dist/server/contracts-adapter-input.d.ts +9 -0
  404. package/dist/server/contracts-adapter-input.js +77 -0
  405. package/dist/server/graphql-pothos.d.ts +31 -0
  406. package/dist/server/graphql-pothos.js +127 -1
  407. package/dist/server/index.d.ts +9 -0
  408. package/dist/server/index.js +10 -1
  409. package/dist/server/mcp/createMcpServer.d.ts +15 -0
  410. package/dist/server/mcp/createMcpServer.js +28 -1
  411. package/dist/server/mcp/mcpTypes.d.ts +30 -0
  412. package/dist/server/mcp/registerPresentations.d.ts +7 -0
  413. package/dist/server/mcp/registerPresentations.js +112 -1
  414. package/dist/server/mcp/registerPrompts.d.ts +8 -0
  415. package/dist/server/mcp/registerPrompts.js +36 -2
  416. package/dist/server/mcp/registerResources.d.ts +8 -0
  417. package/dist/server/mcp/registerResources.js +35 -1
  418. package/dist/server/mcp/registerTools.d.ts +8 -0
  419. package/dist/server/mcp/registerTools.js +22 -1
  420. package/dist/server/provider-mcp.d.ts +2 -0
  421. package/dist/server/provider-mcp.js +3 -1
  422. package/dist/server/rest-elysia.d.ts +40 -0
  423. package/dist/server/rest-elysia.js +20 -1
  424. package/dist/server/rest-express.d.ts +16 -0
  425. package/dist/server/rest-express.js +36 -1
  426. package/dist/server/rest-generic.d.ts +32 -0
  427. package/dist/server/rest-generic.js +124 -1
  428. package/dist/server/rest-next-app.d.ts +35 -0
  429. package/dist/server/rest-next-app.js +38 -1
  430. package/dist/server/rest-next-mcp.d.ts +11 -0
  431. package/dist/server/rest-next-mcp.js +45 -1
  432. package/dist/server/rest-next-pages.d.ts +9 -0
  433. package/dist/server/rest-next-pages.js +22 -1
  434. package/dist/telemetry/anomaly.d.ts +27 -0
  435. package/dist/telemetry/anomaly.js +48 -1
  436. package/dist/telemetry/docs/telemetry.docblock.d.ts +6 -0
  437. package/dist/telemetry/docs/telemetry.docblock.js +21 -139
  438. package/dist/telemetry/index.d.ts +4 -0
  439. package/dist/telemetry/index.js +5 -1
  440. package/dist/telemetry/spec.d.ts +91 -0
  441. package/dist/telemetry/spec.js +69 -1
  442. package/dist/telemetry/tracker.d.ts +51 -0
  443. package/dist/telemetry/tracker.js +76 -1
  444. package/dist/tests/index.d.ts +3 -0
  445. package/dist/tests/index.js +4 -1
  446. package/dist/tests/runner.d.ts +43 -0
  447. package/dist/tests/runner.js +150 -1
  448. package/dist/tests/spec.d.ts +89 -0
  449. package/dist/tests/spec.js +33 -1
  450. package/dist/themes.d.ts +53 -0
  451. package/dist/themes.js +39 -1
  452. package/dist/translations/catalog.d.ts +28 -0
  453. package/dist/translations/tenant.d.ts +15 -0
  454. package/dist/types.d.ts +92 -0
  455. package/dist/workflow/adapters/db-adapter.d.ts +46 -0
  456. package/dist/workflow/adapters/db-adapter.js +83 -1
  457. package/dist/workflow/adapters/file-adapter.d.ts +14 -0
  458. package/dist/workflow/adapters/file-adapter.js +11 -1
  459. package/dist/workflow/adapters/index.d.ts +4 -0
  460. package/dist/workflow/adapters/index.js +5 -1
  461. package/dist/workflow/adapters/memory-store.d.ts +18 -0
  462. package/dist/workflow/adapters/memory-store.js +58 -1
  463. package/dist/workflow/expression.d.ts +9 -0
  464. package/dist/workflow/expression.js +99 -1
  465. package/dist/workflow/index.d.ts +10 -0
  466. package/dist/workflow/index.js +9 -1
  467. package/dist/workflow/runner.d.ts +74 -0
  468. package/dist/workflow/runner.js +337 -1
  469. package/dist/workflow/sla-monitor.d.ts +20 -0
  470. package/dist/workflow/sla-monitor.js +47 -1
  471. package/dist/workflow/spec.d.ts +105 -0
  472. package/dist/workflow/spec.js +55 -1
  473. package/dist/workflow/state.d.ts +35 -0
  474. package/dist/workflow/validation.d.ts +29 -0
  475. package/dist/workflow/validation.js +176 -1
  476. package/dist/workspace-config/contractsrc-schema.d.ts +786 -0
  477. package/dist/workspace-config/contractsrc-schema.js +247 -0
  478. package/dist/workspace-config/index.d.ts +2 -0
  479. package/dist/workspace-config/index.js +3 -0
  480. package/package.json +286 -266
  481. package/dist/capabilities.js +0 -1
  482. package/dist/contracts-adapter-hydration.js +0 -1
  483. package/dist/contracts-adapter-input.js +0 -1
  484. package/dist/data-views.js +0 -1
  485. package/dist/docs/PUBLISHING.docblock.js +0 -76
  486. package/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +0 -383
  487. package/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +0 -68
  488. package/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +0 -140
  489. package/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +0 -86
  490. package/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +0 -1
  491. package/dist/forms.js +0 -1
  492. package/dist/integrations/contracts.js +0 -1
  493. package/dist/knowledge/contracts.js +0 -1
  494. package/dist/openbanking/docs/openbanking.docblock.js +0 -109
  495. package/dist/presentations.backcompat.js +0 -1
  496. package/dist/presentations.js +0 -1
  497. package/dist/presentations.v2.js +0 -7
  498. package/dist/spec.js +0 -1
  499. /package/dist/{types/all.js → integrations/secrets-types.js} +0 -0
@@ -1 +1,538 @@
1
- var e=class{blueprintRules=[];tenantRules=[];resolvedRules=[];register(e){return e.scope===`blueprint`?this.blueprintRules.push(e):e.scope===`tenant`?this.tenantRules.push(e):this.resolvedRules.push(e),this}validateBlueprint(e,t){return w(this.blueprintRules.flatMap(n=>n.validate(e,t)))}validateTenant(e,t,n){return w(this.tenantRules.flatMap(r=>r.validate(e,t,n)))}validateResolved(e,t,n){return w(this.resolvedRules.flatMap(r=>r.validate(e,t,n)))}};const t=/^(?!:\/\/)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[A-Za-z]{2,}$/,n=/^https:\/\//i,r={logo:[`png`,`svg`,`webp`],"logo-dark":[`png`,`svg`,`webp`],favicon:[`ico`,`png`,`svg`],"og-image":[`png`,`jpg`,`jpeg`,`webp`]},i={};let a;function o(){return a||=p(),a}function s(e,t,n=i){let r=o();return f(d(r.validateBlueprint(e,n)),d(r.validateTenant(e,t,n)))}function c(e,t=i){return d(o().validateBlueprint(e,t))}function l(e,t,n=i){return d(o().validateTenant(e,t,n))}function u(e,t,n=i){return d(o().validateResolved(e,t,n))}function d(e){let t=e.filter(e=>e.severity===`error`),n=e.filter(e=>e.severity===`warning`),r=e.filter(e=>e.severity===`info`);return{valid:t.length===0,errors:t,warnings:n,info:r}}function f(...e){let t=e.flatMap(e=>e.errors),n=e.flatMap(e=>e.warnings),r=e.flatMap(e=>e.info);return{valid:t.length===0,errors:t,warnings:n,info:r}}function p(){return new e().register(m).register(h).register(g).register(_).register(v).register(y).register(b).register(x).register(S)}const m={scope:`blueprint`,name:`integration.duplicate-slots`,category:`integration`,validate(e){let t=[],n=new Set;for(let r of e.integrationSlots??[])n.has(r.slotId)?t.push(C({code:`DUPLICATE_SLOT`,severity:`error`,path:`integrationSlots.${r.slotId}`,message:`Duplicate integration slot id "${r.slotId}".`})):n.add(r.slotId),r.allowedModes&&r.allowedModes.length===0&&t.push(C({code:`EMPTY_ALLOWED_MODES`,severity:`warning`,path:`integrationSlots.${r.slotId}.allowedModes`,message:`allowedModes is empty; the slot will accept any supported mode.`}));return e.branding&&!e.branding.appNameKey.trim()&&t.push(C({code:`MISSING_APP_NAME_KEY`,severity:`warning`,path:`branding.appNameKey`,message:`branding.appNameKey should reference a translation catalog key.`})),t}},h={scope:`blueprint`,name:`capability.registry-check`,category:`capability`,validate(e,t){let n=[],r=t.capabilities;return r&&(e.capabilities?.enabled??[]).forEach((e,t)=>{r.get(e.key,e.version)||n.push(C({code:`MISSING_CAPABILITY`,severity:`error`,path:`capabilities.enabled[${t}]`,message:`Capability "${e.key}@${e.version}" is not registered.`}))}),n}},g={scope:`tenant`,name:`capability.required-enabled`,category:`capability`,validate(e,t,n){let r=[],i=n.capabilities,a=new Set((e.capabilities?.enabled??[]).map(T)),o=t.capabilities?.disable??[];return o.forEach((e,t)=>{a.has(T(e))&&r.push(C({code:`DISABLED_REQUIRED_CAPABILITY`,severity:`error`,path:`capabilities.disable[${t}]`,message:`Capability "${e.key}@${e.version}" is required by the blueprint and cannot be disabled.`}))}),i&&((t.capabilities?.enable??[]).forEach((e,t)=>{i.get(e.key,e.version)||r.push(C({code:`UNKNOWN_CAPABILITY_ENABLE`,severity:`error`,path:`capabilities.enable[${t}]`,message:`Capability "${e.key}@${e.version}" is not registered.`}))}),o.forEach((e,t)=>{i.get(e.key,e.version)||r.push(C({code:`UNKNOWN_CAPABILITY_DISABLE`,severity:`warning`,path:`capabilities.disable[${t}]`,message:`Capability "${e.key}@${e.version}" is not registered.`}))})),r}},_={scope:`tenant`,name:`integration.slot-binding`,category:`integration`,validate(e,t,n){let r=[],i=new Map((e.integrationSlots??[]).map(e=>[e.slotId,e])),a=t.integrations??[],o=n.tenantConnections?.reduce((e,t)=>e.set(t.meta.id,t),new Map)??new Map,s=new Set;a.forEach(e=>{let a=`integrations.${e.slotId}`,c=i.get(e.slotId);if(!c){r.push(C({code:`UNKNOWN_SLOT_BINDING`,severity:`error`,path:a,message:`Integration slot "${e.slotId}" is not defined in the blueprint.`}));return}let l=!0,u=o.get(e.connectionId);if(!u){r.push(C({code:`MISSING_INTEGRATION_CONNECTION`,severity:`error`,path:a,message:`Integration connection "${e.connectionId}" was not found for tenant "${t.meta.tenantId}".`})),l=!1;return}u.meta.tenantId!==t.meta.tenantId&&(r.push(C({code:`FOREIGN_CONNECTION`,severity:`error`,path:a,message:`Connection "${e.connectionId}" belongs to tenant "${u.meta.tenantId}", not "${t.meta.tenantId}".`})),l=!1),c.allowedModes&&c.allowedModes.length>0&&(c.allowedModes.includes(u.ownershipMode)||(r.push(C({code:`MODE_MISMATCH`,severity:`error`,path:a,message:`Slot "${c.slotId}" only allows modes [${c.allowedModes.join(`, `)}] but connection is "${u.ownershipMode}".`})),l=!1)),u.status===`disconnected`||u.status===`error`?(r.push(C({code:`CONNECTION_NOT_READY`,severity:`error`,path:a,message:`Connection "${u.meta.label}" is in status "${u.status}".`})),l=!1):u.status===`unknown`&&r.push(C({code:`CONNECTION_STATUS_UNKNOWN`,severity:`warning`,path:a,message:`Connection "${u.meta.label}" has unknown health status.`}));let d=D(n.integrationSpecs,u);if(!d){r.push(C({code:`INTEGRATION_SPEC_NOT_FOUND`,severity:`warning`,path:a,message:`Integration spec "${u.meta.integrationKey}@${u.meta.integrationVersion}" is not registered.`})),l=!1;return}d.meta.category!==c.requiredCategory&&(r.push(C({code:`CATEGORY_MISMATCH`,severity:`error`,path:a,message:`Slot "${c.slotId}" requires category "${c.requiredCategory}" but connection provides "${d.meta.category}".`})),l=!1),d.supportedModes.includes(u.ownershipMode)||(r.push(C({code:`UNSUPPORTED_OWNERSHIP_MODE`,severity:`error`,path:a,message:`Integration spec "${d.meta.key}" does not support ownership mode "${u.ownershipMode}".`})),l=!1);for(let e of c.requiredCapabilities??[])E(d,e)||(r.push(C({code:`CAPABILITY_NOT_PROVIDED`,severity:`error`,path:a,message:`Integration "${d.meta.key}" does not provide required capability "${e.key}@${e.version}".`})),l=!1);l&&s.add(c.slotId)});for(let e of i.values())e.required&&!s.has(e.slotId)&&r.push(C({code:`MISSING_REQUIRED_SLOT`,severity:`error`,path:`integrations.${e.slotId}`,message:`Required integration slot "${e.slotId}" is not bound.`}));return r}},v={scope:`tenant`,name:`knowledge.bindings`,category:`knowledge`,validate(e,t,n){let r=[],i=n.knowledgeSpaces;if(!i)return r;let a=n.knowledgeSources??[];return(t.knowledge??[]).forEach((e,n)=>{let o=`knowledge[${n}]`,s=i.get(e.spaceKey,e.spaceVersion);if(!s){r.push(C({code:`UNKNOWN_KNOWLEDGE_SPACE`,severity:`error`,path:`${o}.spaceKey`,message:`Knowledge space "${e.spaceKey}" is not registered.`}));return}a.some(t=>t.meta.spaceKey===e.spaceKey?e.spaceVersion==null?!0:t.meta.spaceVersion===e.spaceVersion:!1)||r.push(C({code:`MISSING_KNOWLEDGE_SOURCES`,severity:`error`,path:o,message:`Knowledge space "${e.spaceKey}" has no configured sources for tenant "${t.meta.tenantId}".`})),(s.meta.category===`external`||s.meta.category===`ephemeral`)&&r.push(C({code:`LOW_TRUST_KNOWLEDGE`,severity:`warning`,path:o,message:`Knowledge space "${e.spaceKey}" has category "${s.meta.category}". Avoid using it for irreversible or policy decisions.`}))}),r}},y={scope:`tenant`,name:`branding.constraints`,category:`branding`,validate(e,i,a){let o=[],s=i.branding;if(!s)return o;let c=s.customDomain?.trim();if(c){t.test(c)||o.push(C({code:`INVALID_DOMAIN`,severity:`error`,path:`branding.customDomain`,message:`Custom domain "${c}" is not a valid hostname.`}));let e=(a.existingConfigs??[]).find(e=>{if(e.meta.id===i.meta.id)return!1;let t=e.branding?.customDomain?.trim();return t?t.toLowerCase()===c.toLowerCase():!1});e&&o.push(C({code:`DUPLICATE_DOMAIN`,severity:`error`,path:`branding.customDomain`,message:`Custom domain "${c}" is already used by tenant "${e.meta.tenantId}".`}))}return(s.assets??[]).forEach((e,t)=>{let i=`branding.assets[${t}]`;n.test(e.url)||o.push(C({code:`INSECURE_ASSET_URL`,severity:`error`,path:`${i}.url`,message:`Branding asset "${e.type}" must use an HTTPS URL.`}));let a=r[e.type]??r.logo,s=O(e.url);s&&a&&!a.includes(s)&&o.push(C({code:`UNEXPECTED_ASSET_TYPE`,severity:`warning`,path:`${i}.url`,message:`Asset "${e.type}" should use one of: ${(a??[]).join(`, `)}. Detected "${s}".`}))}),o}},b={scope:`tenant`,name:`translation.consistency`,category:`translation`,validate(e,t,n){let r=[],i=e.translationCatalog,a=k(n.translationCatalogs),o=i?a.blueprint.find(e=>e.meta.name===i.name&&e.meta.version===i.version):void 0;i&&!o&&r.push(C({code:`MISSING_BLUEPRINT_CATALOG`,severity:`error`,path:`translationCatalog`,message:`Blueprint translation catalog "${i.name}@${i.version}" is not loaded in context.`}));let s=new Set;e.branding?.appNameKey&&(s.add(e.branding.appNameKey),o&&!A(o.entries,e.branding.appNameKey,o.defaultLocale)&&r.push(C({code:`MISSING_TRANSLATION_KEY`,severity:`error`,path:`branding.appNameKey`,message:`Translation key "${e.branding.appNameKey}" is missing for locale "${o.defaultLocale}".`})));let c=t.locales;if(c){let{defaultLocale:e,enabledLocales:t}=c;if(t.includes(e)||r.push(C({code:`LOCALE_NOT_ENABLED`,severity:`warning`,path:`locales.enabledLocales`,message:`enabledLocales does not include defaultLocale "${e}".`})),o){let n=new Set(o.supportedLocales);for(let i of[e,...t])n.has(i)||r.push(C({code:`UNSUPPORTED_LOCALE`,severity:`error`,path:`locales.enabledLocales`,message:`Locale "${i}" is not supported by blueprint catalog "${o.meta.name}".`}))}}let l=new Set;for(let e of a.blueprint)for(let t of e.entries)l.add(t.key);for(let e of a.platform)for(let t of e.entries)l.add(t.key);return(t.translationOverrides?.entries??[]).forEach((e,n)=>{let i=`translationOverrides.entries[${n}]`;l.has(e.key)||r.push(C({code:`UNKNOWN_TRANSLATION_KEY`,severity:`error`,path:i,message:`Override references unknown key "${e.key}".`})),o&&(new Set([...o.supportedLocales,...t.locales?.enabledLocales??[],t.locales?.defaultLocale??o.defaultLocale]).has(e.locale)||r.push(C({code:`UNSUPPORTED_LOCALE_OVERRIDE`,severity:`error`,path:i,message:`Locale "${e.locale}" is not enabled for tenant overrides.`})))}),r}},x={scope:`resolved`,name:`integration.required-slots`,category:`integration`,validate(e,t){let n=[],r=(e.integrationSlots??[]).filter(e=>e.required);for(let e of r)t.integrations.some(t=>t.slot.slotId===e.slotId)||n.push(C({code:`MISSING_REQUIRED_SLOT`,severity:`error`,path:`integrations.${e.slotId}`,message:`Resolved config is missing integration slot "${e.slotId}".`}));for(let e of t.integrations)(e.connection.status===`disconnected`||e.connection.status===`error`)&&n.push(C({code:`CONNECTION_NOT_READY`,severity:`error`,path:`integrations.${e.slot.slotId}`,message:`Resolved integration "${e.slot.slotId}" uses a connection in status "${e.connection.status}".`}));return n}},S={scope:`resolved`,name:`translation.default-locale`,category:`translation`,validate(e,t){let n=[],r=t.translation;return r&&!r.supportedLocales.includes(r.defaultLocale)&&n.push(C({code:`DEFAULT_LOCALE_NOT_SUPPORTED`,severity:`warning`,path:`translation.defaultLocale`,message:`supportedLocales should include defaultLocale for consistent fallback behaviour.`})),n}};function C(e){return e}function w(e){let t=new Map;for(let n of e){let e=`${n.code}|${n.path}|${n.severity}`;t.has(e)||t.set(e,n)}return[...t.values()]}function T(e){return`${e.key}@${e.version}`}function E(e,t){return e.capabilities.provides.some(e=>e.key===t.key&&e.version===t.version)}function D(e,t){if(e)return e.get(t.meta.integrationKey,t.meta.integrationVersion)}function O(e){let[t]=e.split(`?`);if(!t)return;let n=t.lastIndexOf(`.`);if(n!==-1)return t.slice(n+1).toLowerCase()}function k(e){return e?{platform:e.platform?Array.isArray(e.platform)?e.platform:[e.platform]:[],blueprint:e.blueprint?Array.isArray(e.blueprint)?e.blueprint:[e.blueprint]:[]}:{platform:[],blueprint:[]}}function A(e,t,n){return e.some(e=>e.key===t&&e.locale===n)}export{c as validateBlueprint,s as validateConfig,u as validateResolvedConfig,l as validateTenantConfig};
1
+ //#region src/app-config/validation.ts
2
+ var ValidationRuleRegistry = class {
3
+ blueprintRules = [];
4
+ tenantRules = [];
5
+ resolvedRules = [];
6
+ register(rule) {
7
+ if (rule.scope === "blueprint") this.blueprintRules.push(rule);
8
+ else if (rule.scope === "tenant") this.tenantRules.push(rule);
9
+ else this.resolvedRules.push(rule);
10
+ return this;
11
+ }
12
+ validateBlueprint(blueprint, context) {
13
+ return dedupeIssues(this.blueprintRules.flatMap((rule) => rule.validate(blueprint, context)));
14
+ }
15
+ validateTenant(blueprint, tenant, context) {
16
+ return dedupeIssues(this.tenantRules.flatMap((rule) => rule.validate(blueprint, tenant, context)));
17
+ }
18
+ validateResolved(blueprint, resolved, context) {
19
+ return dedupeIssues(this.resolvedRules.flatMap((rule) => rule.validate(blueprint, resolved, context)));
20
+ }
21
+ };
22
+ const DOMAIN_REGEX = /^(?!:\/\/)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[A-Za-z]{2,}$/;
23
+ const HTTPS_URL_REGEX = /^https:\/\//i;
24
+ const ALLOWED_ASSET_EXTENSIONS = {
25
+ logo: [
26
+ "png",
27
+ "svg",
28
+ "webp"
29
+ ],
30
+ "logo-dark": [
31
+ "png",
32
+ "svg",
33
+ "webp"
34
+ ],
35
+ favicon: [
36
+ "ico",
37
+ "png",
38
+ "svg"
39
+ ],
40
+ "og-image": [
41
+ "png",
42
+ "jpg",
43
+ "jpeg",
44
+ "webp"
45
+ ]
46
+ };
47
+ const EMPTY_CONTEXT = {};
48
+ let registryInstance;
49
+ function getRegistry() {
50
+ if (!registryInstance) registryInstance = createDefaultRegistry();
51
+ return registryInstance;
52
+ }
53
+ function validateConfig(blueprint, tenant, context = EMPTY_CONTEXT) {
54
+ const registry = getRegistry();
55
+ return mergeResults(buildResult(registry.validateBlueprint(blueprint, context)), buildResult(registry.validateTenant(blueprint, tenant, context)));
56
+ }
57
+ function validateBlueprint(blueprint, context = EMPTY_CONTEXT) {
58
+ return buildResult(getRegistry().validateBlueprint(blueprint, context));
59
+ }
60
+ function validateTenantConfig(blueprint, tenant, context = EMPTY_CONTEXT) {
61
+ return buildResult(getRegistry().validateTenant(blueprint, tenant, context));
62
+ }
63
+ function validateResolvedConfig(blueprint, resolved, context = EMPTY_CONTEXT) {
64
+ return buildResult(getRegistry().validateResolved(blueprint, resolved, context));
65
+ }
66
+ function buildResult(issues) {
67
+ const errors = issues.filter((issue$1) => issue$1.severity === "error");
68
+ const warnings = issues.filter((issue$1) => issue$1.severity === "warning");
69
+ const info = issues.filter((issue$1) => issue$1.severity === "info");
70
+ return {
71
+ valid: errors.length === 0,
72
+ errors,
73
+ warnings,
74
+ info
75
+ };
76
+ }
77
+ function mergeResults(...results) {
78
+ const errors = results.flatMap((result) => result.errors);
79
+ const warnings = results.flatMap((result) => result.warnings);
80
+ const info = results.flatMap((result) => result.info);
81
+ return {
82
+ valid: errors.length === 0,
83
+ errors,
84
+ warnings,
85
+ info
86
+ };
87
+ }
88
+ function createDefaultRegistry() {
89
+ return new ValidationRuleRegistry().register(blueprintIntegrationSlotRule).register(blueprintCapabilityRegistryRule).register(tenantCapabilityRule).register(tenantIntegrationBindingRule).register(tenantKnowledgeRule).register(tenantBrandingRule).register(tenantTranslationRule).register(resolvedIntegrationRule).register(resolvedTranslationRule);
90
+ }
91
+ const blueprintIntegrationSlotRule = {
92
+ scope: "blueprint",
93
+ name: "integration.duplicate-slots",
94
+ category: "integration",
95
+ validate(blueprint) {
96
+ const issues = [];
97
+ const seen = /* @__PURE__ */ new Set();
98
+ for (const slot of blueprint.integrationSlots ?? []) {
99
+ if (seen.has(slot.slotId)) issues.push(issue({
100
+ code: "DUPLICATE_SLOT",
101
+ severity: "error",
102
+ path: `integrationSlots.${slot.slotId}`,
103
+ message: `Duplicate integration slot id "${slot.slotId}".`
104
+ }));
105
+ else seen.add(slot.slotId);
106
+ if (slot.allowedModes && slot.allowedModes.length === 0) issues.push(issue({
107
+ code: "EMPTY_ALLOWED_MODES",
108
+ severity: "warning",
109
+ path: `integrationSlots.${slot.slotId}.allowedModes`,
110
+ message: "allowedModes is empty; the slot will accept any supported mode."
111
+ }));
112
+ }
113
+ if (blueprint.branding && !blueprint.branding.appNameKey.trim()) issues.push(issue({
114
+ code: "MISSING_APP_NAME_KEY",
115
+ severity: "warning",
116
+ path: "branding.appNameKey",
117
+ message: "branding.appNameKey should reference a translation catalog key."
118
+ }));
119
+ return issues;
120
+ }
121
+ };
122
+ const blueprintCapabilityRegistryRule = {
123
+ scope: "blueprint",
124
+ name: "capability.registry-check",
125
+ category: "capability",
126
+ validate(blueprint, context) {
127
+ const issues = [];
128
+ const registry = context.capabilities;
129
+ if (!registry) return issues;
130
+ (blueprint.capabilities?.enabled ?? []).forEach((ref, index) => {
131
+ if (!registry.get(ref.key, ref.version)) issues.push(issue({
132
+ code: "MISSING_CAPABILITY",
133
+ severity: "error",
134
+ path: `capabilities.enabled[${index}]`,
135
+ message: `Capability "${ref.key}@${ref.version}" is not registered.`
136
+ }));
137
+ });
138
+ return issues;
139
+ }
140
+ };
141
+ const tenantCapabilityRule = {
142
+ scope: "tenant",
143
+ name: "capability.required-enabled",
144
+ category: "capability",
145
+ validate(blueprint, tenant, context) {
146
+ const issues = [];
147
+ const registry = context.capabilities;
148
+ const requiredKeys = new Set((blueprint.capabilities?.enabled ?? []).map(capabilityRefKey));
149
+ const disabled = tenant.capabilities?.disable ?? [];
150
+ disabled.forEach((ref, index) => {
151
+ if (requiredKeys.has(capabilityRefKey(ref))) issues.push(issue({
152
+ code: "DISABLED_REQUIRED_CAPABILITY",
153
+ severity: "error",
154
+ path: `capabilities.disable[${index}]`,
155
+ message: `Capability "${ref.key}@${ref.version}" is required by the blueprint and cannot be disabled.`
156
+ }));
157
+ });
158
+ if (registry) {
159
+ (tenant.capabilities?.enable ?? []).forEach((ref, index) => {
160
+ if (!registry.get(ref.key, ref.version)) issues.push(issue({
161
+ code: "UNKNOWN_CAPABILITY_ENABLE",
162
+ severity: "error",
163
+ path: `capabilities.enable[${index}]`,
164
+ message: `Capability "${ref.key}@${ref.version}" is not registered.`
165
+ }));
166
+ });
167
+ disabled.forEach((ref, index) => {
168
+ if (!registry.get(ref.key, ref.version)) issues.push(issue({
169
+ code: "UNKNOWN_CAPABILITY_DISABLE",
170
+ severity: "warning",
171
+ path: `capabilities.disable[${index}]`,
172
+ message: `Capability "${ref.key}@${ref.version}" is not registered.`
173
+ }));
174
+ });
175
+ }
176
+ return issues;
177
+ }
178
+ };
179
+ const tenantIntegrationBindingRule = {
180
+ scope: "tenant",
181
+ name: "integration.slot-binding",
182
+ category: "integration",
183
+ validate(blueprint, tenant, context) {
184
+ const issues = [];
185
+ const slots = new Map((blueprint.integrationSlots ?? []).map((slot) => [slot.slotId, slot]));
186
+ const bindings = tenant.integrations ?? [];
187
+ const connections = context.tenantConnections?.reduce((map, connection) => map.set(connection.meta.id, connection), /* @__PURE__ */ new Map()) ?? /* @__PURE__ */ new Map();
188
+ const satisfiedSlots = /* @__PURE__ */ new Set();
189
+ bindings.forEach((binding) => {
190
+ const path = `integrations.${binding.slotId}`;
191
+ const slot = slots.get(binding.slotId);
192
+ if (!slot) {
193
+ issues.push(issue({
194
+ code: "UNKNOWN_SLOT_BINDING",
195
+ severity: "error",
196
+ path,
197
+ message: `Integration slot "${binding.slotId}" is not defined in the blueprint.`
198
+ }));
199
+ return;
200
+ }
201
+ let slotValid = true;
202
+ const connection = connections.get(binding.connectionId);
203
+ if (!connection) {
204
+ issues.push(issue({
205
+ code: "MISSING_INTEGRATION_CONNECTION",
206
+ severity: "error",
207
+ path,
208
+ message: `Integration connection "${binding.connectionId}" was not found for tenant "${tenant.meta.tenantId}".`
209
+ }));
210
+ slotValid = false;
211
+ return;
212
+ }
213
+ if (connection.meta.tenantId !== tenant.meta.tenantId) {
214
+ issues.push(issue({
215
+ code: "FOREIGN_CONNECTION",
216
+ severity: "error",
217
+ path,
218
+ message: `Connection "${binding.connectionId}" belongs to tenant "${connection.meta.tenantId}", not "${tenant.meta.tenantId}".`
219
+ }));
220
+ slotValid = false;
221
+ }
222
+ if (slot.allowedModes && slot.allowedModes.length > 0) {
223
+ if (!slot.allowedModes.includes(connection.ownershipMode)) {
224
+ issues.push(issue({
225
+ code: "MODE_MISMATCH",
226
+ severity: "error",
227
+ path,
228
+ message: `Slot "${slot.slotId}" only allows modes [${slot.allowedModes.join(", ")}] but connection is "${connection.ownershipMode}".`
229
+ }));
230
+ slotValid = false;
231
+ }
232
+ }
233
+ if (connection.status === "disconnected" || connection.status === "error") {
234
+ issues.push(issue({
235
+ code: "CONNECTION_NOT_READY",
236
+ severity: "error",
237
+ path,
238
+ message: `Connection "${connection.meta.label}" is in status "${connection.status}".`
239
+ }));
240
+ slotValid = false;
241
+ } else if (connection.status === "unknown") issues.push(issue({
242
+ code: "CONNECTION_STATUS_UNKNOWN",
243
+ severity: "warning",
244
+ path,
245
+ message: `Connection "${connection.meta.label}" has unknown health status.`
246
+ }));
247
+ const spec = lookupIntegrationSpec(context.integrationSpecs, connection);
248
+ if (!spec) {
249
+ issues.push(issue({
250
+ code: "INTEGRATION_SPEC_NOT_FOUND",
251
+ severity: "warning",
252
+ path,
253
+ message: `Integration spec "${connection.meta.integrationKey}@${connection.meta.integrationVersion}" is not registered.`
254
+ }));
255
+ slotValid = false;
256
+ return;
257
+ }
258
+ if (spec.meta.category !== slot.requiredCategory) {
259
+ issues.push(issue({
260
+ code: "CATEGORY_MISMATCH",
261
+ severity: "error",
262
+ path,
263
+ message: `Slot "${slot.slotId}" requires category "${slot.requiredCategory}" but connection provides "${spec.meta.category}".`
264
+ }));
265
+ slotValid = false;
266
+ }
267
+ if (!spec.supportedModes.includes(connection.ownershipMode)) {
268
+ issues.push(issue({
269
+ code: "UNSUPPORTED_OWNERSHIP_MODE",
270
+ severity: "error",
271
+ path,
272
+ message: `Integration spec "${spec.meta.key}" does not support ownership mode "${connection.ownershipMode}".`
273
+ }));
274
+ slotValid = false;
275
+ }
276
+ for (const required of slot.requiredCapabilities ?? []) if (!integrationProvidesCapability(spec, required)) {
277
+ issues.push(issue({
278
+ code: "CAPABILITY_NOT_PROVIDED",
279
+ severity: "error",
280
+ path,
281
+ message: `Integration "${spec.meta.key}" does not provide required capability "${required.key}@${required.version}".`
282
+ }));
283
+ slotValid = false;
284
+ }
285
+ if (slotValid) satisfiedSlots.add(slot.slotId);
286
+ });
287
+ for (const slot of slots.values()) if (slot.required && !satisfiedSlots.has(slot.slotId)) issues.push(issue({
288
+ code: "MISSING_REQUIRED_SLOT",
289
+ severity: "error",
290
+ path: `integrations.${slot.slotId}`,
291
+ message: `Required integration slot "${slot.slotId}" is not bound.`
292
+ }));
293
+ return issues;
294
+ }
295
+ };
296
+ const tenantKnowledgeRule = {
297
+ scope: "tenant",
298
+ name: "knowledge.bindings",
299
+ category: "knowledge",
300
+ validate(_blueprint, tenant, context) {
301
+ const issues = [];
302
+ const registry = context.knowledgeSpaces;
303
+ if (!registry) return issues;
304
+ const sources = context.knowledgeSources ?? [];
305
+ (tenant.knowledge ?? []).forEach((binding, index) => {
306
+ const path = `knowledge[${index}]`;
307
+ const space = registry.get(binding.spaceKey, binding.spaceVersion);
308
+ if (!space) {
309
+ issues.push(issue({
310
+ code: "UNKNOWN_KNOWLEDGE_SPACE",
311
+ severity: "error",
312
+ path: `${path}.spaceKey`,
313
+ message: `Knowledge space "${binding.spaceKey}" is not registered.`
314
+ }));
315
+ return;
316
+ }
317
+ if (!sources.some((source) => {
318
+ if (source.meta.spaceKey !== binding.spaceKey) return false;
319
+ if (binding.spaceVersion != null) return source.meta.spaceVersion === binding.spaceVersion;
320
+ return true;
321
+ })) issues.push(issue({
322
+ code: "MISSING_KNOWLEDGE_SOURCES",
323
+ severity: "error",
324
+ path,
325
+ message: `Knowledge space "${binding.spaceKey}" has no configured sources for tenant "${tenant.meta.tenantId}".`
326
+ }));
327
+ if (space.meta.category === "external" || space.meta.category === "ephemeral") issues.push(issue({
328
+ code: "LOW_TRUST_KNOWLEDGE",
329
+ severity: "warning",
330
+ path,
331
+ message: `Knowledge space "${binding.spaceKey}" has category "${space.meta.category}". Avoid using it for irreversible or policy decisions.`
332
+ }));
333
+ });
334
+ return issues;
335
+ }
336
+ };
337
+ const tenantBrandingRule = {
338
+ scope: "tenant",
339
+ name: "branding.constraints",
340
+ category: "branding",
341
+ validate(_blueprint, tenant, context) {
342
+ const issues = [];
343
+ const branding = tenant.branding;
344
+ if (!branding) return issues;
345
+ const domain = branding.customDomain?.trim();
346
+ if (domain) {
347
+ if (!DOMAIN_REGEX.test(domain)) issues.push(issue({
348
+ code: "INVALID_DOMAIN",
349
+ severity: "error",
350
+ path: "branding.customDomain",
351
+ message: `Custom domain "${domain}" is not a valid hostname.`
352
+ }));
353
+ const conflict = (context.existingConfigs ?? []).find((config) => {
354
+ if (config.meta.id === tenant.meta.id) return false;
355
+ const otherDomain = config.branding?.customDomain?.trim();
356
+ if (!otherDomain) return false;
357
+ return otherDomain.toLowerCase() === domain.toLowerCase();
358
+ });
359
+ if (conflict) issues.push(issue({
360
+ code: "DUPLICATE_DOMAIN",
361
+ severity: "error",
362
+ path: "branding.customDomain",
363
+ message: `Custom domain "${domain}" is already used by tenant "${conflict.meta.tenantId}".`
364
+ }));
365
+ }
366
+ (branding.assets ?? []).forEach((asset, index) => {
367
+ const assetPath = `branding.assets[${index}]`;
368
+ if (!HTTPS_URL_REGEX.test(asset.url)) issues.push(issue({
369
+ code: "INSECURE_ASSET_URL",
370
+ severity: "error",
371
+ path: `${assetPath}.url`,
372
+ message: `Branding asset "${asset.type}" must use an HTTPS URL.`
373
+ }));
374
+ const allowed = ALLOWED_ASSET_EXTENSIONS[asset.type] ?? ALLOWED_ASSET_EXTENSIONS.logo;
375
+ const extension = extractExtension(asset.url);
376
+ if (extension && allowed && !allowed.includes(extension)) issues.push(issue({
377
+ code: "UNEXPECTED_ASSET_TYPE",
378
+ severity: "warning",
379
+ path: `${assetPath}.url`,
380
+ message: `Asset "${asset.type}" should use one of: ${(allowed ?? []).join(", ")}. Detected "${extension}".`
381
+ }));
382
+ });
383
+ return issues;
384
+ }
385
+ };
386
+ const tenantTranslationRule = {
387
+ scope: "tenant",
388
+ name: "translation.consistency",
389
+ category: "translation",
390
+ validate(blueprint, tenant, context) {
391
+ const issues = [];
392
+ const pointer = blueprint.translationCatalog;
393
+ const catalogs = normalizeCatalogs(context.translationCatalogs);
394
+ const blueprintCatalog = pointer ? catalogs.blueprint.find((catalog) => catalog.meta.key === pointer.key && catalog.meta.version === pointer.version) : void 0;
395
+ if (pointer && !blueprintCatalog) issues.push(issue({
396
+ code: "MISSING_BLUEPRINT_CATALOG",
397
+ severity: "error",
398
+ path: "translationCatalog",
399
+ message: `Blueprint translation catalog "${pointer.key}@${pointer.version}" is not loaded in context.`
400
+ }));
401
+ const requiredKeys = /* @__PURE__ */ new Set();
402
+ if (blueprint.branding?.appNameKey) {
403
+ requiredKeys.add(blueprint.branding.appNameKey);
404
+ if (blueprintCatalog && !hasTranslationEntry(blueprintCatalog.entries, blueprint.branding.appNameKey, blueprintCatalog.defaultLocale)) issues.push(issue({
405
+ code: "MISSING_TRANSLATION_KEY",
406
+ severity: "error",
407
+ path: "branding.appNameKey",
408
+ message: `Translation key "${blueprint.branding.appNameKey}" is missing for locale "${blueprintCatalog.defaultLocale}".`
409
+ }));
410
+ }
411
+ const tenantLocales = tenant.locales;
412
+ if (tenantLocales) {
413
+ const { defaultLocale, enabledLocales } = tenantLocales;
414
+ if (!enabledLocales.includes(defaultLocale)) issues.push(issue({
415
+ code: "LOCALE_NOT_ENABLED",
416
+ severity: "warning",
417
+ path: "locales.enabledLocales",
418
+ message: `enabledLocales does not include defaultLocale "${defaultLocale}".`
419
+ }));
420
+ if (blueprintCatalog) {
421
+ const supported = new Set(blueprintCatalog.supportedLocales);
422
+ for (const locale of [defaultLocale, ...enabledLocales]) if (!supported.has(locale)) issues.push(issue({
423
+ code: "UNSUPPORTED_LOCALE",
424
+ severity: "error",
425
+ path: "locales.enabledLocales",
426
+ message: `Locale "${locale}" is not supported by blueprint catalog "${blueprintCatalog.meta.key}".`
427
+ }));
428
+ }
429
+ }
430
+ const allowedKeys = /* @__PURE__ */ new Set();
431
+ for (const catalog of catalogs.blueprint) for (const entry of catalog.entries) allowedKeys.add(entry.key);
432
+ for (const catalog of catalogs.platform) for (const entry of catalog.entries) allowedKeys.add(entry.key);
433
+ (tenant.translationOverrides?.entries ?? []).forEach((entry, index) => {
434
+ const path = `translationOverrides.entries[${index}]`;
435
+ if (!allowedKeys.has(entry.key)) issues.push(issue({
436
+ code: "UNKNOWN_TRANSLATION_KEY",
437
+ severity: "error",
438
+ path,
439
+ message: `Override references unknown key "${entry.key}".`
440
+ }));
441
+ if (blueprintCatalog) {
442
+ if (!new Set([
443
+ ...blueprintCatalog.supportedLocales,
444
+ ...tenant.locales?.enabledLocales ?? [],
445
+ tenant.locales?.defaultLocale ?? blueprintCatalog.defaultLocale
446
+ ]).has(entry.locale)) issues.push(issue({
447
+ code: "UNSUPPORTED_LOCALE_OVERRIDE",
448
+ severity: "error",
449
+ path,
450
+ message: `Locale "${entry.locale}" is not enabled for tenant overrides.`
451
+ }));
452
+ }
453
+ });
454
+ return issues;
455
+ }
456
+ };
457
+ const resolvedIntegrationRule = {
458
+ scope: "resolved",
459
+ name: "integration.required-slots",
460
+ category: "integration",
461
+ validate(blueprint, resolved) {
462
+ const issues = [];
463
+ const requiredSlots = (blueprint.integrationSlots ?? []).filter((slot) => slot.required);
464
+ for (const slot of requiredSlots) if (!resolved.integrations.some((integration) => integration.slot.slotId === slot.slotId)) issues.push(issue({
465
+ code: "MISSING_REQUIRED_SLOT",
466
+ severity: "error",
467
+ path: `integrations.${slot.slotId}`,
468
+ message: `Resolved config is missing integration slot "${slot.slotId}".`
469
+ }));
470
+ for (const integration of resolved.integrations) if (integration.connection.status === "disconnected" || integration.connection.status === "error") issues.push(issue({
471
+ code: "CONNECTION_NOT_READY",
472
+ severity: "error",
473
+ path: `integrations.${integration.slot.slotId}`,
474
+ message: `Resolved integration "${integration.slot.slotId}" uses a connection in status "${integration.connection.status}".`
475
+ }));
476
+ return issues;
477
+ }
478
+ };
479
+ const resolvedTranslationRule = {
480
+ scope: "resolved",
481
+ name: "translation.default-locale",
482
+ category: "translation",
483
+ validate(_blueprint, resolved) {
484
+ const issues = [];
485
+ const translation = resolved.translation;
486
+ if (translation && !translation.supportedLocales.includes(translation.defaultLocale)) issues.push(issue({
487
+ code: "DEFAULT_LOCALE_NOT_SUPPORTED",
488
+ severity: "warning",
489
+ path: "translation.defaultLocale",
490
+ message: "supportedLocales should include defaultLocale for consistent fallback behaviour."
491
+ }));
492
+ return issues;
493
+ }
494
+ };
495
+ function issue(input) {
496
+ return input;
497
+ }
498
+ function dedupeIssues(issues) {
499
+ const map = /* @__PURE__ */ new Map();
500
+ for (const current of issues) {
501
+ const key = `${current.code}|${current.path}|${current.severity}`;
502
+ if (!map.has(key)) map.set(key, current);
503
+ }
504
+ return [...map.values()];
505
+ }
506
+ function capabilityRefKey(ref) {
507
+ return `${ref.key}@${ref.version}`;
508
+ }
509
+ function integrationProvidesCapability(spec, required) {
510
+ return spec.capabilities.provides.some((provided) => provided.key === required.key && provided.version === required.version);
511
+ }
512
+ function lookupIntegrationSpec(registry, connection) {
513
+ if (!registry) return void 0;
514
+ return registry.get(connection.meta.integrationKey, connection.meta.integrationVersion);
515
+ }
516
+ function extractExtension(url) {
517
+ const [raw] = url.split("?");
518
+ if (!raw) return void 0;
519
+ const lastDot = raw.lastIndexOf(".");
520
+ if (lastDot === -1) return void 0;
521
+ return raw.slice(lastDot + 1).toLowerCase();
522
+ }
523
+ function normalizeCatalogs(catalogs) {
524
+ if (!catalogs) return {
525
+ platform: [],
526
+ blueprint: []
527
+ };
528
+ return {
529
+ platform: catalogs.platform ? Array.isArray(catalogs.platform) ? catalogs.platform : [catalogs.platform] : [],
530
+ blueprint: catalogs.blueprint ? Array.isArray(catalogs.blueprint) ? catalogs.blueprint : [catalogs.blueprint] : []
531
+ };
532
+ }
533
+ function hasTranslationEntry(entries, key, locale) {
534
+ return entries.some((entry) => entry.key === key && entry.locale === locale);
535
+ }
536
+
537
+ //#endregion
538
+ export { validateBlueprint, validateConfig, validateResolvedConfig, validateTenantConfig };
@@ -0,0 +1,48 @@
1
+ import { DocId } from "../docs/registry.js";
2
+ import { OwnerShipMeta } from "../ownership.js";
3
+
4
+ //#region src/capabilities/capabilities.d.ts
5
+ type CapabilityKind = 'api' | 'event' | 'data' | 'ui' | 'integration';
6
+ type CapabilitySurface = 'operation' | 'event' | 'workflow' | 'presentation' | 'resource';
7
+ interface CapabilitySurfaceRef {
8
+ surface: CapabilitySurface;
9
+ key: string;
10
+ version: number;
11
+ description?: string;
12
+ }
13
+ interface CapabilityMeta extends OwnerShipMeta {
14
+ /** Stable capability slug (e.g., "payments.stripe"). */
15
+ key: string;
16
+ /** Increment when the capability shape changes. */
17
+ version: number;
18
+ kind: CapabilityKind;
19
+ /** Optional doc block id for governance and navigation. */
20
+ docId?: DocId[];
21
+ }
22
+ interface CapabilityRequirement {
23
+ key: string;
24
+ version?: number;
25
+ kind?: CapabilityKind;
26
+ optional?: boolean;
27
+ reason?: string;
28
+ }
29
+ interface CapabilityRef {
30
+ key: string;
31
+ version: number;
32
+ }
33
+ interface CapabilitySpec {
34
+ meta: CapabilityMeta;
35
+ provides?: CapabilitySurfaceRef[];
36
+ requires?: CapabilityRequirement[];
37
+ }
38
+ declare class CapabilityRegistry {
39
+ private readonly items;
40
+ register(spec: CapabilitySpec): this;
41
+ list(): CapabilitySpec[];
42
+ get(key: string, version?: number): CapabilitySpec | undefined;
43
+ satisfies(requirement: CapabilityRequirement, additional?: CapabilityRef[] | undefined): boolean;
44
+ }
45
+ declare function capabilityKey(spec: CapabilitySpec): string;
46
+ declare function defineCapability(spec: CapabilitySpec): CapabilitySpec;
47
+ //#endregion
48
+ export { CapabilityKind, CapabilityMeta, CapabilityRef, CapabilityRegistry, CapabilityRequirement, CapabilitySpec, CapabilitySurface, CapabilitySurfaceRef, capabilityKey, defineCapability };
@@ -0,0 +1,50 @@
1
+ //#region src/capabilities/capabilities.ts
2
+ const capKey = (key, version) => `${key}.v${version}`;
3
+ var CapabilityRegistry = class {
4
+ items = /* @__PURE__ */ new Map();
5
+ register(spec) {
6
+ const key = capKey(spec.meta.key, spec.meta.version);
7
+ if (this.items.has(key)) throw new Error(`Duplicate capability ${key}`);
8
+ this.items.set(key, spec);
9
+ return this;
10
+ }
11
+ list() {
12
+ return [...this.items.values()];
13
+ }
14
+ get(key, version) {
15
+ if (version != null) return this.items.get(capKey(key, version));
16
+ let candidate;
17
+ let max = -Infinity;
18
+ for (const spec of this.items.values()) {
19
+ if (spec.meta.key !== key) continue;
20
+ if (spec.meta.version > max) {
21
+ max = spec.meta.version;
22
+ candidate = spec;
23
+ }
24
+ }
25
+ return candidate;
26
+ }
27
+ satisfies(requirement, additional) {
28
+ if (requirement.optional) return true;
29
+ if (additional?.some((ref) => matchesRequirement(ref, requirement))) return true;
30
+ const spec = requirement.version ? this.get(requirement.key, requirement.version) : this.get(requirement.key);
31
+ if (!spec) return false;
32
+ if (requirement.kind && spec.meta.kind !== requirement.kind) return false;
33
+ if (requirement.version != null && spec.meta.version !== requirement.version) return false;
34
+ return true;
35
+ }
36
+ };
37
+ function matchesRequirement(ref, requirement) {
38
+ if (ref.key !== requirement.key) return false;
39
+ if (requirement.version != null && ref.version !== requirement.version) return false;
40
+ return true;
41
+ }
42
+ function capabilityKey(spec) {
43
+ return capKey(spec.meta.key, spec.meta.version);
44
+ }
45
+ function defineCapability(spec) {
46
+ return spec;
47
+ }
48
+
49
+ //#endregion
50
+ export { CapabilityRegistry, capabilityKey, defineCapability };
@@ -0,0 +1,6 @@
1
+ import { DocBlock } from "@lssm/lib.contracts/docs";
2
+
3
+ //#region src/capabilities/docs/capabilities.docblock.d.ts
4
+ declare const tech_contracts_capabilities_DocBlocks: DocBlock[];
5
+ //#endregion
6
+ export { tech_contracts_capabilities_DocBlocks };