@lssm/lib.contracts 1.7.4 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/README.md +62 -325
  2. package/dist/app-config/contracts.d.ts +50 -50
  3. package/dist/app-config/contracts.d.ts.map +1 -1
  4. package/dist/app-config/contracts.js.map +1 -1
  5. package/dist/app-config/events.d.ts +27 -27
  6. package/dist/app-config/events.d.ts.map +1 -1
  7. package/dist/app-config/events.js.map +1 -1
  8. package/dist/app-config/lifecycle-contracts.d.ts +80 -80
  9. package/dist/app-config/lifecycle-contracts.d.ts.map +1 -1
  10. package/dist/app-config/lifecycle-contracts.js.map +1 -1
  11. package/dist/app-config/runtime.d.ts.map +1 -1
  12. package/dist/app-config/runtime.js.map +1 -1
  13. package/dist/app-config/spec.d.ts +2 -2
  14. package/dist/app-config/spec.d.ts.map +1 -1
  15. package/dist/app-config/spec.js.map +1 -1
  16. package/dist/app-config/validation.d.ts.map +1 -1
  17. package/dist/app-config/validation.js.map +1 -1
  18. package/dist/capabilities/openbanking.d.ts.map +1 -1
  19. package/dist/capabilities/openbanking.js.map +1 -1
  20. package/dist/capabilities.d.ts +2 -1
  21. package/dist/capabilities.d.ts.map +1 -1
  22. package/dist/capabilities.js +1 -1
  23. package/dist/capabilities.js.map +1 -1
  24. package/dist/data-views/query-generator.d.ts +40 -0
  25. package/dist/data-views/query-generator.d.ts.map +1 -0
  26. package/dist/data-views/query-generator.js +2 -0
  27. package/dist/data-views/query-generator.js.map +1 -0
  28. package/dist/data-views/runtime.d.ts +27 -0
  29. package/dist/data-views/runtime.d.ts.map +1 -0
  30. package/dist/data-views/runtime.js +2 -0
  31. package/dist/data-views/runtime.js.map +1 -0
  32. package/dist/data-views.js.map +1 -1
  33. package/dist/experiments/evaluator.d.ts.map +1 -1
  34. package/dist/experiments/evaluator.js.map +1 -1
  35. package/dist/experiments/spec-resolver.d.ts +17 -0
  36. package/dist/experiments/spec-resolver.d.ts.map +1 -0
  37. package/dist/experiments/spec-resolver.js +0 -0
  38. package/dist/experiments/spec.js.map +1 -1
  39. package/dist/index.d.ts +4 -3
  40. package/dist/index.js +1 -1
  41. package/dist/install.d.ts.map +1 -1
  42. package/dist/integrations/connection.d.ts.map +1 -1
  43. package/dist/integrations/contracts.d.ts.map +1 -1
  44. package/dist/integrations/contracts.js.map +1 -1
  45. package/dist/integrations/health.d.ts.map +1 -1
  46. package/dist/integrations/health.js.map +1 -1
  47. package/dist/integrations/openbanking/contracts/accounts.d.ts +66 -66
  48. package/dist/integrations/openbanking/contracts/accounts.d.ts.map +1 -1
  49. package/dist/integrations/openbanking/contracts/accounts.js.map +1 -1
  50. package/dist/integrations/openbanking/contracts/balances.d.ts +34 -34
  51. package/dist/integrations/openbanking/contracts/balances.d.ts.map +1 -1
  52. package/dist/integrations/openbanking/contracts/balances.js.map +1 -1
  53. package/dist/integrations/openbanking/contracts/index.js.map +1 -1
  54. package/dist/integrations/openbanking/contracts/transactions.d.ts +48 -48
  55. package/dist/integrations/openbanking/contracts/transactions.d.ts.map +1 -1
  56. package/dist/integrations/openbanking/contracts/transactions.js.map +1 -1
  57. package/dist/integrations/openbanking/guards.js.map +1 -1
  58. package/dist/integrations/openbanking/models.d.ts +55 -55
  59. package/dist/integrations/openbanking/models.d.ts.map +1 -1
  60. package/dist/integrations/openbanking/models.js.map +1 -1
  61. package/dist/integrations/openbanking/telemetry.js.map +1 -1
  62. package/dist/integrations/providers/elevenlabs.d.ts.map +1 -1
  63. package/dist/integrations/providers/elevenlabs.js.map +1 -1
  64. package/dist/integrations/providers/gcs-storage.js.map +1 -1
  65. package/dist/integrations/providers/gmail.d.ts.map +1 -1
  66. package/dist/integrations/providers/gmail.js.map +1 -1
  67. package/dist/integrations/providers/google-calendar.js.map +1 -1
  68. package/dist/integrations/providers/impls/elevenlabs-voice.js.map +1 -1
  69. package/dist/integrations/providers/impls/gcs-storage.js.map +1 -1
  70. package/dist/integrations/providers/impls/gmail-inbound.js.map +1 -1
  71. package/dist/integrations/providers/impls/gmail-outbound.d.ts.map +1 -1
  72. package/dist/integrations/providers/impls/gmail-outbound.js.map +1 -1
  73. package/dist/integrations/providers/impls/google-calendar.d.ts.map +1 -1
  74. package/dist/integrations/providers/impls/google-calendar.js.map +1 -1
  75. package/dist/integrations/providers/impls/mistral-embedding.js.map +1 -1
  76. package/dist/integrations/providers/impls/mistral-llm.js.map +1 -1
  77. package/dist/integrations/providers/impls/postmark-email.js.map +1 -1
  78. package/dist/integrations/providers/impls/powens-client.d.ts.map +1 -1
  79. package/dist/integrations/providers/impls/powens-client.js.map +1 -1
  80. package/dist/integrations/providers/impls/powens-openbanking.d.ts.map +1 -1
  81. package/dist/integrations/providers/impls/powens-openbanking.js.map +1 -1
  82. package/dist/integrations/providers/impls/provider-factory.d.ts.map +1 -1
  83. package/dist/integrations/providers/impls/provider-factory.js.map +1 -1
  84. package/dist/integrations/providers/impls/qdrant-vector.d.ts.map +1 -1
  85. package/dist/integrations/providers/impls/qdrant-vector.js.map +1 -1
  86. package/dist/integrations/providers/impls/stripe-payments.d.ts.map +1 -1
  87. package/dist/integrations/providers/impls/stripe-payments.js.map +1 -1
  88. package/dist/integrations/providers/impls/twilio-sms.js.map +1 -1
  89. package/dist/integrations/providers/llm.d.ts.map +1 -1
  90. package/dist/integrations/providers/mistral.d.ts.map +1 -1
  91. package/dist/integrations/providers/mistral.js.map +1 -1
  92. package/dist/integrations/providers/payments.d.ts.map +1 -1
  93. package/dist/integrations/providers/postmark.d.ts.map +1 -1
  94. package/dist/integrations/providers/postmark.js.map +1 -1
  95. package/dist/integrations/providers/powens.js.map +1 -1
  96. package/dist/integrations/providers/qdrant.d.ts.map +1 -1
  97. package/dist/integrations/providers/qdrant.js.map +1 -1
  98. package/dist/integrations/providers/stripe.js.map +1 -1
  99. package/dist/integrations/providers/twilio-sms.js.map +1 -1
  100. package/dist/integrations/runtime.d.ts.map +1 -1
  101. package/dist/integrations/runtime.js.map +1 -1
  102. package/dist/integrations/secrets/env-secret-provider.js.map +1 -1
  103. package/dist/integrations/secrets/gcp-secret-manager.d.ts.map +1 -1
  104. package/dist/integrations/secrets/gcp-secret-manager.js.map +1 -1
  105. package/dist/integrations/secrets/manager.d.ts +2 -2
  106. package/dist/integrations/secrets/manager.d.ts.map +1 -1
  107. package/dist/integrations/secrets/manager.js.map +1 -1
  108. package/dist/integrations/secrets/provider.js.map +1 -1
  109. package/dist/integrations/spec.d.ts.map +1 -1
  110. package/dist/integrations/spec.js.map +1 -1
  111. package/dist/jobs/gcp-cloud-tasks.js.map +1 -1
  112. package/dist/jobs/gcp-pubsub.d.ts.map +1 -1
  113. package/dist/jobs/gcp-pubsub.js.map +1 -1
  114. package/dist/jobs/handlers/gmail-sync-handler.js.map +1 -1
  115. package/dist/jobs/handlers/storage-document-handler.js.map +1 -1
  116. package/dist/jobs/memory-queue.d.ts.map +1 -1
  117. package/dist/jobs/memory-queue.js.map +1 -1
  118. package/dist/jobs/queue.d.ts.map +1 -1
  119. package/dist/knowledge/contracts.d.ts +66 -66
  120. package/dist/knowledge/contracts.d.ts.map +1 -1
  121. package/dist/knowledge/contracts.js.map +1 -1
  122. package/dist/knowledge/ingestion/document-processor.js.map +1 -1
  123. package/dist/knowledge/ingestion/embedding-service.d.ts.map +1 -1
  124. package/dist/knowledge/ingestion/embedding-service.js.map +1 -1
  125. package/dist/knowledge/ingestion/gmail-adapter.d.ts.map +1 -1
  126. package/dist/knowledge/ingestion/gmail-adapter.js.map +1 -1
  127. package/dist/knowledge/ingestion/storage-adapter.js.map +1 -1
  128. package/dist/knowledge/ingestion/vector-indexer.js.map +1 -1
  129. package/dist/knowledge/query/service.d.ts +2 -2
  130. package/dist/knowledge/query/service.d.ts.map +1 -1
  131. package/dist/knowledge/query/service.js.map +1 -1
  132. package/dist/knowledge/runtime.d.ts.map +1 -1
  133. package/dist/knowledge/runtime.js.map +1 -1
  134. package/dist/knowledge/spaces/email-threads.js.map +1 -1
  135. package/dist/knowledge/spaces/financial-docs.js.map +1 -1
  136. package/dist/knowledge/spaces/financial-overview.js.map +1 -1
  137. package/dist/knowledge/spaces/product-canon.js.map +1 -1
  138. package/dist/knowledge/spaces/support-faq.js.map +1 -1
  139. package/dist/knowledge/spaces/uploaded-docs.js.map +1 -1
  140. package/dist/knowledge/spec.js.map +1 -1
  141. package/dist/migrations.d.ts.map +1 -1
  142. package/dist/migrations.js.map +1 -1
  143. package/dist/onboarding-base.d.ts +29 -29
  144. package/dist/onboarding-base.d.ts.map +1 -1
  145. package/dist/policy/engine.js.map +1 -1
  146. package/dist/policy/opa-adapter.d.ts.map +1 -1
  147. package/dist/policy/opa-adapter.js.map +1 -1
  148. package/dist/policy/spec.d.ts.map +1 -1
  149. package/dist/policy/spec.js.map +1 -1
  150. package/dist/regenerator/executor.d.ts.map +1 -1
  151. package/dist/regenerator/executor.js.map +1 -1
  152. package/dist/regenerator/service.d.ts.map +1 -1
  153. package/dist/regenerator/service.js.map +1 -1
  154. package/dist/regenerator/sinks.d.ts.map +1 -1
  155. package/dist/regenerator/sinks.js.map +1 -1
  156. package/dist/regenerator/types.d.ts.map +1 -1
  157. package/dist/regenerator/utils.js.map +1 -1
  158. package/dist/registry.d.ts +36 -9
  159. package/dist/registry.d.ts.map +1 -1
  160. package/dist/registry.js +1 -1
  161. package/dist/registry.js.map +1 -1
  162. package/dist/resources.d.ts.map +1 -1
  163. package/dist/schema/dist/FieldType.js +1 -1
  164. package/dist/schema/dist/FieldType.js.map +1 -1
  165. package/dist/schema/dist/ScalarTypeEnum.js +1 -1
  166. package/dist/schema/dist/ScalarTypeEnum.js.map +1 -1
  167. package/dist/schema/dist/index.js +1 -1
  168. package/dist/server/graphql-pothos.d.ts +15 -2
  169. package/dist/server/graphql-pothos.d.ts.map +1 -1
  170. package/dist/server/graphql-pothos.js.map +1 -1
  171. package/dist/server/provider-mcp.d.ts +22 -4
  172. package/dist/server/provider-mcp.d.ts.map +1 -1
  173. package/dist/server/provider-mcp.js.map +1 -1
  174. package/dist/server/rest-next-app.d.ts +23 -3
  175. package/dist/server/rest-next-app.d.ts.map +1 -1
  176. package/dist/server/rest-next-app.js.map +1 -1
  177. package/dist/spec.d.ts +22 -0
  178. package/dist/spec.d.ts.map +1 -1
  179. package/dist/spec.js.map +1 -1
  180. package/dist/telemetry/anomaly.js.map +1 -1
  181. package/dist/telemetry/spec.d.ts.map +1 -1
  182. package/dist/telemetry/spec.js.map +1 -1
  183. package/dist/telemetry/tracker.d.ts.map +1 -1
  184. package/dist/telemetry/tracker.js.map +1 -1
  185. package/dist/tests/runner.js.map +1 -1
  186. package/dist/tests/spec.js.map +1 -1
  187. package/dist/themes.d.ts.map +1 -1
  188. package/dist/themes.js.map +1 -1
  189. package/dist/types/all.d.ts +2 -2
  190. package/dist/types.d.ts +3 -0
  191. package/dist/types.d.ts.map +1 -1
  192. package/dist/workflow/adapters/db-adapter.d.ts +30 -10
  193. package/dist/workflow/adapters/db-adapter.d.ts.map +1 -1
  194. package/dist/workflow/adapters/db-adapter.js +1 -1
  195. package/dist/workflow/adapters/db-adapter.js.map +1 -1
  196. package/dist/workflow/adapters/file-adapter.js.map +1 -1
  197. package/dist/workflow/adapters/index.d.ts +2 -2
  198. package/dist/workflow/adapters/index.js +1 -1
  199. package/dist/workflow/adapters/memory-store.d.ts.map +1 -1
  200. package/dist/workflow/adapters/memory-store.js.map +1 -1
  201. package/dist/workflow/expression.js.map +1 -1
  202. package/dist/workflow/index.d.ts +2 -2
  203. package/dist/workflow/index.js +1 -1
  204. package/dist/workflow/runner.d.ts +1 -0
  205. package/dist/workflow/runner.d.ts.map +1 -1
  206. package/dist/workflow/runner.js +1 -1
  207. package/dist/workflow/runner.js.map +1 -1
  208. package/dist/workflow/sla-monitor.d.ts +21 -0
  209. package/dist/workflow/sla-monitor.d.ts.map +1 -0
  210. package/dist/workflow/sla-monitor.js +2 -0
  211. package/dist/workflow/sla-monitor.js.map +1 -0
  212. package/dist/workflow/spec.js.map +1 -1
  213. package/dist/workflow/state.d.ts +1 -0
  214. package/dist/workflow/state.d.ts.map +1 -1
  215. package/dist/workflow/validation.d.ts.map +1 -1
  216. package/dist/workflow/validation.js.map +1 -1
  217. package/package.json +15 -11
@@ -1 +1 @@
1
- {"version":3,"file":"financial-docs.js","names":["financialDocsKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/financial-docs.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const financialDocsKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.financial-docs',\n version: 1,\n category: 'canonical',\n displayName: 'Financial Documents',\n title: 'Household Financial Documents',\n description:\n 'Invoices, bills, and contracts powering Pocket Family Office financial automation.',\n domain: 'finance',\n owners: ['platform.finance'],\n tags: ['finance', 'documents'],\n stability: StabilityEnum.Beta,\n },\n retention: {\n ttlDays: null,\n },\n access: {\n policy: { name: 'knowledge.access.financial-docs', version: 1 },\n trustLevel: 'high',\n automationWritable: true,\n },\n indexing: {\n embeddingModel: 'mistral-embed',\n chunkSize: 700,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'Normalized financial documents enabling bill pay automation, reminders, and summaries.',\n};\n\nexport function registerFinancialDocsKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(financialDocsKnowledgeSpace);\n}\n\n\n"],"mappings":"mDAGA,MAAaA,EAAkD,CAC7D,KAAM,CACJ,IAAK,2BACL,QAAS,EACT,SAAU,YACV,YAAa,sBACb,MAAO,gCACP,YACE,qFACF,OAAQ,UACR,OAAQ,CAAC,mBAAmB,CAC5B,KAAM,CAAC,UAAW,YAAY,CAC9B,UAAW,EAAc,KAC1B,CACD,UAAW,CACT,QAAS,KACV,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,kCAAmC,QAAS,EAAG,CAC/D,WAAY,OACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,gBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,yFACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAA4B"}
1
+ {"version":3,"file":"financial-docs.js","names":["financialDocsKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/financial-docs.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const financialDocsKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.financial-docs',\n version: 1,\n category: 'canonical',\n displayName: 'Financial Documents',\n title: 'Household Financial Documents',\n description:\n 'Invoices, bills, and contracts powering Pocket Family Office financial automation.',\n domain: 'finance',\n owners: ['platform.finance'],\n tags: ['finance', 'documents'],\n stability: StabilityEnum.Beta,\n },\n retention: {\n ttlDays: null,\n },\n access: {\n policy: { name: 'knowledge.access.financial-docs', version: 1 },\n trustLevel: 'high',\n automationWritable: true,\n },\n indexing: {\n embeddingModel: 'mistral-embed',\n chunkSize: 700,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'Normalized financial documents enabling bill pay automation, reminders, and summaries.',\n};\n\nexport function registerFinancialDocsKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(financialDocsKnowledgeSpace);\n}\n"],"mappings":"mDAGA,MAAaA,EAAkD,CAC7D,KAAM,CACJ,IAAK,2BACL,QAAS,EACT,SAAU,YACV,YAAa,sBACb,MAAO,gCACP,YACE,qFACF,OAAQ,UACR,OAAQ,CAAC,mBAAmB,CAC5B,KAAM,CAAC,UAAW,YAAY,CAC9B,UAAW,EAAc,KAC1B,CACD,UAAW,CACT,QAAS,KACV,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,kCAAmC,QAAS,EAAG,CAC/D,WAAY,OACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,gBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,yFACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"financial-overview.js","names":["financialOverviewKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/financial-overview.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const financialOverviewKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.financial-overview',\n version: 1,\n category: 'operational',\n displayName: 'Financial Overview Summaries',\n title: 'Derived Financial Summaries',\n description:\n 'Aggregated cashflow summaries, category breakdowns, and balance trends derived from open banking data.',\n domain: 'finance',\n owners: ['platform.finance'],\n tags: ['open-banking', 'summaries', 'cashflow'],\n stability: StabilityEnum.Experimental,\n },\n retention: {\n ttlDays: 180,\n },\n access: {\n policy: { name: 'knowledge.access.financial-overview', version: 1 },\n trustLevel: 'medium',\n automationWritable: true,\n },\n indexing: {\n embeddingModel: 'mistral-embed',\n chunkSize: 600,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'Derived knowledge space containing weekly/monthly cashflow rollups and account health summaries. Raw transactions are excluded to respect privacy guardrails.',\n};\n\nexport function registerFinancialOverviewKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(financialOverviewKnowledgeSpace);\n}\n\n"],"mappings":"mDAGA,MAAaA,EAAsD,CACjE,KAAM,CACJ,IAAK,+BACL,QAAS,EACT,SAAU,cACV,YAAa,+BACb,MAAO,8BACP,YACE,yGACF,OAAQ,UACR,OAAQ,CAAC,mBAAmB,CAC5B,KAAM,CAAC,eAAgB,YAAa,WAAW,CAC/C,UAAW,EAAc,aAC1B,CACD,UAAW,CACT,QAAS,IACV,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,sCAAuC,QAAS,EAAG,CACnE,WAAY,SACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,gBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,gKACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAAgC"}
1
+ {"version":3,"file":"financial-overview.js","names":["financialOverviewKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/financial-overview.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const financialOverviewKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.financial-overview',\n version: 1,\n category: 'operational',\n displayName: 'Financial Overview Summaries',\n title: 'Derived Financial Summaries',\n description:\n 'Aggregated cashflow summaries, category breakdowns, and balance trends derived from open banking data.',\n domain: 'finance',\n owners: ['platform.finance'],\n tags: ['open-banking', 'summaries', 'cashflow'],\n stability: StabilityEnum.Experimental,\n },\n retention: {\n ttlDays: 180,\n },\n access: {\n policy: { name: 'knowledge.access.financial-overview', version: 1 },\n trustLevel: 'medium',\n automationWritable: true,\n },\n indexing: {\n embeddingModel: 'mistral-embed',\n chunkSize: 600,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'Derived knowledge space containing weekly/monthly cashflow rollups and account health summaries. Raw transactions are excluded to respect privacy guardrails.',\n};\n\nexport function registerFinancialOverviewKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(financialOverviewKnowledgeSpace);\n}\n"],"mappings":"mDAGA,MAAaA,EAAsD,CACjE,KAAM,CACJ,IAAK,+BACL,QAAS,EACT,SAAU,cACV,YAAa,+BACb,MAAO,8BACP,YACE,yGACF,OAAQ,UACR,OAAQ,CAAC,mBAAmB,CAC5B,KAAM,CAAC,eAAgB,YAAa,WAAW,CAC/C,UAAW,EAAc,aAC1B,CACD,UAAW,CACT,QAAS,IACV,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,sCAAuC,QAAS,EAAG,CACnE,WAAY,SACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,gBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,gKACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAAgC"}
@@ -1 +1 @@
1
- {"version":3,"file":"product-canon.js","names":["productCanonKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/product-canon.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const productCanonKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.product-canon',\n version: 1,\n category: 'canonical',\n displayName: 'Product Canon',\n title: 'Product Canon Knowledge Space',\n description:\n 'Authoritative product knowledge covering strategy, roadmap, and delivery canon.',\n domain: 'product',\n owners: ['platform.product'],\n tags: ['knowledge', 'product'],\n stability: StabilityEnum.Stable,\n },\n retention: {\n ttlDays: null,\n },\n access: {\n policy: { name: 'knowledge.access.product-canon', version: 1 },\n trustLevel: 'high',\n automationWritable: false,\n },\n indexing: {\n embeddingModel: 'text-embedding-3-large',\n chunkSize: 800,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'Single source of truth for product canon, principles, and strategic narratives.',\n};\n\nexport function registerProductCanonKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(productCanonKnowledgeSpace);\n}\n\n\n\n\n\n\n"],"mappings":"mDAGA,MAAaA,EAAiD,CAC5D,KAAM,CACJ,IAAK,0BACL,QAAS,EACT,SAAU,YACV,YAAa,gBACb,MAAO,gCACP,YACE,kFACF,OAAQ,UACR,OAAQ,CAAC,mBAAmB,CAC5B,KAAM,CAAC,YAAa,UAAU,CAC9B,UAAW,EAAc,OAC1B,CACD,UAAW,CACT,QAAS,KACV,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,iCAAkC,QAAS,EAAG,CAC9D,WAAY,OACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,yBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,kFACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAA2B"}
1
+ {"version":3,"file":"product-canon.js","names":["productCanonKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/product-canon.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const productCanonKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.product-canon',\n version: 1,\n category: 'canonical',\n displayName: 'Product Canon',\n title: 'Product Canon Knowledge Space',\n description:\n 'Authoritative product knowledge covering strategy, roadmap, and delivery canon.',\n domain: 'product',\n owners: ['platform.product'],\n tags: ['knowledge', 'product'],\n stability: StabilityEnum.Stable,\n },\n retention: {\n ttlDays: null,\n },\n access: {\n policy: { name: 'knowledge.access.product-canon', version: 1 },\n trustLevel: 'high',\n automationWritable: false,\n },\n indexing: {\n embeddingModel: 'text-embedding-3-large',\n chunkSize: 800,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'Single source of truth for product canon, principles, and strategic narratives.',\n};\n\nexport function registerProductCanonKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(productCanonKnowledgeSpace);\n}\n"],"mappings":"mDAGA,MAAaA,EAAiD,CAC5D,KAAM,CACJ,IAAK,0BACL,QAAS,EACT,SAAU,YACV,YAAa,gBACb,MAAO,gCACP,YACE,kFACF,OAAQ,UACR,OAAQ,CAAC,mBAAmB,CAC5B,KAAM,CAAC,YAAa,UAAU,CAC9B,UAAW,EAAc,OAC1B,CACD,UAAW,CACT,QAAS,KACV,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,iCAAkC,QAAS,EAAG,CAC9D,WAAY,OACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,yBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,kFACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"support-faq.js","names":["supportFaqKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/support-faq.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const supportFaqKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.support-faq',\n version: 1,\n category: 'operational',\n displayName: 'Support FAQ',\n title: 'Support & Success FAQ',\n description: 'Operational knowledge base for customer support and success.',\n domain: 'support',\n owners: ['platform.support'],\n tags: ['knowledge', 'support'],\n stability: StabilityEnum.Beta,\n },\n retention: {\n ttlDays: 365,\n archiveAfterDays: 180,\n },\n access: {\n policy: { name: 'knowledge.access.support', version: 1 },\n trustLevel: 'medium',\n automationWritable: true,\n },\n indexing: {\n embeddingModel: 'text-embedding-3-small',\n chunkSize: 700,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'Operational FAQs, runbooks, and customer success playbooks augmented with automation updates.',\n};\n\nexport function registerSupportFaqKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(supportFaqKnowledgeSpace);\n}\n\n\n\n\n\n\n"],"mappings":"mDAGA,MAAaA,EAA+C,CAC1D,KAAM,CACJ,IAAK,wBACL,QAAS,EACT,SAAU,cACV,YAAa,cACb,MAAO,wBACP,YAAa,+DACb,OAAQ,UACR,OAAQ,CAAC,mBAAmB,CAC5B,KAAM,CAAC,YAAa,UAAU,CAC9B,UAAW,EAAc,KAC1B,CACD,UAAW,CACT,QAAS,IACT,iBAAkB,IACnB,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,2BAA4B,QAAS,EAAG,CACxD,WAAY,SACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,yBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,gGACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAAyB"}
1
+ {"version":3,"file":"support-faq.js","names":["supportFaqKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/support-faq.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const supportFaqKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.support-faq',\n version: 1,\n category: 'operational',\n displayName: 'Support FAQ',\n title: 'Support & Success FAQ',\n description: 'Operational knowledge base for customer support and success.',\n domain: 'support',\n owners: ['platform.support'],\n tags: ['knowledge', 'support'],\n stability: StabilityEnum.Beta,\n },\n retention: {\n ttlDays: 365,\n archiveAfterDays: 180,\n },\n access: {\n policy: { name: 'knowledge.access.support', version: 1 },\n trustLevel: 'medium',\n automationWritable: true,\n },\n indexing: {\n embeddingModel: 'text-embedding-3-small',\n chunkSize: 700,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'Operational FAQs, runbooks, and customer success playbooks augmented with automation updates.',\n};\n\nexport function registerSupportFaqKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(supportFaqKnowledgeSpace);\n}\n"],"mappings":"mDAGA,MAAaA,EAA+C,CAC1D,KAAM,CACJ,IAAK,wBACL,QAAS,EACT,SAAU,cACV,YAAa,cACb,MAAO,wBACP,YAAa,+DACb,OAAQ,UACR,OAAQ,CAAC,mBAAmB,CAC5B,KAAM,CAAC,YAAa,UAAU,CAC9B,UAAW,EAAc,KAC1B,CACD,UAAW,CACT,QAAS,IACT,iBAAkB,IACnB,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,2BAA4B,QAAS,EAAG,CACxD,WAAY,SACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,yBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,gGACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAAyB"}
@@ -1 +1 @@
1
- {"version":3,"file":"uploaded-docs.js","names":["uploadedDocsKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/uploaded-docs.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const uploadedDocsKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.uploaded-docs',\n version: 1,\n category: 'external',\n displayName: 'Uploaded Documents',\n title: 'Uploaded Knowledge Assets',\n description:\n 'Documents uploaded by households, including invoices, contracts, and reference files.',\n domain: 'operations',\n owners: ['platform.operations'],\n tags: ['documents', 'storage'],\n stability: StabilityEnum.Beta,\n },\n retention: {\n ttlDays: null,\n },\n access: {\n policy: { name: 'knowledge.access.uploaded-docs', version: 1 },\n trustLevel: 'medium',\n automationWritable: true,\n },\n indexing: {\n embeddingModel: 'mistral-embed',\n chunkSize: 900,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'User-provided documents normalized and embedded for retrieval augmented workflows.',\n};\n\nexport function registerUploadedDocsKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(uploadedDocsKnowledgeSpace);\n}\n\n\n"],"mappings":"mDAGA,MAAaA,EAAiD,CAC5D,KAAM,CACJ,IAAK,0BACL,QAAS,EACT,SAAU,WACV,YAAa,qBACb,MAAO,4BACP,YACE,wFACF,OAAQ,aACR,OAAQ,CAAC,sBAAsB,CAC/B,KAAM,CAAC,YAAa,UAAU,CAC9B,UAAW,EAAc,KAC1B,CACD,UAAW,CACT,QAAS,KACV,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,iCAAkC,QAAS,EAAG,CAC9D,WAAY,SACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,gBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,qFACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAA2B"}
1
+ {"version":3,"file":"uploaded-docs.js","names":["uploadedDocsKnowledgeSpace: KnowledgeSpaceSpec"],"sources":["../../../src/knowledge/spaces/uploaded-docs.ts"],"sourcesContent":["import { StabilityEnum } from '../../ownership';\nimport type { KnowledgeSpaceRegistry, KnowledgeSpaceSpec } from '../spec';\n\nexport const uploadedDocsKnowledgeSpace: KnowledgeSpaceSpec = {\n meta: {\n key: 'knowledge.uploaded-docs',\n version: 1,\n category: 'external',\n displayName: 'Uploaded Documents',\n title: 'Uploaded Knowledge Assets',\n description:\n 'Documents uploaded by households, including invoices, contracts, and reference files.',\n domain: 'operations',\n owners: ['platform.operations'],\n tags: ['documents', 'storage'],\n stability: StabilityEnum.Beta,\n },\n retention: {\n ttlDays: null,\n },\n access: {\n policy: { name: 'knowledge.access.uploaded-docs', version: 1 },\n trustLevel: 'medium',\n automationWritable: true,\n },\n indexing: {\n embeddingModel: 'mistral-embed',\n chunkSize: 900,\n vectorDbIntegration: 'vectordb.qdrant',\n },\n description:\n 'User-provided documents normalized and embedded for retrieval augmented workflows.',\n};\n\nexport function registerUploadedDocsKnowledgeSpace(\n registry: KnowledgeSpaceRegistry\n): KnowledgeSpaceRegistry {\n return registry.register(uploadedDocsKnowledgeSpace);\n}\n"],"mappings":"mDAGA,MAAaA,EAAiD,CAC5D,KAAM,CACJ,IAAK,0BACL,QAAS,EACT,SAAU,WACV,YAAa,qBACb,MAAO,4BACP,YACE,wFACF,OAAQ,aACR,OAAQ,CAAC,sBAAsB,CAC/B,KAAM,CAAC,YAAa,UAAU,CAC9B,UAAW,EAAc,KAC1B,CACD,UAAW,CACT,QAAS,KACV,CACD,OAAQ,CACN,OAAQ,CAAE,KAAM,iCAAkC,QAAS,EAAG,CAC9D,WAAY,SACZ,mBAAoB,GACrB,CACD,SAAU,CACR,eAAgB,gBAChB,UAAW,IACX,oBAAqB,kBACtB,CACD,YACE,qFACH,CAED,SAAgB,EACd,EACwB,CACxB,OAAO,EAAS,SAAS,EAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","names":["latest: KnowledgeSpaceSpec | undefined"],"sources":["../../src/knowledge/spec.ts"],"sourcesContent":["import type { OwnerShipMeta } from '../ownership';\nimport type { PolicyRef } from '../policy/spec';\n\nexport type KnowledgeCategory =\n | 'canonical'\n | 'operational'\n | 'external'\n | 'ephemeral';\n\nexport interface KnowledgeSpaceMeta extends OwnerShipMeta {\n /** Stable space identifier (e.g., \"product-canon\", \"support-faq\"). */\n key: string;\n version: number;\n category: KnowledgeCategory;\n displayName: string;\n}\n\nexport interface KnowledgeRetentionPolicy {\n /** TTL in days (null = indefinite). */\n ttlDays?: number | null;\n /** Auto-archive after inactivity. */\n archiveAfterDays?: number;\n}\n\nexport interface KnowledgeAccessPolicy {\n /** Which PolicySpec governs access. */\n policy?: PolicyRef;\n /** Trust level for agent/workflow consumption. */\n trustLevel: 'high' | 'medium' | 'low';\n /** Can this space be mutated by automation? */\n automationWritable: boolean;\n}\n\nexport interface KnowledgeIndexingConfig {\n embeddingModel?: string;\n chunkSize?: number;\n vectorDbIntegration?: string;\n}\n\nexport interface KnowledgeSpaceSpec {\n meta: KnowledgeSpaceMeta;\n /** Retention and cleanup rules. */\n retention: KnowledgeRetentionPolicy;\n /** Access control and trust. */\n access: KnowledgeAccessPolicy;\n /** Optional embedding/indexing config. */\n indexing?: KnowledgeIndexingConfig;\n /** Documentation. */\n description?: string;\n}\n\nconst knowledgeKey = (meta: Pick<KnowledgeSpaceMeta, 'key' | 'version'>) =>\n `${meta.key}.v${meta.version}`;\n\nexport class KnowledgeSpaceRegistry {\n private readonly items = new Map<string, KnowledgeSpaceSpec>();\n\n register(spec: KnowledgeSpaceSpec): this {\n const key = knowledgeKey(spec.meta);\n if (this.items.has(key)) {\n throw new Error(`Duplicate KnowledgeSpaceSpec ${key}`);\n }\n this.items.set(key, spec);\n return this;\n }\n\n list(): KnowledgeSpaceSpec[] {\n return [...this.items.values()];\n }\n\n get(key: string, version?: number): KnowledgeSpaceSpec | undefined {\n if (version != null) {\n return this.items.get(knowledgeKey({ key, version }));\n }\n let latest: KnowledgeSpaceSpec | undefined;\n let maxVersion = -Infinity;\n for (const spec of this.items.values()) {\n if (spec.meta.key !== key) continue;\n if (spec.meta.version > maxVersion) {\n maxVersion = spec.meta.version;\n latest = spec;\n }\n }\n return latest;\n }\n\n getByCategory(category: KnowledgeCategory): KnowledgeSpaceSpec[] {\n return this.list().filter((spec) => spec.meta.category === category);\n }\n}\n\nexport function makeKnowledgeSpaceKey(meta: KnowledgeSpaceMeta) {\n return knowledgeKey(meta);\n}\n\n\n\n\n\n\n"],"mappings":"AAmDA,MAAM,EAAgB,GACpB,GAAG,EAAK,IAAI,IAAI,EAAK,UAEvB,IAAa,EAAb,KAAoC,CAClC,MAAyB,IAAI,IAE7B,SAAS,EAAgC,CACvC,IAAM,EAAM,EAAa,EAAK,KAAK,CACnC,GAAI,KAAK,MAAM,IAAI,EAAI,CACrB,MAAU,MAAM,gCAAgC,IAAM,CAGxD,OADA,KAAK,MAAM,IAAI,EAAK,EAAK,CAClB,KAGT,MAA6B,CAC3B,MAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CAGjC,IAAI,EAAa,EAAkD,CACjE,GAAI,GAAW,KACb,OAAO,KAAK,MAAM,IAAI,EAAa,CAAE,MAAK,UAAS,CAAC,CAAC,CAEvD,IAAIA,EACA,EAAa,KACjB,IAAK,IAAM,KAAQ,KAAK,MAAM,QAAQ,CAChC,EAAK,KAAK,MAAQ,GAClB,EAAK,KAAK,QAAU,IACtB,EAAa,EAAK,KAAK,QACvB,EAAS,GAGb,OAAO,EAGT,cAAc,EAAmD,CAC/D,OAAO,KAAK,MAAM,CAAC,OAAQ,GAAS,EAAK,KAAK,WAAa,EAAS,GAIxE,SAAgB,EAAsB,EAA0B,CAC9D,OAAO,EAAa,EAAK"}
1
+ {"version":3,"file":"spec.js","names":["latest: KnowledgeSpaceSpec | undefined"],"sources":["../../src/knowledge/spec.ts"],"sourcesContent":["import type { OwnerShipMeta } from '../ownership';\nimport type { PolicyRef } from '../policy/spec';\n\nexport type KnowledgeCategory =\n | 'canonical' // Ground truth - product specs, schemas, official policies\n | 'operational' // Internal docs - support tickets, runbooks, sales materials\n | 'external' // Third-party - PSP docs, regulations, integration guides\n | 'ephemeral'; // Temporary - agent scratchpads, session context, drafts\n\nexport interface KnowledgeSpaceMeta extends OwnerShipMeta {\n /** Stable space identifier (e.g., \"product-canon\", \"support-faq\"). */\n key: string;\n version: number;\n category: KnowledgeCategory;\n displayName: string;\n}\n\nexport interface KnowledgeRetentionPolicy {\n /** TTL in days (null = indefinite). */\n ttlDays?: number | null;\n /** Auto-archive after inactivity. */\n archiveAfterDays?: number;\n}\n\nexport interface KnowledgeAccessPolicy {\n /** Which PolicySpec governs access. */\n policy?: PolicyRef;\n /** Trust level for agent/workflow consumption. */\n trustLevel: 'high' | 'medium' | 'low';\n /** Can this space be mutated by automation? */\n automationWritable: boolean;\n}\n\nexport interface KnowledgeIndexingConfig {\n embeddingModel?: string;\n chunkSize?: number;\n vectorDbIntegration?: string;\n}\n\nexport interface KnowledgeSpaceSpec {\n meta: KnowledgeSpaceMeta;\n /** Retention and cleanup rules. */\n retention: KnowledgeRetentionPolicy;\n /** Access control and trust. */\n access: KnowledgeAccessPolicy;\n /** Optional embedding/indexing config. */\n indexing?: KnowledgeIndexingConfig;\n /** Documentation. */\n description?: string;\n}\n\nconst knowledgeKey = (meta: Pick<KnowledgeSpaceMeta, 'key' | 'version'>) =>\n `${meta.key}.v${meta.version}`;\n\nexport class KnowledgeSpaceRegistry {\n private readonly items = new Map<string, KnowledgeSpaceSpec>();\n\n register(spec: KnowledgeSpaceSpec): this {\n const key = knowledgeKey(spec.meta);\n if (this.items.has(key)) {\n throw new Error(`Duplicate KnowledgeSpaceSpec ${key}`);\n }\n this.items.set(key, spec);\n return this;\n }\n\n list(): KnowledgeSpaceSpec[] {\n return [...this.items.values()];\n }\n\n get(key: string, version?: number): KnowledgeSpaceSpec | undefined {\n if (version != null) {\n return this.items.get(knowledgeKey({ key, version }));\n }\n let latest: KnowledgeSpaceSpec | undefined;\n let maxVersion = -Infinity;\n for (const spec of this.items.values()) {\n if (spec.meta.key !== key) continue;\n if (spec.meta.version > maxVersion) {\n maxVersion = spec.meta.version;\n latest = spec;\n }\n }\n return latest;\n }\n\n getByCategory(category: KnowledgeCategory): KnowledgeSpaceSpec[] {\n return this.list().filter((spec) => spec.meta.category === category);\n }\n}\n\nexport function makeKnowledgeSpaceKey(meta: KnowledgeSpaceMeta) {\n return knowledgeKey(meta);\n}\n"],"mappings":"AAmDA,MAAM,EAAgB,GACpB,GAAG,EAAK,IAAI,IAAI,EAAK,UAEvB,IAAa,EAAb,KAAoC,CAClC,MAAyB,IAAI,IAE7B,SAAS,EAAgC,CACvC,IAAM,EAAM,EAAa,EAAK,KAAK,CACnC,GAAI,KAAK,MAAM,IAAI,EAAI,CACrB,MAAU,MAAM,gCAAgC,IAAM,CAGxD,OADA,KAAK,MAAM,IAAI,EAAK,EAAK,CAClB,KAGT,MAA6B,CAC3B,MAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CAGjC,IAAI,EAAa,EAAkD,CACjE,GAAI,GAAW,KACb,OAAO,KAAK,MAAM,IAAI,EAAa,CAAE,MAAK,UAAS,CAAC,CAAC,CAEvD,IAAIA,EACA,EAAa,KACjB,IAAK,IAAM,KAAQ,KAAK,MAAM,QAAQ,CAChC,EAAK,KAAK,MAAQ,GAClB,EAAK,KAAK,QAAU,IACtB,EAAa,EAAK,KAAK,QACvB,EAAS,GAGb,OAAO,EAGT,cAAc,EAAmD,CAC/D,OAAO,KAAK,MAAM,CAAC,OAAQ,GAAS,EAAK,KAAK,WAAa,EAAS,GAIxE,SAAgB,EAAsB,EAA0B,CAC9D,OAAO,EAAa,EAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","names":[],"sources":["../src/migrations.ts"],"sourcesContent":[],"mappings":";;;KAEY,iBAAA;UAEK,cAAA;EAFL,WAAA,EAAA,MAAA;EAEK,UAAA,EAAA,MAAc;AAK/B;AACQ,UADS,iBAAA,CACT;EAIM,IAAA,EAJN,iBAIM;EACC,WAAA,CAAA,EAAA,MAAA;EAAc,SAAA,CAAA,EAAA,MAAA;EAGZ,OAAA,CAAA,EAAA,MAAA;EAKA,SAAA,CAAA,EATH,cASqB,EAAA;EAKlB,UAAA,CAAA,EAbF,cAa0B,EAAA;AAKzC;AACI,UAhBa,mBAAA,SAA4B,iBAgBzC,CAAA;EACA,IAAA,EAAA,QAAA;EACA,GAAA,EAAA,MAAA;;AAEa,UAfA,iBAAA,SAA0B,iBAeS,CAAA;EAOnC,IAAA,EAAA,MAAA;EAKA,MAAA,EAAA,MAAA;AAQjB;AAGiB,UAjCA,uBAAA,SAAgC,iBAiChC,CAAA;EAQP,IAAA,EAAA,YAAA;EAO6B,SAAA,EAAA,MAAA;;KA3C3B,aAAA,GACR,sBACA,oBACA;UAEa,aAAA,SAAsB;;;;;;UAOtB,aAAA;MACX;SACG;;UAGQ,aAAA;QACT;QACA;;;cAMK,iBAAA;;iBAGI;UAQP;uCAO6B"}
1
+ {"version":3,"file":"migrations.d.ts","names":[],"sources":["../src/migrations.ts"],"sourcesContent":[],"mappings":";;;KAEY,iBAAA;UAEK,cAAA;EAFL,WAAA,EAAA,MAAA;EAEK,UAAA,EAAA,MAAc;AAK/B;AACQ,UADS,iBAAA,CACT;EAIM,IAAA,EAJN,iBAIM;EACC,WAAA,CAAA,EAAA,MAAA;EAAc,SAAA,CAAA,EAAA,MAAA;EAGZ,OAAA,CAAA,EAAA,MAAA;EAKA,SAAA,CAAA,EATH,cASqB,EAAA;EAKlB,UAAA,CAAA,EAbF,cAa0B,EAAA;AAKzC;AACI,UAhBa,mBAAA,SAA4B,iBAgBzC,CAAA;EACA,IAAA,EAAA,QAAA;EACA,GAAA,EAAA,MAAA;;AAEa,UAfA,iBAAA,SAA0B,iBAeS,CAAA;EAOnC,IAAA,EAAA,MAAA;EAKA,MAAA,EAAA,MAAA;AAQjB;AAGiB,UAjCA,uBAAA,SAAgC,iBAiChC,CAAA;EAOP,IAAA,EAAA,YAAA;EAS6B,SAAA,EAAA,MAAA;;KA5C3B,aAAA,GACR,sBACA,oBACA;UAEa,aAAA,SAAsB;;;;;;UAOtB,aAAA;MACX;SACG;;UAGQ,aAAA;QACT;QACA;;;cAMK,iBAAA;;iBAGI;UAOP;uCAS6B"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.js","names":["candidate: MigrationSpec | undefined"],"sources":["../src/migrations.ts"],"sourcesContent":["import type { OwnerShipMeta } from './ownership';\n\nexport type MigrationStepKind = 'schema' | 'data' | 'validation';\n\nexport interface MigrationCheck {\n description: string;\n expression: string;\n}\n\nexport interface MigrationStepBase {\n kind: MigrationStepKind;\n description?: string;\n timeoutMs?: number;\n retries?: number;\n preChecks?: MigrationCheck[];\n postChecks?: MigrationCheck[];\n}\n\nexport interface SchemaMigrationStep extends MigrationStepBase {\n kind: 'schema';\n sql: string;\n}\n\nexport interface DataMigrationStep extends MigrationStepBase {\n kind: 'data';\n script: string;\n}\n\nexport interface ValidationMigrationStep extends MigrationStepBase {\n kind: 'validation';\n assertion: string;\n}\n\nexport type MigrationStep =\n | SchemaMigrationStep\n | DataMigrationStep\n | ValidationMigrationStep;\n\nexport interface MigrationMeta extends OwnerShipMeta {\n /** Fully qualified migration name (e.g., \"sigil.db.2025_01_add_users\"). */\n name: string;\n /** Increment when the migration changes. */\n version: number;\n}\n\nexport interface MigrationPlan {\n up: MigrationStep[];\n down?: MigrationStep[];\n}\n\nexport interface MigrationSpec {\n meta: MigrationMeta;\n plan: MigrationPlan;\n dependencies?: string[];\n}\n\nconst migrationKey = (name: string, version: number) => `${name}.v${version}`;\n\nexport class MigrationRegistry {\n private readonly items = new Map<string, MigrationSpec>();\n\n register(spec: MigrationSpec): this {\n const key = migrationKey(spec.meta.name, spec.meta.version);\n if (this.items.has(key))\n throw new Error(`Duplicate migration ${key}`);\n this.items.set(key, spec);\n return this;\n }\n\n list(): MigrationSpec[] {\n return [...this.items.values()].sort(\n (a, b) =>\n compareKey(migrationKey(a.meta.name, a.meta.version), migrationKey(b.meta.name, b.meta.version))\n );\n }\n\n get(name: string, version?: number): MigrationSpec | undefined {\n if (version != null) return this.items.get(migrationKey(name, version));\n let candidate: MigrationSpec | undefined;\n let max = -Infinity;\n for (const spec of this.items.values()) {\n if (spec.meta.name !== name) continue;\n if (spec.meta.version > max) {\n max = spec.meta.version;\n candidate = spec;\n }\n }\n return candidate;\n }\n}\n\nfunction compareKey(a: string, b: string) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n"],"mappings":"AAwDA,MAAM,GAAgB,EAAc,IAAoB,GAAG,EAAK,IAAI,IAEpE,IAAa,EAAb,KAA+B,CAC7B,MAAyB,IAAI,IAE7B,SAAS,EAA2B,CAClC,IAAM,EAAM,EAAa,EAAK,KAAK,KAAM,EAAK,KAAK,QAAQ,CAC3D,GAAI,KAAK,MAAM,IAAI,EAAI,CACrB,MAAU,MAAM,uBAAuB,IAAM,CAE/C,OADA,KAAK,MAAM,IAAI,EAAK,EAAK,CAClB,KAGT,MAAwB,CACtB,MAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CAAC,MAC7B,EAAG,IACF,EAAW,EAAa,EAAE,KAAK,KAAM,EAAE,KAAK,QAAQ,CAAE,EAAa,EAAE,KAAK,KAAM,EAAE,KAAK,QAAQ,CAAC,CACnG,CAGH,IAAI,EAAc,EAA6C,CAC7D,GAAI,GAAW,KAAM,OAAO,KAAK,MAAM,IAAI,EAAa,EAAM,EAAQ,CAAC,CACvE,IAAIA,EACA,EAAM,KACV,IAAK,IAAM,KAAQ,KAAK,MAAM,QAAQ,CAChC,EAAK,KAAK,OAAS,GACnB,EAAK,KAAK,QAAU,IACtB,EAAM,EAAK,KAAK,QAChB,EAAY,GAGhB,OAAO,IAIX,SAAS,EAAW,EAAW,EAAW,CACxC,OAAO,EAAI,EAAI,GAAK,EAAI,EAAI,EAAI"}
1
+ {"version":3,"file":"migrations.js","names":["candidate: MigrationSpec | undefined"],"sources":["../src/migrations.ts"],"sourcesContent":["import type { OwnerShipMeta } from './ownership';\n\nexport type MigrationStepKind = 'schema' | 'data' | 'validation';\n\nexport interface MigrationCheck {\n description: string;\n expression: string;\n}\n\nexport interface MigrationStepBase {\n kind: MigrationStepKind;\n description?: string;\n timeoutMs?: number;\n retries?: number;\n preChecks?: MigrationCheck[];\n postChecks?: MigrationCheck[];\n}\n\nexport interface SchemaMigrationStep extends MigrationStepBase {\n kind: 'schema';\n sql: string;\n}\n\nexport interface DataMigrationStep extends MigrationStepBase {\n kind: 'data';\n script: string;\n}\n\nexport interface ValidationMigrationStep extends MigrationStepBase {\n kind: 'validation';\n assertion: string;\n}\n\nexport type MigrationStep =\n | SchemaMigrationStep\n | DataMigrationStep\n | ValidationMigrationStep;\n\nexport interface MigrationMeta extends OwnerShipMeta {\n /** Fully qualified migration name (e.g., \"sigil.db.2025_01_add_users\"). */\n name: string;\n /** Increment when the migration changes. */\n version: number;\n}\n\nexport interface MigrationPlan {\n up: MigrationStep[];\n down?: MigrationStep[];\n}\n\nexport interface MigrationSpec {\n meta: MigrationMeta;\n plan: MigrationPlan;\n dependencies?: string[];\n}\n\nconst migrationKey = (name: string, version: number) => `${name}.v${version}`;\n\nexport class MigrationRegistry {\n private readonly items = new Map<string, MigrationSpec>();\n\n register(spec: MigrationSpec): this {\n const key = migrationKey(spec.meta.name, spec.meta.version);\n if (this.items.has(key)) throw new Error(`Duplicate migration ${key}`);\n this.items.set(key, spec);\n return this;\n }\n\n list(): MigrationSpec[] {\n return [...this.items.values()].sort((a, b) =>\n compareKey(\n migrationKey(a.meta.name, a.meta.version),\n migrationKey(b.meta.name, b.meta.version)\n )\n );\n }\n\n get(name: string, version?: number): MigrationSpec | undefined {\n if (version != null) return this.items.get(migrationKey(name, version));\n let candidate: MigrationSpec | undefined;\n let max = -Infinity;\n for (const spec of this.items.values()) {\n if (spec.meta.name !== name) continue;\n if (spec.meta.version > max) {\n max = spec.meta.version;\n candidate = spec;\n }\n }\n return candidate;\n }\n}\n\nfunction compareKey(a: string, b: string) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n"],"mappings":"AAwDA,MAAM,GAAgB,EAAc,IAAoB,GAAG,EAAK,IAAI,IAEpE,IAAa,EAAb,KAA+B,CAC7B,MAAyB,IAAI,IAE7B,SAAS,EAA2B,CAClC,IAAM,EAAM,EAAa,EAAK,KAAK,KAAM,EAAK,KAAK,QAAQ,CAC3D,GAAI,KAAK,MAAM,IAAI,EAAI,CAAE,MAAU,MAAM,uBAAuB,IAAM,CAEtE,OADA,KAAK,MAAM,IAAI,EAAK,EAAK,CAClB,KAGT,MAAwB,CACtB,MAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CAAC,MAAM,EAAG,IACvC,EACE,EAAa,EAAE,KAAK,KAAM,EAAE,KAAK,QAAQ,CACzC,EAAa,EAAE,KAAK,KAAM,EAAE,KAAK,QAAQ,CAC1C,CACF,CAGH,IAAI,EAAc,EAA6C,CAC7D,GAAI,GAAW,KAAM,OAAO,KAAK,MAAM,IAAI,EAAa,EAAM,EAAQ,CAAC,CACvE,IAAIA,EACA,EAAM,KACV,IAAK,IAAM,KAAQ,KAAK,MAAM,QAAQ,CAChC,EAAK,KAAK,OAAS,GACnB,EAAK,KAAK,QAAU,IACtB,EAAM,EAAK,KAAK,QAChB,EAAY,GAGhB,OAAO,IAIX,SAAS,EAAW,EAAW,EAAW,CACxC,OAAO,EAAI,EAAI,GAAK,EAAI,EAAI,EAAI"}
@@ -1,135 +1,135 @@
1
1
  import { ContractSpec } from "./spec.js";
2
- import * as _lssm_lib_schema153 from "@lssm/lib.schema";
2
+ import * as _lssm_lib_schema0 from "@lssm/lib.schema";
3
3
  import { SchemaModel } from "@lssm/lib.schema";
4
4
 
5
5
  //#region src/onboarding-base.d.ts
6
6
  /** Save/update onboarding draft (auto-save during flow) */
7
7
  declare const SaveOnboardingDraftInput: SchemaModel<{
8
8
  data: {
9
- type: _lssm_lib_schema153.FieldType<unknown, unknown>;
9
+ type: _lssm_lib_schema0.FieldType<unknown, unknown>;
10
10
  isOptional: false;
11
11
  };
12
12
  }>;
13
13
  declare const SaveOnboardingDraftOutput: SchemaModel<{
14
14
  id: {
15
- type: _lssm_lib_schema153.FieldType<string, string>;
15
+ type: _lssm_lib_schema0.FieldType<string, string>;
16
16
  isOptional: false;
17
17
  };
18
18
  organizationId: {
19
- type: _lssm_lib_schema153.FieldType<string, string>;
19
+ type: _lssm_lib_schema0.FieldType<string, string>;
20
20
  isOptional: false;
21
21
  };
22
22
  }>;
23
23
  declare const SaveOnboardingDraftBaseSpec: ContractSpec<SchemaModel<{
24
24
  data: {
25
- type: _lssm_lib_schema153.FieldType<unknown, unknown>;
25
+ type: _lssm_lib_schema0.FieldType<unknown, unknown>;
26
26
  isOptional: false;
27
27
  };
28
28
  }>, SchemaModel<{
29
29
  id: {
30
- type: _lssm_lib_schema153.FieldType<string, string>;
30
+ type: _lssm_lib_schema0.FieldType<string, string>;
31
31
  isOptional: false;
32
32
  };
33
33
  organizationId: {
34
- type: _lssm_lib_schema153.FieldType<string, string>;
34
+ type: _lssm_lib_schema0.FieldType<string, string>;
35
35
  isOptional: false;
36
36
  };
37
37
  }>, undefined>;
38
38
  /** Get current onboarding draft (on mount/restore) */
39
39
  declare const GetOnboardingDraftOutput: SchemaModel<{
40
40
  id: {
41
- type: _lssm_lib_schema153.FieldType<string, string>;
41
+ type: _lssm_lib_schema0.FieldType<string, string>;
42
42
  isOptional: true;
43
43
  };
44
44
  organizationId: {
45
- type: _lssm_lib_schema153.FieldType<string, string>;
45
+ type: _lssm_lib_schema0.FieldType<string, string>;
46
46
  isOptional: true;
47
47
  };
48
48
  data: {
49
- type: _lssm_lib_schema153.FieldType<unknown, unknown>;
49
+ type: _lssm_lib_schema0.FieldType<unknown, unknown>;
50
50
  isOptional: true;
51
51
  };
52
52
  createdAt: {
53
- type: _lssm_lib_schema153.FieldType<Date, string>;
53
+ type: _lssm_lib_schema0.FieldType<Date, string>;
54
54
  isOptional: true;
55
55
  };
56
56
  updatedAt: {
57
- type: _lssm_lib_schema153.FieldType<Date, string>;
57
+ type: _lssm_lib_schema0.FieldType<Date, string>;
58
58
  isOptional: true;
59
59
  };
60
60
  }>;
61
- declare const GetOnboardingDraftBaseSpec: ContractSpec<_lssm_lib_schema153.AnySchemaModel, SchemaModel<{
61
+ declare const GetOnboardingDraftBaseSpec: ContractSpec<_lssm_lib_schema0.AnySchemaModel, SchemaModel<{
62
62
  id: {
63
- type: _lssm_lib_schema153.FieldType<string, string>;
63
+ type: _lssm_lib_schema0.FieldType<string, string>;
64
64
  isOptional: true;
65
65
  };
66
66
  organizationId: {
67
- type: _lssm_lib_schema153.FieldType<string, string>;
67
+ type: _lssm_lib_schema0.FieldType<string, string>;
68
68
  isOptional: true;
69
69
  };
70
70
  data: {
71
- type: _lssm_lib_schema153.FieldType<unknown, unknown>;
71
+ type: _lssm_lib_schema0.FieldType<unknown, unknown>;
72
72
  isOptional: true;
73
73
  };
74
74
  createdAt: {
75
- type: _lssm_lib_schema153.FieldType<Date, string>;
75
+ type: _lssm_lib_schema0.FieldType<Date, string>;
76
76
  isOptional: true;
77
77
  };
78
78
  updatedAt: {
79
- type: _lssm_lib_schema153.FieldType<Date, string>;
79
+ type: _lssm_lib_schema0.FieldType<Date, string>;
80
80
  isOptional: true;
81
81
  };
82
82
  }>, undefined>;
83
83
  /** Delete onboarding draft (cleanup after completion or cancel) */
84
84
  declare const DeleteOnboardingDraftOutput: SchemaModel<{
85
85
  ok: {
86
- type: _lssm_lib_schema153.FieldType<boolean, boolean>;
86
+ type: _lssm_lib_schema0.FieldType<boolean, boolean>;
87
87
  isOptional: false;
88
88
  };
89
89
  }>;
90
- declare const DeleteOnboardingDraftBaseSpec: ContractSpec<_lssm_lib_schema153.AnySchemaModel, SchemaModel<{
90
+ declare const DeleteOnboardingDraftBaseSpec: ContractSpec<_lssm_lib_schema0.AnySchemaModel, SchemaModel<{
91
91
  ok: {
92
- type: _lssm_lib_schema153.FieldType<boolean, boolean>;
92
+ type: _lssm_lib_schema0.FieldType<boolean, boolean>;
93
93
  isOptional: false;
94
94
  };
95
95
  }>, undefined>;
96
96
  /** Complete onboarding (final submit, creates entities) */
97
97
  declare const CompleteOnboardingBaseInput: SchemaModel<{
98
98
  data: {
99
- type: _lssm_lib_schema153.FieldType<unknown, unknown>;
99
+ type: _lssm_lib_schema0.FieldType<unknown, unknown>;
100
100
  isOptional: false;
101
101
  };
102
102
  }>;
103
103
  declare const CompleteOnboardingBaseOutput: SchemaModel<{
104
104
  success: {
105
- type: _lssm_lib_schema153.FieldType<boolean, boolean>;
105
+ type: _lssm_lib_schema0.FieldType<boolean, boolean>;
106
106
  isOptional: false;
107
107
  };
108
108
  userId: {
109
- type: _lssm_lib_schema153.FieldType<string, string>;
109
+ type: _lssm_lib_schema0.FieldType<string, string>;
110
110
  isOptional: true;
111
111
  };
112
112
  organizationId: {
113
- type: _lssm_lib_schema153.FieldType<string, string>;
113
+ type: _lssm_lib_schema0.FieldType<string, string>;
114
114
  isOptional: true;
115
115
  };
116
116
  }>;
117
117
  declare const CompleteOnboardingBaseSpec: ContractSpec<SchemaModel<{
118
118
  data: {
119
- type: _lssm_lib_schema153.FieldType<unknown, unknown>;
119
+ type: _lssm_lib_schema0.FieldType<unknown, unknown>;
120
120
  isOptional: false;
121
121
  };
122
122
  }>, SchemaModel<{
123
123
  success: {
124
- type: _lssm_lib_schema153.FieldType<boolean, boolean>;
124
+ type: _lssm_lib_schema0.FieldType<boolean, boolean>;
125
125
  isOptional: false;
126
126
  };
127
127
  userId: {
128
- type: _lssm_lib_schema153.FieldType<string, string>;
128
+ type: _lssm_lib_schema0.FieldType<string, string>;
129
129
  isOptional: true;
130
130
  };
131
131
  organizationId: {
132
- type: _lssm_lib_schema153.FieldType<string, string>;
132
+ type: _lssm_lib_schema0.FieldType<string, string>;
133
133
  isOptional: true;
134
134
  };
135
135
  }>, undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"onboarding-base.d.ts","names":[],"sources":["../src/onboarding-base.ts"],"sourcesContent":[],"mappings":";;;;;;cASa,0BAAwB;;UAMnC,mBAAA,CAAA;IANW,UAAA,EAAA,KAAA;EAQA,CAAA;CAOX,CAAA;cAPW,2BAAyB;EAAA,EAAA,EAAA;IAAA,IAAA,EAOpC,mBAAA,CAAA,SAPoC,CAAA,MAAA,EAAA,MAAA,CAAA;IASzB,UAAA,EAAA,KAAA;EAwBX,CAAA;EAxBsC,cAAA,EAAA;IAAA,IAAA,+BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;AAAA,cAA3B,2BAA2B,cAAA,CAAA,WAAA,CAAA;EA2B3B,IAAA,EAAA;IAUX,IAAA,EAbA,mBAAA,CAAA,SAaA,CAAA,OAAA,EAAA,OAAA,CAAA;;;;;UArCsC,mBAAA,CAAA;;EA2BH,CAAA;EAAA,cAAA,EAAA;IAYxB,IAAA,+BAuBX,CAAA,MAAA,EAAA,MAAA,CAAA;IAAA,UAAA,EAAA,KAvBqC;EAAA,CAAA;;;cAZ1B,0BAAwB;;UAUnC,mBAAA,CAAA;;EAEqC,CAAA;EAAA,cAAA,EAAA;IAAA,IAAA,+BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;IA0B1B,UAAA,EAAA,IAAA;EAQA,CAAA;EAuBX,IAAA,EAAA;IAvBwC,IAAA,+BAAA,CAAA,OAAA,EAAA,OAAA,CAAA;IAAA,UAAA,EAAA,IAAA;EAAA,CAAA;EAAA,SAAA,EAAA;IA0B7B,IAAA,+BAMX,KAAA,EAAA,MAAA,CAAA;IAEW,UAAA,EAAA,IAAA;EAQX,CAAA;;;IARuC,UAAA,EAAA,IAAA;EAAA,CAAA;AAUzC,CAAA,CAAA;AAwBE,cAtGW,0BAsGX,EAtGqC,YAsGrC,CA/EA,mBAAA,CAvBqC,cAAA,EAAA,WAsGrC,CAAA;EAxBqC,EAAA,EAAA;IAAA,IAAA,EA9EA,mBAAA,CAAA,SA8EA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;IAAA,UAAA,EAAA,IAAA;;;;;;;;;;;;;;;;cApD1B,6BAA2B;;UAMtC,mBAAA,CAAA;;;;cAEW,+BAA6B,aAuBxC,mBAAA,CAvBwC,cAAA,EAAA;;UAAA,mBAAA,CAAA;;;;;cA0B7B,6BAA2B;;UAMtC,mBAAA,CAAA;;;;cAEW,8BAA4B;;UAQvC,mBAAA,CAAA;;;;;;;;;;;;cAEW,yCAA0B;;UAwBrC,mBAAA,CAAA;;;;;UAxBqC,mBAAA,CAAA"}
1
+ {"version":3,"file":"onboarding-base.d.ts","names":[],"sources":["../src/onboarding-base.ts"],"sourcesContent":[],"mappings":";;;;;;cASa,0BAAwB;;UAMnC,iBAAA,CAAA;IANW,UAAA,EAAA,KAAA;EAQA,CAAA;CAOX,CAAA;cAPW,2BAAyB;EAAA,EAAA,EAAA;IAAA,IAAA,EAOpC,iBAAA,CAAA,SAPoC,CAAA,MAAA,EAAA,MAAA,CAAA;IASzB,UAAA,EAAA,KAAA;EAwBX,CAAA;EAxBsC,cAAA,EAAA;IAAA,IAAA,6BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;AAAA,cAA3B,2BAA2B,cAAA,CAAA,WAAA,CAAA;EA2B3B,IAAA,EAAA;IAUX,IAAA,EAbA,iBAAA,CAAA,SAaA,CAAA,OAAA,EAAA,OAAA,CAAA;;;;;UArCsC,iBAAA,CAAA;;EA2BH,CAAA;EAAA,cAAA,EAAA;IAYxB,IAAA,6BAuBX,CAAA,MAAA,EAAA,MAAA,CAAA;IAAA,UAAA,EAvBqC,KAAA;EAAA,CAAA;;;cAZ1B,0BAAwB;;UAUnC,iBAAA,CAAA;;EAEqC,CAAA;EAAA,cAAA,EAAA;IAAA,IAAA,6BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;IA0B1B,UAAA,EAAA,IAAA;EAQA,CAAA;EAuBX,IAAA,EAAA;IAvBwC,IAAA,6BAAA,CAAA,OAAA,EAAA,OAAA,CAAA;IAAA,UAAA,EAAA,IAAA;EAAA,CAAA;EAAA,SAAA,EAAA;IA0B7B,IAAA,6BAMX,KAAA,EAAA,MAAA,CAAA;IAEW,UAAA,EAAA,IAAA;EAQX,CAAA;;;IARuC,UAAA,EAAA,IAAA;EAAA,CAAA;AAUzC,CAAA,CAAA;AAwBE,cAtGW,0BAsGX,EAtGqC,YAsGrC,CA/EA,iBAAA,CAvBqC,cAAA,EAAA,WAsGrC,CAAA;EAxBqC,EAAA,EAAA;IAAA,IAAA,EA9EA,iBAAA,CAAA,SA8EA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;IAAA,UAAA,EAAA,IAAA;;;;;;;;;;;;;;;;cApD1B,6BAA2B;;UAMtC,iBAAA,CAAA;;;;cAEW,+BAA6B,aAuBxC,iBAAA,CAvBwC,cAAA,EAAA;;UAAA,iBAAA,CAAA;;;;;cA0B7B,6BAA2B;;UAMtC,iBAAA,CAAA;;;;cAEW,8BAA4B;;UAQvC,iBAAA,CAAA;;;;;;;;;;;;cAEW,yCAA0B;;UAwBrC,iBAAA,CAAA;;;;;UAxBqC,iBAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","names":["registry: PolicyRegistry","allowReason: string | undefined","appliedRateLimit: PolicyDecision['rateLimit']","escalate: 'human_review' | null | undefined","specs: PolicySpec[]","allowMatch: RuleEvaluation | undefined","evaluation: RuleEvaluation","definition: RateLimitDefinition | undefined"],"sources":["../../src/policy/engine.ts"],"sourcesContent":["import {\n PolicyRegistry,\n type PolicyRef,\n type PolicySpec,\n type PolicyRule,\n type FieldPolicyRule,\n type PolicyCondition,\n type ConsentDefinition,\n type RateLimitDefinition,\n type RelationshipMatcher,\n} from './spec';\nimport type { PolicyDecision, FieldLevelDecision } from '../types';\n\nexport interface SubjectRelationship {\n relation: string;\n object: string;\n objectType?: string;\n}\n\nexport interface SubjectContext {\n roles?: string[];\n attributes?: Record<string, unknown>;\n relationships?: SubjectRelationship[];\n}\n\nexport interface ResourceContext {\n type: string;\n id?: string;\n fields?: string[];\n attributes?: Record<string, unknown>;\n}\n\nexport interface DecisionContext {\n subject: SubjectContext;\n resource: ResourceContext;\n context?: Record<string, unknown>;\n action: string;\n policies: PolicyRef[];\n consents?: string[];\n flags?: string[];\n}\n\ninterface RuleEvaluation {\n rule: PolicyRule;\n missingConsents: ConsentDefinition[];\n rateLimit?: PolicyDecision['rateLimit'];\n}\n\nexport class PolicyEngine {\n constructor(private readonly registry: PolicyRegistry) {}\n\n decide(input: DecisionContext): PolicyDecision {\n const policies = this.resolvePolicies(input.policies);\n let allowReason: string | undefined;\n let appliedRateLimit: PolicyDecision['rateLimit'];\n let escalate: 'human_review' | null | undefined;\n\n for (const policy of policies) {\n const match = this.matchRuleSet(policy, input);\n if (!match) continue;\n if (match.rule.effect === 'deny') {\n return {\n effect: 'deny',\n reason: match.rule.reason ?? policy.meta.name,\n requiredConsents: match.missingConsents.length\n ? match.missingConsents\n : undefined,\n evaluatedBy: 'engine',\n };\n }\n if (match.rule.effect === 'allow') {\n if (match.missingConsents.length) {\n return {\n effect: 'deny',\n reason: 'consent_required',\n requiredConsents: match.missingConsents,\n evaluatedBy: 'engine',\n };\n }\n if (!allowReason) {\n allowReason = match.rule.reason ?? policy.meta.name;\n }\n if (!appliedRateLimit && match.rateLimit) {\n appliedRateLimit = match.rateLimit;\n }\n if (!escalate && match.rule.escalate) {\n escalate = match.rule.escalate;\n }\n }\n }\n\n const fieldDecisions = this.evaluateFields(policies, input);\n const pii = policies.find((p) => p.pii)?.pii;\n const escalateValue =\n typeof escalate === 'undefined' ? undefined : escalate;\n\n return {\n effect: allowReason ? 'allow' : 'deny',\n reason: allowReason,\n rateLimit: appliedRateLimit,\n escalate: escalateValue,\n fieldDecisions: fieldDecisions.length ? fieldDecisions : undefined,\n pii,\n evaluatedBy: 'engine',\n };\n }\n\n private resolvePolicies(refs: PolicyRef[]): PolicySpec[] {\n const specs: PolicySpec[] = [];\n for (const ref of refs) {\n const spec = this.registry.get(ref.name, ref.version);\n if (!spec)\n throw new Error(\n `PolicyEngine: policy not found ${ref.name}.v${ref.version}`\n );\n specs.push(spec);\n }\n return specs;\n }\n\n private matchRuleSet(\n policy: PolicySpec,\n input: DecisionContext\n ): RuleEvaluation | undefined {\n let allowMatch: RuleEvaluation | undefined;\n for (const rule of policy.rules) {\n if (!rule.actions.includes(input.action)) continue;\n if (!matchesSubject(rule, input.subject)) continue;\n if (!matchesResource(rule, input.resource)) continue;\n if (!matchesFlags(rule, input)) continue;\n if (!matchesRelationships(rule.relationships, input)) continue;\n if (!matchesConditions(rule, input)) continue;\n const missingConsents = collectMissingConsents(rule, policy, input);\n const rateLimit = resolveRateLimit(rule, policy, input);\n const evaluation: RuleEvaluation = {\n rule,\n missingConsents,\n rateLimit,\n };\n if (rule.effect === 'deny') return evaluation;\n if (rule.effect === 'allow' && !allowMatch) allowMatch = evaluation;\n }\n return allowMatch;\n }\n\n private evaluateFields(\n policies: PolicySpec[],\n input: DecisionContext\n ): FieldLevelDecision[] {\n const out = new Map<string, FieldLevelDecision>();\n for (const policy of policies) {\n if (!policy.fieldPolicies) continue;\n for (const rule of policy.fieldPolicies) {\n if (!rule.actions.includes(mapActionToFieldAction(input.action))) continue;\n if (!matchesSubject(rule, input.subject)) continue;\n if (!matchesResource(rule, input.resource)) continue;\n if (!matchesConditions(rule, input)) continue;\n const existing = out.get(rule.field);\n if (rule.effect === 'deny') {\n out.set(rule.field, {\n field: rule.field,\n effect: 'deny',\n reason: rule.reason ?? policy.meta.name,\n });\n } else if (!existing) {\n out.set(rule.field, {\n field: rule.field,\n effect: 'allow',\n reason: rule.reason ?? policy.meta.name,\n });\n }\n }\n }\n return [...out.values()];\n }\n}\n\nfunction mapActionToFieldAction(action: string): 'read' | 'write' {\n if (action.startsWith('write')) return 'write';\n return 'read';\n}\n\nfunction matchesSubject(\n rule: { subject?: PolicyRule['subject'] | FieldPolicyRule['subject'] },\n subject: SubjectContext\n): boolean {\n const matcher = rule.subject;\n if (!matcher) return true;\n if (matcher.roles?.length) {\n const roles = subject.roles ?? [];\n const hasRole = matcher.roles.some((role) => roles.includes(role));\n if (!hasRole) return false;\n }\n if (matcher.attributes) {\n const attributes = subject.attributes ?? {};\n if (!matchAttributes(matcher.attributes, attributes)) return false;\n }\n return true;\n}\n\nfunction matchesResource(\n rule: { resource?: PolicyRule['resource'] | FieldPolicyRule['resource'] },\n resource: ResourceContext\n): boolean {\n const matcher = rule.resource;\n if (!matcher) return true;\n if (matcher.type && matcher.type !== resource.type) return false;\n if (matcher.fields?.length) {\n const targetFields = resource.fields ?? [];\n if (!matcher.fields.some((field) => targetFields.includes(field)))\n return false;\n }\n if (matcher.attributes) {\n const attributes = resource.attributes ?? {};\n if (!matchAttributes(matcher.attributes, attributes)) return false;\n }\n return true;\n}\n\nfunction matchesFlags(rule: PolicyRule, input: DecisionContext): boolean {\n if (!rule.flags?.length) return true;\n const available = new Set<string>();\n if (input.flags) {\n for (const flag of input.flags) available.add(flag);\n }\n const attributeFlags = input.subject.attributes?.featureFlags;\n if (Array.isArray(attributeFlags)) {\n for (const flag of attributeFlags) available.add(flag);\n }\n return rule.flags.every((flag) => available.has(flag));\n}\n\nfunction matchesRelationships(\n matchers: RelationshipMatcher[] | undefined,\n input: DecisionContext\n): boolean {\n if (!matchers || matchers.length === 0) return true;\n const relationships = input.subject.relationships ?? [];\n const resourceId = getResourceId(input.resource);\n const resourceType = input.resource.type;\n\n return matchers.every((matcher) =>\n relationships.some((relation) => {\n if (relation.relation !== matcher.relation) return false;\n\n const typeMatches =\n !matcher.objectType ||\n relation.objectType === matcher.objectType ||\n matcher.objectType === resourceType;\n\n if (!typeMatches) return false;\n\n if (!matcher.objectId) return true;\n\n if (matcher.objectId === '$resource') {\n if (resourceId) {\n return relation.object === resourceId;\n }\n return (\n relation.object === resourceType ||\n relation.objectType === resourceType\n );\n }\n\n return relation.object === matcher.objectId;\n })\n );\n}\n\nfunction matchesConditions(\n rule: { conditions?: PolicyCondition[] },\n input: DecisionContext\n): boolean {\n if (!rule.conditions || rule.conditions.length === 0) return true;\n return rule.conditions.every((condition) =>\n evaluateCondition(condition.expression, input)\n );\n}\n\nfunction matchAttributes(\n matcher: Record<string, import('./spec').AttributeMatcher>,\n actual: Record<string, unknown>\n): boolean {\n for (const [key, attrMatcher] of Object.entries(matcher)) {\n const value = actual[key];\n if (attrMatcher.exists && typeof value === 'undefined') return false;\n if (typeof attrMatcher.equals !== 'undefined') {\n if (value !== attrMatcher.equals) return false;\n }\n if (attrMatcher.oneOf && !attrMatcher.oneOf.includes(value)) return false;\n }\n return true;\n}\n\nfunction collectMissingConsents(\n rule: PolicyRule,\n policy: PolicySpec,\n input: DecisionContext\n): ConsentDefinition[] {\n if (!rule.requiresConsent?.length) return [];\n const granted = new Set(input.consents ?? []);\n const missingIds = rule.requiresConsent.filter((id) => !granted.has(id));\n if (missingIds.length === 0) return [];\n return resolveConsentDefinitions(policy, missingIds);\n}\n\nfunction resolveConsentDefinitions(\n policy: PolicySpec,\n ids: string[]\n): ConsentDefinition[] {\n const catalog = policy.consents ?? [];\n return ids.map((id) => {\n const found = catalog.find((consent) => consent.id === id);\n return (\n found ?? {\n id,\n scope: 'unspecified',\n purpose: 'unspecified',\n description: `Consent \"${id}\" required by ${policy.meta.name}`,\n required: true,\n }\n );\n });\n}\n\nfunction resolveRateLimit(\n rule: PolicyRule,\n policy: PolicySpec,\n input: DecisionContext\n): PolicyDecision['rateLimit'] | undefined {\n if (!rule.rateLimit) return undefined;\n const definition: RateLimitDefinition | undefined =\n typeof rule.rateLimit === 'string'\n ? (policy.rateLimits ?? []).find((item) => item.id === rule.rateLimit)\n : rule.rateLimit;\n\n if (!definition) {\n throw new Error(\n `PolicyEngine: rate limit \"${String(\n rule.rateLimit\n )}\" not declared in ${policy.meta.name}`\n );\n }\n\n return {\n rpm: definition.rpm,\n key: definition.key ?? input.resource.type,\n windowSeconds: definition.windowSeconds,\n burst: definition.burst,\n };\n}\n\nfunction evaluateCondition(\n expression: string,\n input: DecisionContext\n): boolean {\n const trimmed = expression.trim();\n if (!trimmed) return true;\n\n const context = {\n subject: input.subject,\n resource: input.resource,\n context: input.context ?? {},\n };\n\n try {\n // very small whitelist of expressions\n // Supports subject/resource/context dot paths, comparisons, and logical operators.\n const fn = new Function(\n 'subject',\n 'resource',\n 'context',\n `return (${transformExpression(trimmed)});`\n );\n const result = fn(context.subject, context.resource, context.context);\n return Boolean(result);\n } catch (_error) {\n return false;\n }\n}\n\nfunction transformExpression(expression: string): string {\n return expression.replace(/&&/g, '&&').replace(/\\|\\|/g, '||');\n}\n\nfunction getResourceId(resource: ResourceContext): string | undefined {\n if (resource.id) return resource.id;\n const candidate = resource.attributes?.id;\n if (typeof candidate === 'string') return candidate;\n if (typeof candidate === 'number') return String(candidate);\n return undefined;\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"engine.js","names":["registry: PolicyRegistry","allowReason: string | undefined","appliedRateLimit: PolicyDecision['rateLimit']","escalate: 'human_review' | null | undefined","specs: PolicySpec[]","allowMatch: RuleEvaluation | undefined","evaluation: RuleEvaluation","definition: RateLimitDefinition | undefined"],"sources":["../../src/policy/engine.ts"],"sourcesContent":["import {\n PolicyRegistry,\n type PolicyRef,\n type PolicySpec,\n type PolicyRule,\n type FieldPolicyRule,\n type PolicyCondition,\n type ConsentDefinition,\n type RateLimitDefinition,\n type RelationshipMatcher,\n} from './spec';\nimport type { PolicyDecision, FieldLevelDecision } from '../types';\n\nexport interface SubjectRelationship {\n relation: string;\n object: string;\n objectType?: string;\n}\n\nexport interface SubjectContext {\n roles?: string[];\n attributes?: Record<string, unknown>;\n relationships?: SubjectRelationship[];\n}\n\nexport interface ResourceContext {\n type: string;\n id?: string;\n fields?: string[];\n attributes?: Record<string, unknown>;\n}\n\nexport interface DecisionContext {\n subject: SubjectContext;\n resource: ResourceContext;\n context?: Record<string, unknown>;\n action: string;\n policies: PolicyRef[];\n consents?: string[];\n flags?: string[];\n}\n\ninterface RuleEvaluation {\n rule: PolicyRule;\n missingConsents: ConsentDefinition[];\n rateLimit?: PolicyDecision['rateLimit'];\n}\n\nexport class PolicyEngine {\n constructor(private readonly registry: PolicyRegistry) {}\n\n decide(input: DecisionContext): PolicyDecision {\n const policies = this.resolvePolicies(input.policies);\n let allowReason: string | undefined;\n let appliedRateLimit: PolicyDecision['rateLimit'];\n let escalate: 'human_review' | null | undefined;\n\n for (const policy of policies) {\n const match = this.matchRuleSet(policy, input);\n if (!match) continue;\n if (match.rule.effect === 'deny') {\n return {\n effect: 'deny',\n reason: match.rule.reason ?? policy.meta.name,\n requiredConsents: match.missingConsents.length\n ? match.missingConsents\n : undefined,\n evaluatedBy: 'engine',\n };\n }\n if (match.rule.effect === 'allow') {\n if (match.missingConsents.length) {\n return {\n effect: 'deny',\n reason: 'consent_required',\n requiredConsents: match.missingConsents,\n evaluatedBy: 'engine',\n };\n }\n if (!allowReason) {\n allowReason = match.rule.reason ?? policy.meta.name;\n }\n if (!appliedRateLimit && match.rateLimit) {\n appliedRateLimit = match.rateLimit;\n }\n if (!escalate && match.rule.escalate) {\n escalate = match.rule.escalate;\n }\n }\n }\n\n const fieldDecisions = this.evaluateFields(policies, input);\n const pii = policies.find((p) => p.pii)?.pii;\n const escalateValue =\n typeof escalate === 'undefined' ? undefined : escalate;\n\n return {\n effect: allowReason ? 'allow' : 'deny',\n reason: allowReason,\n rateLimit: appliedRateLimit,\n escalate: escalateValue,\n fieldDecisions: fieldDecisions.length ? fieldDecisions : undefined,\n pii,\n evaluatedBy: 'engine',\n };\n }\n\n private resolvePolicies(refs: PolicyRef[]): PolicySpec[] {\n const specs: PolicySpec[] = [];\n for (const ref of refs) {\n const spec = this.registry.get(ref.name, ref.version);\n if (!spec)\n throw new Error(\n `PolicyEngine: policy not found ${ref.name}.v${ref.version}`\n );\n specs.push(spec);\n }\n return specs;\n }\n\n private matchRuleSet(\n policy: PolicySpec,\n input: DecisionContext\n ): RuleEvaluation | undefined {\n let allowMatch: RuleEvaluation | undefined;\n for (const rule of policy.rules) {\n if (!rule.actions.includes(input.action)) continue;\n if (!matchesSubject(rule, input.subject)) continue;\n if (!matchesResource(rule, input.resource)) continue;\n if (!matchesFlags(rule, input)) continue;\n if (!matchesRelationships(rule.relationships, input)) continue;\n if (!matchesConditions(rule, input)) continue;\n const missingConsents = collectMissingConsents(rule, policy, input);\n const rateLimit = resolveRateLimit(rule, policy, input);\n const evaluation: RuleEvaluation = {\n rule,\n missingConsents,\n rateLimit,\n };\n if (rule.effect === 'deny') return evaluation;\n if (rule.effect === 'allow' && !allowMatch) allowMatch = evaluation;\n }\n return allowMatch;\n }\n\n private evaluateFields(\n policies: PolicySpec[],\n input: DecisionContext\n ): FieldLevelDecision[] {\n const out = new Map<string, FieldLevelDecision>();\n for (const policy of policies) {\n if (!policy.fieldPolicies) continue;\n for (const rule of policy.fieldPolicies) {\n if (!rule.actions.includes(mapActionToFieldAction(input.action)))\n continue;\n if (!matchesSubject(rule, input.subject)) continue;\n if (!matchesResource(rule, input.resource)) continue;\n if (!matchesConditions(rule, input)) continue;\n const existing = out.get(rule.field);\n if (rule.effect === 'deny') {\n out.set(rule.field, {\n field: rule.field,\n effect: 'deny',\n reason: rule.reason ?? policy.meta.name,\n });\n } else if (!existing) {\n out.set(rule.field, {\n field: rule.field,\n effect: 'allow',\n reason: rule.reason ?? policy.meta.name,\n });\n }\n }\n }\n return [...out.values()];\n }\n}\n\nfunction mapActionToFieldAction(action: string): 'read' | 'write' {\n if (action.startsWith('write')) return 'write';\n return 'read';\n}\n\nfunction matchesSubject(\n rule: { subject?: PolicyRule['subject'] | FieldPolicyRule['subject'] },\n subject: SubjectContext\n): boolean {\n const matcher = rule.subject;\n if (!matcher) return true;\n if (matcher.roles?.length) {\n const roles = subject.roles ?? [];\n const hasRole = matcher.roles.some((role) => roles.includes(role));\n if (!hasRole) return false;\n }\n if (matcher.attributes) {\n const attributes = subject.attributes ?? {};\n if (!matchAttributes(matcher.attributes, attributes)) return false;\n }\n return true;\n}\n\nfunction matchesResource(\n rule: { resource?: PolicyRule['resource'] | FieldPolicyRule['resource'] },\n resource: ResourceContext\n): boolean {\n const matcher = rule.resource;\n if (!matcher) return true;\n if (matcher.type && matcher.type !== resource.type) return false;\n if (matcher.fields?.length) {\n const targetFields = resource.fields ?? [];\n if (!matcher.fields.some((field) => targetFields.includes(field)))\n return false;\n }\n if (matcher.attributes) {\n const attributes = resource.attributes ?? {};\n if (!matchAttributes(matcher.attributes, attributes)) return false;\n }\n return true;\n}\n\nfunction matchesFlags(rule: PolicyRule, input: DecisionContext): boolean {\n if (!rule.flags?.length) return true;\n const available = new Set<string>();\n if (input.flags) {\n for (const flag of input.flags) available.add(flag);\n }\n const attributeFlags = input.subject.attributes?.featureFlags;\n if (Array.isArray(attributeFlags)) {\n for (const flag of attributeFlags) available.add(flag);\n }\n return rule.flags.every((flag) => available.has(flag));\n}\n\nfunction matchesRelationships(\n matchers: RelationshipMatcher[] | undefined,\n input: DecisionContext\n): boolean {\n if (!matchers || matchers.length === 0) return true;\n const relationships = input.subject.relationships ?? [];\n const resourceId = getResourceId(input.resource);\n const resourceType = input.resource.type;\n\n return matchers.every((matcher) =>\n relationships.some((relation) => {\n if (relation.relation !== matcher.relation) return false;\n\n const typeMatches =\n !matcher.objectType ||\n relation.objectType === matcher.objectType ||\n matcher.objectType === resourceType;\n\n if (!typeMatches) return false;\n\n if (!matcher.objectId) return true;\n\n if (matcher.objectId === '$resource') {\n if (resourceId) {\n return relation.object === resourceId;\n }\n return (\n relation.object === resourceType ||\n relation.objectType === resourceType\n );\n }\n\n return relation.object === matcher.objectId;\n })\n );\n}\n\nfunction matchesConditions(\n rule: { conditions?: PolicyCondition[] },\n input: DecisionContext\n): boolean {\n if (!rule.conditions || rule.conditions.length === 0) return true;\n return rule.conditions.every((condition) =>\n evaluateCondition(condition.expression, input)\n );\n}\n\nfunction matchAttributes(\n matcher: Record<string, import('./spec').AttributeMatcher>,\n actual: Record<string, unknown>\n): boolean {\n for (const [key, attrMatcher] of Object.entries(matcher)) {\n const value = actual[key];\n if (attrMatcher.exists && typeof value === 'undefined') return false;\n if (typeof attrMatcher.equals !== 'undefined') {\n if (value !== attrMatcher.equals) return false;\n }\n if (attrMatcher.oneOf && !attrMatcher.oneOf.includes(value)) return false;\n }\n return true;\n}\n\nfunction collectMissingConsents(\n rule: PolicyRule,\n policy: PolicySpec,\n input: DecisionContext\n): ConsentDefinition[] {\n if (!rule.requiresConsent?.length) return [];\n const granted = new Set(input.consents ?? []);\n const missingIds = rule.requiresConsent.filter((id) => !granted.has(id));\n if (missingIds.length === 0) return [];\n return resolveConsentDefinitions(policy, missingIds);\n}\n\nfunction resolveConsentDefinitions(\n policy: PolicySpec,\n ids: string[]\n): ConsentDefinition[] {\n const catalog = policy.consents ?? [];\n return ids.map((id) => {\n const found = catalog.find((consent) => consent.id === id);\n return (\n found ?? {\n id,\n scope: 'unspecified',\n purpose: 'unspecified',\n description: `Consent \"${id}\" required by ${policy.meta.name}`,\n required: true,\n }\n );\n });\n}\n\nfunction resolveRateLimit(\n rule: PolicyRule,\n policy: PolicySpec,\n input: DecisionContext\n): PolicyDecision['rateLimit'] | undefined {\n if (!rule.rateLimit) return undefined;\n const definition: RateLimitDefinition | undefined =\n typeof rule.rateLimit === 'string'\n ? (policy.rateLimits ?? []).find((item) => item.id === rule.rateLimit)\n : rule.rateLimit;\n\n if (!definition) {\n throw new Error(\n `PolicyEngine: rate limit \"${String(\n rule.rateLimit\n )}\" not declared in ${policy.meta.name}`\n );\n }\n\n return {\n rpm: definition.rpm,\n key: definition.key ?? input.resource.type,\n windowSeconds: definition.windowSeconds,\n burst: definition.burst,\n };\n}\n\nfunction evaluateCondition(\n expression: string,\n input: DecisionContext\n): boolean {\n const trimmed = expression.trim();\n if (!trimmed) return true;\n\n const context = {\n subject: input.subject,\n resource: input.resource,\n context: input.context ?? {},\n };\n\n try {\n // very small whitelist of expressions\n // Supports subject/resource/context dot paths, comparisons, and logical operators.\n const fn = new Function(\n 'subject',\n 'resource',\n 'context',\n `return (${transformExpression(trimmed)});`\n );\n const result = fn(context.subject, context.resource, context.context);\n return Boolean(result);\n } catch (_error) {\n return false;\n }\n}\n\nfunction transformExpression(expression: string): string {\n return expression.replace(/&&/g, '&&').replace(/\\|\\|/g, '||');\n}\n\nfunction getResourceId(resource: ResourceContext): string | undefined {\n if (resource.id) return resource.id;\n const candidate = resource.attributes?.id;\n if (typeof candidate === 'string') return candidate;\n if (typeof candidate === 'number') return String(candidate);\n return undefined;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"opa-adapter.d.ts","names":[],"sources":["../../src/policy/opa-adapter.ts"],"sourcesContent":[],"mappings":";;;;;UAIiB,SAAA;qDACoC,QAAQ;AAD7D;AAIiB,UAAA,mBAAA,CAAmB;EAOnB,MAAA,CAAA,EAAA,OAAA,GAAA,MAAiB;EAWrB,MAAA,CAAA,EAAA,MAAA;EAA0B,cAAA,CAAA,EAfpB,cAeoB,CAAA,gBAAA,CAAA;EAEV,gBAAA,CAAA,EAAA,MAAA,EAAA;;AACC,UAdb,iBAca,CAAA,SAdc,mBAcd,GAAA,IAAA,CAAA,CAAA;EAIjB;;;EAGA,YAAA,EAAA,MAAA;EAAR;;AAsCL;EACW,SAAA,CAAA,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,GApDuB,MAoDvB;;AAEO,cAnDL,gBAmDK,CAAA,SAnDqB,mBAmDrB,GAAA,IAAA,CAAA,CAAA;;;sBAjDW,oBACC,kBAAkB;oBAInC,2BACC,8BACM,iBACf,QAAQ;;iBAsCG,aAAA,UACL,2BACC,8BACM"}
1
+ {"version":3,"file":"opa-adapter.d.ts","names":[],"sources":["../../src/policy/opa-adapter.ts"],"sourcesContent":[],"mappings":";;;;;UAIiB,SAAA;qDACoC,QAAQ;AAD7D;AAIiB,UAAA,mBAAA,CAAmB;EAOnB,MAAA,CAAA,EAAA,OAAA,GAAA,MAAiB;EAWrB,MAAA,CAAA,EAAA,MAAA;EAA0B,cAAA,CAAA,EAfpB,cAeoB,CAAA,gBAAA,CAAA;EAEV,gBAAA,CAAA,EAAA,MAAA,EAAA;;AACC,UAdb,iBAca,CAAA,SAdc,mBAcd,GAAA,IAAA,CAAA,CAAA;EAIjB;;;EAGA,YAAA,EAAA,MAAA;EAAR;;AAqCL;EACW,SAAA,CAAA,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,GAnDuB,MAmDvB;;AAEO,cAlDL,gBAkDK,CAAA,SAlDqB,mBAkDrB,GAAA,IAAA,CAAA,CAAA;;;sBAhDW,oBACC,kBAAkB;oBAInC,2BACC,8BACM,iBACf,QAAQ;;iBAqCG,aAAA,UACL,2BACC,8BACM"}
@@ -1 +1 @@
1
- {"version":3,"file":"opa-adapter.js","names":["client: OPAClient","options: OPAAdapterOptions<Result>"],"sources":["../../src/policy/opa-adapter.ts"],"sourcesContent":["import type { PolicyDecision } from '../types';\nimport type { PolicySpec, ConsentDefinition } from './spec';\nimport type { DecisionContext } from './engine';\n\nexport interface OPAClient {\n evaluate<T>(decisionPath: string, input: unknown): Promise<T>;\n}\n\nexport interface OPAEvaluationResult {\n effect?: 'allow' | 'deny';\n reason?: string;\n fieldDecisions?: PolicyDecision['fieldDecisions'];\n requiredConsents?: string[];\n}\n\nexport interface OPAAdapterOptions<Result = OPAEvaluationResult | null> {\n /**\n * Path fed to the OPA client (e.g., \"sigil/authz/allow\").\n */\n decisionPath: string;\n /**\n * Optional mapper when the OPA client returns a non-standard payload.\n */\n mapResult?: (value: unknown) => Result;\n}\n\nexport class OPAPolicyAdapter<Result = OPAEvaluationResult | null> {\n constructor(\n private readonly client: OPAClient,\n private readonly options: OPAAdapterOptions<Result>\n ) {}\n\n async evaluate(\n context: DecisionContext,\n policies: PolicySpec[],\n engineDecision: PolicyDecision\n ): Promise<PolicyDecision> {\n const input = buildOPAInput(context, policies, engineDecision);\n const raw = await this.client.evaluate<unknown>(\n this.options.decisionPath,\n input\n );\n const resolved = this.options.mapResult\n ? this.options.mapResult(raw)\n : (raw as OPAEvaluationResult | null);\n\n if (!resolved) {\n return {\n ...engineDecision,\n evaluatedBy: engineDecision.evaluatedBy ?? 'engine',\n };\n }\n\n const opaResult = resolved as OPAEvaluationResult;\n const mergedRequiredConsents = mergeRequiredConsents(\n policies,\n engineDecision.requiredConsents ?? [],\n opaResult.requiredConsents ?? []\n );\n\n return {\n ...engineDecision,\n effect: opaResult.effect ?? engineDecision.effect,\n reason: opaResult.reason ?? engineDecision.reason,\n fieldDecisions:\n opaResult.fieldDecisions ?? engineDecision.fieldDecisions,\n requiredConsents: mergedRequiredConsents.length\n ? mergedRequiredConsents\n : undefined,\n evaluatedBy: 'opa',\n };\n }\n}\n\nexport function buildOPAInput(\n context: DecisionContext,\n policies: PolicySpec[],\n engineDecision: PolicyDecision\n) {\n return {\n context,\n decision: engineDecision,\n policies: policies.map((policy) => ({\n meta: policy.meta,\n rules: policy.rules,\n fieldPolicies: policy.fieldPolicies,\n pii: policy.pii,\n relationships: policy.relationships,\n consents: policy.consents,\n rateLimits: policy.rateLimits,\n })),\n };\n}\n\nfunction mergeRequiredConsents(\n policies: PolicySpec[],\n existing: ConsentDefinition[],\n incomingIds: string[]\n): ConsentDefinition[] {\n if (incomingIds.length === 0) return existing;\n const existingIds = new Set(existing.map((consent) => consent.id));\n const merged = [...existing];\n\n for (const id of incomingIds) {\n if (existingIds.has(id)) continue;\n const resolved = resolveConsentAcrossPolicies(policies, id);\n if (resolved) {\n merged.push(resolved);\n existingIds.add(resolved.id);\n }\n }\n\n return merged;\n}\n\nfunction resolveConsentAcrossPolicies(\n policies: PolicySpec[],\n id: string\n): ConsentDefinition | null {\n for (const policy of policies) {\n const match = policy.consents?.find((consent) => consent.id === id);\n if (match) return match;\n }\n\n return {\n id,\n scope: 'unspecified',\n purpose: 'unspecified',\n description: `Consent \"${id}\" returned by OPA`,\n required: true,\n };\n}\n\n"],"mappings":"AA0BA,IAAa,EAAb,KAAmE,CACjE,YACE,EACA,EACA,CAFiB,KAAA,OAAA,EACA,KAAA,QAAA,EAGnB,MAAM,SACJ,EACA,EACA,EACyB,CACzB,IAAM,EAAQ,EAAc,EAAS,EAAU,EAAe,CACxD,EAAM,MAAM,KAAK,OAAO,SAC5B,KAAK,QAAQ,aACb,EACD,CACK,EAAW,KAAK,QAAQ,UAC1B,KAAK,QAAQ,UAAU,EAAI,CAC1B,EAEL,GAAI,CAAC,EACH,MAAO,CACL,GAAG,EACH,YAAa,EAAe,aAAe,SAC5C,CAGH,IAAM,EAAY,EACZ,EAAyB,EAC7B,EACA,EAAe,kBAAoB,EAAE,CACrC,EAAU,kBAAoB,EAAE,CACjC,CAED,MAAO,CACL,GAAG,EACH,OAAQ,EAAU,QAAU,EAAe,OAC3C,OAAQ,EAAU,QAAU,EAAe,OAC3C,eACE,EAAU,gBAAkB,EAAe,eAC7C,iBAAkB,EAAuB,OACrC,EACA,IAAA,GACJ,YAAa,MACd,GAIL,SAAgB,EACd,EACA,EACA,EACA,CACA,MAAO,CACL,UACA,SAAU,EACV,SAAU,EAAS,IAAK,IAAY,CAClC,KAAM,EAAO,KACb,MAAO,EAAO,MACd,cAAe,EAAO,cACtB,IAAK,EAAO,IACZ,cAAe,EAAO,cACtB,SAAU,EAAO,SACjB,WAAY,EAAO,WACpB,EAAE,CACJ,CAGH,SAAS,EACP,EACA,EACA,EACqB,CACrB,GAAI,EAAY,SAAW,EAAG,OAAO,EACrC,IAAM,EAAc,IAAI,IAAI,EAAS,IAAK,GAAY,EAAQ,GAAG,CAAC,CAC5D,EAAS,CAAC,GAAG,EAAS,CAE5B,IAAK,IAAM,KAAM,EAAa,CAC5B,GAAI,EAAY,IAAI,EAAG,CAAE,SACzB,IAAM,EAAW,EAA6B,EAAU,EAAG,CACvD,IACF,EAAO,KAAK,EAAS,CACrB,EAAY,IAAI,EAAS,GAAG,EAIhC,OAAO,EAGT,SAAS,EACP,EACA,EAC0B,CAC1B,IAAK,IAAM,KAAU,EAAU,CAC7B,IAAM,EAAQ,EAAO,UAAU,KAAM,GAAY,EAAQ,KAAO,EAAG,CACnE,GAAI,EAAO,OAAO,EAGpB,MAAO,CACL,KACA,MAAO,cACP,QAAS,cACT,YAAa,YAAY,EAAG,mBAC5B,SAAU,GACX"}
1
+ {"version":3,"file":"opa-adapter.js","names":["client: OPAClient","options: OPAAdapterOptions<Result>"],"sources":["../../src/policy/opa-adapter.ts"],"sourcesContent":["import type { PolicyDecision } from '../types';\nimport type { PolicySpec, ConsentDefinition } from './spec';\nimport type { DecisionContext } from './engine';\n\nexport interface OPAClient {\n evaluate<T>(decisionPath: string, input: unknown): Promise<T>;\n}\n\nexport interface OPAEvaluationResult {\n effect?: 'allow' | 'deny';\n reason?: string;\n fieldDecisions?: PolicyDecision['fieldDecisions'];\n requiredConsents?: string[];\n}\n\nexport interface OPAAdapterOptions<Result = OPAEvaluationResult | null> {\n /**\n * Path fed to the OPA client (e.g., \"sigil/authz/allow\").\n */\n decisionPath: string;\n /**\n * Optional mapper when the OPA client returns a non-standard payload.\n */\n mapResult?: (value: unknown) => Result;\n}\n\nexport class OPAPolicyAdapter<Result = OPAEvaluationResult | null> {\n constructor(\n private readonly client: OPAClient,\n private readonly options: OPAAdapterOptions<Result>\n ) {}\n\n async evaluate(\n context: DecisionContext,\n policies: PolicySpec[],\n engineDecision: PolicyDecision\n ): Promise<PolicyDecision> {\n const input = buildOPAInput(context, policies, engineDecision);\n const raw = await this.client.evaluate<unknown>(\n this.options.decisionPath,\n input\n );\n const resolved = this.options.mapResult\n ? this.options.mapResult(raw)\n : (raw as OPAEvaluationResult | null);\n\n if (!resolved) {\n return {\n ...engineDecision,\n evaluatedBy: engineDecision.evaluatedBy ?? 'engine',\n };\n }\n\n const opaResult = resolved as OPAEvaluationResult;\n const mergedRequiredConsents = mergeRequiredConsents(\n policies,\n engineDecision.requiredConsents ?? [],\n opaResult.requiredConsents ?? []\n );\n\n return {\n ...engineDecision,\n effect: opaResult.effect ?? engineDecision.effect,\n reason: opaResult.reason ?? engineDecision.reason,\n fieldDecisions: opaResult.fieldDecisions ?? engineDecision.fieldDecisions,\n requiredConsents: mergedRequiredConsents.length\n ? mergedRequiredConsents\n : undefined,\n evaluatedBy: 'opa',\n };\n }\n}\n\nexport function buildOPAInput(\n context: DecisionContext,\n policies: PolicySpec[],\n engineDecision: PolicyDecision\n) {\n return {\n context,\n decision: engineDecision,\n policies: policies.map((policy) => ({\n meta: policy.meta,\n rules: policy.rules,\n fieldPolicies: policy.fieldPolicies,\n pii: policy.pii,\n relationships: policy.relationships,\n consents: policy.consents,\n rateLimits: policy.rateLimits,\n })),\n };\n}\n\nfunction mergeRequiredConsents(\n policies: PolicySpec[],\n existing: ConsentDefinition[],\n incomingIds: string[]\n): ConsentDefinition[] {\n if (incomingIds.length === 0) return existing;\n const existingIds = new Set(existing.map((consent) => consent.id));\n const merged = [...existing];\n\n for (const id of incomingIds) {\n if (existingIds.has(id)) continue;\n const resolved = resolveConsentAcrossPolicies(policies, id);\n if (resolved) {\n merged.push(resolved);\n existingIds.add(resolved.id);\n }\n }\n\n return merged;\n}\n\nfunction resolveConsentAcrossPolicies(\n policies: PolicySpec[],\n id: string\n): ConsentDefinition | null {\n for (const policy of policies) {\n const match = policy.consents?.find((consent) => consent.id === id);\n if (match) return match;\n }\n\n return {\n id,\n scope: 'unspecified',\n purpose: 'unspecified',\n description: `Consent \"${id}\" returned by OPA`,\n required: true,\n };\n}\n"],"mappings":"AA0BA,IAAa,EAAb,KAAmE,CACjE,YACE,EACA,EACA,CAFiB,KAAA,OAAA,EACA,KAAA,QAAA,EAGnB,MAAM,SACJ,EACA,EACA,EACyB,CACzB,IAAM,EAAQ,EAAc,EAAS,EAAU,EAAe,CACxD,EAAM,MAAM,KAAK,OAAO,SAC5B,KAAK,QAAQ,aACb,EACD,CACK,EAAW,KAAK,QAAQ,UAC1B,KAAK,QAAQ,UAAU,EAAI,CAC1B,EAEL,GAAI,CAAC,EACH,MAAO,CACL,GAAG,EACH,YAAa,EAAe,aAAe,SAC5C,CAGH,IAAM,EAAY,EACZ,EAAyB,EAC7B,EACA,EAAe,kBAAoB,EAAE,CACrC,EAAU,kBAAoB,EAAE,CACjC,CAED,MAAO,CACL,GAAG,EACH,OAAQ,EAAU,QAAU,EAAe,OAC3C,OAAQ,EAAU,QAAU,EAAe,OAC3C,eAAgB,EAAU,gBAAkB,EAAe,eAC3D,iBAAkB,EAAuB,OACrC,EACA,IAAA,GACJ,YAAa,MACd,GAIL,SAAgB,EACd,EACA,EACA,EACA,CACA,MAAO,CACL,UACA,SAAU,EACV,SAAU,EAAS,IAAK,IAAY,CAClC,KAAM,EAAO,KACb,MAAO,EAAO,MACd,cAAe,EAAO,cACtB,IAAK,EAAO,IACZ,cAAe,EAAO,cACtB,SAAU,EAAO,SACjB,WAAY,EAAO,WACpB,EAAE,CACJ,CAGH,SAAS,EACP,EACA,EACA,EACqB,CACrB,GAAI,EAAY,SAAW,EAAG,OAAO,EACrC,IAAM,EAAc,IAAI,IAAI,EAAS,IAAK,GAAY,EAAQ,GAAG,CAAC,CAC5D,EAAS,CAAC,GAAG,EAAS,CAE5B,IAAK,IAAM,KAAM,EAAa,CAC5B,GAAI,EAAY,IAAI,EAAG,CAAE,SACzB,IAAM,EAAW,EAA6B,EAAU,EAAG,CACvD,IACF,EAAO,KAAK,EAAS,CACrB,EAAY,IAAI,EAAS,GAAG,EAIhC,OAAO,EAGT,SAAS,EACP,EACA,EAC0B,CAC1B,IAAK,IAAM,KAAU,EAAU,CAC7B,IAAM,EAAQ,EAAO,UAAU,KAAM,GAAY,EAAQ,KAAO,EAAG,CACnE,GAAI,EAAO,OAAO,EAGpB,MAAO,CACL,KACA,MAAO,cACP,QAAS,cACT,YAAa,YAAY,EAAG,mBAC5B,SAAU,GACX"}
@@ -1 +1 @@
1
- {"version":3,"file":"spec.d.ts","names":[],"sources":["../../src/policy/spec.ts"],"sourcesContent":[],"mappings":";;;KAEY,YAAA;UAEK,sBAAA;EAFL,WAAA,EAAA,MAAY;EAEP,QAAA,EAAA,MAAA;EAQA,UAAA,EAAA,MAAA;EAMA,WAAA,CAAA,EAAA,MAAiB;EAUjB,UAAA,CAAA,EAAA,OAAA;AAQjB;AAOiB,UA/BA,mBAAA,CA+BmB;EASnB,QAAA,EAAA,MAAA;EAMA,UAAA,CAAA,EAAA,MAAc;EAKd,QAAA,CAAA,EAAA,MAAA;AAMjB;AAKiB,UAxDA,iBAAA,CAwDU;EACjB,EAAA,EAAA,MAAA;EAEE,KAAA,EAAA,MAAA;EACC,OAAA,EAAA,MAAA;EACK,WAAA,CAAA,EAAA,MAAA;EAGK,WAAA,CAAA,EAAA,SAAA,GAAA,UAAA,GAAA,kBAAA,GAAA,qBAAA;EAER,aAAA,CAAA,EAAA,MAAA;EAAe,QAAA,CAAA,EAAA,OAAA;AAI9B;AACU,UA7DO,mBAAA,CA6DP;EAGE,EAAA,EAAA,MAAA;EACC,GAAA,EAAA,MAAA;EACE,GAAA,CAAA,EAAA,MAAA;EAAe,aAAA,CAAA,EAAA,MAAA;EAIb,KAAA,CAAA,EAAA,MAAS;AAM1B;AACQ,UArES,eAAA,CAqET;EACC;EACS,OAAA,EAAA,MAAA;EACV;EACU,QAAA,CAAA,EAAA,MAAA;;AAEH,UApEE,UAAA,SAAmB,aAoErB,CAAA;EACP;EAAe,IAAA,EAAA,MAAA;EAGN;EAOJ,OAAA,EAAA,MAAA;EAGI;EAQP,KAAA,CAAA,EAAA,QAAA,GAAA,SAAA,GAAA,WAAA;;AAIuC,UArFhC,gBAAA,CAqFgC;EAejC,MAAA,CAAA,EAAA,OAAa;;;;UA9FZ,cAAA;;eAEF,eAAe;;UAGb,eAAA;;;eAGF,eAAe;;UAGb,eAAA;;;;UAKA,UAAA;UACP;;YAEE;aACC;kBACK;;;uBAGK;;eAER;;;UAIE,eAAA;UACP;;;YAGE;aACC;eACE;;;UAIE,SAAA;;;;;UAMA,UAAA;QACT;SACC;kBACS;QACV;kBACU;aACL;eACE;QACP;;UAGS,SAAA;;;;cAOJ,cAAA;;iBAGI;UAQP;uCAI6B;;iBAevB,aAAA,MAAmB"}
1
+ {"version":3,"file":"spec.d.ts","names":[],"sources":["../../src/policy/spec.ts"],"sourcesContent":[],"mappings":";;;KAEY,YAAA;UAEK,sBAAA;EAFL,WAAA,EAAA,MAAY;EAEP,QAAA,EAAA,MAAA;EAQA,UAAA,EAAA,MAAA;EAMA,WAAA,CAAA,EAAA,MAAiB;EAcjB,UAAA,CAAA,EAAA,OAAA;AAQjB;AAOiB,UAnCA,mBAAA,CAmCmB;EASnB,QAAA,EAAA,MAAA;EAMA,UAAA,CAAA,EAAA,MAAc;EAKd,QAAA,CAAA,EAAA,MAAA;AAMjB;AAKiB,UA5DA,iBAAA,CA4DU;EACjB,EAAA,EAAA,MAAA;EAEE,KAAA,EAAA,MAAA;EACC,OAAA,EAAA,MAAA;EACK,WAAA,CAAA,EAAA,MAAA;EAGK,WAAA,CAAA,EAAA,SAAA,GAAA,UAAA,GAAA,kBAAA,GAAA,qBAAA;EAER,aAAA,CAAA,EAAA,MAAA;EAAe,QAAA,CAAA,EAAA,OAAA;AAI9B;AACU,UA7DO,mBAAA,CA6DP;EAGE,EAAA,EAAA,MAAA;EACC,GAAA,EAAA,MAAA;EACE,GAAA,CAAA,EAAA,MAAA;EAAe,aAAA,CAAA,EAAA,MAAA;EAIb,KAAA,CAAA,EAAA,MAAS;AAM1B;AACQ,UArES,eAAA,CAqET;EACC;EACS,OAAA,EAAA,MAAA;EACV;EACU,QAAA,CAAA,EAAA,MAAA;;AAEH,UApEE,UAAA,SAAmB,aAoErB,CAAA;EACP;EAAe,IAAA,EAAA,MAAA;EAGN;EAOJ,OAAA,EAAA,MAAA;EAGI;EAOP,KAAA,CAAA,EAAA,QAAA,GAAA,SAAA,GAAA,WAAA;;AAIuC,UApFhC,gBAAA,CAoFgC;EAejC,MAAA,CAAA,EAAA,OAAa;;;;UA7FZ,cAAA;;eAEF,eAAe;;UAGb,eAAA;;;eAGF,eAAe;;UAGb,eAAA;;;;UAKA,UAAA;UACP;;YAEE;aACC;kBACK;;;uBAGK;;eAER;;;UAIE,eAAA;UACP;;;YAGE;aACC;eACE;;;UAIE,SAAA;;;;;UAMA,UAAA;QACT;SACC;kBACS;QACV;kBACU;aACL;eACE;QACP;;UAGS,SAAA;;;;cAOJ,cAAA;;iBAGI;UAOP;uCAI6B;;iBAevB,aAAA,MAAmB"}
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","names":["candidate: PolicySpec | undefined"],"sources":["../../src/policy/spec.ts"],"sourcesContent":["import type { OwnerShipMeta } from '../ownership';\n\nexport type PolicyEffect = 'allow' | 'deny';\n\nexport interface RelationshipDefinition {\n subjectType: string;\n relation: string;\n objectType: string;\n description?: string;\n transitive?: boolean;\n}\n\nexport interface RelationshipMatcher {\n relation: string;\n objectType?: string;\n objectId?: string;\n}\n\nexport interface ConsentDefinition {\n id: string;\n scope: string;\n purpose: string;\n description?: string;\n lawfulBasis?: 'consent' | 'contract' | 'legal_obligation' | 'legitimate_interest';\n expiresInDays?: number;\n required?: boolean;\n}\n\nexport interface RateLimitDefinition {\n id: string;\n rpm: number;\n key?: string;\n windowSeconds?: number;\n burst?: number;\n}\n\nexport interface PolicyOPAConfig {\n /** Fully-qualified package, e.g. \"sigil.authz\" */\n package: string;\n /** Optional rule within package (defaults to \"allow\") */\n decision?: string;\n}\n\nexport interface PolicyMeta extends OwnerShipMeta {\n /** Fully-qualified policy name (e.g., \"sigil.core.default\"). */\n name: string;\n /** Version of the policy; bump on breaking changes. */\n version: number;\n /** Optional scope hint used for discovery. */\n scope?: 'global' | 'feature' | 'operation';\n}\n\nexport interface AttributeMatcher {\n equals?: unknown;\n oneOf?: unknown[];\n exists?: boolean;\n}\n\nexport interface SubjectMatcher {\n roles?: string[];\n attributes?: Record<string, AttributeMatcher>;\n}\n\nexport interface ResourceMatcher {\n type: string;\n fields?: string[];\n attributes?: Record<string, AttributeMatcher>;\n}\n\nexport interface PolicyCondition {\n /** Simple expression evaluated against { subject, resource, context }. */\n expression: string;\n}\n\nexport interface PolicyRule {\n effect: PolicyEffect;\n actions: string[];\n subject?: SubjectMatcher;\n resource?: ResourceMatcher;\n relationships?: RelationshipMatcher[];\n requiresConsent?: string[];\n flags?: string[];\n rateLimit?: string | RateLimitDefinition;\n escalate?: 'human_review' | null;\n conditions?: PolicyCondition[];\n reason?: string;\n}\n\nexport interface FieldPolicyRule {\n effect: PolicyEffect;\n field: string;\n actions: ('read' | 'write')[];\n subject?: SubjectMatcher;\n resource?: ResourceMatcher;\n conditions?: PolicyCondition[];\n reason?: string;\n}\n\nexport interface PIIPolicy {\n fields: string[];\n consentRequired?: boolean;\n retentionDays?: number;\n}\n\nexport interface PolicySpec {\n meta: PolicyMeta;\n rules: PolicyRule[];\n fieldPolicies?: FieldPolicyRule[];\n pii?: PIIPolicy;\n relationships?: RelationshipDefinition[];\n consents?: ConsentDefinition[];\n rateLimits?: RateLimitDefinition[];\n opa?: PolicyOPAConfig;\n}\n\nexport interface PolicyRef {\n name: string;\n version: number;\n}\n\nconst policyKey = (name: string, version: number) => `${name}.v${version}`;\n\nexport class PolicyRegistry {\n private readonly items = new Map<string, PolicySpec>();\n\n register(spec: PolicySpec): this {\n const key = policyKey(spec.meta.name, spec.meta.version);\n if (this.items.has(key))\n throw new Error(`Duplicate policy ${key}`);\n this.items.set(key, spec);\n return this;\n }\n\n list(): PolicySpec[] {\n return [...this.items.values()];\n }\n\n get(name: string, version?: number): PolicySpec | undefined {\n if (version != null) return this.items.get(policyKey(name, version));\n let candidate: PolicySpec | undefined;\n let max = -Infinity;\n for (const spec of this.items.values()) {\n if (spec.meta.name !== name) continue;\n if (spec.meta.version > max) {\n max = spec.meta.version;\n candidate = spec;\n }\n }\n return candidate;\n }\n}\n\nexport function makePolicyKey(ref: PolicyRef) {\n return policyKey(ref.name, ref.version);\n}\n\n"],"mappings":"AAwHA,MAAM,GAAa,EAAc,IAAoB,GAAG,EAAK,IAAI,IAEjE,IAAa,EAAb,KAA4B,CAC1B,MAAyB,IAAI,IAE7B,SAAS,EAAwB,CAC/B,IAAM,EAAM,EAAU,EAAK,KAAK,KAAM,EAAK,KAAK,QAAQ,CACxD,GAAI,KAAK,MAAM,IAAI,EAAI,CACrB,MAAU,MAAM,oBAAoB,IAAM,CAE5C,OADA,KAAK,MAAM,IAAI,EAAK,EAAK,CAClB,KAGT,MAAqB,CACnB,MAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CAGjC,IAAI,EAAc,EAA0C,CAC1D,GAAI,GAAW,KAAM,OAAO,KAAK,MAAM,IAAI,EAAU,EAAM,EAAQ,CAAC,CACpE,IAAIA,EACA,EAAM,KACV,IAAK,IAAM,KAAQ,KAAK,MAAM,QAAQ,CAChC,EAAK,KAAK,OAAS,GACnB,EAAK,KAAK,QAAU,IACtB,EAAM,EAAK,KAAK,QAChB,EAAY,GAGhB,OAAO,IAIX,SAAgB,EAAc,EAAgB,CAC5C,OAAO,EAAU,EAAI,KAAM,EAAI,QAAQ"}
1
+ {"version":3,"file":"spec.js","names":["candidate: PolicySpec | undefined"],"sources":["../../src/policy/spec.ts"],"sourcesContent":["import type { OwnerShipMeta } from '../ownership';\n\nexport type PolicyEffect = 'allow' | 'deny';\n\nexport interface RelationshipDefinition {\n subjectType: string;\n relation: string;\n objectType: string;\n description?: string;\n transitive?: boolean;\n}\n\nexport interface RelationshipMatcher {\n relation: string;\n objectType?: string;\n objectId?: string;\n}\n\nexport interface ConsentDefinition {\n id: string;\n scope: string;\n purpose: string;\n description?: string;\n lawfulBasis?:\n | 'consent'\n | 'contract'\n | 'legal_obligation'\n | 'legitimate_interest';\n expiresInDays?: number;\n required?: boolean;\n}\n\nexport interface RateLimitDefinition {\n id: string;\n rpm: number;\n key?: string;\n windowSeconds?: number;\n burst?: number;\n}\n\nexport interface PolicyOPAConfig {\n /** Fully-qualified package, e.g. \"sigil.authz\" */\n package: string;\n /** Optional rule within package (defaults to \"allow\") */\n decision?: string;\n}\n\nexport interface PolicyMeta extends OwnerShipMeta {\n /** Fully-qualified policy name (e.g., \"sigil.core.default\"). */\n name: string;\n /** Version of the policy; bump on breaking changes. */\n version: number;\n /** Optional scope hint used for discovery. */\n scope?: 'global' | 'feature' | 'operation';\n}\n\nexport interface AttributeMatcher {\n equals?: unknown;\n oneOf?: unknown[];\n exists?: boolean;\n}\n\nexport interface SubjectMatcher {\n roles?: string[];\n attributes?: Record<string, AttributeMatcher>;\n}\n\nexport interface ResourceMatcher {\n type: string;\n fields?: string[];\n attributes?: Record<string, AttributeMatcher>;\n}\n\nexport interface PolicyCondition {\n /** Simple expression evaluated against { subject, resource, context }. */\n expression: string;\n}\n\nexport interface PolicyRule {\n effect: PolicyEffect;\n actions: string[];\n subject?: SubjectMatcher;\n resource?: ResourceMatcher;\n relationships?: RelationshipMatcher[];\n requiresConsent?: string[];\n flags?: string[];\n rateLimit?: string | RateLimitDefinition;\n escalate?: 'human_review' | null;\n conditions?: PolicyCondition[];\n reason?: string;\n}\n\nexport interface FieldPolicyRule {\n effect: PolicyEffect;\n field: string;\n actions: ('read' | 'write')[];\n subject?: SubjectMatcher;\n resource?: ResourceMatcher;\n conditions?: PolicyCondition[];\n reason?: string;\n}\n\nexport interface PIIPolicy {\n fields: string[];\n consentRequired?: boolean;\n retentionDays?: number;\n}\n\nexport interface PolicySpec {\n meta: PolicyMeta;\n rules: PolicyRule[];\n fieldPolicies?: FieldPolicyRule[];\n pii?: PIIPolicy;\n relationships?: RelationshipDefinition[];\n consents?: ConsentDefinition[];\n rateLimits?: RateLimitDefinition[];\n opa?: PolicyOPAConfig;\n}\n\nexport interface PolicyRef {\n name: string;\n version: number;\n}\n\nconst policyKey = (name: string, version: number) => `${name}.v${version}`;\n\nexport class PolicyRegistry {\n private readonly items = new Map<string, PolicySpec>();\n\n register(spec: PolicySpec): this {\n const key = policyKey(spec.meta.name, spec.meta.version);\n if (this.items.has(key)) throw new Error(`Duplicate policy ${key}`);\n this.items.set(key, spec);\n return this;\n }\n\n list(): PolicySpec[] {\n return [...this.items.values()];\n }\n\n get(name: string, version?: number): PolicySpec | undefined {\n if (version != null) return this.items.get(policyKey(name, version));\n let candidate: PolicySpec | undefined;\n let max = -Infinity;\n for (const spec of this.items.values()) {\n if (spec.meta.name !== name) continue;\n if (spec.meta.version > max) {\n max = spec.meta.version;\n candidate = spec;\n }\n }\n return candidate;\n }\n}\n\nexport function makePolicyKey(ref: PolicyRef) {\n return policyKey(ref.name, ref.version);\n}\n"],"mappings":"AA4HA,MAAM,GAAa,EAAc,IAAoB,GAAG,EAAK,IAAI,IAEjE,IAAa,EAAb,KAA4B,CAC1B,MAAyB,IAAI,IAE7B,SAAS,EAAwB,CAC/B,IAAM,EAAM,EAAU,EAAK,KAAK,KAAM,EAAK,KAAK,QAAQ,CACxD,GAAI,KAAK,MAAM,IAAI,EAAI,CAAE,MAAU,MAAM,oBAAoB,IAAM,CAEnE,OADA,KAAK,MAAM,IAAI,EAAK,EAAK,CAClB,KAGT,MAAqB,CACnB,MAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CAGjC,IAAI,EAAc,EAA0C,CAC1D,GAAI,GAAW,KAAM,OAAO,KAAK,MAAM,IAAI,EAAU,EAAM,EAAQ,CAAC,CACpE,IAAIA,EACA,EAAM,KACV,IAAK,IAAM,KAAQ,KAAK,MAAM,QAAQ,CAChC,EAAK,KAAK,OAAS,GACnB,EAAK,KAAK,QAAU,IACtB,EAAM,EAAK,KAAK,QAChB,EAAY,GAGhB,OAAO,IAIX,SAAgB,EAAc,EAAgB,CAC5C,OAAO,EAAU,EAAI,KAAM,EAAI,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","names":[],"sources":["../../src/regenerator/executor.ts"],"sourcesContent":[],"mappings":";;;KAEY,eAAA;UAEK,qBAAA;EAFL,KAAA,EAAA,MAAA;EAEK,MAAA,EAEP,cAFO;EAEP,MAAA,EACA,eADA;EACA,SAAA,EACG,IADH;EACG,UAAA,EACC,IADD;EACC,MAAA,CAAA,EAAA,MAAA;EAEJ,KAAA,CAAA,EAAA,KAAA;EAAK,MAAA,CAAA,EAAA,OAAA;AAIf;AAGa,UAHI,uBAAA,CAGJ;EACC,UAAA,EAAA,MAAA;EAEH,SAAA,EAAA,MAAA;EAAqB,SAAA,EAHnB,IAGmB;EAGpB,UAAA,EALE,IAKF;EACA,MAAA,EAAA,SAAA,GAAA,SAAwB,GAAA,QAAW;EACnC,OAAA,EALD,qBAK0B,EAAA;AACrC;AACY,KAJA,qBAAA,GAAwB,OAIC,CAJO,cAII,EAAA;EAE/B,IAAA,EAAA,kBAAgB;CAEpB,CAAA;AACC,KARF,wBAAA,GAA2B,OAQzB,CARiC,cAQjC,EAAA;EACF,IAAA,EAAA,sBAAA;CACP,CAAA;AAAO,KATA,cAAA,GAAiB,OASjB,CATyB,cASzB,EAAA;EAGK,IAAA,EAAA,WAAA;CAEJ,CAAA;AACC,KAdF,mBAAA,GAAsB,OAcpB,CAd4B,cAc5B,EAAA;EACF,IAAA,EAAA,gBAAA;CACP,CAAA;AAAO,KAfA,yBAAA,GAA4B,OAe5B,CAfoC,cAepC,EAAA;EAGK,IAAA,EAAA,sBAAY;CAEhB,CAAA;AACC,UAnBG,gBAAA,CAmBH;EACF,oBAAA,CAAA,OAAA,EAlBC,mBAkBD,EAAA,QAAA,EAjBE,kBAiBF,EAAA,MAAA,EAhBA,qBAgBA,CAAA,EAfP,OAeO,CAAA,OAAA,CAAA;;AACA,UAbK,mBAAA,CAaL;EAGK,uBAAiB,CAAA,OAAA,EAdrB,mBAcqB,EAAA,QAAA,EAbpB,kBAaoB,EAAA,MAAA,EAZtB,wBAYsB,CAAA,EAX7B,OAW6B,CAAA,OAAA,CAAA;;AAGpB,UAXG,YAAA,CAWH;EACF,QAAA,CAAA,OAAA,EAVC,mBAUD,EAAA,QAAA,EATE,kBASF,EAAA,MAAA,EARA,cAQA,CAAA,EAPP,OAOO,CAAA,OAAA,CAAA;;AACA,UALK,iBAAA,CAKL;EAGK,aAAA,CAAA,OAAA,EANJ,mBAMuB,EAAA,QAAA,EALtB,kBAKsB,EAAA,MAAA,EAJxB,mBAIwB,CAAA,EAH/B,OAG+B,CAAA,OAAA,CAAA;;AAGtB,UAHG,mBAAA,CAGH;EACF,mBAAA,CAAA,OAAA,EAFC,mBAED,EAAA,QAAA,EADE,kBACF,EAAA,MAAA,EAAA,yBAAA,CAAA,EACP,OADO,CAAA,OAAA,CAAA;;AACA,UAGK,uBAAA,CAHL;EAGK,MAAA,CAAA,EAAA,OAAA;AAIjB;AACqB,UADJ,oBAAA,CACI;EACG,gBAAA,CAAA,EADH,gBACG;EACP,mBAAA,CAAA,EADO,mBACP;EACK,YAAA,CAAA,EADL,YACK;EACE,iBAAA,CAAA,EADF,iBACE;EAAmB,mBAAA,CAAA,EAAnB,mBAAmB;AAG3C;AACqC,cADxB,gBAAA,CACwB;EAGxB,iBAAA,IAAA;EACC,WAAA,CAAA,IAAA,CAAA,EAJuB,oBAIvB;EACD,OAAA,CAAA,OAAA,EAFA,mBAEA,EAAA,QAAA,EADC,kBACD,EAAA,OAAA,CAAA,EAAA,uBAAA,CAAA,EACR,OADQ,CACA,uBADA,CAAA;EACA,QAAA,aAAA"}
1
+ {"version":3,"file":"executor.d.ts","names":[],"sources":["../../src/regenerator/executor.ts"],"sourcesContent":[],"mappings":";;;KAMY,eAAA;UAEK,qBAAA;EAFL,KAAA,EAAA,MAAA;EAEK,MAAA,EAEP,cAFO;EAEP,MAAA,EACA,eADA;EACA,SAAA,EACG,IADH;EACG,UAAA,EACC,IADD;EACC,MAAA,CAAA,EAAA,MAAA;EAEJ,KAAA,CAAA,EAAA,KAAA;EAAK,MAAA,CAAA,EAAA,OAAA;AAIf;AAGa,UAHI,uBAAA,CAGJ;EACC,UAAA,EAAA,MAAA;EAEH,SAAA,EAAA,MAAA;EAAqB,SAAA,EAHnB,IAGmB;EAGpB,UAAA,EALE,IAKF;EAIA,MAAA,EAAA,SAAA,GAAA,SAAwB,GAAA,QAClC;EAGU,OAAA,EAXD,qBAW0B,EAAA;AACrC;AAIY,KAbA,qBAAA,GAAwB,OAaC,CAZnC,cAaA,EAAA;EAIe,IAAA,EAAA,kBAAgB;CAEpB,CAAA;AACC,KAjBF,wBAAA,GAA2B,OAiBzB,CAhBZ,cAgBY,EAAA;EACF,IAAA,EAAA,sBAAA;CACP,CAAA;AAAO,KAfA,cAAA,GAAiB,OAejB,CAfyB,cAezB,EAAA;EAGK,IAAA,EAAA,WAAA;CAEJ,CAAA;AACC,KApBF,mBAAA,GAAsB,OAoBpB,CAnBZ,cAmBY,EAAA;EACF,IAAA,EAAA,gBAAA;CACP,CAAA;AAAO,KAlBA,yBAAA,GAA4B,OAkB5B,CAjBV,cAiBU,EAAA;EAGK,IAAA,EAAA,sBAAY;CAEhB,CAAA;AACC,UAnBG,gBAAA,CAmBH;EACF,oBAAA,CAAA,OAAA,EAlBC,mBAkBD,EAAA,QAAA,EAjBE,kBAiBF,EAAA,MAAA,EAhBA,qBAgBA,CAAA,EAfP,OAeO,CAAA,OAAA,CAAA;;AACA,UAbK,mBAAA,CAaL;EAGK,uBAAiB,CAAA,OAAA,EAdrB,mBAcqB,EAAA,QAAA,EAbpB,kBAaoB,EAAA,MAAA,EAZtB,wBAYsB,CAAA,EAX7B,OAW6B,CAAA,OAAA,CAAA;;AAGpB,UAXG,YAAA,CAWH;EACF,QAAA,CAAA,OAAA,EAVC,mBAUD,EAAA,QAAA,EATE,kBASF,EAAA,MAAA,EARA,cAQA,CAAA,EAPP,OAOO,CAAA,OAAA,CAAA;;AACA,UALK,iBAAA,CAKL;EAGK,aAAA,CAAA,OAAA,EANJ,mBAMuB,EAAA,QAAA,EALtB,kBAKsB,EAAA,MAAA,EAJxB,mBAIwB,CAAA,EAH/B,OAG+B,CAAA,OAAA,CAAA;;AAGtB,UAHG,mBAAA,CAGH;EACF,mBAAA,CAAA,OAAA,EAFC,mBAED,EAAA,QAAA,EADE,kBACF,EAAA,MAAA,EAAA,yBAAA,CAAA,EACP,OADO,CAAA,OAAA,CAAA;;AACA,UAGK,uBAAA,CAHL;EAGK,MAAA,CAAA,EAAA,OAAA;AAIjB;AACqB,UADJ,oBAAA,CACI;EACG,gBAAA,CAAA,EADH,gBACG;EACP,mBAAA,CAAA,EADO,mBACP;EACK,YAAA,CAAA,EADL,YACK;EACE,iBAAA,CAAA,EADF,iBACE;EAAmB,mBAAA,CAAA,EAAnB,mBAAmB;AAG3C;AACqC,cADxB,gBAAA,CACwB;EAGxB,iBAAA,IAAA;EACC,WAAA,CAAA,IAAA,CAAA,EAJuB,oBAIvB;EACD,OAAA,CAAA,OAAA,EAFA,mBAEA,EAAA,QAAA,EADC,kBACD,EAAA,OAAA,CAAA,EAAA,uBAAA,CAAA,EACR,OADQ,CACA,uBADA,CAAA;EACA,QAAA,aAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","names":["deps: ProposalExecutorDeps","actionResults: ActionExecutionResult[]"],"sources":["../../src/regenerator/executor.ts"],"sourcesContent":["import type { SpecChangeProposal, ProposalAction, RegenerationContext } from './types';\n\nexport type ExecutionStatus = 'success' | 'skipped' | 'failed';\n\nexport interface ActionExecutionResult {\n index: number;\n action: ProposalAction;\n status: ExecutionStatus;\n startedAt: Date;\n finishedAt: Date;\n reason?: string;\n error?: Error;\n output?: unknown;\n}\n\nexport interface ProposalExecutionResult {\n proposalId: string;\n contextId: string;\n startedAt: Date;\n finishedAt: Date;\n status: 'success' | 'partial' | 'failed';\n actions: ActionExecutionResult[];\n}\n\nexport type UpdateBlueprintAction = Extract<ProposalAction, { kind: 'update_blueprint' }>;\nexport type UpdateTenantConfigAction = Extract<ProposalAction, { kind: 'update_tenant_config' }>;\nexport type RunTestsAction = Extract<ProposalAction, { kind: 'run_tests' }>;\nexport type RunMigrationsAction = Extract<ProposalAction, { kind: 'run_migrations' }>;\nexport type TriggerRegenerationAction = Extract<ProposalAction, { kind: 'trigger_regeneration' }>;\n\nexport interface BlueprintUpdater {\n applyBlueprintUpdate(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: UpdateBlueprintAction\n ): Promise<unknown>;\n}\n\nexport interface TenantConfigUpdater {\n applyTenantConfigUpdate(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: UpdateTenantConfigAction\n ): Promise<unknown>;\n}\n\nexport interface TestExecutor {\n runTests(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: RunTestsAction\n ): Promise<unknown>;\n}\n\nexport interface MigrationExecutor {\n runMigrations(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: RunMigrationsAction\n ): Promise<unknown>;\n}\n\nexport interface RegenerationTrigger {\n triggerRegeneration(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: TriggerRegenerationAction\n ): Promise<unknown>;\n}\n\nexport interface ProposalExecutorOptions {\n dryRun?: boolean;\n}\n\nexport interface ProposalExecutorDeps {\n blueprintUpdater?: BlueprintUpdater;\n tenantConfigUpdater?: TenantConfigUpdater;\n testExecutor?: TestExecutor;\n migrationExecutor?: MigrationExecutor;\n regenerationTrigger?: RegenerationTrigger;\n}\n\nexport class ProposalExecutor {\n constructor(private readonly deps: ProposalExecutorDeps = {}) {}\n\n async execute(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n options: ProposalExecutorOptions = {}\n ): Promise<ProposalExecutionResult> {\n const startedAt = new Date();\n const actionResults: ActionExecutionResult[] = [];\n\n for (const [index, action] of proposal.actions.entries()) {\n // eslint-disable-next-line no-await-in-loop\n const result = await this.executeAction({\n index,\n action,\n context,\n proposal,\n options,\n });\n actionResults.push(result);\n }\n\n const finishedAt = new Date();\n const summaryStatus = summarizeStatus(actionResults);\n\n return {\n proposalId: proposal.id,\n contextId: context.id,\n startedAt,\n finishedAt,\n status: summaryStatus,\n actions: actionResults,\n };\n }\n\n private async executeAction({\n index,\n action,\n context,\n proposal,\n options,\n }: {\n index: number;\n action: ProposalAction;\n context: RegenerationContext;\n proposal: SpecChangeProposal;\n options: ProposalExecutorOptions;\n }): Promise<ActionExecutionResult> {\n const startedAt = new Date();\n const dryRun = options.dryRun ?? false;\n\n const complete = (\n status: ExecutionStatus,\n params: {\n reason?: string;\n output?: unknown;\n error?: Error;\n } = {}\n ): ActionExecutionResult => ({\n index,\n action,\n status,\n startedAt,\n finishedAt: new Date(),\n reason: params.reason,\n output: params.output,\n error: params.error,\n });\n\n if (dryRun) {\n return complete('skipped', { reason: 'dry_run' });\n }\n\n try {\n switch (action.kind) {\n case 'update_blueprint': {\n const updater = this.deps.blueprintUpdater;\n if (!updater) {\n return complete('skipped', { reason: 'missing_blueprint_updater' });\n }\n const output = await updater.applyBlueprintUpdate(context, proposal, action);\n return complete('success', { output });\n }\n case 'update_tenant_config': {\n const updater = this.deps.tenantConfigUpdater;\n if (!updater) {\n return complete('skipped', { reason: 'missing_tenant_config_updater' });\n }\n const output = await updater.applyTenantConfigUpdate(context, proposal, action);\n return complete('success', { output });\n }\n case 'run_tests': {\n const executor = this.deps.testExecutor;\n if (!executor) {\n return complete('skipped', { reason: 'missing_test_executor' });\n }\n const output = await executor.runTests(context, proposal, action);\n return complete('success', { output });\n }\n case 'run_migrations': {\n const executor = this.deps.migrationExecutor;\n if (!executor) {\n return complete('skipped', { reason: 'missing_migration_executor' });\n }\n const output = await executor.runMigrations(context, proposal, action);\n return complete('success', { output });\n }\n case 'trigger_regeneration': {\n const trigger = this.deps.regenerationTrigger;\n if (!trigger) {\n return complete('skipped', { reason: 'missing_regeneration_trigger' });\n }\n const output = await trigger.triggerRegeneration(context, proposal, action);\n return complete('success', { output });\n }\n default: {\n return complete('skipped', { reason: 'unknown_action' });\n }\n }\n } catch (error) {\n return complete('failed', {\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n}\n\nfunction summarizeStatus(actionResults: ActionExecutionResult[]): ProposalExecutionResult['status'] {\n if (actionResults.some((result) => result.status === 'failed')) {\n return 'failed';\n }\n if (actionResults.some((result) => result.status === 'success') &&\n actionResults.some((result) => result.status === 'skipped')) {\n return 'partial';\n }\n if (actionResults.every((result) => result.status === 'skipped')) {\n return 'partial';\n }\n return 'success';\n}\n\n\n\n\n\n\n"],"mappings":"AAkFA,IAAa,EAAb,KAA8B,CAC5B,YAAY,EAA8C,EAAE,CAAE,CAAjC,KAAA,KAAA,EAE7B,MAAM,QACJ,EACA,EACA,EAAmC,EAAE,CACH,CAClC,IAAM,EAAY,IAAI,KAChBC,EAAyC,EAAE,CAEjD,IAAK,GAAM,CAAC,EAAO,KAAW,EAAS,QAAQ,SAAS,CAAE,CAExD,IAAM,EAAS,MAAM,KAAK,cAAc,CACtC,QACA,SACA,UACA,WACA,UACD,CAAC,CACF,EAAc,KAAK,EAAO,CAG5B,IAAM,EAAa,IAAI,KACjB,EAAgB,EAAgB,EAAc,CAEpD,MAAO,CACL,WAAY,EAAS,GACrB,UAAW,EAAQ,GACnB,YACA,aACA,OAAQ,EACR,QAAS,EACV,CAGH,MAAc,cAAc,CAC1B,QACA,SACA,UACA,WACA,WAOiC,CACjC,IAAM,EAAY,IAAI,KAChB,EAAS,EAAQ,QAAU,GAE3B,GACJ,EACA,EAII,EAAE,IACqB,CAC3B,QACA,SACA,SACA,YACA,WAAY,IAAI,KAChB,OAAQ,EAAO,OACf,OAAQ,EAAO,OACf,MAAO,EAAO,MACf,EAED,GAAI,EACF,OAAO,EAAS,UAAW,CAAE,OAAQ,UAAW,CAAC,CAGnD,GAAI,CACF,OAAQ,EAAO,KAAf,CACE,IAAK,mBAAoB,CACvB,IAAM,EAAU,KAAK,KAAK,iBAK1B,OAJK,EAIE,EAAS,UAAW,CAAE,OADd,MAAM,EAAQ,qBAAqB,EAAS,EAAU,EAAO,CACvC,CAAC,CAH7B,EAAS,UAAW,CAAE,OAAQ,4BAA6B,CAAC,CAKvE,IAAK,uBAAwB,CAC3B,IAAM,EAAU,KAAK,KAAK,oBAK1B,OAJK,EAIE,EAAS,UAAW,CAAE,OADd,MAAM,EAAQ,wBAAwB,EAAS,EAAU,EAAO,CAC1C,CAAC,CAH7B,EAAS,UAAW,CAAE,OAAQ,gCAAiC,CAAC,CAK3E,IAAK,YAAa,CAChB,IAAM,EAAW,KAAK,KAAK,aAK3B,OAJK,EAIE,EAAS,UAAW,CAAE,OADd,MAAM,EAAS,SAAS,EAAS,EAAU,EAAO,CAC5B,CAAC,CAH7B,EAAS,UAAW,CAAE,OAAQ,wBAAyB,CAAC,CAKnE,IAAK,iBAAkB,CACrB,IAAM,EAAW,KAAK,KAAK,kBAK3B,OAJK,EAIE,EAAS,UAAW,CAAE,OADd,MAAM,EAAS,cAAc,EAAS,EAAU,EAAO,CACjC,CAAC,CAH7B,EAAS,UAAW,CAAE,OAAQ,6BAA8B,CAAC,CAKxE,IAAK,uBAAwB,CAC3B,IAAM,EAAU,KAAK,KAAK,oBAK1B,OAJK,EAIE,EAAS,UAAW,CAAE,OADd,MAAM,EAAQ,oBAAoB,EAAS,EAAU,EAAO,CACtC,CAAC,CAH7B,EAAS,UAAW,CAAE,OAAQ,+BAAgC,CAAC,CAK1E,QACE,OAAO,EAAS,UAAW,CAAE,OAAQ,iBAAkB,CAAC,QAGrD,EAAO,CACd,OAAO,EAAS,SAAU,CACxB,MAAO,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC,CACjE,CAAC,IAKR,SAAS,EAAgB,EAA2E,CAWlG,OAVI,EAAc,KAAM,GAAW,EAAO,SAAW,SAAS,CACrD,SAEL,EAAc,KAAM,GAAW,EAAO,SAAW,UAAU,EAC3D,EAAc,KAAM,GAAW,EAAO,SAAW,UAAU,EAG3D,EAAc,MAAO,GAAW,EAAO,SAAW,UAAU,CACvD,UAEF"}
1
+ {"version":3,"file":"executor.js","names":["deps: ProposalExecutorDeps","actionResults: ActionExecutionResult[]"],"sources":["../../src/regenerator/executor.ts"],"sourcesContent":["import type {\n SpecChangeProposal,\n ProposalAction,\n RegenerationContext,\n} from './types';\n\nexport type ExecutionStatus = 'success' | 'skipped' | 'failed';\n\nexport interface ActionExecutionResult {\n index: number;\n action: ProposalAction;\n status: ExecutionStatus;\n startedAt: Date;\n finishedAt: Date;\n reason?: string;\n error?: Error;\n output?: unknown;\n}\n\nexport interface ProposalExecutionResult {\n proposalId: string;\n contextId: string;\n startedAt: Date;\n finishedAt: Date;\n status: 'success' | 'partial' | 'failed';\n actions: ActionExecutionResult[];\n}\n\nexport type UpdateBlueprintAction = Extract<\n ProposalAction,\n { kind: 'update_blueprint' }\n>;\nexport type UpdateTenantConfigAction = Extract<\n ProposalAction,\n { kind: 'update_tenant_config' }\n>;\nexport type RunTestsAction = Extract<ProposalAction, { kind: 'run_tests' }>;\nexport type RunMigrationsAction = Extract<\n ProposalAction,\n { kind: 'run_migrations' }\n>;\nexport type TriggerRegenerationAction = Extract<\n ProposalAction,\n { kind: 'trigger_regeneration' }\n>;\n\nexport interface BlueprintUpdater {\n applyBlueprintUpdate(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: UpdateBlueprintAction\n ): Promise<unknown>;\n}\n\nexport interface TenantConfigUpdater {\n applyTenantConfigUpdate(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: UpdateTenantConfigAction\n ): Promise<unknown>;\n}\n\nexport interface TestExecutor {\n runTests(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: RunTestsAction\n ): Promise<unknown>;\n}\n\nexport interface MigrationExecutor {\n runMigrations(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: RunMigrationsAction\n ): Promise<unknown>;\n}\n\nexport interface RegenerationTrigger {\n triggerRegeneration(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n action: TriggerRegenerationAction\n ): Promise<unknown>;\n}\n\nexport interface ProposalExecutorOptions {\n dryRun?: boolean;\n}\n\nexport interface ProposalExecutorDeps {\n blueprintUpdater?: BlueprintUpdater;\n tenantConfigUpdater?: TenantConfigUpdater;\n testExecutor?: TestExecutor;\n migrationExecutor?: MigrationExecutor;\n regenerationTrigger?: RegenerationTrigger;\n}\n\nexport class ProposalExecutor {\n constructor(private readonly deps: ProposalExecutorDeps = {}) {}\n\n async execute(\n context: RegenerationContext,\n proposal: SpecChangeProposal,\n options: ProposalExecutorOptions = {}\n ): Promise<ProposalExecutionResult> {\n const startedAt = new Date();\n const actionResults: ActionExecutionResult[] = [];\n\n for (const [index, action] of proposal.actions.entries()) {\n const result = await this.executeAction({\n index,\n action,\n context,\n proposal,\n options,\n });\n actionResults.push(result);\n }\n\n const finishedAt = new Date();\n const summaryStatus = summarizeStatus(actionResults);\n\n return {\n proposalId: proposal.id,\n contextId: context.id,\n startedAt,\n finishedAt,\n status: summaryStatus,\n actions: actionResults,\n };\n }\n\n private async executeAction({\n index,\n action,\n context,\n proposal,\n options,\n }: {\n index: number;\n action: ProposalAction;\n context: RegenerationContext;\n proposal: SpecChangeProposal;\n options: ProposalExecutorOptions;\n }): Promise<ActionExecutionResult> {\n const startedAt = new Date();\n const dryRun = options.dryRun ?? false;\n\n const complete = (\n status: ExecutionStatus,\n params: {\n reason?: string;\n output?: unknown;\n error?: Error;\n } = {}\n ): ActionExecutionResult => ({\n index,\n action,\n status,\n startedAt,\n finishedAt: new Date(),\n reason: params.reason,\n output: params.output,\n error: params.error,\n });\n\n if (dryRun) {\n return complete('skipped', { reason: 'dry_run' });\n }\n\n try {\n switch (action.kind) {\n case 'update_blueprint': {\n const updater = this.deps.blueprintUpdater;\n if (!updater) {\n return complete('skipped', { reason: 'missing_blueprint_updater' });\n }\n const output = await updater.applyBlueprintUpdate(\n context,\n proposal,\n action\n );\n return complete('success', { output });\n }\n case 'update_tenant_config': {\n const updater = this.deps.tenantConfigUpdater;\n if (!updater) {\n return complete('skipped', {\n reason: 'missing_tenant_config_updater',\n });\n }\n const output = await updater.applyTenantConfigUpdate(\n context,\n proposal,\n action\n );\n return complete('success', { output });\n }\n case 'run_tests': {\n const executor = this.deps.testExecutor;\n if (!executor) {\n return complete('skipped', { reason: 'missing_test_executor' });\n }\n const output = await executor.runTests(context, proposal, action);\n return complete('success', { output });\n }\n case 'run_migrations': {\n const executor = this.deps.migrationExecutor;\n if (!executor) {\n return complete('skipped', {\n reason: 'missing_migration_executor',\n });\n }\n const output = await executor.runMigrations(\n context,\n proposal,\n action\n );\n return complete('success', { output });\n }\n case 'trigger_regeneration': {\n const trigger = this.deps.regenerationTrigger;\n if (!trigger) {\n return complete('skipped', {\n reason: 'missing_regeneration_trigger',\n });\n }\n const output = await trigger.triggerRegeneration(\n context,\n proposal,\n action\n );\n return complete('success', { output });\n }\n default: {\n return complete('skipped', { reason: 'unknown_action' });\n }\n }\n } catch (error) {\n return complete('failed', {\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n}\n\nfunction summarizeStatus(\n actionResults: ActionExecutionResult[]\n): ProposalExecutionResult['status'] {\n if (actionResults.some((result) => result.status === 'failed')) {\n return 'failed';\n }\n if (\n actionResults.some((result) => result.status === 'success') &&\n actionResults.some((result) => result.status === 'skipped')\n ) {\n return 'partial';\n }\n if (actionResults.every((result) => result.status === 'skipped')) {\n return 'partial';\n }\n return 'success';\n}\n"],"mappings":"AAkGA,IAAa,EAAb,KAA8B,CAC5B,YAAY,EAA8C,EAAE,CAAE,CAAjC,KAAA,KAAA,EAE7B,MAAM,QACJ,EACA,EACA,EAAmC,EAAE,CACH,CAClC,IAAM,EAAY,IAAI,KAChBC,EAAyC,EAAE,CAEjD,IAAK,GAAM,CAAC,EAAO,KAAW,EAAS,QAAQ,SAAS,CAAE,CACxD,IAAM,EAAS,MAAM,KAAK,cAAc,CACtC,QACA,SACA,UACA,WACA,UACD,CAAC,CACF,EAAc,KAAK,EAAO,CAG5B,IAAM,EAAa,IAAI,KACjB,EAAgB,EAAgB,EAAc,CAEpD,MAAO,CACL,WAAY,EAAS,GACrB,UAAW,EAAQ,GACnB,YACA,aACA,OAAQ,EACR,QAAS,EACV,CAGH,MAAc,cAAc,CAC1B,QACA,SACA,UACA,WACA,WAOiC,CACjC,IAAM,EAAY,IAAI,KAChB,EAAS,EAAQ,QAAU,GAE3B,GACJ,EACA,EAII,EAAE,IACqB,CAC3B,QACA,SACA,SACA,YACA,WAAY,IAAI,KAChB,OAAQ,EAAO,OACf,OAAQ,EAAO,OACf,MAAO,EAAO,MACf,EAED,GAAI,EACF,OAAO,EAAS,UAAW,CAAE,OAAQ,UAAW,CAAC,CAGnD,GAAI,CACF,OAAQ,EAAO,KAAf,CACE,IAAK,mBAAoB,CACvB,IAAM,EAAU,KAAK,KAAK,iBAS1B,OARK,EAQE,EAAS,UAAW,CAAE,OALd,MAAM,EAAQ,qBAC3B,EACA,EACA,EACD,CACoC,CAAC,CAP7B,EAAS,UAAW,CAAE,OAAQ,4BAA6B,CAAC,CASvE,IAAK,uBAAwB,CAC3B,IAAM,EAAU,KAAK,KAAK,oBAW1B,OAVK,EAUE,EAAS,UAAW,CAAE,OALd,MAAM,EAAQ,wBAC3B,EACA,EACA,EACD,CACoC,CAAC,CAT7B,EAAS,UAAW,CACzB,OAAQ,gCACT,CAAC,CASN,IAAK,YAAa,CAChB,IAAM,EAAW,KAAK,KAAK,aAK3B,OAJK,EAIE,EAAS,UAAW,CAAE,OADd,MAAM,EAAS,SAAS,EAAS,EAAU,EAAO,CAC5B,CAAC,CAH7B,EAAS,UAAW,CAAE,OAAQ,wBAAyB,CAAC,CAKnE,IAAK,iBAAkB,CACrB,IAAM,EAAW,KAAK,KAAK,kBAW3B,OAVK,EAUE,EAAS,UAAW,CAAE,OALd,MAAM,EAAS,cAC5B,EACA,EACA,EACD,CACoC,CAAC,CAT7B,EAAS,UAAW,CACzB,OAAQ,6BACT,CAAC,CASN,IAAK,uBAAwB,CAC3B,IAAM,EAAU,KAAK,KAAK,oBAW1B,OAVK,EAUE,EAAS,UAAW,CAAE,OALd,MAAM,EAAQ,oBAC3B,EACA,EACA,EACD,CACoC,CAAC,CAT7B,EAAS,UAAW,CACzB,OAAQ,+BACT,CAAC,CASN,QACE,OAAO,EAAS,UAAW,CAAE,OAAQ,iBAAkB,CAAC,QAGrD,EAAO,CACd,OAAO,EAAS,SAAU,CACxB,MAAO,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC,CACjE,CAAC,IAKR,SAAS,EACP,EACmC,CAanC,OAZI,EAAc,KAAM,GAAW,EAAO,SAAW,SAAS,CACrD,SAGP,EAAc,KAAM,GAAW,EAAO,SAAW,UAAU,EAC3D,EAAc,KAAM,GAAW,EAAO,SAAW,UAAU,EAIzD,EAAc,MAAO,GAAW,EAAO,SAAW,UAAU,CACvD,UAEF"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","names":[],"sources":["../../src/regenerator/service.ts"],"sourcesContent":[],"mappings":";;;;UAWiB,kBAAA;YACL;EADK,QAAA,EAEL,cAFuB;EACvB,KAAA,EAEH,gBAFG,EAAA;EACA,IAAA,EAEJ,YAFI;EACH,cAAA,CAAA,EAAA,MAAA;EACD,eAAA,CAAA,EAAA,MAAA;EAGQ,KAAA,CAAA,EAAA,GAAA,GAAA,IAAA;;AAMH,cAAA,kBAAA,CAS2B;;;;;;;;;uBAAA;;;aA8BrB"}
1
+ {"version":3,"file":"service.d.ts","names":[],"sources":["../../src/regenerator/service.ts"],"sourcesContent":[],"mappings":";;;;UAeiB,kBAAA;YACL;EADK,QAAA,EAEL,cAFuB;EACvB,KAAA,EAEH,gBAFG,EAAA;EACA,IAAA,EAEJ,YAFI;EACH,cAAA,CAAA,EAAA,MAAA;EACD,eAAA,CAAA,EAAA,MAAA;EAGQ,KAAA,CAAA,EAAA,GAAA,GAAA,IAAA;;AAMH,cAAA,kBAAA,CAS2B;;;;;;;;;uBAAA;;;aA4BrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","names":["options: RegeneratorOptions","proposals: SpecChangeProposal[]","envelopes: RegeneratorSignal[]","delay"],"sources":["../../src/regenerator/service.ts"],"sourcesContent":["import { setTimeout as delay } from 'node:timers/promises';\nimport type {\n ProposalSink,\n RegeneratorSignal,\n RegenerationRule,\n RegenerationContext,\n SpecChangeProposal,\n} from './types';\nimport type { SignalAdapters } from './adapters';\nimport { telemetryToEnvelope, errorToEnvelope, behaviorToEnvelope } from './utils';\n\nexport interface RegeneratorOptions {\n contexts: RegenerationContext[];\n adapters: SignalAdapters;\n rules: RegenerationRule[];\n sink: ProposalSink;\n pollIntervalMs?: number;\n batchDurationMs?: number;\n clock?: () => Date;\n}\n\nconst DEFAULT_POLL_INTERVAL = 60_000;\nconst DEFAULT_BATCH_DURATION = 5 * 60_000;\n\nexport class RegeneratorService {\n private readonly contexts: Map<string, RegenerationContext>;\n private readonly lastPoll = new Map<string, Date>();\n private timer?: NodeJS.Timeout;\n private running = false;\n private readonly pollInterval: number;\n private readonly batchDuration: number;\n private readonly clock: () => Date;\n\n constructor(private readonly options: RegeneratorOptions) {\n this.contexts = new Map(\n options.contexts.map((ctx) => [ctx.id, ctx])\n );\n this.pollInterval = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL;\n this.batchDuration = options.batchDurationMs ?? DEFAULT_BATCH_DURATION;\n this.clock = options.clock ?? (() => new Date());\n if (this.options.rules.length === 0) {\n throw new Error('RegeneratorService requires at least one rule');\n }\n }\n\n start() {\n if (this.running) return;\n this.running = true;\n void this.tick();\n this.timer = setInterval(() => {\n void this.tick();\n }, this.pollInterval);\n }\n\n stop() {\n if (!this.running) return;\n this.running = false;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n async runOnce(): Promise<void> {\n await this.tick();\n }\n\n private async tick(): Promise<void> {\n const now = this.clock();\n const sinceDefault = new Date(now.getTime() - this.batchDuration);\n for (const context of this.contexts.values()) {\n const last = this.lastPoll.get(context.id) ?? sinceDefault;\n await this.evaluateContext(context, last, now);\n this.lastPoll.set(context.id, now);\n }\n }\n\n private async evaluateContext(\n context: RegenerationContext,\n since: Date,\n until: Date\n ): Promise<void> {\n const signals = await this.collectSignals(context, since, until);\n if (signals.length === 0) return;\n\n for (const rule of this.options.rules) {\n let proposals: SpecChangeProposal[] = [];\n try {\n proposals = await rule.evaluate(context, signals);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n `[regenerator] rule ${rule.id} failed`,\n error instanceof Error ? error : new Error(String(error))\n );\n continue;\n }\n await this.flushProposals(context, proposals);\n }\n }\n\n private async collectSignals(\n context: RegenerationContext,\n since: Date,\n until: Date\n ): Promise<RegeneratorSignal[]> {\n const envelopes: RegeneratorSignal[] = [];\n const { adapters } = this.options;\n if (adapters.telemetry) {\n const telemetrySignals = await adapters.telemetry.pollTelemetry(\n context,\n since,\n until\n );\n envelopes.push(\n ...telemetrySignals.map((signal) =>\n telemetryToEnvelope(context.id, signal, this.clock)\n )\n );\n }\n if (adapters.errors) {\n const errorSignals = await adapters.errors.pollErrors(\n context,\n since,\n until\n );\n envelopes.push(\n ...errorSignals.map((signal) =>\n errorToEnvelope(context.id, signal, this.clock)\n )\n );\n }\n if (adapters.behavior) {\n const behaviorSignals = await adapters.behavior.pollBehavior(\n context,\n since,\n until\n );\n envelopes.push(\n ...behaviorSignals.map((signal) =>\n behaviorToEnvelope(context.id, signal, this.clock)\n )\n );\n }\n return envelopes;\n }\n\n private async flushProposals(\n context: RegenerationContext,\n proposals: SpecChangeProposal[]\n ): Promise<void> {\n for (const proposal of proposals) {\n if (proposal.signalIds.length === 0) continue;\n await this.options.sink.submit(context, proposal);\n // allow event loop to breathe when large volumes\n if (proposals.length > 10) {\n await delay(0);\n }\n }\n }\n}\n\n\n\n\n\n\n"],"mappings":"gJAwBA,IAAa,EAAb,KAAgC,CAC9B,SACA,SAA4B,IAAI,IAChC,MACA,QAAkB,GAClB,aACA,cACA,MAEA,YAAY,EAA8C,CAOxD,GAP2B,KAAA,QAAA,EAC3B,KAAK,SAAW,IAAI,IAClB,EAAQ,SAAS,IAAK,GAAQ,CAAC,EAAI,GAAI,EAAI,CAAC,CAC7C,CACD,KAAK,aAAe,EAAQ,gBAAkB,IAC9C,KAAK,cAAgB,EAAQ,iBAAmB,IAChD,KAAK,MAAQ,EAAQ,YAAgB,IAAI,MACrC,KAAK,QAAQ,MAAM,SAAW,EAChC,MAAU,MAAM,gDAAgD,CAIpE,OAAQ,CACF,KAAK,UACT,KAAK,QAAU,GACV,KAAK,MAAM,CAChB,KAAK,MAAQ,gBAAkB,CACxB,KAAK,MAAM,EACf,KAAK,aAAa,EAGvB,MAAO,CACA,KAAK,UACV,KAAK,QAAU,GACf,AAEE,KAAK,SADL,cAAc,KAAK,MAAM,CACZ,IAAA,KAIjB,MAAM,SAAyB,CAC7B,MAAM,KAAK,MAAM,CAGnB,MAAc,MAAsB,CAClC,IAAM,EAAM,KAAK,OAAO,CAClB,EAAe,IAAI,KAAK,EAAI,SAAS,CAAG,KAAK,cAAc,CACjE,IAAK,IAAM,KAAW,KAAK,SAAS,QAAQ,CAAE,CAC5C,IAAM,EAAO,KAAK,SAAS,IAAI,EAAQ,GAAG,EAAI,EAC9C,MAAM,KAAK,gBAAgB,EAAS,EAAM,EAAI,CAC9C,KAAK,SAAS,IAAI,EAAQ,GAAI,EAAI,EAItC,MAAc,gBACZ,EACA,EACA,EACe,CACf,IAAM,EAAU,MAAM,KAAK,eAAe,EAAS,EAAO,EAAM,CAC5D,KAAQ,SAAW,EAEvB,IAAK,IAAM,KAAQ,KAAK,QAAQ,MAAO,CACrC,IAAIC,EAAkC,EAAE,CACxC,GAAI,CACF,EAAY,MAAM,EAAK,SAAS,EAAS,EAAQ,OAC1C,EAAO,CAEd,QAAQ,MACN,sBAAsB,EAAK,GAAG,SAC9B,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC,CAC1D,CACD,SAEF,MAAM,KAAK,eAAe,EAAS,EAAU,EAIjD,MAAc,eACZ,EACA,EACA,EAC8B,CAC9B,IAAMC,EAAiC,EAAE,CACnC,CAAE,YAAa,KAAK,QAC1B,GAAI,EAAS,UAAW,CACtB,IAAM,EAAmB,MAAM,EAAS,UAAU,cAChD,EACA,EACA,EACD,CACD,EAAU,KACR,GAAG,EAAiB,IAAK,GACvB,EAAoB,EAAQ,GAAI,EAAQ,KAAK,MAAM,CACpD,CACF,CAEH,GAAI,EAAS,OAAQ,CACnB,IAAM,EAAe,MAAM,EAAS,OAAO,WACzC,EACA,EACA,EACD,CACD,EAAU,KACR,GAAG,EAAa,IAAK,GACnB,EAAgB,EAAQ,GAAI,EAAQ,KAAK,MAAM,CAChD,CACF,CAEH,GAAI,EAAS,SAAU,CACrB,IAAM,EAAkB,MAAM,EAAS,SAAS,aAC9C,EACA,EACA,EACD,CACD,EAAU,KACR,GAAG,EAAgB,IAAK,GACtB,EAAmB,EAAQ,GAAI,EAAQ,KAAK,MAAM,CACnD,CACF,CAEH,OAAO,EAGT,MAAc,eACZ,EACA,EACe,CACf,IAAK,IAAM,KAAY,EACjB,EAAS,UAAU,SAAW,IAClC,MAAM,KAAK,QAAQ,KAAK,OAAO,EAAS,EAAS,CAE7C,EAAU,OAAS,IACrB,MAAMC,EAAM,EAAE"}
1
+ {"version":3,"file":"service.js","names":["options: RegeneratorOptions","proposals: SpecChangeProposal[]","envelopes: RegeneratorSignal[]","delay"],"sources":["../../src/regenerator/service.ts"],"sourcesContent":["import { setTimeout as delay } from 'node:timers/promises';\nimport type {\n ProposalSink,\n RegeneratorSignal,\n RegenerationRule,\n RegenerationContext,\n SpecChangeProposal,\n} from './types';\nimport type { SignalAdapters } from './adapters';\nimport {\n telemetryToEnvelope,\n errorToEnvelope,\n behaviorToEnvelope,\n} from './utils';\n\nexport interface RegeneratorOptions {\n contexts: RegenerationContext[];\n adapters: SignalAdapters;\n rules: RegenerationRule[];\n sink: ProposalSink;\n pollIntervalMs?: number;\n batchDurationMs?: number;\n clock?: () => Date;\n}\n\nconst DEFAULT_POLL_INTERVAL = 60_000;\nconst DEFAULT_BATCH_DURATION = 5 * 60_000;\n\nexport class RegeneratorService {\n private readonly contexts: Map<string, RegenerationContext>;\n private readonly lastPoll = new Map<string, Date>();\n private timer?: NodeJS.Timeout;\n private running = false;\n private readonly pollInterval: number;\n private readonly batchDuration: number;\n private readonly clock: () => Date;\n\n constructor(private readonly options: RegeneratorOptions) {\n this.contexts = new Map(options.contexts.map((ctx) => [ctx.id, ctx]));\n this.pollInterval = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL;\n this.batchDuration = options.batchDurationMs ?? DEFAULT_BATCH_DURATION;\n this.clock = options.clock ?? (() => new Date());\n if (this.options.rules.length === 0) {\n throw new Error('RegeneratorService requires at least one rule');\n }\n }\n\n start() {\n if (this.running) return;\n this.running = true;\n void this.tick();\n this.timer = setInterval(() => {\n void this.tick();\n }, this.pollInterval);\n }\n\n stop() {\n if (!this.running) return;\n this.running = false;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n async runOnce(): Promise<void> {\n await this.tick();\n }\n\n private async tick(): Promise<void> {\n const now = this.clock();\n const sinceDefault = new Date(now.getTime() - this.batchDuration);\n for (const context of this.contexts.values()) {\n const last = this.lastPoll.get(context.id) ?? sinceDefault;\n await this.evaluateContext(context, last, now);\n this.lastPoll.set(context.id, now);\n }\n }\n\n private async evaluateContext(\n context: RegenerationContext,\n since: Date,\n until: Date\n ): Promise<void> {\n const signals = await this.collectSignals(context, since, until);\n if (signals.length === 0) return;\n\n for (const rule of this.options.rules) {\n let proposals: SpecChangeProposal[] = [];\n try {\n proposals = await rule.evaluate(context, signals);\n } catch (error) {\n console.error(\n `[regenerator] rule ${rule.id} failed`,\n error instanceof Error ? error : new Error(String(error))\n );\n continue;\n }\n await this.flushProposals(context, proposals);\n }\n }\n\n private async collectSignals(\n context: RegenerationContext,\n since: Date,\n until: Date\n ): Promise<RegeneratorSignal[]> {\n const envelopes: RegeneratorSignal[] = [];\n const { adapters } = this.options;\n if (adapters.telemetry) {\n const telemetrySignals = await adapters.telemetry.pollTelemetry(\n context,\n since,\n until\n );\n envelopes.push(\n ...telemetrySignals.map((signal) =>\n telemetryToEnvelope(context.id, signal, this.clock)\n )\n );\n }\n if (adapters.errors) {\n const errorSignals = await adapters.errors.pollErrors(\n context,\n since,\n until\n );\n envelopes.push(\n ...errorSignals.map((signal) =>\n errorToEnvelope(context.id, signal, this.clock)\n )\n );\n }\n if (adapters.behavior) {\n const behaviorSignals = await adapters.behavior.pollBehavior(\n context,\n since,\n until\n );\n envelopes.push(\n ...behaviorSignals.map((signal) =>\n behaviorToEnvelope(context.id, signal, this.clock)\n )\n );\n }\n return envelopes;\n }\n\n private async flushProposals(\n context: RegenerationContext,\n proposals: SpecChangeProposal[]\n ): Promise<void> {\n for (const proposal of proposals) {\n if (proposal.signalIds.length === 0) continue;\n await this.options.sink.submit(context, proposal);\n // allow event loop to breathe when large volumes\n if (proposals.length > 10) {\n await delay(0);\n }\n }\n }\n}\n"],"mappings":"gJA4BA,IAAa,EAAb,KAAgC,CAC9B,SACA,SAA4B,IAAI,IAChC,MACA,QAAkB,GAClB,aACA,cACA,MAEA,YAAY,EAA8C,CAKxD,GAL2B,KAAA,QAAA,EAC3B,KAAK,SAAW,IAAI,IAAI,EAAQ,SAAS,IAAK,GAAQ,CAAC,EAAI,GAAI,EAAI,CAAC,CAAC,CACrE,KAAK,aAAe,EAAQ,gBAAkB,IAC9C,KAAK,cAAgB,EAAQ,iBAAmB,IAChD,KAAK,MAAQ,EAAQ,YAAgB,IAAI,MACrC,KAAK,QAAQ,MAAM,SAAW,EAChC,MAAU,MAAM,gDAAgD,CAIpE,OAAQ,CACF,KAAK,UACT,KAAK,QAAU,GACV,KAAK,MAAM,CAChB,KAAK,MAAQ,gBAAkB,CACxB,KAAK,MAAM,EACf,KAAK,aAAa,EAGvB,MAAO,CACA,KAAK,UACV,KAAK,QAAU,GACf,AAEE,KAAK,SADL,cAAc,KAAK,MAAM,CACZ,IAAA,KAIjB,MAAM,SAAyB,CAC7B,MAAM,KAAK,MAAM,CAGnB,MAAc,MAAsB,CAClC,IAAM,EAAM,KAAK,OAAO,CAClB,EAAe,IAAI,KAAK,EAAI,SAAS,CAAG,KAAK,cAAc,CACjE,IAAK,IAAM,KAAW,KAAK,SAAS,QAAQ,CAAE,CAC5C,IAAM,EAAO,KAAK,SAAS,IAAI,EAAQ,GAAG,EAAI,EAC9C,MAAM,KAAK,gBAAgB,EAAS,EAAM,EAAI,CAC9C,KAAK,SAAS,IAAI,EAAQ,GAAI,EAAI,EAItC,MAAc,gBACZ,EACA,EACA,EACe,CACf,IAAM,EAAU,MAAM,KAAK,eAAe,EAAS,EAAO,EAAM,CAC5D,KAAQ,SAAW,EAEvB,IAAK,IAAM,KAAQ,KAAK,QAAQ,MAAO,CACrC,IAAIC,EAAkC,EAAE,CACxC,GAAI,CACF,EAAY,MAAM,EAAK,SAAS,EAAS,EAAQ,OAC1C,EAAO,CACd,QAAQ,MACN,sBAAsB,EAAK,GAAG,SAC9B,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC,CAC1D,CACD,SAEF,MAAM,KAAK,eAAe,EAAS,EAAU,EAIjD,MAAc,eACZ,EACA,EACA,EAC8B,CAC9B,IAAMC,EAAiC,EAAE,CACnC,CAAE,YAAa,KAAK,QAC1B,GAAI,EAAS,UAAW,CACtB,IAAM,EAAmB,MAAM,EAAS,UAAU,cAChD,EACA,EACA,EACD,CACD,EAAU,KACR,GAAG,EAAiB,IAAK,GACvB,EAAoB,EAAQ,GAAI,EAAQ,KAAK,MAAM,CACpD,CACF,CAEH,GAAI,EAAS,OAAQ,CACnB,IAAM,EAAe,MAAM,EAAS,OAAO,WACzC,EACA,EACA,EACD,CACD,EAAU,KACR,GAAG,EAAa,IAAK,GACnB,EAAgB,EAAQ,GAAI,EAAQ,KAAK,MAAM,CAChD,CACF,CAEH,GAAI,EAAS,SAAU,CACrB,IAAM,EAAkB,MAAM,EAAS,SAAS,aAC9C,EACA,EACA,EACD,CACD,EAAU,KACR,GAAG,EAAgB,IAAK,GACtB,EAAmB,EAAQ,GAAI,EAAQ,KAAK,MAAM,CACnD,CACF,CAEH,OAAO,EAGT,MAAc,eACZ,EACA,EACe,CACf,IAAK,IAAM,KAAY,EACjB,EAAS,UAAU,SAAW,IAClC,MAAM,KAAK,QAAQ,KAAK,OAAO,EAAS,EAAS,CAE7C,EAAU,OAAS,IACrB,MAAMC,EAAM,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"sinks.d.ts","names":[],"sources":["../../src/regenerator/sinks.ts"],"sourcesContent":[],"mappings":";;;;UAIiB,qBAAA;EAAA,OAAA,EACN,mBAD2B;EAC3B,QAAA,EACC,kBADD;EACC,MAAA,EACF,uBADE;;AACqB,UAGhB,kBAAA,CAHgB;EAGhB,IAAA,CAAA,EAAA,CAAA,OAAA,EAAA,MAAkB,EAAA,IAAA,CAAA,EACD,MADC,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GAAA,IAAA;EACD,KAAA,CAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,KAAA,EACC,KADD,EAAA,IAAA,CAAA,EACe,MADf,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GAAA,IAAA;;AACe,UAGhC,mBAAA,CAHgC;EAAM,MAAA,CAAA,EAAA,OAAA;EAGtC,QAAA,CAAA,EAAA,CAAA,OAAA,EAEM,qBAFa,EAAA,GAAA,IAAA,GAEoB,OAFpB,CAAA,IAAA,CAAA;EAEb,MAAA,CAAA,EACZ,kBADY;;AACZ,cAGE,oBAAA,YAAgC,YAHlC,CAAA;EAAkB,iBAAA,QAAA;EAGhB,iBAAA,OAAqB;EAEH,WAAA,CAAA,QAAA,EAAA,gBAAA,EAAA,OAAA,CAAA,EACD,mBADC;EACD,MAAA,CAAA,OAAA,EAIjB,mBAJiB,EAAA,QAAA,EAKhB,kBALgB,CAAA,EAMzB,OANyB,CAAA,IAAA,CAAA"}
1
+ {"version":3,"file":"sinks.d.ts","names":[],"sources":["../../src/regenerator/sinks.ts"],"sourcesContent":[],"mappings":";;;;UAQiB,qBAAA;EAAA,OAAA,EACN,mBAD2B;EAC3B,QAAA,EACC,kBADD;EACC,MAAA,EACF,uBADE;;AACqB,UAGhB,kBAAA,CAHgB;EAGhB,IAAA,CAAA,EAAA,CAAA,OAAA,EAAA,MAAkB,EAAA,IAAA,CAAA,EACD,MADC,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GAAA,IAAA;EACD,KAAA,CAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,KAAA,EAGvB,KAHuB,EAAA,IAAA,CAAA,EAIvB,MAJuB,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GAAA,IAAA;;AAIvB,UAIM,mBAAA,CAJN;EAAM,MAAA,CAAA,EAAA,OAAA;EAIA,QAAA,CAAA,EAAA,CAAA,OAAA,EAEM,qBAFa,EAAA,GAAA,IAAA,GAEoB,OAFpB,CAAA,IAAA,CAAA;EAEb,MAAA,CAAA,EACZ,kBADY;;AACZ,cAGE,oBAAA,YAAgC,YAHlC,CAAA;EAAkB,iBAAA,QAAA;EAGhB,iBAAA,OAAqB;EAEH,WAAA,CAAA,QAAA,EAAA,gBAAA,EAAA,OAAA,CAAA,EACD,mBADC;EACD,MAAA,CAAA,OAAA,EAIjB,mBAJiB,EAAA,QAAA,EAKhB,kBALgB,CAAA,EAMzB,OANyB,CAAA,IAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"sinks.js","names":["executor: ProposalExecutor","options: ExecutorSinkOptions"],"sources":["../../src/regenerator/sinks.ts"],"sourcesContent":["import type { ProposalSink, RegenerationContext, SpecChangeProposal } from './types';\nimport { ProposalExecutor } from './executor';\nimport type { ProposalExecutionResult } from './executor';\n\nexport interface ExecutorResultPayload {\n context: RegenerationContext;\n proposal: SpecChangeProposal;\n result: ProposalExecutionResult;\n}\n\nexport interface ExecutorSinkLogger {\n info?: (message: string, meta?: Record<string, unknown>) => void;\n error?: (message: string, error: Error, meta?: Record<string, unknown>) => void;\n}\n\nexport interface ExecutorSinkOptions {\n dryRun?: boolean;\n onResult?: (payload: ExecutorResultPayload) => void | Promise<void>;\n logger?: ExecutorSinkLogger;\n}\n\nexport class ExecutorProposalSink implements ProposalSink {\n constructor(\n private readonly executor: ProposalExecutor,\n private readonly options: ExecutorSinkOptions = {}\n ) {}\n\n async submit(\n context: RegenerationContext,\n proposal: SpecChangeProposal\n ): Promise<void> {\n const dryRun = this.options.dryRun ?? false;\n try {\n const result = await this.executor.execute(context, proposal, { dryRun });\n if (this.options.logger?.info) {\n this.options.logger.info('[regenerator] proposal executed', {\n proposalId: proposal.id,\n contextId: context.id,\n status: result.status,\n });\n }\n if (this.options.onResult) {\n await this.options.onResult({ context, proposal, result });\n }\n } catch (error) {\n if (this.options.logger?.error) {\n this.options.logger.error(\n '[regenerator] proposal execution failed',\n error instanceof Error ? error : new Error(String(error)),\n { proposalId: proposal.id, contextId: context.id }\n );\n }\n throw error instanceof Error ? error : new Error(String(error));\n }\n }\n}\n\n\n\n\n\n\n"],"mappings":"AAqBA,IAAa,EAAb,KAA0D,CACxD,YACE,EACA,EAAgD,EAAE,CAClD,CAFiB,KAAA,SAAA,EACA,KAAA,QAAA,EAGnB,MAAM,OACJ,EACA,EACe,CACf,IAAM,EAAS,KAAK,QAAQ,QAAU,GACtC,GAAI,CACF,IAAM,EAAS,MAAM,KAAK,SAAS,QAAQ,EAAS,EAAU,CAAE,SAAQ,CAAC,CACrE,KAAK,QAAQ,QAAQ,MACvB,KAAK,QAAQ,OAAO,KAAK,kCAAmC,CAC1D,WAAY,EAAS,GACrB,UAAW,EAAQ,GACnB,OAAQ,EAAO,OAChB,CAAC,CAEA,KAAK,QAAQ,UACf,MAAM,KAAK,QAAQ,SAAS,CAAE,UAAS,WAAU,SAAQ,CAAC,OAErD,EAAO,CAQd,MAPI,KAAK,QAAQ,QAAQ,OACvB,KAAK,QAAQ,OAAO,MAClB,0CACA,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC,CACzD,CAAE,WAAY,EAAS,GAAI,UAAW,EAAQ,GAAI,CACnD,CAEG,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC"}
1
+ {"version":3,"file":"sinks.js","names":["executor: ProposalExecutor","options: ExecutorSinkOptions"],"sources":["../../src/regenerator/sinks.ts"],"sourcesContent":["import type {\n ProposalSink,\n RegenerationContext,\n SpecChangeProposal,\n} from './types';\nimport { ProposalExecutor } from './executor';\nimport type { ProposalExecutionResult } from './executor';\n\nexport interface ExecutorResultPayload {\n context: RegenerationContext;\n proposal: SpecChangeProposal;\n result: ProposalExecutionResult;\n}\n\nexport interface ExecutorSinkLogger {\n info?: (message: string, meta?: Record<string, unknown>) => void;\n error?: (\n message: string,\n error: Error,\n meta?: Record<string, unknown>\n ) => void;\n}\n\nexport interface ExecutorSinkOptions {\n dryRun?: boolean;\n onResult?: (payload: ExecutorResultPayload) => void | Promise<void>;\n logger?: ExecutorSinkLogger;\n}\n\nexport class ExecutorProposalSink implements ProposalSink {\n constructor(\n private readonly executor: ProposalExecutor,\n private readonly options: ExecutorSinkOptions = {}\n ) {}\n\n async submit(\n context: RegenerationContext,\n proposal: SpecChangeProposal\n ): Promise<void> {\n const dryRun = this.options.dryRun ?? false;\n try {\n const result = await this.executor.execute(context, proposal, { dryRun });\n if (this.options.logger?.info) {\n this.options.logger.info('[regenerator] proposal executed', {\n proposalId: proposal.id,\n contextId: context.id,\n status: result.status,\n });\n }\n if (this.options.onResult) {\n await this.options.onResult({ context, proposal, result });\n }\n } catch (error) {\n if (this.options.logger?.error) {\n this.options.logger.error(\n '[regenerator] proposal execution failed',\n error instanceof Error ? error : new Error(String(error)),\n { proposalId: proposal.id, contextId: context.id }\n );\n }\n throw error instanceof Error ? error : new Error(String(error));\n }\n }\n}\n"],"mappings":"AA6BA,IAAa,EAAb,KAA0D,CACxD,YACE,EACA,EAAgD,EAAE,CAClD,CAFiB,KAAA,SAAA,EACA,KAAA,QAAA,EAGnB,MAAM,OACJ,EACA,EACe,CACf,IAAM,EAAS,KAAK,QAAQ,QAAU,GACtC,GAAI,CACF,IAAM,EAAS,MAAM,KAAK,SAAS,QAAQ,EAAS,EAAU,CAAE,SAAQ,CAAC,CACrE,KAAK,QAAQ,QAAQ,MACvB,KAAK,QAAQ,OAAO,KAAK,kCAAmC,CAC1D,WAAY,EAAS,GACrB,UAAW,EAAQ,GACnB,OAAQ,EAAO,OAChB,CAAC,CAEA,KAAK,QAAQ,UACf,MAAM,KAAK,QAAQ,SAAS,CAAE,UAAS,WAAU,SAAQ,CAAC,OAErD,EAAO,CAQd,MAPI,KAAK,QAAQ,QAAQ,OACvB,KAAK,QAAQ,OAAO,MAClB,0CACA,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC,CACzD,CAAE,WAAY,EAAS,GAAI,UAAW,EAAQ,GAAI,CACnD,CAEG,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/regenerator/types.ts"],"sourcesContent":[],"mappings":";;;;;KAOY,iBAAA,GACR,0BACA,sBACA;UAEa,uBAAA;EALL,IAAA,EAAA,WAAA;EACR,SAAA,EAAA,MAAA;EACA,MAAA,EAMM,eANN;;AACsB,UAQT,eAAA,CARS;EAET,SAAA,EAAA,MAAA;EAMA,YAAA,EAAA,MAAe;EAIjB,KAAA,EAAA,MAAA;EACF,WAAA,EADE,IACF;EAGA,SAAA,EAHA,IAGA;EACK,YAAA,CAAA,EAAA,MAAA;EAAa,cAAA,CAAA,EAAA,QAAA,GAAA,SAAA,GAAA,UAAA;EAGd,QAAA,CAAA,EAJJ,MAII,CAAA,MAAmB,EAAA,OAAA,CAAA;EAMnB,aAAA,CAAW,EATV,aAaJ;AAKd;AAMiB,UArBA,mBAAA,CAqBc;EAKhB,IAAA,EAAA,OAAA;EACF,SAAA,EAAA,MAAA;EACA,MAAA,EAzBH,WAyBG;;AAGI,UAzBA,WAAA,CAyBkB;EAIrB,EAAA,EAAA,MAAA;EAEJ,cAAA,EAAA,SAAA,GAAA,QAAA,GAAA,UAAA,GAAA,SAAA;EAEC,OAAA,EAAA,MAAA;EACE,UAAA,EA9BC,IA8BD;EACA,KAAA,EAAA,MAAA;EAAI,QAAA,CAAA,EA7BJ,MA6BI,CAAA,MAAA,EAAA,OAAA,CAAA;AAIjB;AAEiB,UAhCA,sBAAA,CAgCc;EAiBnB,IAAA,EAAA,UAAA;EAsBK,SAAA,EAAA,MAAA;EAKA,MAAA,EAzEP,cAyE0B;;AAGpB,UAzEC,cAAA,CAyED;EACJ,OAAA,EAAA,MAAA;EAAiB,MAAA,EAAA,OAAA,GAAA,YAAA,GAAA,SAAA,GAAA,QAAA;EAGZ,KAAA,EAAA,MAAA;EAIJ,QAAA,CAAA,EAAA,MAAA;EACA,WAAA,EA7EE,IA6EF;EACA,SAAA,EA7EA,IA6EA;EAAR,QAAA,CAAA,EA5EQ,MA4ER,CAAA,MAAA,EAAA,OAAA,CAAA;;AAGY,UA5EA,kBAAA,CA4EY;EAEhB,EAAA,EAAA,MAAA;EACC,KAAA,EAAA,MAAA;EACT,OAAA,EAAA,MAAA;EAAO,UAAA,EA5EE,kBA4EF;;UA1EF;;WAEC;aACE;aACA;;;KAID,kBAAA;UAEK,cAAA;;;;;;;;KAiBL,cAAA;;;;;;;;;;;;;;;;UAsBK,eAAA;;;;UAKA,mBAAA;;aAEJ;gBACG;YACJ;;UAGK,gBAAA;;;oBAIJ,8BACA,sBACR,QAAQ;;UAGI,YAAA;kBAEJ,+BACC,qBACT"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/regenerator/types.ts"],"sourcesContent":[],"mappings":";;;;;KAIY,iBAAA,GACR,0BACA,sBACA;UAEa,uBAAA;EALL,IAAA,EAAA,WAAA;EACR,SAAA,EAAA,MAAA;EACA,MAAA,EAMM,eANN;;AACsB,UAQT,eAAA,CARS;EAET,SAAA,EAAA,MAAA;EAMA,YAAA,EAAA,MAAe;EAIjB,KAAA,EAAA,MAAA;EACF,WAAA,EADE,IACF;EAGA,SAAA,EAHA,IAGA;EACK,YAAA,CAAA,EAAA,MAAA;EAAa,cAAA,CAAA,EAAA,QAAA,GAAA,SAAA,GAAA,UAAA;EAGd,QAAA,CAAA,EAJJ,MAII,CAAA,MAAmB,EAAA,OAAA,CAAA;EAMnB,aAAA,CAAW,EATV,aAaJ;AAKd;AAMiB,UArBA,mBAAA,CAqBc;EAKhB,IAAA,EAAA,OAAA;EACF,SAAA,EAAA,MAAA;EACA,MAAA,EAzBH,WAyBG;;AAGI,UAzBA,WAAA,CAyBkB;EAIrB,EAAA,EAAA,MAAA;EAEJ,cAAA,EAAA,SAAA,GAAA,QAAA,GAAA,UAAA,GAAA,SAAA;EAEC,OAAA,EAAA,MAAA;EACE,UAAA,EA9BC,IA8BD;EACA,KAAA,EAAA,MAAA;EAAI,QAAA,CAAA,EA7BJ,MA6BI,CAAA,MAAA,EAAA,OAAA,CAAA;AAIjB;AAEiB,UAhCA,sBAAA,CAgCc;EAiBnB,IAAA,EAAA,UAAA;EAsBK,SAAA,EAAA,MAAA;EASA,MAAA,EA7EP,cA6E0B;;AAGpB,UA7EC,cAAA,CA6ED;EACJ,OAAA,EAAA,MAAA;EAAiB,MAAA,EAAA,OAAA,GAAA,YAAA,GAAA,SAAA,GAAA,QAAA;EAGZ,KAAA,EAAA,MAAA;EAIJ,QAAA,CAAA,EAAA,MAAA;EACA,WAAA,EAjFE,IAiFF;EACA,SAAA,EAjFA,IAiFA;EAAR,QAAA,CAAA,EAhFQ,MAgFR,CAAA,MAAA,EAAA,OAAA,CAAA;;AAGY,UAhFA,kBAAA,CAgFY;EAEhB,EAAA,EAAA,MAAA;EACC,KAAA,EAAA,MAAA;EACT,OAAA,EAAA,MAAA;EAAO,UAAA,EAhFE,kBAgFF;;UA9EF;;WAEC;aACE;aACA;;;KAID,kBAAA;UAEK,cAAA;;;;;;;;KAiBL,cAAA;;;;;;;;;;;;;;;;UAsBK,eAAA;;;;UASA,mBAAA;;aAEJ;gBACG;YACJ;;UAGK,gBAAA;;;oBAIJ,8BACA,sBACR,QAAQ;;UAGI,YAAA;kBAEJ,+BACC,qBACT"}