@noodleseed/one 0.45.0 → 0.47.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/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 +14 -3
- 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 +16 -8
- package/dist/deploy.js.map +1 -1
- package/dist/saas-scaffold-template.js +1 -1
- package/dist/saas-scaffold-template.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/dist/widget-scaffold-template.d.ts.map +1 -1
- package/dist/widget-scaffold-template.js +4 -2
- package/dist/widget-scaffold-template.js.map +1 -1
- 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 +6 -4
- 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/assistant.d.ts +9 -0
- package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/assistant.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +7 -0
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +2 -0
- package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +10 -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 +6 -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 +4 -0
- package/node_modules/@noodle-borg/compiler/dist/compile.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +52 -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 +17 -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 +1 -0
- package/node_modules/@noodle-borg/protocol/dist/mapping.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.js +18 -0
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts +3 -0
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js +12 -3
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/assistant-interactive.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/assistant-interactive.js +7 -3
- package/node_modules/@noodle-borg/service/dist/assistant-interactive.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/assistant-presentation.d.ts +11 -0
- package/node_modules/@noodle-borg/service/dist/assistant-presentation.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/assistant-presentation.js +67 -3
- package/node_modules/@noodle-borg/service/dist/assistant-presentation.js.map +1 -1
- 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 +2 -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 +1 -1
- 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-interaction-stream.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-stream.js +2 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-stream.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js +6 -2
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.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.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +3 -1
- 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/node_modules/@noodle-borg/wire-contracts/dist/assistant.d.ts +3 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/assistant.d.ts.map +1 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/assistant.js +3 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/assistant.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { readBillingMeterTransactionTime } from './postgres-meter-clock.js';
|
|
3
|
+
import { BILLING_METER_CLEAN_WINDOW_RECONCILIATION_INTERVAL_MS, BILLING_METER_FAILED_WINDOW_RECONCILIATION_DELAY_MS, BILLING_METER_INTEGRITY_MODULUS, billingMeterWindowLockKey, } from './postgres-meter-window-lock.js';
|
|
4
|
+
import { validateScalarId } from './postgres-records.js';
|
|
5
|
+
import { normalizeBillingUsageInstant } from './usage-window.js';
|
|
6
|
+
/** The session cannot be returned to a pool because advisory-lock ownership is uncertain. */
|
|
7
|
+
export class BillingMeterConnectionUnsafeError extends Error {
|
|
8
|
+
constructor(cause) {
|
|
9
|
+
super('billing meter database session cannot be reused', { cause });
|
|
10
|
+
this.name = 'BillingMeterConnectionUnsafeError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function reconcileBillingMeterWindow(pool, input) {
|
|
14
|
+
const client = await pool.connect();
|
|
15
|
+
let reusable = true;
|
|
16
|
+
try {
|
|
17
|
+
return await reconcileBillingMeterWindowOnClient(client, input);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
if (error instanceof BillingMeterConnectionUnsafeError)
|
|
21
|
+
reusable = false;
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
client.release(reusable ? undefined : true);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Open checks remain lock-free for writers; only a due final seal owns the exclusive window lock. */
|
|
29
|
+
export async function reconcileBillingMeterWindowOnClient(client, input) {
|
|
30
|
+
const identity = normalizeIdentity(input);
|
|
31
|
+
const runId = `bmrr_${randomUUID()}`;
|
|
32
|
+
const windowLockKey = billingMeterWindowLockKey(identity);
|
|
33
|
+
const preflight = await readPreflight(client, identity);
|
|
34
|
+
const finalLockRequired = isFinalDue(preflight, identity.windowEnd, preflight.checkedAt);
|
|
35
|
+
let windowLockHeld = false;
|
|
36
|
+
let reconciliationResult;
|
|
37
|
+
let reconciliationError;
|
|
38
|
+
try {
|
|
39
|
+
if (finalLockRequired) {
|
|
40
|
+
await client.query('SELECT pg_advisory_lock(hashtextextended($1, 0))', [windowLockKey]);
|
|
41
|
+
windowLockHeld = true;
|
|
42
|
+
}
|
|
43
|
+
await client.query('BEGIN ISOLATION LEVEL REPEATABLE READ');
|
|
44
|
+
const checkedAt = await readBillingMeterTransactionTime(client);
|
|
45
|
+
const meterWindow = await readWindowCheckpoint(client, identity);
|
|
46
|
+
if (meterWindow.sealed_at !== null) {
|
|
47
|
+
throw new Error('billing meter reconciliation window is sealed');
|
|
48
|
+
}
|
|
49
|
+
if (meterWindow.first_observed_at === null) {
|
|
50
|
+
throw new Error('billing meter reconciliation requires a validation window');
|
|
51
|
+
}
|
|
52
|
+
const receipts = [
|
|
53
|
+
safeCount(meterWindow.receipt_included_calls),
|
|
54
|
+
safeCount(meterWindow.receipt_overage_calls),
|
|
55
|
+
safeCount(meterWindow.receipt_denied_calls),
|
|
56
|
+
];
|
|
57
|
+
const accounts = await readCounterCheckpoint(client, 'account', identity);
|
|
58
|
+
const organizations = await readCounterCheckpoint(client, 'organization', identity);
|
|
59
|
+
const accountMismatchDetected = !checkpointMatches(receipts, meterWindow.account_integrity_a, meterWindow.account_integrity_b, accounts);
|
|
60
|
+
const orgMismatchDetected = !checkpointMatches(receipts, meterWindow.org_integrity_a, meterWindow.org_integrity_b, organizations);
|
|
61
|
+
const status = !accountMismatchDetected && !orgMismatchDetected ? 'succeeded' : 'failed';
|
|
62
|
+
const epochRetiredAt = normalizeRetirement(meterWindow);
|
|
63
|
+
const sealBasis = deriveSealBasis({
|
|
64
|
+
status,
|
|
65
|
+
checkedAt,
|
|
66
|
+
windowEnd: identity.windowEnd,
|
|
67
|
+
epochRetiredAt,
|
|
68
|
+
windowLockHeld,
|
|
69
|
+
});
|
|
70
|
+
const sealed = sealBasis !== null;
|
|
71
|
+
const nextReconcileAt = sealed
|
|
72
|
+
? null
|
|
73
|
+
: addMilliseconds(checkedAt, status === 'succeeded'
|
|
74
|
+
? BILLING_METER_CLEAN_WINDOW_RECONCILIATION_INTERVAL_MS
|
|
75
|
+
: BILLING_METER_FAILED_WINDOW_RECONCILIATION_DELAY_MS);
|
|
76
|
+
await client.query(`INSERT INTO billing_meter_reconciliation_runs
|
|
77
|
+
(run_id, epoch_id, window_start, window_end, status, sealed, seal_basis,
|
|
78
|
+
epoch_retired_at,
|
|
79
|
+
receipt_included_calls, receipt_overage_calls, receipt_denied_calls,
|
|
80
|
+
account_included_calls, account_overage_calls, account_denied_calls,
|
|
81
|
+
org_included_calls, org_overage_calls, org_denied_calls,
|
|
82
|
+
account_integrity_mismatch, org_integrity_mismatch, checked_at, next_reconcile_at)
|
|
83
|
+
VALUES
|
|
84
|
+
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15,
|
|
85
|
+
$16, $17, $18, $19, $20, $21)`, [
|
|
86
|
+
runId,
|
|
87
|
+
identity.epochId,
|
|
88
|
+
identity.windowStart,
|
|
89
|
+
identity.windowEnd,
|
|
90
|
+
status,
|
|
91
|
+
sealed,
|
|
92
|
+
sealBasis,
|
|
93
|
+
sealBasis === 'epoch_retired' ? epochRetiredAt : null,
|
|
94
|
+
...receipts,
|
|
95
|
+
...accounts.counts,
|
|
96
|
+
...organizations.counts,
|
|
97
|
+
accountMismatchDetected,
|
|
98
|
+
orgMismatchDetected,
|
|
99
|
+
checkedAt,
|
|
100
|
+
nextReconcileAt,
|
|
101
|
+
]);
|
|
102
|
+
if (status === 'failed') {
|
|
103
|
+
const markedEpoch = await client.query(`UPDATE billing_meter_epochs
|
|
104
|
+
SET reconciliation_failed_at = least(
|
|
105
|
+
coalesce(reconciliation_failed_at, $2::timestamptz),
|
|
106
|
+
$2::timestamptz
|
|
107
|
+
)
|
|
108
|
+
WHERE id = $1`, [identity.epochId, checkedAt]);
|
|
109
|
+
if (markedEpoch.rowCount !== 1) {
|
|
110
|
+
throw new Error('billing meter reconciliation failure marker was not persisted');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (sealed) {
|
|
114
|
+
const sealedWindow = await client.query(`UPDATE billing_meter_windows
|
|
115
|
+
SET sealed_at = $4
|
|
116
|
+
WHERE epoch_id = $1 AND window_start = $2 AND window_end = $3
|
|
117
|
+
AND sealed_at IS NULL`, [identity.epochId, identity.windowStart, identity.windowEnd, checkedAt]);
|
|
118
|
+
if (sealedWindow.rowCount !== 1) {
|
|
119
|
+
throw new Error('billing meter reconciliation window seal was not persisted');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
await client.query('COMMIT');
|
|
123
|
+
reconciliationResult = {
|
|
124
|
+
runId,
|
|
125
|
+
status,
|
|
126
|
+
sealed,
|
|
127
|
+
sealBasis,
|
|
128
|
+
includedCalls: receipts[0],
|
|
129
|
+
overageCalls: receipts[1],
|
|
130
|
+
deniedCalls: receipts[2],
|
|
131
|
+
accountMismatchDetected,
|
|
132
|
+
orgMismatchDetected,
|
|
133
|
+
checkedAt,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
await rollbackQuietly(client);
|
|
138
|
+
reconciliationError = error;
|
|
139
|
+
}
|
|
140
|
+
if (windowLockHeld)
|
|
141
|
+
await releaseWindowLock(client, windowLockKey);
|
|
142
|
+
if (reconciliationError !== undefined)
|
|
143
|
+
throw reconciliationError;
|
|
144
|
+
if (reconciliationResult === undefined) {
|
|
145
|
+
throw new Error('billing meter reconciliation produced no result');
|
|
146
|
+
}
|
|
147
|
+
return reconciliationResult;
|
|
148
|
+
}
|
|
149
|
+
async function readPreflight(client, identity) {
|
|
150
|
+
const result = await client.query(`SELECT epoch.state, epoch.retired_at,
|
|
151
|
+
billing_meter_transaction_time() AS checked_at, meter_window.sealed_at
|
|
152
|
+
FROM billing_meter_epochs AS epoch
|
|
153
|
+
JOIN billing_meter_windows AS meter_window ON meter_window.epoch_id = epoch.id
|
|
154
|
+
WHERE epoch.id = $1 AND meter_window.window_start = $2 AND meter_window.window_end = $3`, [identity.epochId, identity.windowStart, identity.windowEnd]);
|
|
155
|
+
const row = result.rows[0];
|
|
156
|
+
if (row === undefined)
|
|
157
|
+
throw new Error('billing meter reconciliation requires a validation window');
|
|
158
|
+
if (row.state !== 'prepared' && row.state !== 'retired') {
|
|
159
|
+
throw new Error('billing meter reconciliation requires a prepared or retired epoch');
|
|
160
|
+
}
|
|
161
|
+
if (row.sealed_at !== null)
|
|
162
|
+
throw new Error('billing meter reconciliation window is sealed');
|
|
163
|
+
return {
|
|
164
|
+
state: row.state,
|
|
165
|
+
retiredAt: row.retired_at === null
|
|
166
|
+
? null
|
|
167
|
+
: normalizeBillingUsageInstant('billing meter epoch retirement', row.retired_at instanceof Date ? row.retired_at.toISOString() : row.retired_at),
|
|
168
|
+
checkedAt: normalizeBillingUsageInstant('billing meter reconciliation preflight', row.checked_at instanceof Date ? row.checked_at.toISOString() : row.checked_at),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
async function readWindowCheckpoint(client, identity) {
|
|
172
|
+
const result = await client.query(`SELECT epoch.state, epoch.retired_at, meter_window.sealed_at,
|
|
173
|
+
meter_window.first_observed_at,
|
|
174
|
+
meter_window.receipt_included_calls::text,
|
|
175
|
+
meter_window.receipt_overage_calls::text,
|
|
176
|
+
meter_window.receipt_denied_calls::text,
|
|
177
|
+
meter_window.account_integrity_a::text,
|
|
178
|
+
meter_window.account_integrity_b::text,
|
|
179
|
+
meter_window.org_integrity_a::text,
|
|
180
|
+
meter_window.org_integrity_b::text
|
|
181
|
+
FROM billing_meter_epochs AS epoch
|
|
182
|
+
JOIN billing_meter_windows AS meter_window ON meter_window.epoch_id = epoch.id
|
|
183
|
+
WHERE epoch.id = $1 AND meter_window.window_start = $2 AND meter_window.window_end = $3`, [identity.epochId, identity.windowStart, identity.windowEnd]);
|
|
184
|
+
const row = result.rows[0];
|
|
185
|
+
if (row === undefined)
|
|
186
|
+
throw new Error('billing meter reconciliation requires a validation window');
|
|
187
|
+
if (row.state !== 'prepared' && row.state !== 'retired') {
|
|
188
|
+
throw new Error('billing meter reconciliation requires a prepared or retired epoch');
|
|
189
|
+
}
|
|
190
|
+
return row;
|
|
191
|
+
}
|
|
192
|
+
async function readCounterCheckpoint(client, scope, identity) {
|
|
193
|
+
const organization = scope === 'organization';
|
|
194
|
+
const table = organization ? 'billing_meter_org_windows' : 'billing_meter_account_windows';
|
|
195
|
+
const orgExpression = organization ? 'counter.org_slug' : "''";
|
|
196
|
+
const result = await client.query(`SELECT coalesce(sum(counter.included_calls), 0)::text AS included,
|
|
197
|
+
coalesce(sum(counter.overage_calls), 0)::text AS overage,
|
|
198
|
+
coalesce(sum(counter.denied_calls), 0)::text AS denied,
|
|
199
|
+
mod(coalesce(sum(
|
|
200
|
+
counter.included_calls::numeric * billing_meter_integrity_lane(
|
|
201
|
+
$4, counter.billing_account_id, ${orgExpression}, 'included', 1
|
|
202
|
+
) +
|
|
203
|
+
counter.overage_calls::numeric * billing_meter_integrity_lane(
|
|
204
|
+
$4, counter.billing_account_id, ${orgExpression}, 'overage', 1
|
|
205
|
+
) +
|
|
206
|
+
counter.denied_calls::numeric * billing_meter_integrity_lane(
|
|
207
|
+
$4, counter.billing_account_id, ${orgExpression}, 'denied', 1
|
|
208
|
+
)
|
|
209
|
+
), 0), ${BILLING_METER_INTEGRITY_MODULUS})::numeric(19, 0)::text AS integrity_a,
|
|
210
|
+
mod(coalesce(sum(
|
|
211
|
+
counter.included_calls::numeric * billing_meter_integrity_lane(
|
|
212
|
+
$4, counter.billing_account_id, ${orgExpression}, 'included', 2
|
|
213
|
+
) +
|
|
214
|
+
counter.overage_calls::numeric * billing_meter_integrity_lane(
|
|
215
|
+
$4, counter.billing_account_id, ${orgExpression}, 'overage', 2
|
|
216
|
+
) +
|
|
217
|
+
counter.denied_calls::numeric * billing_meter_integrity_lane(
|
|
218
|
+
$4, counter.billing_account_id, ${orgExpression}, 'denied', 2
|
|
219
|
+
)
|
|
220
|
+
), 0), ${BILLING_METER_INTEGRITY_MODULUS})::numeric(19, 0)::text AS integrity_b
|
|
221
|
+
FROM ${table} AS counter
|
|
222
|
+
WHERE counter.epoch_id = $1 AND counter.window_start = $2 AND counter.window_end = $3`, [identity.epochId, identity.windowStart, identity.windowEnd, scope]);
|
|
223
|
+
const row = result.rows[0];
|
|
224
|
+
if (row === undefined)
|
|
225
|
+
throw new Error('billing meter counter checkpoint returned no result');
|
|
226
|
+
return {
|
|
227
|
+
counts: [safeCount(row.included), safeCount(row.overage), safeCount(row.denied)],
|
|
228
|
+
integrityA: normalizeIntegrity(row.integrity_a),
|
|
229
|
+
integrityB: normalizeIntegrity(row.integrity_b),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function checkpointMatches(receiptCounts, receiptIntegrityA, receiptIntegrityB, counter) {
|
|
233
|
+
return (receiptCounts.every((value, index) => value === counter.counts[index]) &&
|
|
234
|
+
normalizeIntegrity(receiptIntegrityA) === counter.integrityA &&
|
|
235
|
+
normalizeIntegrity(receiptIntegrityB) === counter.integrityB);
|
|
236
|
+
}
|
|
237
|
+
function deriveSealBasis(input) {
|
|
238
|
+
if (input.status !== 'succeeded' || !input.windowLockHeld)
|
|
239
|
+
return null;
|
|
240
|
+
if (input.epochRetiredAt !== null &&
|
|
241
|
+
Date.parse(input.checkedAt) >= Date.parse(input.epochRetiredAt)) {
|
|
242
|
+
return 'epoch_retired';
|
|
243
|
+
}
|
|
244
|
+
return Date.parse(input.checkedAt) >= Date.parse(input.windowEnd) ? 'window_end' : null;
|
|
245
|
+
}
|
|
246
|
+
function normalizeRetirement(row) {
|
|
247
|
+
if (row.state !== 'retired' || row.retired_at === null)
|
|
248
|
+
return null;
|
|
249
|
+
return normalizeBillingUsageInstant('billing meter epoch retirement', row.retired_at instanceof Date ? row.retired_at.toISOString() : row.retired_at);
|
|
250
|
+
}
|
|
251
|
+
function isFinalDue(epoch, windowEnd, checkedAt) {
|
|
252
|
+
return (Date.parse(checkedAt) >= Date.parse(windowEnd) ||
|
|
253
|
+
(epoch.state === 'retired' &&
|
|
254
|
+
epoch.retiredAt !== null &&
|
|
255
|
+
Date.parse(checkedAt) >= Date.parse(epoch.retiredAt)));
|
|
256
|
+
}
|
|
257
|
+
function normalizeIdentity(input) {
|
|
258
|
+
const identity = {
|
|
259
|
+
epochId: validateScalarId('billing meter epoch id', input.epochId),
|
|
260
|
+
windowStart: normalizeBillingUsageInstant('billing meter window start', input.windowStart),
|
|
261
|
+
windowEnd: normalizeBillingUsageInstant('billing meter window end', input.windowEnd),
|
|
262
|
+
};
|
|
263
|
+
if (Date.parse(identity.windowEnd) <= Date.parse(identity.windowStart)) {
|
|
264
|
+
throw new Error('billing meter reconciliation window is invalid');
|
|
265
|
+
}
|
|
266
|
+
return identity;
|
|
267
|
+
}
|
|
268
|
+
function addMilliseconds(value, milliseconds) {
|
|
269
|
+
return new Date(Date.parse(value) + milliseconds).toISOString();
|
|
270
|
+
}
|
|
271
|
+
function normalizeIntegrity(value) {
|
|
272
|
+
const normalized = BigInt(value);
|
|
273
|
+
if (normalized < 0n || normalized >= BigInt(BILLING_METER_INTEGRITY_MODULUS)) {
|
|
274
|
+
throw new Error('billing meter integrity checkpoint is invalid');
|
|
275
|
+
}
|
|
276
|
+
return normalized.toString();
|
|
277
|
+
}
|
|
278
|
+
function safeCount(value) {
|
|
279
|
+
const count = Number(value);
|
|
280
|
+
if (!Number.isSafeInteger(count) || count < 0) {
|
|
281
|
+
throw new Error('billing meter count exceeds the supported safe integer range');
|
|
282
|
+
}
|
|
283
|
+
return count;
|
|
284
|
+
}
|
|
285
|
+
async function releaseWindowLock(client, windowLockKey) {
|
|
286
|
+
try {
|
|
287
|
+
const unlocked = await client.query('SELECT pg_advisory_unlock(hashtextextended($1, 0)) AS unlocked', [windowLockKey]);
|
|
288
|
+
if (unlocked.rows[0]?.unlocked !== true) {
|
|
289
|
+
throw new Error('billing meter window lock ownership was not confirmed');
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
throw new BillingMeterConnectionUnsafeError(error);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async function rollbackQuietly(client) {
|
|
297
|
+
try {
|
|
298
|
+
await client.query('ROLLBACK');
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
// Preserve the original reconciliation failure.
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=postgres-meter-reconciliation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-reconciliation.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-reconciliation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PoolClient } from 'pg';
|
|
2
|
+
export interface BillingMeterReceiptRetirementResult {
|
|
3
|
+
readonly partitionsDropped: number;
|
|
4
|
+
readonly receiptsDeleted: number;
|
|
5
|
+
}
|
|
6
|
+
export interface BillingMeterExpiredRowRetirementResult {
|
|
7
|
+
readonly tombstonesDeleted: number;
|
|
8
|
+
readonly accountWindowsDeleted: number;
|
|
9
|
+
readonly orgWindowsDeleted: number;
|
|
10
|
+
readonly meterWindowsDeleted: number;
|
|
11
|
+
}
|
|
12
|
+
export interface BillingMeterRetentionBatchLimits {
|
|
13
|
+
readonly batchSize: number;
|
|
14
|
+
readonly maxBatchesPerTarget: number;
|
|
15
|
+
}
|
|
16
|
+
export declare const DEFAULT_BILLING_METER_RETENTION_BATCH_LIMITS: Readonly<{
|
|
17
|
+
batchSize: 25000;
|
|
18
|
+
maxBatchesPerTarget: 40;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function retireExpiredBillingMeterReceipts(client: PoolClient, decisionAt: string, limits?: BillingMeterRetentionBatchLimits): Promise<BillingMeterReceiptRetirementResult>;
|
|
21
|
+
export declare function retireExpiredBillingMeterRows(client: PoolClient, decisionAt: string, limits?: BillingMeterRetentionBatchLimits): Promise<BillingMeterExpiredRowRetirementResult>;
|
|
22
|
+
//# sourceMappingURL=postgres-meter-retention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-retention.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-retention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAIrC,MAAM,WAAW,mCAAmC;IAClD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,sCAAsC;IACrD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,eAAO,MAAM,4CAA4C;;;EAGZ,CAAC;AAgB9C,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,gCAA+E,GACtF,OAAO,CAAC,mCAAmC,CAAC,CAuF9C;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,gCAA+E,GACtF,OAAO,CAAC,sCAAsC,CAAC,CA+BjD"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { BILLING_METER_RECEIPT_RETENTION_DAYS } from './meter-readiness.js';
|
|
2
|
+
import { parseBillingMeterPartitionRange } from './postgres-meter-partition.js';
|
|
3
|
+
export const DEFAULT_BILLING_METER_RETENTION_BATCH_LIMITS = Object.freeze({
|
|
4
|
+
batchSize: 25_000,
|
|
5
|
+
maxBatchesPerTarget: 40,
|
|
6
|
+
});
|
|
7
|
+
const PARTITION_DROP_LOCK_TIMEOUT = '100ms';
|
|
8
|
+
const PARTITION_DROP_STATEMENT_TIMEOUT = '5s';
|
|
9
|
+
export async function retireExpiredBillingMeterReceipts(client, decisionAt, limits = DEFAULT_BILLING_METER_RETENTION_BATCH_LIMITS) {
|
|
10
|
+
const bounded = validateBatchLimits(limits);
|
|
11
|
+
await client.query(`SELECT set_config('noodle.billing_meter_receipt_maintenance', 'on', true)`);
|
|
12
|
+
const decisionTime = Date.parse(decisionAt);
|
|
13
|
+
if (!Number.isFinite(decisionTime)) {
|
|
14
|
+
throw new Error('billing meter receipt retirement decision is invalid');
|
|
15
|
+
}
|
|
16
|
+
const partitions = await client.query(`
|
|
17
|
+
SELECT child.relname AS name,
|
|
18
|
+
format('%I.%I', namespace.nspname, child.relname) AS relation,
|
|
19
|
+
pg_get_expr(child.relpartbound, child.oid) AS bound
|
|
20
|
+
FROM pg_inherits
|
|
21
|
+
JOIN pg_class AS parent ON parent.oid = pg_inherits.inhparent
|
|
22
|
+
JOIN pg_class AS child ON child.oid = pg_inherits.inhrelid
|
|
23
|
+
JOIN pg_namespace AS namespace ON namespace.oid = child.relnamespace
|
|
24
|
+
WHERE parent.oid = 'billing_meter_usage_events'::regclass
|
|
25
|
+
ORDER BY namespace.nspname, child.relname
|
|
26
|
+
`);
|
|
27
|
+
for (const partition of partitions.rows) {
|
|
28
|
+
validatePartition(partition);
|
|
29
|
+
}
|
|
30
|
+
let receiptsDeleted = 0;
|
|
31
|
+
let receiptBatches = 0;
|
|
32
|
+
const dropCandidates = [];
|
|
33
|
+
for (const partition of partitions.rows) {
|
|
34
|
+
const range = parseBillingMeterPartitionRange(partition.bound);
|
|
35
|
+
if (range === undefined)
|
|
36
|
+
throw new Error('billing meter receipt partition bound is invalid');
|
|
37
|
+
if (Date.parse(range.start) > decisionTime)
|
|
38
|
+
continue;
|
|
39
|
+
const oldPartition = Date.parse(range.end) <= decisionTime;
|
|
40
|
+
if (oldPartition && (await partitionIsFullyRetirable(client, range, decisionAt))) {
|
|
41
|
+
dropCandidates.push(partition);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
while (receiptBatches < bounded.maxBatchesPerTarget) {
|
|
45
|
+
const deleted = await client.query(`WITH candidates AS MATERIALIZED (
|
|
46
|
+
SELECT receipt.ctid
|
|
47
|
+
FROM ${partition.relation} AS receipt
|
|
48
|
+
WHERE receipt.retention_until <= $1
|
|
49
|
+
AND EXISTS (
|
|
50
|
+
SELECT 1
|
|
51
|
+
FROM billing_meter_reconciliation_runs AS reconciliation
|
|
52
|
+
WHERE reconciliation.epoch_id = receipt.epoch_id
|
|
53
|
+
AND reconciliation.window_start = receipt.window_start
|
|
54
|
+
AND reconciliation.window_end = receipt.window_end
|
|
55
|
+
AND reconciliation.sealed
|
|
56
|
+
AND reconciliation.status = 'succeeded'
|
|
57
|
+
AND NOT reconciliation.account_integrity_mismatch
|
|
58
|
+
AND NOT reconciliation.org_integrity_mismatch
|
|
59
|
+
AND (
|
|
60
|
+
(
|
|
61
|
+
reconciliation.seal_basis = 'window_end' AND
|
|
62
|
+
reconciliation.checked_at >= receipt.window_end
|
|
63
|
+
) OR (
|
|
64
|
+
reconciliation.seal_basis = 'epoch_retired' AND
|
|
65
|
+
reconciliation.epoch_retired_at IS NOT NULL AND
|
|
66
|
+
reconciliation.checked_at >= reconciliation.epoch_retired_at
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
ORDER BY receipt.retention_until, receipt.ctid
|
|
71
|
+
LIMIT $2
|
|
72
|
+
FOR UPDATE OF receipt SKIP LOCKED
|
|
73
|
+
)
|
|
74
|
+
DELETE FROM ${partition.relation} AS receipt
|
|
75
|
+
USING candidates
|
|
76
|
+
WHERE receipt.ctid = candidates.ctid`, [decisionAt, bounded.batchSize]);
|
|
77
|
+
const rowCount = safeRowCount(deleted.rowCount);
|
|
78
|
+
receiptsDeleted += rowCount;
|
|
79
|
+
receiptBatches += 1;
|
|
80
|
+
if (rowCount < bounded.batchSize)
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
if (oldPartition && (await partitionIsFullyRetirable(client, range, decisionAt))) {
|
|
84
|
+
dropCandidates.push(partition);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
let partitionsDropped = 0;
|
|
88
|
+
for (const partition of dropCandidates) {
|
|
89
|
+
if (await dropEmptyOldPartition(client, partition, decisionAt)) {
|
|
90
|
+
partitionsDropped += 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { partitionsDropped, receiptsDeleted };
|
|
94
|
+
}
|
|
95
|
+
export async function retireExpiredBillingMeterRows(client, decisionAt, limits = DEFAULT_BILLING_METER_RETENTION_BATCH_LIMITS) {
|
|
96
|
+
const bounded = validateBatchLimits(limits);
|
|
97
|
+
const tombstonesDeleted = await deleteExpiredRowsInBatches(client, 'billing_meter_exact_key_tombstones', decisionAt, bounded);
|
|
98
|
+
const accountWindowsDeleted = await deleteExpiredRowsInBatches(client, 'billing_meter_account_windows', decisionAt, bounded);
|
|
99
|
+
const orgWindowsDeleted = await deleteExpiredRowsInBatches(client, 'billing_meter_org_windows', decisionAt, bounded);
|
|
100
|
+
return {
|
|
101
|
+
tombstonesDeleted,
|
|
102
|
+
accountWindowsDeleted,
|
|
103
|
+
orgWindowsDeleted,
|
|
104
|
+
meterWindowsDeleted: await deleteExpiredRowsInBatches(client, 'billing_meter_windows', decisionAt, bounded),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
async function deleteExpiredRowsInBatches(client, table, decisionAt, limits) {
|
|
108
|
+
let deleted = 0;
|
|
109
|
+
for (let batch = 0; batch < limits.maxBatchesPerTarget; batch += 1) {
|
|
110
|
+
const result = await client.query(`WITH candidates AS MATERIALIZED (
|
|
111
|
+
SELECT target.ctid
|
|
112
|
+
FROM ${table} AS target
|
|
113
|
+
WHERE target.retention_until <= $1
|
|
114
|
+
${table === 'billing_meter_windows'
|
|
115
|
+
? `AND target.sealed_at IS NOT NULL
|
|
116
|
+
AND NOT EXISTS (
|
|
117
|
+
SELECT 1 FROM billing_meter_usage_events AS receipt
|
|
118
|
+
WHERE receipt.epoch_id = target.epoch_id
|
|
119
|
+
AND receipt.window_start = target.window_start
|
|
120
|
+
AND receipt.window_end = target.window_end
|
|
121
|
+
)`
|
|
122
|
+
: ''}
|
|
123
|
+
ORDER BY target.retention_until, target.ctid
|
|
124
|
+
LIMIT $2
|
|
125
|
+
FOR UPDATE OF target SKIP LOCKED
|
|
126
|
+
)
|
|
127
|
+
DELETE FROM ${table} AS target
|
|
128
|
+
USING candidates
|
|
129
|
+
WHERE target.ctid = candidates.ctid`, [decisionAt, limits.batchSize]);
|
|
130
|
+
const rowCount = safeRowCount(result.rowCount);
|
|
131
|
+
deleted += rowCount;
|
|
132
|
+
if (rowCount < limits.batchSize)
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
return deleted;
|
|
136
|
+
}
|
|
137
|
+
async function dropEmptyOldPartition(client, partition, decisionAt) {
|
|
138
|
+
const prior = await client.query(`SELECT current_setting('lock_timeout') AS lock_timeout,
|
|
139
|
+
current_setting('statement_timeout') AS statement_timeout`);
|
|
140
|
+
const timeouts = prior.rows[0];
|
|
141
|
+
if (timeouts === undefined)
|
|
142
|
+
throw new Error('billing meter timeout settings are unavailable');
|
|
143
|
+
await client.query('SAVEPOINT billing_meter_partition_drop');
|
|
144
|
+
try {
|
|
145
|
+
await client.query(`SELECT set_config('lock_timeout', $1, true),
|
|
146
|
+
set_config('statement_timeout', $2, true)`, [PARTITION_DROP_LOCK_TIMEOUT, PARTITION_DROP_STATEMENT_TIMEOUT]);
|
|
147
|
+
await client.query(`LOCK TABLE ${partition.relation} IN ACCESS EXCLUSIVE MODE NOWAIT`);
|
|
148
|
+
const attached = await client.query(`SELECT pg_get_expr(child.relpartbound, child.oid) AS bound
|
|
149
|
+
FROM pg_inherits
|
|
150
|
+
JOIN pg_class AS parent ON parent.oid = pg_inherits.inhparent
|
|
151
|
+
JOIN pg_class AS child ON child.oid = pg_inherits.inhrelid
|
|
152
|
+
WHERE parent.oid = 'billing_meter_usage_events'::regclass
|
|
153
|
+
AND child.oid = $1::regclass`, [partition.relation]);
|
|
154
|
+
const range = parseBillingMeterPartitionRange(attached.rows[0]?.bound ?? '');
|
|
155
|
+
if (range === undefined ||
|
|
156
|
+
Date.parse(range.end) > Date.parse(decisionAt) ||
|
|
157
|
+
!(await partitionIsFullyRetirable(client, range, decisionAt))) {
|
|
158
|
+
await client.query('ROLLBACK TO SAVEPOINT billing_meter_partition_drop');
|
|
159
|
+
await client.query('RELEASE SAVEPOINT billing_meter_partition_drop');
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
await client.query(`DROP TABLE ${partition.relation}`);
|
|
163
|
+
await client.query('RELEASE SAVEPOINT billing_meter_partition_drop');
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
await client.query('ROLLBACK TO SAVEPOINT billing_meter_partition_drop');
|
|
167
|
+
await client.query('RELEASE SAVEPOINT billing_meter_partition_drop');
|
|
168
|
+
if (isBoundedLockFailure(error))
|
|
169
|
+
return false;
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
await client.query(`SELECT set_config('lock_timeout', $1, true),
|
|
173
|
+
set_config('statement_timeout', $2, true)`, [timeouts.lock_timeout, timeouts.statement_timeout]);
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
async function partitionIsFullyRetirable(client, range, decisionAt) {
|
|
177
|
+
const registryTable = await client.query(`SELECT to_regclass('billing_meter_windows') IS NOT NULL AS present`);
|
|
178
|
+
if (registryTable.rows[0]?.present !== true)
|
|
179
|
+
return false;
|
|
180
|
+
const registry = await client.query(`SELECT NOT EXISTS (
|
|
181
|
+
SELECT 1
|
|
182
|
+
FROM billing_meter_windows
|
|
183
|
+
WHERE first_observed_at < $2
|
|
184
|
+
AND last_observed_at >= $1
|
|
185
|
+
AND (
|
|
186
|
+
sealed_at IS NULL OR
|
|
187
|
+
window_end + interval '${BILLING_METER_RECEIPT_RETENTION_DAYS} days' > $3
|
|
188
|
+
)
|
|
189
|
+
) AS all_receipts_sealed`, [range.start, range.end, decisionAt]);
|
|
190
|
+
return registry.rows[0]?.all_receipts_sealed === true;
|
|
191
|
+
}
|
|
192
|
+
function validatePartition(partition) {
|
|
193
|
+
if (!/^billing_meter_usage_events_y\d{4}m\d{2}$/.test(partition.name)) {
|
|
194
|
+
throw new Error('billing meter receipt partition has an invalid name');
|
|
195
|
+
}
|
|
196
|
+
if (parseBillingMeterPartitionRange(partition.bound) === undefined) {
|
|
197
|
+
throw new Error('billing meter receipt partition bound is invalid');
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function safeRowCount(value) {
|
|
201
|
+
if (value === null || !Number.isSafeInteger(value) || value < 0) {
|
|
202
|
+
throw new Error('billing meter maintenance returned an invalid row count');
|
|
203
|
+
}
|
|
204
|
+
return value;
|
|
205
|
+
}
|
|
206
|
+
function isBoundedLockFailure(error) {
|
|
207
|
+
if (typeof error !== 'object' || error === null || !('code' in error))
|
|
208
|
+
return false;
|
|
209
|
+
return error.code === '55P03' || error.code === '57014';
|
|
210
|
+
}
|
|
211
|
+
function validateBatchLimits(limits) {
|
|
212
|
+
if (!Number.isSafeInteger(limits.batchSize) ||
|
|
213
|
+
limits.batchSize < 1 ||
|
|
214
|
+
limits.batchSize > 100_000) {
|
|
215
|
+
throw new Error('billing meter retention batch size is invalid');
|
|
216
|
+
}
|
|
217
|
+
if (!Number.isSafeInteger(limits.maxBatchesPerTarget) ||
|
|
218
|
+
limits.maxBatchesPerTarget < 1 ||
|
|
219
|
+
limits.maxBatchesPerTarget > 100) {
|
|
220
|
+
throw new Error('billing meter retention batch count is invalid');
|
|
221
|
+
}
|
|
222
|
+
return limits;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=postgres-meter-retention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-retention.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-retention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Logger } from '@noodle-borg/transport-http';
|
|
2
|
+
import type { Pool } from 'pg';
|
|
3
|
+
import type { BillingMeterReadinessStore } from './meter-readiness.js';
|
|
4
|
+
import { type BillingMeterLiveRuntimeExpectation } from './meter-readiness-health.js';
|
|
5
|
+
import type { BillingMeterValidationRuntimeConfig } from './meter-runtime-config.js';
|
|
6
|
+
import { type BillingMeterValidationEpochStore } from './meter-validation-epoch.js';
|
|
7
|
+
import { type BillingMeterSchedulerOperations } from './postgres-meter-scheduler.js';
|
|
8
|
+
import type { BillingUsageObserver } from './usage-observer.js';
|
|
9
|
+
import type { BillingUsageStore } from './usage-store.js';
|
|
10
|
+
export interface PostgresBillingMeterRuntime {
|
|
11
|
+
readonly readinessStore: BillingMeterReadinessStore;
|
|
12
|
+
readonly validationEpochStore: BillingMeterValidationEpochStore;
|
|
13
|
+
readonly observer?: BillingUsageObserver;
|
|
14
|
+
start(): void;
|
|
15
|
+
stop(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function createPostgresBillingMeterRuntime(input: {
|
|
18
|
+
readonly pool: Pool;
|
|
19
|
+
readonly usageStore: BillingUsageStore;
|
|
20
|
+
readonly billingUsageHmacKey?: string;
|
|
21
|
+
readonly releaseSha: string;
|
|
22
|
+
readonly validation?: BillingMeterValidationRuntimeConfig;
|
|
23
|
+
/** Test-only orchestration seam; production always uses the durable scheduler operations. */
|
|
24
|
+
readonly schedulerOperations?: BillingMeterSchedulerOperations;
|
|
25
|
+
readonly clock?: () => Date;
|
|
26
|
+
readonly logger: Logger;
|
|
27
|
+
}): Promise<PostgresBillingMeterRuntime>;
|
|
28
|
+
export declare function resolvePostgresBillingMeterRuntimeExpectation(input: {
|
|
29
|
+
readonly billingUsageHmacKey?: string;
|
|
30
|
+
readonly releaseSha: string;
|
|
31
|
+
readonly validation?: BillingMeterValidationRuntimeConfig;
|
|
32
|
+
}): BillingMeterLiveRuntimeExpectation | undefined;
|
|
33
|
+
//# sourceMappingURL=postgres-meter-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-runtime.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAM/B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAKvE,OAAO,EAEL,KAAK,kCAAkC,EACxC,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAEL,KAAK,gCAAgC,EACtC,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAEL,KAAK,+BAA+B,EAGrC,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,cAAc,EAAE,0BAA0B,CAAC;IACpD,QAAQ,CAAC,oBAAoB,EAAE,gCAAgC,CAAC;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IACzC,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,wBAAsB,iCAAiC,CAAC,KAAK,EAAE;IAC7D,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,mCAAmC,CAAC;IAC1D,6FAA6F;IAC7F,QAAQ,CAAC,mBAAmB,CAAC,EAAE,+BAA+B,CAAC;IAC/D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CA2DvC;AA0FD,wBAAgB,6CAA6C,CAAC,KAAK,EAAE;IACnE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,mCAAmC,CAAC;CAC3D,GAAG,kCAAkC,GAAG,SAAS,CAmBjD"}
|