@noodleseed/one 0.46.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/assistant-ops.d.ts.map +1 -1
- package/dist/commands/assistant-ops.js +65 -1
- package/dist/commands/assistant-ops.js.map +1 -1
- package/dist/commands/auth-ops.d.ts.map +1 -1
- package/dist/commands/auth-ops.js +28 -4
- package/dist/commands/auth-ops.js.map +1 -1
- package/dist/commands/billing-enforcement-ops.d.ts +2 -0
- package/dist/commands/billing-enforcement-ops.d.ts.map +1 -0
- package/dist/commands/billing-enforcement-ops.js +312 -0
- package/dist/commands/billing-enforcement-ops.js.map +1 -0
- package/dist/commands/billing-metering-ops.d.ts +2 -0
- package/dist/commands/billing-metering-ops.d.ts.map +1 -0
- package/dist/commands/billing-metering-ops.js +128 -0
- package/dist/commands/billing-metering-ops.js.map +1 -0
- package/dist/commands/billing-metering-validation-ops.d.ts +2 -0
- package/dist/commands/billing-metering-validation-ops.d.ts.map +1 -0
- package/dist/commands/billing-metering-validation-ops.js +186 -0
- package/dist/commands/billing-metering-validation-ops.js.map +1 -0
- package/dist/commands/billing-ops.d.ts.map +1 -1
- package/dist/commands/billing-ops.js +6 -0
- package/dist/commands/billing-ops.js.map +1 -1
- package/dist/commands/catalog-data-resources.d.ts.map +1 -1
- package/dist/commands/catalog-data-resources.js +25 -4
- package/dist/commands/catalog-data-resources.js.map +1 -1
- package/dist/commands/catalog-render.d.ts.map +1 -1
- package/dist/commands/catalog-render.js +7 -5
- package/dist/commands/catalog-render.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +10 -1
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/commands/deploy-output.d.ts.map +1 -1
- package/dist/commands/deploy-output.js +4 -0
- package/dist/commands/deploy-output.js.map +1 -1
- package/dist/commands/deploy-version-resolution.d.ts +1 -0
- package/dist/commands/deploy-version-resolution.d.ts.map +1 -1
- package/dist/commands/deploy-version-resolution.js +8 -0
- package/dist/commands/deploy-version-resolution.js.map +1 -1
- package/dist/commands/mcp-apps-chatgpt.d.ts +7 -0
- package/dist/commands/mcp-apps-chatgpt.d.ts.map +1 -0
- package/dist/commands/mcp-apps-chatgpt.js +143 -0
- package/dist/commands/mcp-apps-chatgpt.js.map +1 -0
- package/dist/commands/mcp-apps.d.ts.map +1 -1
- package/dist/commands/mcp-apps.js +2 -114
- package/dist/commands/mcp-apps.js.map +1 -1
- package/dist/deploy-payload-size.d.ts +3 -0
- package/dist/deploy-payload-size.d.ts.map +1 -0
- package/dist/deploy-payload-size.js +29 -0
- package/dist/deploy-payload-size.js.map +1 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +19 -8
- package/dist/deploy.js.map +1 -1
- package/dist/sdk-version-skew.d.ts +3 -0
- package/dist/sdk-version-skew.d.ts.map +1 -0
- package/dist/sdk-version-skew.js +34 -0
- package/dist/sdk-version-skew.js.map +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +3 -3
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +10 -2
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +5 -0
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +1 -0
- package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +7 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.js +4 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.js +3 -0
- package/node_modules/@noodle-borg/compiler/dist/compile.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +12 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +7 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.js +40 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.js +109 -1
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts +10 -3
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js +69 -5
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/widget/action-wiring-bootstrap.d.ts +3 -0
- package/node_modules/@noodle-borg/protocol/dist/widget/action-wiring-bootstrap.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/widget/action-wiring-bootstrap.js +17 -0
- package/node_modules/@noodle-borg/protocol/dist/widget/action-wiring-bootstrap.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/widget/bootstrap.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/widget/bootstrap.js +8 -16
- package/node_modules/@noodle-borg/protocol/dist/widget/bootstrap.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/widget/interaction-bootstrap.d.ts +3 -0
- package/node_modules/@noodle-borg/protocol/dist/widget/interaction-bootstrap.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/widget/interaction-bootstrap.js +177 -0
- package/node_modules/@noodle-borg/protocol/dist/widget/interaction-bootstrap.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.d.ts +96 -0
- package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.js +198 -0
- package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/integration.d.ts +25 -2
- package/node_modules/@noodle-borg/service/dist/billing/integration.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/integration.js +51 -5
- package/node_modules/@noodle-borg/service/dist/billing/integration.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.d.ts +77 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.js +202 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.d.ts +8 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.js +93 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.d.ts +76 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.js +233 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.d.ts +89 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.js +191 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.d.ts +99 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.js +136 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.d.ts +9 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.js +24 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.d.ts +75 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.js +127 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.js +107 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.d.ts +18 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.js +341 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.d.ts +3 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.js +9 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.d.ts +13 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.js +102 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.d.ts +41 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.js +289 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.d.ts +16 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.js +126 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.d.ts +33 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.js +436 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.d.ts +26 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.js +146 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.d.ts +8 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.js +42 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.d.ts +8 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.js +44 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.d.ts +13 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.js +189 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.d.ts +18 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.js +342 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.d.ts +27 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.js +304 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.d.ts +22 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.js +224 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.d.ts +33 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.js +173 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.js +50 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.d.ts +34 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.js +157 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.d.ts +56 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.js +264 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.js +414 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.d.ts +43 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.js +321 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.d.ts +10 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.js +13 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.js +248 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.d.ts +29 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.js +240 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.js +140 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.js +4 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.js +6 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres.js +3 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.js +19 -0
- package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.d.ts +9 -4
- package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.js +34 -95
- package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.d.ts +14 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.js +87 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-observer.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-observer.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-observer.js +26 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-observer.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing-public.d.ts +16 -0
- package/node_modules/@noodle-borg/service/dist/billing-public.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing-public.js +15 -0
- package/node_modules/@noodle-borg/service/dist/billing-public.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/customer-verifier.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/customer-verifier.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/customer-verifier.js +15 -0
- package/node_modules/@noodle-borg/service/dist/customer-verifier.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/http-util.d.ts +13 -0
- package/node_modules/@noodle-borg/service/dist/http-util.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/http-util.js +42 -2
- package/node_modules/@noodle-borg/service/dist/http-util.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.d.ts +2 -7
- package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.js +1 -6
- package/node_modules/@noodle-borg/service/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/main.js +3 -0
- package/node_modules/@noodle-borg/service/dist/main.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/options.d.ts +18 -0
- package/node_modules/@noodle-borg/service/dist/options.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/persistence-options.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/persistence-options.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/persistence-options.js +22 -0
- package/node_modules/@noodle-borg/service/dist/persistence-options.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant-dispatch.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-dispatch.js +10 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-dispatch.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant.js +85 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.d.ts +17 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.js +145 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.d.ts +15 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.js +78 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.d.ts +15 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.js +108 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.js +99 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.d.ts +25 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.js +35 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +3 -3
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve-options.d.ts +93 -0
- package/node_modules/@noodle-borg/service/dist/serve-options.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/serve-options.js +2 -0
- package/node_modules/@noodle-borg/service/dist/serve-options.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/serve.d.ts +2 -92
- package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve.js +64 -59
- package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts +22 -0
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js +51 -0
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.js +10 -21
- package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.js +7 -1
- package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-billing.d.ts +6 -2
- package/node_modules/@noodle-borg/service/dist/store/postgres-billing.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-billing.js +11 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-billing.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { createPostgresBillingMeterReadinessStore, createPostgresBillingMeterValidationEpochStore, } from './integration.js';
|
|
3
|
+
import { createBillingMeterValidationMirror } from './meter-live-validation.js';
|
|
4
|
+
import { BILLING_METER_RETRY_IDENTITY_VERSION, deriveBillingMeterKeyGeneration, } from './meter-readiness.js';
|
|
5
|
+
import { BILLING_METER_WRITER_HEARTBEAT_INTERVAL_MS, } from './meter-readiness-health.js';
|
|
6
|
+
import { BILLING_METER_VALIDATION_WRITER_CONTRACT_VERSION, } from './meter-validation-epoch.js';
|
|
7
|
+
import { registerPostgresBillingMeterWriterSession } from './postgres-meter-live-validation.js';
|
|
8
|
+
import { checkBillingMeterValidationFoundationPreflight } from './postgres-meter-prepare-preflight.js';
|
|
9
|
+
import { BILLING_METER_SCHEDULER_CONTRACT_VERSION, ensureBillingMeterSchedulerSchema, PostgresBillingMeterScheduler, } from './postgres-meter-scheduler.js';
|
|
10
|
+
import { createShadowBillingSink } from './shadow-meter.js';
|
|
11
|
+
import { parseBillingUsageHmacKey } from './usage-identity.js';
|
|
12
|
+
export async function createPostgresBillingMeterRuntime(input) {
|
|
13
|
+
const expectation = resolvePostgresBillingMeterRuntimeExpectation(input);
|
|
14
|
+
await ensureBillingMeterSchedulerSchema(input.pool);
|
|
15
|
+
const readinessStore = await createPostgresBillingMeterReadinessStore(input.pool, {
|
|
16
|
+
...(input.billingUsageHmacKey === undefined
|
|
17
|
+
? {}
|
|
18
|
+
: { billingUsageHmacKey: input.billingUsageHmacKey }),
|
|
19
|
+
...(expectation === undefined ? {} : { validationRuntime: expectation }),
|
|
20
|
+
});
|
|
21
|
+
const validationEpochStore = await createPostgresBillingMeterValidationEpochStore(input.pool, {
|
|
22
|
+
...(input.billingUsageHmacKey === undefined
|
|
23
|
+
? {}
|
|
24
|
+
: { billingUsageHmacKey: input.billingUsageHmacKey }),
|
|
25
|
+
releaseSha: input.releaseSha,
|
|
26
|
+
foundationPreflight: ({ client }) => checkBillingMeterValidationFoundationPreflight(client),
|
|
27
|
+
});
|
|
28
|
+
if (expectation === undefined || input.validation === undefined) {
|
|
29
|
+
return {
|
|
30
|
+
readinessStore,
|
|
31
|
+
validationEpochStore,
|
|
32
|
+
start: () => undefined,
|
|
33
|
+
stop: () => Promise.resolve(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const writer = await registerPostgresBillingMeterWriterSession(input.pool, {
|
|
37
|
+
sessionId: `bmws_${randomUUID()}`,
|
|
38
|
+
releaseSha: expectation.releaseSha,
|
|
39
|
+
keyGeneration: expectation.keyGeneration,
|
|
40
|
+
retryIdentityVersion: expectation.retryIdentityVersion,
|
|
41
|
+
writerContractVersion: expectation.writerContractVersion,
|
|
42
|
+
});
|
|
43
|
+
const mirror = createBillingMeterValidationMirror({
|
|
44
|
+
hmacKey: input.billingUsageHmacKey,
|
|
45
|
+
shadowSink: createShadowBillingSink({
|
|
46
|
+
store: input.usageStore,
|
|
47
|
+
...(input.clock === undefined ? {} : { clock: input.clock }),
|
|
48
|
+
logger: input.logger,
|
|
49
|
+
}),
|
|
50
|
+
writer,
|
|
51
|
+
logger: input.logger,
|
|
52
|
+
});
|
|
53
|
+
const scheduler = new PostgresBillingMeterScheduler(input.pool, {
|
|
54
|
+
releaseSha: expectation.releaseSha,
|
|
55
|
+
cpuAlwaysAllocated: true,
|
|
56
|
+
...(input.validation.schedulerIntervalMs === undefined
|
|
57
|
+
? {}
|
|
58
|
+
: { intervalMs: input.validation.schedulerIntervalMs }),
|
|
59
|
+
...(input.schedulerOperations === undefined ? {} : { operations: input.schedulerOperations }),
|
|
60
|
+
logger: input.logger,
|
|
61
|
+
});
|
|
62
|
+
return new LivePostgresBillingMeterRuntime(readinessStore, validationEpochStore, mirror, scheduler, input.validation.writerHeartbeatIntervalMs ?? BILLING_METER_WRITER_HEARTBEAT_INTERVAL_MS, input.logger);
|
|
63
|
+
}
|
|
64
|
+
class LivePostgresBillingMeterRuntime {
|
|
65
|
+
readinessStore;
|
|
66
|
+
validationEpochStore;
|
|
67
|
+
observer;
|
|
68
|
+
#mirror;
|
|
69
|
+
#scheduler;
|
|
70
|
+
#heartbeatIntervalMs;
|
|
71
|
+
#logger;
|
|
72
|
+
#started = false;
|
|
73
|
+
#closed = false;
|
|
74
|
+
#heartbeatTimer;
|
|
75
|
+
#heartbeatInFlight;
|
|
76
|
+
constructor(readinessStore, validationEpochStore, mirror, scheduler, heartbeatIntervalMs, logger) {
|
|
77
|
+
this.readinessStore = readinessStore;
|
|
78
|
+
this.validationEpochStore = validationEpochStore;
|
|
79
|
+
this.observer = mirror.observe;
|
|
80
|
+
this.#mirror = mirror;
|
|
81
|
+
this.#scheduler = scheduler;
|
|
82
|
+
this.#heartbeatIntervalMs = positiveInterval(heartbeatIntervalMs);
|
|
83
|
+
this.#logger = logger;
|
|
84
|
+
}
|
|
85
|
+
start() {
|
|
86
|
+
if (this.#closed)
|
|
87
|
+
throw new Error('billing meter runtime is closed');
|
|
88
|
+
if (this.#started)
|
|
89
|
+
return;
|
|
90
|
+
this.#started = true;
|
|
91
|
+
this.#scheduler.start();
|
|
92
|
+
void this.#reportAndScheduleHeartbeat();
|
|
93
|
+
}
|
|
94
|
+
async stop() {
|
|
95
|
+
if (this.#closed)
|
|
96
|
+
return;
|
|
97
|
+
this.#closed = true;
|
|
98
|
+
this.#started = false;
|
|
99
|
+
if (this.#heartbeatTimer !== undefined) {
|
|
100
|
+
clearTimeout(this.#heartbeatTimer);
|
|
101
|
+
this.#heartbeatTimer = undefined;
|
|
102
|
+
}
|
|
103
|
+
// Stop future scheduler recursion immediately, but do not put its potentially long current cycle in
|
|
104
|
+
// front of the writer's bounded drain. The service process has a shorter shutdown deadline than a
|
|
105
|
+
// scheduler cycle, so clean writer evidence must be persisted first.
|
|
106
|
+
const schedulerStop = this.#scheduler.stop();
|
|
107
|
+
const writerErrors = [];
|
|
108
|
+
if (this.#heartbeatInFlight !== undefined) {
|
|
109
|
+
try {
|
|
110
|
+
await this.#heartbeatInFlight;
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
writerErrors.push(error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
await this.#mirror.close();
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
writerErrors.push(error);
|
|
121
|
+
}
|
|
122
|
+
await schedulerStop.catch(() => undefined);
|
|
123
|
+
if (writerErrors.length > 0) {
|
|
124
|
+
throw new AggregateError(writerErrors, 'billing meter writer shutdown failed');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async #reportAndScheduleHeartbeat() {
|
|
128
|
+
const report = this.#mirror.reportHealth().catch((error) => {
|
|
129
|
+
this.#logger.warn('billing.meter.writer_health_report_failed', {
|
|
130
|
+
errorKind: error instanceof Error ? error.name : 'unknown',
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
this.#heartbeatInFlight = report;
|
|
134
|
+
await report;
|
|
135
|
+
if (this.#heartbeatInFlight === report)
|
|
136
|
+
this.#heartbeatInFlight = undefined;
|
|
137
|
+
if (this.#started) {
|
|
138
|
+
this.#heartbeatTimer = setTimeout(() => {
|
|
139
|
+
this.#heartbeatTimer = undefined;
|
|
140
|
+
void this.#reportAndScheduleHeartbeat();
|
|
141
|
+
}, this.#heartbeatIntervalMs);
|
|
142
|
+
this.#heartbeatTimer.unref?.();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export function resolvePostgresBillingMeterRuntimeExpectation(input) {
|
|
147
|
+
if (input.validation === undefined)
|
|
148
|
+
return undefined;
|
|
149
|
+
if (input.validation.cpuAlwaysAllocated !== true) {
|
|
150
|
+
throw new Error('billing meter validation requires CPU to be always allocated');
|
|
151
|
+
}
|
|
152
|
+
if (input.billingUsageHmacKey === undefined) {
|
|
153
|
+
throw new Error('billing meter validation requires NOODLE_BILLING_USAGE_HMAC_KEY');
|
|
154
|
+
}
|
|
155
|
+
parseBillingUsageHmacKey(input.billingUsageHmacKey);
|
|
156
|
+
if (!/^[0-9a-f]{40}$/.test(input.releaseSha)) {
|
|
157
|
+
throw new Error('billing meter validation requires a full 40-character release SHA');
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
releaseSha: input.releaseSha,
|
|
161
|
+
keyGeneration: deriveBillingMeterKeyGeneration(input.billingUsageHmacKey),
|
|
162
|
+
retryIdentityVersion: BILLING_METER_RETRY_IDENTITY_VERSION,
|
|
163
|
+
writerContractVersion: BILLING_METER_VALIDATION_WRITER_CONTRACT_VERSION,
|
|
164
|
+
schedulerContractVersion: BILLING_METER_SCHEDULER_CONTRACT_VERSION,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function positiveInterval(value) {
|
|
168
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
169
|
+
throw new Error('billing meter writer heartbeat interval must be positive');
|
|
170
|
+
}
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=postgres-meter-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-runtime.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Pool } from 'pg';
|
|
2
|
+
/**
|
|
3
|
+
* Additive scheduler evidence for the inactive validation meter. The scheduler owns this schema
|
|
4
|
+
* separately so boot wiring can create it without coupling scheduler evolution to receipt storage.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ensureBillingMeterSchedulerSchema(database: Pick<Pool, 'query'>): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=postgres-meter-scheduler-schema.d.ts.map
|
package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-scheduler-schema.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-scheduler-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B;;;GAGG;AACH,wBAAsB,iCAAiC,CACrD,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CA4Cf"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Additive scheduler evidence for the inactive validation meter. The scheduler owns this schema
|
|
3
|
+
* separately so boot wiring can create it without coupling scheduler evolution to receipt storage.
|
|
4
|
+
*/
|
|
5
|
+
export async function ensureBillingMeterSchedulerSchema(database) {
|
|
6
|
+
await database.query(`
|
|
7
|
+
CREATE TABLE IF NOT EXISTS billing_meter_scheduler_runs (
|
|
8
|
+
run_id text PRIMARY KEY,
|
|
9
|
+
run_sequence bigint GENERATED ALWAYS AS IDENTITY UNIQUE,
|
|
10
|
+
contract_version integer NOT NULL CHECK (contract_version = 1),
|
|
11
|
+
release_sha text NOT NULL CHECK (release_sha ~ '^[0-9a-f]{40}$'),
|
|
12
|
+
cpu_always_allocated boolean NOT NULL CHECK (cpu_always_allocated),
|
|
13
|
+
status text NOT NULL
|
|
14
|
+
CHECK (status IN ('running', 'succeeded', 'failed', 'backlogged')),
|
|
15
|
+
started_at timestamptz NOT NULL,
|
|
16
|
+
completed_at timestamptz,
|
|
17
|
+
windows_discovered integer NOT NULL DEFAULT 0 CHECK (windows_discovered >= 0),
|
|
18
|
+
windows_processed integer NOT NULL DEFAULT 0 CHECK (windows_processed >= 0),
|
|
19
|
+
windows_succeeded integer NOT NULL DEFAULT 0 CHECK (windows_succeeded >= 0),
|
|
20
|
+
windows_failed integer NOT NULL DEFAULT 0 CHECK (windows_failed >= 0),
|
|
21
|
+
backlog_detected boolean NOT NULL DEFAULT false,
|
|
22
|
+
maintenance_run_id text,
|
|
23
|
+
failure_code text CHECK (
|
|
24
|
+
failure_code IN (
|
|
25
|
+
'reconciliation_failed',
|
|
26
|
+
'maintenance_failed',
|
|
27
|
+
'reconciliation_and_maintenance_failed',
|
|
28
|
+
'cycle_failed',
|
|
29
|
+
'leader_lost'
|
|
30
|
+
)
|
|
31
|
+
),
|
|
32
|
+
CHECK (windows_discovered >= windows_processed),
|
|
33
|
+
CHECK (windows_processed = windows_succeeded + windows_failed),
|
|
34
|
+
CHECK (NOT backlog_detected OR windows_discovered > windows_processed),
|
|
35
|
+
CHECK (
|
|
36
|
+
(status = 'running' AND completed_at IS NULL AND failure_code IS NULL) OR
|
|
37
|
+
(status = 'succeeded' AND completed_at IS NOT NULL AND NOT backlog_detected AND
|
|
38
|
+
failure_code IS NULL) OR
|
|
39
|
+
(status = 'backlogged' AND completed_at IS NOT NULL AND backlog_detected AND
|
|
40
|
+
failure_code IS NULL) OR
|
|
41
|
+
(status = 'failed' AND completed_at IS NOT NULL AND failure_code IS NOT NULL)
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
`);
|
|
45
|
+
await database.query(`
|
|
46
|
+
CREATE INDEX IF NOT EXISTS billing_meter_scheduler_runs_latest_idx
|
|
47
|
+
ON billing_meter_scheduler_runs (run_sequence DESC)
|
|
48
|
+
`);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=postgres-meter-scheduler-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-scheduler-schema.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-scheduler-schema.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,QAA6B;IAE7B,MAAM,QAAQ,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCpB,CAAC,CAAC;IACH,MAAM,QAAQ,CAAC,KAAK,CAAC;;;GAGpB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { PoolClient } from 'pg';
|
|
2
|
+
export declare const BILLING_METER_SCHEDULER_CONTRACT_VERSION = 1;
|
|
3
|
+
export type BillingMeterSchedulerFailureCode = 'reconciliation_failed' | 'maintenance_failed' | 'reconciliation_and_maintenance_failed' | 'cycle_failed' | 'leader_lost';
|
|
4
|
+
export interface BillingMeterSchedulerWindow {
|
|
5
|
+
readonly epochId: string;
|
|
6
|
+
readonly windowStart: string;
|
|
7
|
+
readonly windowEnd: string;
|
|
8
|
+
}
|
|
9
|
+
export interface BillingMeterSchedulerCycleCounts {
|
|
10
|
+
readonly windowsDiscovered: number;
|
|
11
|
+
readonly windowsProcessed: number;
|
|
12
|
+
readonly windowsSucceeded: number;
|
|
13
|
+
readonly windowsFailed: number;
|
|
14
|
+
readonly backlogDetected: boolean;
|
|
15
|
+
readonly maintenanceRunId: string | null;
|
|
16
|
+
}
|
|
17
|
+
export interface BillingMeterSchedulerCompletedCycle extends BillingMeterSchedulerCycleCounts {
|
|
18
|
+
readonly status: 'succeeded' | 'failed' | 'backlogged';
|
|
19
|
+
readonly runId: string;
|
|
20
|
+
readonly startedAt: string;
|
|
21
|
+
readonly completedAt: string;
|
|
22
|
+
readonly failureCode: BillingMeterSchedulerFailureCode | null;
|
|
23
|
+
}
|
|
24
|
+
export declare function startBillingMeterSchedulerRun(client: PoolClient, releaseSha: string): Promise<{
|
|
25
|
+
readonly runId: string;
|
|
26
|
+
readonly startedAt: string;
|
|
27
|
+
}>;
|
|
28
|
+
export declare function completeBillingMeterSchedulerRun(client: PoolClient, evidence: {
|
|
29
|
+
readonly runId: string;
|
|
30
|
+
readonly startedAt: string;
|
|
31
|
+
}, counts: BillingMeterSchedulerCycleCounts, status: BillingMeterSchedulerCompletedCycle['status'], failureCode: BillingMeterSchedulerFailureCode | null): Promise<BillingMeterSchedulerCompletedCycle>;
|
|
32
|
+
export declare function discoverBillingMeterSchedulerWindows(client: Pick<PoolClient, 'query'>, limit: number): Promise<readonly BillingMeterSchedulerWindow[]>;
|
|
33
|
+
export declare function configureBillingMeterSchedulerSession(client: PoolClient, statementTimeoutMs: number, lockTimeoutMs: number): Promise<void>;
|
|
34
|
+
//# sourceMappingURL=postgres-meter-scheduler-store.d.ts.map
|
package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-scheduler-store.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-scheduler-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAUrC,eAAO,MAAM,wCAAwC,IAAI,CAAC;AAE1D,MAAM,MAAM,gCAAgC,GACxC,uBAAuB,GACvB,oBAAoB,GACpB,uCAAuC,GACvC,cAAc,GACd,aAAa,CAAC;AAElB,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,mCAAoC,SAAQ,gCAAgC;IAC3F,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,YAAY,CAAC;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,gCAAgC,GAAG,IAAI,CAAC;CAC/D;AAQD,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAyBjE;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAChE,MAAM,EAAE,gCAAgC,EACxC,MAAM,EAAE,mCAAmC,CAAC,QAAQ,CAAC,EACrD,WAAW,EAAE,gCAAgC,GAAG,IAAI,GACnD,OAAO,CAAC,mCAAmC,CAAC,CAwC9C;AAED,wBAAsB,oCAAoC,CACxD,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,2BAA2B,EAAE,CAAC,CA4EjD;AAED,wBAAsB,qCAAqC,CACzD,MAAM,EAAE,UAAU,EAClB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { readBillingMeterTransactionTime } from './postgres-meter-clock.js';
|
|
3
|
+
import { BILLING_METER_CHANGED_WINDOW_RECONCILIATION_DELAY_MS, BILLING_METER_CLEAN_WINDOW_RECONCILIATION_INTERVAL_MS, BILLING_METER_FAILED_WINDOW_RECONCILIATION_DELAY_MS, } from './postgres-meter-window-lock.js';
|
|
4
|
+
import { validateScalarId } from './postgres-records.js';
|
|
5
|
+
import { normalizeBillingUsageInstant } from './usage-window.js';
|
|
6
|
+
export const BILLING_METER_SCHEDULER_CONTRACT_VERSION = 1;
|
|
7
|
+
export async function startBillingMeterSchedulerRun(client, releaseSha) {
|
|
8
|
+
const runId = `bmsr_${randomUUID()}`;
|
|
9
|
+
await client.query('BEGIN');
|
|
10
|
+
try {
|
|
11
|
+
const startedAt = await readBillingMeterTransactionTime(client);
|
|
12
|
+
// Owning the global session lock proves no prior scheduler session is still alive. Close its
|
|
13
|
+
// durable running marker before starting fresh so takeover cannot mask a crash gap.
|
|
14
|
+
await client.query(`UPDATE billing_meter_scheduler_runs
|
|
15
|
+
SET status = 'failed', completed_at = $1, failure_code = 'leader_lost'
|
|
16
|
+
WHERE status = 'running'`, [startedAt]);
|
|
17
|
+
await client.query(`INSERT INTO billing_meter_scheduler_runs
|
|
18
|
+
(run_id, contract_version, release_sha, cpu_always_allocated, status, started_at)
|
|
19
|
+
VALUES ($1, $2, $3, true, 'running', $4)`, [runId, BILLING_METER_SCHEDULER_CONTRACT_VERSION, releaseSha, startedAt]);
|
|
20
|
+
await client.query('COMMIT');
|
|
21
|
+
return { runId, startedAt };
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
await rollbackQuietly(client);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function completeBillingMeterSchedulerRun(client, evidence, counts, status, failureCode) {
|
|
29
|
+
await client.query('BEGIN');
|
|
30
|
+
try {
|
|
31
|
+
const completedAt = await readBillingMeterTransactionTime(client);
|
|
32
|
+
const updated = await client.query(`UPDATE billing_meter_scheduler_runs
|
|
33
|
+
SET status = $2, completed_at = $3,
|
|
34
|
+
windows_discovered = $4, windows_processed = $5,
|
|
35
|
+
windows_succeeded = $6, windows_failed = $7,
|
|
36
|
+
backlog_detected = $8, maintenance_run_id = $9, failure_code = $10
|
|
37
|
+
WHERE run_id = $1 AND status = 'running'`, [
|
|
38
|
+
evidence.runId,
|
|
39
|
+
status,
|
|
40
|
+
completedAt,
|
|
41
|
+
counts.windowsDiscovered,
|
|
42
|
+
counts.windowsProcessed,
|
|
43
|
+
counts.windowsSucceeded,
|
|
44
|
+
counts.windowsFailed,
|
|
45
|
+
counts.backlogDetected,
|
|
46
|
+
counts.maintenanceRunId,
|
|
47
|
+
failureCode,
|
|
48
|
+
]);
|
|
49
|
+
if (updated.rowCount !== 1) {
|
|
50
|
+
throw new Error('billing meter scheduler evidence was not running');
|
|
51
|
+
}
|
|
52
|
+
await client.query('COMMIT');
|
|
53
|
+
return {
|
|
54
|
+
status,
|
|
55
|
+
runId: evidence.runId,
|
|
56
|
+
startedAt: evidence.startedAt,
|
|
57
|
+
completedAt,
|
|
58
|
+
...counts,
|
|
59
|
+
failureCode,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
await rollbackQuietly(client);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export async function discoverBillingMeterSchedulerWindows(client, limit) {
|
|
68
|
+
const result = await client.query(`WITH scheduler_clock AS (
|
|
69
|
+
SELECT billing_meter_transaction_time() AS checked_at
|
|
70
|
+
)
|
|
71
|
+
SELECT meter_window.epoch_id, meter_window.window_start, meter_window.window_end
|
|
72
|
+
FROM billing_meter_windows AS meter_window
|
|
73
|
+
JOIN billing_meter_epochs AS epoch ON epoch.id = meter_window.epoch_id
|
|
74
|
+
CROSS JOIN scheduler_clock
|
|
75
|
+
LEFT JOIN LATERAL (
|
|
76
|
+
SELECT reconciliation.status, reconciliation.checked_at,
|
|
77
|
+
reconciliation.next_reconcile_at,
|
|
78
|
+
reconciliation.receipt_included_calls,
|
|
79
|
+
reconciliation.receipt_overage_calls,
|
|
80
|
+
reconciliation.receipt_denied_calls
|
|
81
|
+
FROM billing_meter_reconciliation_runs AS reconciliation
|
|
82
|
+
WHERE reconciliation.epoch_id = meter_window.epoch_id
|
|
83
|
+
AND reconciliation.window_start = meter_window.window_start
|
|
84
|
+
AND reconciliation.window_end = meter_window.window_end
|
|
85
|
+
ORDER BY reconciliation.checked_at DESC, reconciliation.run_id DESC
|
|
86
|
+
LIMIT 1
|
|
87
|
+
) AS latest ON true
|
|
88
|
+
CROSS JOIN LATERAL (
|
|
89
|
+
SELECT least(
|
|
90
|
+
CASE
|
|
91
|
+
WHEN latest.checked_at IS NULL THEN meter_window.first_observed_at
|
|
92
|
+
ELSE coalesce(
|
|
93
|
+
latest.next_reconcile_at,
|
|
94
|
+
CASE latest.status
|
|
95
|
+
WHEN 'failed' THEN latest.checked_at + interval '${BILLING_METER_FAILED_WINDOW_RECONCILIATION_DELAY_MS} milliseconds'
|
|
96
|
+
ELSE latest.checked_at + interval '${BILLING_METER_CLEAN_WINDOW_RECONCILIATION_INTERVAL_MS} milliseconds'
|
|
97
|
+
END
|
|
98
|
+
)
|
|
99
|
+
END,
|
|
100
|
+
CASE
|
|
101
|
+
WHEN latest.checked_at IS NOT NULL AND
|
|
102
|
+
(
|
|
103
|
+
meter_window.last_observed_at > latest.checked_at OR
|
|
104
|
+
meter_window.receipt_included_calls <> latest.receipt_included_calls OR
|
|
105
|
+
meter_window.receipt_overage_calls <> latest.receipt_overage_calls OR
|
|
106
|
+
meter_window.receipt_denied_calls <> latest.receipt_denied_calls
|
|
107
|
+
)
|
|
108
|
+
THEN meter_window.last_observed_at + interval '${BILLING_METER_CHANGED_WINDOW_RECONCILIATION_DELAY_MS} milliseconds'
|
|
109
|
+
END,
|
|
110
|
+
CASE
|
|
111
|
+
WHEN latest.checked_at IS NULL OR
|
|
112
|
+
latest.checked_at < meter_window.window_end OR
|
|
113
|
+
latest.status = 'succeeded'
|
|
114
|
+
THEN meter_window.window_end
|
|
115
|
+
END,
|
|
116
|
+
CASE
|
|
117
|
+
WHEN epoch.state = 'retired' AND (
|
|
118
|
+
latest.checked_at IS NULL OR
|
|
119
|
+
latest.checked_at < epoch.retired_at OR
|
|
120
|
+
latest.status = 'succeeded'
|
|
121
|
+
) THEN epoch.retired_at
|
|
122
|
+
END
|
|
123
|
+
) AS due_at
|
|
124
|
+
) AS schedule
|
|
125
|
+
WHERE epoch.state IN ('prepared', 'retired')
|
|
126
|
+
AND meter_window.sealed_at IS NULL
|
|
127
|
+
AND meter_window.first_observed_at IS NOT NULL
|
|
128
|
+
AND schedule.due_at <= scheduler_clock.checked_at
|
|
129
|
+
ORDER BY schedule.due_at,
|
|
130
|
+
meter_window.window_start, meter_window.window_end, meter_window.epoch_id
|
|
131
|
+
LIMIT $1`, [limit]);
|
|
132
|
+
if (result.rows.length > limit) {
|
|
133
|
+
throw new Error('billing meter scheduler window query exceeded its bound');
|
|
134
|
+
}
|
|
135
|
+
return result.rows.map((row) => ({
|
|
136
|
+
epochId: validateScalarId('billing meter epoch id', row.epoch_id),
|
|
137
|
+
windowStart: normalizeSchedulerInstant('billing meter window start', row.window_start),
|
|
138
|
+
windowEnd: normalizeSchedulerInstant('billing meter window end', row.window_end),
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
export async function configureBillingMeterSchedulerSession(client, statementTimeoutMs, lockTimeoutMs) {
|
|
142
|
+
await client.query(`SELECT set_config('statement_timeout', $1, false),
|
|
143
|
+
set_config('lock_timeout', $2, false),
|
|
144
|
+
set_config('idle_in_transaction_session_timeout', $1, false)`, [`${statementTimeoutMs}ms`, `${lockTimeoutMs}ms`]);
|
|
145
|
+
}
|
|
146
|
+
function normalizeSchedulerInstant(label, value) {
|
|
147
|
+
return normalizeBillingUsageInstant(label, value instanceof Date ? value.toISOString() : value);
|
|
148
|
+
}
|
|
149
|
+
async function rollbackQuietly(client) {
|
|
150
|
+
try {
|
|
151
|
+
await client.query('ROLLBACK');
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// Preserve the original scheduler evidence failure.
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=postgres-meter-scheduler-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-scheduler-store.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-scheduler-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Logger } from '@noodle-borg/transport-http';
|
|
2
|
+
import type { Pool, PoolClient } from 'pg';
|
|
3
|
+
import { type BillingMeterSchedulerCompletedCycle, type BillingMeterSchedulerWindow } from './postgres-meter-scheduler-store.js';
|
|
4
|
+
export { ensureBillingMeterSchedulerSchema } from './postgres-meter-scheduler-schema.js';
|
|
5
|
+
export { BILLING_METER_SCHEDULER_CONTRACT_VERSION, type BillingMeterSchedulerCompletedCycle, type BillingMeterSchedulerFailureCode, type BillingMeterSchedulerWindow, } from './postgres-meter-scheduler-store.js';
|
|
6
|
+
export declare const BILLING_METER_SCHEDULER_LOCK_KEY = "billing-meter-maintenance-scheduler:v1";
|
|
7
|
+
export declare const BILLING_METER_SCHEDULER_INTERVAL_MS: number;
|
|
8
|
+
export declare const BILLING_METER_SCHEDULER_MAX_WINDOWS_PER_CYCLE = 100;
|
|
9
|
+
export declare const BILLING_METER_SCHEDULER_STATEMENT_TIMEOUT_MS = 30000;
|
|
10
|
+
export declare const BILLING_METER_SCHEDULER_LOCK_TIMEOUT_MS = 5000;
|
|
11
|
+
export declare const BILLING_METER_SCHEDULER_CYCLE_TIMEOUT_MS: number;
|
|
12
|
+
export interface BillingMeterSchedulerOperations {
|
|
13
|
+
reconcileWindow(client: PoolClient, window: BillingMeterSchedulerWindow): Promise<{
|
|
14
|
+
readonly status: 'succeeded' | 'failed';
|
|
15
|
+
}>;
|
|
16
|
+
runMaintenance(client: PoolClient): Promise<{
|
|
17
|
+
readonly runId: string;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
export interface PostgresBillingMeterSchedulerOptions {
|
|
21
|
+
/** Full source commit identity written into every durable cycle record. */
|
|
22
|
+
readonly releaseSha: string;
|
|
23
|
+
/** An enabled in-service timer requires hosting CPU allocation outside request handling. */
|
|
24
|
+
readonly cpuAlwaysAllocated: true;
|
|
25
|
+
readonly intervalMs?: number;
|
|
26
|
+
readonly maxWindowsPerCycle?: number;
|
|
27
|
+
readonly statementTimeoutMs?: number;
|
|
28
|
+
readonly lockTimeoutMs?: number;
|
|
29
|
+
readonly cycleTimeoutMs?: number;
|
|
30
|
+
readonly logger?: Logger;
|
|
31
|
+
/** Injectable only to isolate orchestration tests; production uses the connected-client stores. */
|
|
32
|
+
readonly operations?: BillingMeterSchedulerOperations;
|
|
33
|
+
}
|
|
34
|
+
export type BillingMeterSchedulerCycleResult = BillingMeterSchedulerCompletedCycle | {
|
|
35
|
+
readonly status: 'skipped';
|
|
36
|
+
readonly reason: 'lock_not_acquired';
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* One scheduler may run in every stateless service instance. Local recursion prevents overlap in
|
|
40
|
+
* one process; the session advisory lock elects one leader across the fleet for the complete cycle.
|
|
41
|
+
* Validation remains fail-open and this class never activates an epoch or changes admission.
|
|
42
|
+
*/
|
|
43
|
+
export declare class PostgresBillingMeterScheduler {
|
|
44
|
+
#private;
|
|
45
|
+
constructor(pool: Pool, options: PostgresBillingMeterSchedulerOptions);
|
|
46
|
+
/** Start one immediate cycle, followed by a recursive delay measured after each completion. */
|
|
47
|
+
start(): void;
|
|
48
|
+
/** Stop future recursion and wait for the current bounded cycle to release its database client. */
|
|
49
|
+
stop(): Promise<void>;
|
|
50
|
+
/** Run now, or join the already-running local cycle rather than overlapping it. */
|
|
51
|
+
runNow(): Promise<BillingMeterSchedulerCycleResult>;
|
|
52
|
+
}
|
|
53
|
+
export declare class BillingMeterSchedulerCycleTimeoutError extends Error {
|
|
54
|
+
constructor();
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=postgres-meter-scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-scheduler.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAM3C,OAAO,EACL,KAAK,mCAAmC,EAGxC,KAAK,2BAA2B,EAKjC,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EAAE,iCAAiC,EAAE,MAAM,sCAAsC,CAAC;AACzF,OAAO,EACL,wCAAwC,EACxC,KAAK,mCAAmC,EACxC,KAAK,gCAAgC,EACrC,KAAK,2BAA2B,GACjC,MAAM,qCAAqC,CAAC;AAE7C,eAAO,MAAM,gCAAgC,2CAA2C,CAAC;AACzF,eAAO,MAAM,mCAAmC,QAAiB,CAAC;AAClE,eAAO,MAAM,6CAA6C,MAAM,CAAC;AACjE,eAAO,MAAM,4CAA4C,QAAS,CAAC;AACnE,eAAO,MAAM,uCAAuC,OAAQ,CAAC;AAC7D,eAAO,MAAM,wCAAwC,QAAiB,CAAC;AAEvE,MAAM,WAAW,+BAA+B;IAC9C,eAAe,CACb,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAA;KAAE,CAAC,CAAC;IACxD,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,oCAAoC;IACnD,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,4FAA4F;IAC5F,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,mGAAmG;IACnG,QAAQ,CAAC,UAAU,CAAC,EAAE,+BAA+B,CAAC;CACvD;AAED,MAAM,MAAM,gCAAgC,GACxC,mCAAmC,GACnC;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAOzE;;;;GAIG;AACH,qBAAa,6BAA6B;;gBAc5B,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,oCAAoC;IA8BrE,+FAA+F;IAC/F,KAAK,IAAI,IAAI;IAMb,mGAAmG;IAC7F,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,mFAAmF;IACnF,MAAM,IAAI,OAAO,CAAC,gCAAgC,CAAC;CA8JpD;AA0BD,qBAAa,sCAAuC,SAAQ,KAAK;;CAKhE"}
|