@nxuss/lemma 1.43.0 → 1.45.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/README.md +26 -8
- package/bin/brain-ingest.js +48 -13
- package/bin/cloud.js +228 -0
- package/dist/cjs/cli/hostHooks.d.ts +44 -7
- package/dist/cjs/cli/hostHooks.d.ts.map +1 -1
- package/dist/cjs/cli/hostHooks.js +201 -11
- package/dist/cjs/cli/hostHooks.js.map +1 -1
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +13 -16
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/cloud/CloudBrainClient.d.ts +52 -0
- package/dist/cjs/cloud/CloudBrainClient.d.ts.map +1 -0
- package/dist/cjs/cloud/CloudBrainClient.js +161 -0
- package/dist/cjs/cloud/CloudBrainClient.js.map +1 -0
- package/dist/cjs/cloud/CloudConfig.d.ts +41 -0
- package/dist/cjs/cloud/CloudConfig.d.ts.map +1 -0
- package/dist/cjs/cloud/CloudConfig.js +133 -0
- package/dist/cjs/cloud/CloudConfig.js.map +1 -0
- package/dist/cjs/cloud/CloudEntitlement.d.ts +55 -0
- package/dist/cjs/cloud/CloudEntitlement.d.ts.map +1 -0
- package/dist/cjs/cloud/CloudEntitlement.js +174 -0
- package/dist/cjs/cloud/CloudEntitlement.js.map +1 -0
- package/dist/cjs/cloud/billing/stripeApi.d.ts +43 -0
- package/dist/cjs/cloud/billing/stripeApi.d.ts.map +1 -0
- package/dist/cjs/cloud/billing/stripeApi.js +116 -0
- package/dist/cjs/cloud/billing/stripeApi.js.map +1 -0
- package/dist/cjs/cloud/billing/stripeWebhook.d.ts +35 -0
- package/dist/cjs/cloud/billing/stripeWebhook.d.ts.map +1 -0
- package/dist/cjs/cloud/billing/stripeWebhook.js +190 -0
- package/dist/cjs/cloud/billing/stripeWebhook.js.map +1 -0
- package/dist/cjs/cloud/console/ConsoleStore.d.ts +111 -0
- package/dist/cjs/cloud/console/ConsoleStore.d.ts.map +1 -0
- package/dist/cjs/cloud/console/ConsoleStore.js +172 -0
- package/dist/cjs/cloud/console/ConsoleStore.js.map +1 -0
- package/dist/cjs/cloud/console/consoleRouter.d.ts +68 -0
- package/dist/cjs/cloud/console/consoleRouter.d.ts.map +1 -0
- package/dist/cjs/cloud/console/consoleRouter.js +301 -0
- package/dist/cjs/cloud/console/consoleRouter.js.map +1 -0
- package/dist/cjs/cloud/console/mailer.d.ts +22 -0
- package/dist/cjs/cloud/console/mailer.d.ts.map +1 -0
- package/dist/cjs/cloud/console/mailer.js +35 -0
- package/dist/cjs/cloud/console/mailer.js.map +1 -0
- package/dist/cjs/cloud/identity/PlanPolicy.d.ts +42 -6
- package/dist/cjs/cloud/identity/PlanPolicy.d.ts.map +1 -1
- package/dist/cjs/cloud/identity/PlanPolicy.js +102 -22
- package/dist/cjs/cloud/identity/PlanPolicy.js.map +1 -1
- package/dist/cjs/cloud/identity/RateLimiter.d.ts +21 -1
- package/dist/cjs/cloud/identity/RateLimiter.d.ts.map +1 -1
- package/dist/cjs/cloud/identity/RateLimiter.js +59 -2
- package/dist/cjs/cloud/identity/RateLimiter.js.map +1 -1
- package/dist/cjs/cloud/identity/TenantResolver.d.ts +6 -1
- package/dist/cjs/cloud/identity/TenantResolver.d.ts.map +1 -1
- package/dist/cjs/cloud/identity/TenantResolver.js +1 -1
- package/dist/cjs/cloud/identity/TenantResolver.js.map +1 -1
- package/dist/cjs/cloud/identity/authenticateV2.d.ts.map +1 -1
- package/dist/cjs/cloud/identity/authenticateV2.js +7 -4
- package/dist/cjs/cloud/identity/authenticateV2.js.map +1 -1
- package/dist/cjs/cloud/identity/identityStore.d.ts +96 -10
- package/dist/cjs/cloud/identity/identityStore.d.ts.map +1 -1
- package/dist/cjs/cloud/identity/identityStore.js +203 -4
- package/dist/cjs/cloud/identity/identityStore.js.map +1 -1
- package/dist/cjs/cloud/metering/PostgresLedgerStore.d.ts +18 -0
- package/dist/cjs/cloud/metering/PostgresLedgerStore.d.ts.map +1 -0
- package/dist/cjs/cloud/metering/PostgresLedgerStore.js +56 -0
- package/dist/cjs/cloud/metering/PostgresLedgerStore.js.map +1 -0
- package/dist/cjs/cloud/metering/UsageLedger.d.ts +74 -0
- package/dist/cjs/cloud/metering/UsageLedger.d.ts.map +1 -1
- package/dist/cjs/cloud/metering/UsageLedger.js +122 -17
- package/dist/cjs/cloud/metering/UsageLedger.js.map +1 -1
- package/dist/cjs/cloud/metering/index.d.ts +1 -0
- package/dist/cjs/cloud/metering/index.d.ts.map +1 -1
- package/dist/cjs/cloud/metering/index.js +1 -0
- package/dist/cjs/cloud/metering/index.js.map +1 -1
- package/dist/cjs/cloud/store/FileBrainStore.d.ts +6 -1
- package/dist/cjs/cloud/store/FileBrainStore.d.ts.map +1 -1
- package/dist/cjs/cloud/store/FileBrainStore.js +8 -0
- package/dist/cjs/cloud/store/FileBrainStore.js.map +1 -1
- package/dist/cjs/cloud/store/PostgresBrainStore.d.ts +11 -1
- package/dist/cjs/cloud/store/PostgresBrainStore.d.ts.map +1 -1
- package/dist/cjs/cloud/store/PostgresBrainStore.js +32 -0
- package/dist/cjs/cloud/store/PostgresBrainStore.js.map +1 -1
- package/dist/cjs/cloud/store/memorySummary.d.ts +29 -0
- package/dist/cjs/cloud/store/memorySummary.d.ts.map +1 -0
- package/dist/cjs/cloud/store/memorySummary.js +66 -0
- package/dist/cjs/cloud/store/memorySummary.js.map +1 -0
- package/dist/cjs/cloud/v2/app.d.ts.map +1 -1
- package/dist/cjs/cloud/v2/app.js +6 -0
- package/dist/cjs/cloud/v2/app.js.map +1 -1
- package/dist/cjs/cloud/v2/inputGuard.d.ts +23 -0
- package/dist/cjs/cloud/v2/inputGuard.d.ts.map +1 -0
- package/dist/cjs/cloud/v2/inputGuard.js +71 -0
- package/dist/cjs/cloud/v2/inputGuard.js.map +1 -0
- package/dist/cjs/cloud/v2/routes/admin.d.ts +24 -0
- package/dist/cjs/cloud/v2/routes/admin.d.ts.map +1 -0
- package/dist/cjs/cloud/v2/routes/admin.js +344 -0
- package/dist/cjs/cloud/v2/routes/admin.js.map +1 -0
- package/dist/cjs/cloud/v2/routes/entitlement.d.ts +13 -0
- package/dist/cjs/cloud/v2/routes/entitlement.d.ts.map +1 -0
- package/dist/cjs/cloud/v2/routes/entitlement.js +24 -0
- package/dist/cjs/cloud/v2/routes/entitlement.js.map +1 -0
- package/dist/cjs/cloud/v2/routes/index.d.ts +14 -1
- package/dist/cjs/cloud/v2/routes/index.d.ts.map +1 -1
- package/dist/cjs/cloud/v2/routes/index.js +36 -0
- package/dist/cjs/cloud/v2/routes/index.js.map +1 -1
- package/dist/cjs/cloud/v2/routes/memories.d.ts +21 -2
- package/dist/cjs/cloud/v2/routes/memories.d.ts.map +1 -1
- package/dist/cjs/cloud/v2/routes/memories.js +77 -0
- package/dist/cjs/cloud/v2/routes/memories.js.map +1 -1
- package/dist/cjs/cloud/v2/routes/recall.d.ts +1 -0
- package/dist/cjs/cloud/v2/routes/recall.d.ts.map +1 -1
- package/dist/cjs/cloud/v2/routes/recall.js +4 -0
- package/dist/cjs/cloud/v2/routes/recall.js.map +1 -1
- package/dist/cjs/cloud/v2/routes/tenant.d.ts +36 -0
- package/dist/cjs/cloud/v2/routes/tenant.d.ts.map +1 -0
- package/dist/cjs/cloud/v2/routes/tenant.js +65 -0
- package/dist/cjs/cloud/v2/routes/tenant.js.map +1 -0
- package/dist/cjs/cloud/v2/routes/usage.d.ts +1 -1
- package/dist/cjs/cloud/v2/routes/usage.d.ts.map +1 -1
- package/dist/cjs/cloud/v2/routes/verify.d.ts +1 -0
- package/dist/cjs/cloud/v2/routes/verify.d.ts.map +1 -1
- package/dist/cjs/cloud/v2/routes/verify.js +4 -0
- package/dist/cjs/cloud/v2/routes/verify.js.map +1 -1
- package/dist/cjs/cloud/v2/server.d.ts +9 -3
- package/dist/cjs/cloud/v2/server.d.ts.map +1 -1
- package/dist/cjs/cloud/v2/server.js +36 -2
- package/dist/cjs/cloud/v2/server.js.map +1 -1
- package/dist/cjs/cloud/v2/usageRecorder.d.ts +19 -0
- package/dist/cjs/cloud/v2/usageRecorder.d.ts.map +1 -0
- package/dist/cjs/cloud/v2/usageRecorder.js +42 -0
- package/dist/cjs/cloud/v2/usageRecorder.js.map +1 -0
- package/dist/cjs/contracts/api-v2.types.d.ts +92 -2
- package/dist/cjs/contracts/api-v2.types.d.ts.map +1 -1
- package/dist/cjs/contracts/store.d.ts +37 -0
- package/dist/cjs/contracts/store.d.ts.map +1 -1
- package/dist/cjs/mcp/index.js +7 -1
- package/dist/cjs/mcp/index.js.map +1 -1
- package/dist/cjs/mcp/tools/memory.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/memory.js +74 -4
- package/dist/cjs/mcp/tools/memory.js.map +1 -1
- package/dist/cjs/mcp/tools/misc.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/misc.js +2 -1
- package/dist/cjs/mcp/tools/misc.js.map +1 -1
- package/dist/cjs/mcp/tools/workspace.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/workspace.js +4 -1
- package/dist/cjs/mcp/tools/workspace.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts +10 -0
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +47 -12
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/proxy/KeyManager.d.ts.map +1 -1
- package/dist/cjs/proxy/KeyManager.js +5 -0
- package/dist/cjs/proxy/KeyManager.js.map +1 -1
- package/dist/cjs/subconscious/CloudBrain.d.ts +77 -0
- package/dist/cjs/subconscious/CloudBrain.d.ts.map +1 -0
- package/dist/cjs/subconscious/CloudBrain.js +347 -0
- package/dist/cjs/subconscious/CloudBrain.js.map +1 -0
- package/dist/cjs/subconscious/HostRecall.d.ts.map +1 -1
- package/dist/cjs/subconscious/HostRecall.js +11 -4
- package/dist/cjs/subconscious/HostRecall.js.map +1 -1
- package/dist/cjs/subconscious/ProjectIdentity.d.ts +9 -0
- package/dist/cjs/subconscious/ProjectIdentity.d.ts.map +1 -0
- package/dist/cjs/subconscious/ProjectIdentity.js +63 -0
- package/dist/cjs/subconscious/ProjectIdentity.js.map +1 -0
- package/dist/cjs/subconscious/TeamBrain.d.ts +9 -3
- package/dist/cjs/subconscious/TeamBrain.d.ts.map +1 -1
- package/dist/cjs/subconscious/TeamBrain.js +39 -5
- package/dist/cjs/subconscious/TeamBrain.js.map +1 -1
- package/dist/cjs/utils/FixCapture.d.ts +7 -5
- package/dist/cjs/utils/FixCapture.d.ts.map +1 -1
- package/dist/cjs/utils/FixCapture.js +64 -32
- package/dist/cjs/utils/FixCapture.js.map +1 -1
- package/dist/cjs/utils/NoTerminal.d.ts +27 -0
- package/dist/cjs/utils/NoTerminal.d.ts.map +1 -0
- package/dist/cjs/utils/NoTerminal.js +37 -0
- package/dist/cjs/utils/NoTerminal.js.map +1 -0
- package/dist/cjs/utils/OpenCodeSession.d.ts +70 -0
- package/dist/cjs/utils/OpenCodeSession.d.ts.map +1 -0
- package/dist/cjs/utils/OpenCodeSession.js +154 -0
- package/dist/cjs/utils/OpenCodeSession.js.map +1 -0
- package/dist/cjs/utils/ProLicense.d.ts.map +1 -1
- package/dist/cjs/utils/ProLicense.js +11 -3
- package/dist/cjs/utils/ProLicense.js.map +1 -1
- package/dist/cjs/utils/SessionCapture.d.ts +31 -7
- package/dist/cjs/utils/SessionCapture.d.ts.map +1 -1
- package/dist/cjs/utils/SessionCapture.js +185 -32
- package/dist/cjs/utils/SessionCapture.js.map +1 -1
- package/dist/cjs/utils/StopNudge.d.ts +8 -0
- package/dist/cjs/utils/StopNudge.d.ts.map +1 -0
- package/dist/cjs/utils/StopNudge.js +93 -0
- package/dist/cjs/utils/StopNudge.js.map +1 -0
- package/dist/cjs/utils/TestAutofixInterceptor.d.ts.map +1 -1
- package/dist/cjs/utils/TestAutofixInterceptor.js +2 -0
- package/dist/cjs/utils/TestAutofixInterceptor.js.map +1 -1
- package/dist/esm/cli/hostHooks.d.ts +44 -7
- package/dist/esm/cli/hostHooks.d.ts.map +1 -1
- package/dist/esm/cli/hostHooks.js +199 -10
- package/dist/esm/cli/hostHooks.js.map +1 -1
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +14 -17
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/cloud/CloudBrainClient.d.ts +52 -0
- package/dist/esm/cloud/CloudBrainClient.d.ts.map +1 -0
- package/dist/esm/cloud/CloudBrainClient.js +153 -0
- package/dist/esm/cloud/CloudBrainClient.js.map +1 -0
- package/dist/esm/cloud/CloudConfig.d.ts +41 -0
- package/dist/esm/cloud/CloudConfig.d.ts.map +1 -0
- package/dist/esm/cloud/CloudConfig.js +118 -0
- package/dist/esm/cloud/CloudConfig.js.map +1 -0
- package/dist/esm/cloud/CloudEntitlement.d.ts +55 -0
- package/dist/esm/cloud/CloudEntitlement.d.ts.map +1 -0
- package/dist/esm/cloud/CloudEntitlement.js +159 -0
- package/dist/esm/cloud/CloudEntitlement.js.map +1 -0
- package/dist/esm/cloud/billing/stripeApi.d.ts +43 -0
- package/dist/esm/cloud/billing/stripeApi.d.ts.map +1 -0
- package/dist/esm/cloud/billing/stripeApi.js +108 -0
- package/dist/esm/cloud/billing/stripeApi.js.map +1 -0
- package/dist/esm/cloud/billing/stripeWebhook.d.ts +35 -0
- package/dist/esm/cloud/billing/stripeWebhook.d.ts.map +1 -0
- package/dist/esm/cloud/billing/stripeWebhook.js +181 -0
- package/dist/esm/cloud/billing/stripeWebhook.js.map +1 -0
- package/dist/esm/cloud/console/ConsoleStore.d.ts +111 -0
- package/dist/esm/cloud/console/ConsoleStore.d.ts.map +1 -0
- package/dist/esm/cloud/console/ConsoleStore.js +161 -0
- package/dist/esm/cloud/console/ConsoleStore.js.map +1 -0
- package/dist/esm/cloud/console/consoleRouter.d.ts +68 -0
- package/dist/esm/cloud/console/consoleRouter.d.ts.map +1 -0
- package/dist/esm/cloud/console/consoleRouter.js +290 -0
- package/dist/esm/cloud/console/consoleRouter.js.map +1 -0
- package/dist/esm/cloud/console/mailer.d.ts +22 -0
- package/dist/esm/cloud/console/mailer.d.ts.map +1 -0
- package/dist/esm/cloud/console/mailer.js +30 -0
- package/dist/esm/cloud/console/mailer.js.map +1 -0
- package/dist/esm/cloud/identity/PlanPolicy.d.ts +42 -6
- package/dist/esm/cloud/identity/PlanPolicy.d.ts.map +1 -1
- package/dist/esm/cloud/identity/PlanPolicy.js +100 -21
- package/dist/esm/cloud/identity/PlanPolicy.js.map +1 -1
- package/dist/esm/cloud/identity/RateLimiter.d.ts +21 -1
- package/dist/esm/cloud/identity/RateLimiter.d.ts.map +1 -1
- package/dist/esm/cloud/identity/RateLimiter.js +57 -2
- package/dist/esm/cloud/identity/RateLimiter.js.map +1 -1
- package/dist/esm/cloud/identity/TenantResolver.d.ts +6 -1
- package/dist/esm/cloud/identity/TenantResolver.d.ts.map +1 -1
- package/dist/esm/cloud/identity/TenantResolver.js +1 -1
- package/dist/esm/cloud/identity/TenantResolver.js.map +1 -1
- package/dist/esm/cloud/identity/authenticateV2.d.ts.map +1 -1
- package/dist/esm/cloud/identity/authenticateV2.js +7 -4
- package/dist/esm/cloud/identity/authenticateV2.js.map +1 -1
- package/dist/esm/cloud/identity/identityStore.d.ts +96 -10
- package/dist/esm/cloud/identity/identityStore.d.ts.map +1 -1
- package/dist/esm/cloud/identity/identityStore.js +199 -3
- package/dist/esm/cloud/identity/identityStore.js.map +1 -1
- package/dist/esm/cloud/metering/PostgresLedgerStore.d.ts +18 -0
- package/dist/esm/cloud/metering/PostgresLedgerStore.d.ts.map +1 -0
- package/dist/esm/cloud/metering/PostgresLedgerStore.js +52 -0
- package/dist/esm/cloud/metering/PostgresLedgerStore.js.map +1 -0
- package/dist/esm/cloud/metering/UsageLedger.d.ts +74 -0
- package/dist/esm/cloud/metering/UsageLedger.d.ts.map +1 -1
- package/dist/esm/cloud/metering/UsageLedger.js +119 -16
- package/dist/esm/cloud/metering/UsageLedger.js.map +1 -1
- package/dist/esm/cloud/metering/index.d.ts +1 -0
- package/dist/esm/cloud/metering/index.d.ts.map +1 -1
- package/dist/esm/cloud/metering/index.js +1 -0
- package/dist/esm/cloud/metering/index.js.map +1 -1
- package/dist/esm/cloud/store/FileBrainStore.d.ts +6 -1
- package/dist/esm/cloud/store/FileBrainStore.d.ts.map +1 -1
- package/dist/esm/cloud/store/FileBrainStore.js +8 -0
- package/dist/esm/cloud/store/FileBrainStore.js.map +1 -1
- package/dist/esm/cloud/store/PostgresBrainStore.d.ts +11 -1
- package/dist/esm/cloud/store/PostgresBrainStore.d.ts.map +1 -1
- package/dist/esm/cloud/store/PostgresBrainStore.js +32 -0
- package/dist/esm/cloud/store/PostgresBrainStore.js.map +1 -1
- package/dist/esm/cloud/store/memorySummary.d.ts +29 -0
- package/dist/esm/cloud/store/memorySummary.d.ts.map +1 -0
- package/dist/esm/cloud/store/memorySummary.js +60 -0
- package/dist/esm/cloud/store/memorySummary.js.map +1 -0
- package/dist/esm/cloud/v2/app.d.ts.map +1 -1
- package/dist/esm/cloud/v2/app.js +6 -0
- package/dist/esm/cloud/v2/app.js.map +1 -1
- package/dist/esm/cloud/v2/inputGuard.d.ts +23 -0
- package/dist/esm/cloud/v2/inputGuard.d.ts.map +1 -0
- package/dist/esm/cloud/v2/inputGuard.js +63 -0
- package/dist/esm/cloud/v2/inputGuard.js.map +1 -0
- package/dist/esm/cloud/v2/routes/admin.d.ts +24 -0
- package/dist/esm/cloud/v2/routes/admin.d.ts.map +1 -0
- package/dist/esm/cloud/v2/routes/admin.js +337 -0
- package/dist/esm/cloud/v2/routes/admin.js.map +1 -0
- package/dist/esm/cloud/v2/routes/entitlement.d.ts +13 -0
- package/dist/esm/cloud/v2/routes/entitlement.d.ts.map +1 -0
- package/dist/esm/cloud/v2/routes/entitlement.js +21 -0
- package/dist/esm/cloud/v2/routes/entitlement.js.map +1 -0
- package/dist/esm/cloud/v2/routes/index.d.ts +14 -1
- package/dist/esm/cloud/v2/routes/index.d.ts.map +1 -1
- package/dist/esm/cloud/v2/routes/index.js +37 -1
- package/dist/esm/cloud/v2/routes/index.js.map +1 -1
- package/dist/esm/cloud/v2/routes/memories.d.ts +21 -2
- package/dist/esm/cloud/v2/routes/memories.d.ts.map +1 -1
- package/dist/esm/cloud/v2/routes/memories.js +75 -0
- package/dist/esm/cloud/v2/routes/memories.js.map +1 -1
- package/dist/esm/cloud/v2/routes/recall.d.ts +1 -0
- package/dist/esm/cloud/v2/routes/recall.d.ts.map +1 -1
- package/dist/esm/cloud/v2/routes/recall.js +5 -1
- package/dist/esm/cloud/v2/routes/recall.js.map +1 -1
- package/dist/esm/cloud/v2/routes/tenant.d.ts +36 -0
- package/dist/esm/cloud/v2/routes/tenant.d.ts.map +1 -0
- package/dist/esm/cloud/v2/routes/tenant.js +61 -0
- package/dist/esm/cloud/v2/routes/tenant.js.map +1 -0
- package/dist/esm/cloud/v2/routes/usage.d.ts +1 -1
- package/dist/esm/cloud/v2/routes/usage.d.ts.map +1 -1
- package/dist/esm/cloud/v2/routes/verify.d.ts +1 -0
- package/dist/esm/cloud/v2/routes/verify.d.ts.map +1 -1
- package/dist/esm/cloud/v2/routes/verify.js +5 -1
- package/dist/esm/cloud/v2/routes/verify.js.map +1 -1
- package/dist/esm/cloud/v2/server.d.ts +9 -3
- package/dist/esm/cloud/v2/server.d.ts.map +1 -1
- package/dist/esm/cloud/v2/server.js +36 -3
- package/dist/esm/cloud/v2/server.js.map +1 -1
- package/dist/esm/cloud/v2/usageRecorder.d.ts +19 -0
- package/dist/esm/cloud/v2/usageRecorder.d.ts.map +1 -0
- package/dist/esm/cloud/v2/usageRecorder.js +37 -0
- package/dist/esm/cloud/v2/usageRecorder.js.map +1 -0
- package/dist/esm/contracts/api-v2.types.d.ts +92 -2
- package/dist/esm/contracts/api-v2.types.d.ts.map +1 -1
- package/dist/esm/contracts/store.d.ts +37 -0
- package/dist/esm/contracts/store.d.ts.map +1 -1
- package/dist/esm/mcp/index.js +8 -2
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/mcp/tools/memory.d.ts.map +1 -1
- package/dist/esm/mcp/tools/memory.js +74 -4
- package/dist/esm/mcp/tools/memory.js.map +1 -1
- package/dist/esm/mcp/tools/misc.d.ts.map +1 -1
- package/dist/esm/mcp/tools/misc.js +2 -1
- package/dist/esm/mcp/tools/misc.js.map +1 -1
- package/dist/esm/mcp/tools/workspace.d.ts.map +1 -1
- package/dist/esm/mcp/tools/workspace.js +4 -1
- package/dist/esm/mcp/tools/workspace.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts +10 -0
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +46 -12
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/proxy/KeyManager.d.ts.map +1 -1
- package/dist/esm/proxy/KeyManager.js +5 -0
- package/dist/esm/proxy/KeyManager.js.map +1 -1
- package/dist/esm/subconscious/CloudBrain.d.ts +77 -0
- package/dist/esm/subconscious/CloudBrain.d.ts.map +1 -0
- package/dist/esm/subconscious/CloudBrain.js +330 -0
- package/dist/esm/subconscious/CloudBrain.js.map +1 -0
- package/dist/esm/subconscious/HostRecall.d.ts.map +1 -1
- package/dist/esm/subconscious/HostRecall.js +11 -4
- package/dist/esm/subconscious/HostRecall.js.map +1 -1
- package/dist/esm/subconscious/ProjectIdentity.d.ts +9 -0
- package/dist/esm/subconscious/ProjectIdentity.d.ts.map +1 -0
- package/dist/esm/subconscious/ProjectIdentity.js +56 -0
- package/dist/esm/subconscious/ProjectIdentity.js.map +1 -0
- package/dist/esm/subconscious/TeamBrain.d.ts +9 -3
- package/dist/esm/subconscious/TeamBrain.d.ts.map +1 -1
- package/dist/esm/subconscious/TeamBrain.js +39 -7
- package/dist/esm/subconscious/TeamBrain.js.map +1 -1
- package/dist/esm/utils/FixCapture.d.ts +7 -5
- package/dist/esm/utils/FixCapture.d.ts.map +1 -1
- package/dist/esm/utils/FixCapture.js +64 -33
- package/dist/esm/utils/FixCapture.js.map +1 -1
- package/dist/esm/utils/NoTerminal.d.ts +27 -0
- package/dist/esm/utils/NoTerminal.d.ts.map +1 -0
- package/dist/esm/utils/NoTerminal.js +33 -0
- package/dist/esm/utils/NoTerminal.js.map +1 -0
- package/dist/esm/utils/OpenCodeSession.d.ts +70 -0
- package/dist/esm/utils/OpenCodeSession.d.ts.map +1 -0
- package/dist/esm/utils/OpenCodeSession.js +146 -0
- package/dist/esm/utils/OpenCodeSession.js.map +1 -0
- package/dist/esm/utils/ProLicense.d.ts.map +1 -1
- package/dist/esm/utils/ProLicense.js +11 -3
- package/dist/esm/utils/ProLicense.js.map +1 -1
- package/dist/esm/utils/SessionCapture.d.ts +31 -7
- package/dist/esm/utils/SessionCapture.d.ts.map +1 -1
- package/dist/esm/utils/SessionCapture.js +185 -32
- package/dist/esm/utils/SessionCapture.js.map +1 -1
- package/dist/esm/utils/StopNudge.d.ts +8 -0
- package/dist/esm/utils/StopNudge.d.ts.map +1 -0
- package/dist/esm/utils/StopNudge.js +86 -0
- package/dist/esm/utils/StopNudge.js.map +1 -0
- package/dist/esm/utils/TestAutofixInterceptor.d.ts.map +1 -1
- package/dist/esm/utils/TestAutofixInterceptor.js +2 -0
- package/dist/esm/utils/TestAutofixInterceptor.js.map +1 -1
- package/lemma-proxy.cjs +5 -0
- package/package.json +2 -1
- package/sdks/crewai/dist/ts/src/client.d.ts +5 -1
- package/sdks/crewai/dist/ts/src/client.js +8 -0
- package/sdks/crewai/dist/ts/src/types.d.ts +32 -1
|
@@ -9,7 +9,16 @@
|
|
|
9
9
|
* This module owns the plan table. The DB migration only stores tenancy; keeping
|
|
10
10
|
* a second copy of the limits in SQL would guarantee drift.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Cloud plans. `vinel` is the team tier (every seat also unlocks the local Pro tools) and `regnum`
|
|
14
|
+
* is the large-organisation tier. They used to be `pro` and `scale`; `pro` now means only the local
|
|
15
|
+
* Pro license, so the two are never confused. `internal` is not sold: it is for the maintainers' own
|
|
16
|
+
* accounts (huge but finite ceilings, because Infinity is banned), assigned only through the admin API,
|
|
17
|
+
* and the Stripe webhook never touches a tenant on it. Add a plan here and the type, the admin API validation
|
|
18
|
+
* and the SQL CHECK (a new migration) follow from this list.
|
|
19
|
+
*/
|
|
20
|
+
export declare const PLAN_IDS: readonly ["free", "vinel", "regnum", "internal"];
|
|
21
|
+
export type PlanId = (typeof PLAN_IDS)[number];
|
|
13
22
|
export interface PlanLimits {
|
|
14
23
|
/** Active AND verified memories the tenant may keep. */
|
|
15
24
|
activeMemories: number;
|
|
@@ -28,12 +37,35 @@ export declare const RATE_LIMIT_WINDOW_MS: number;
|
|
|
28
37
|
export declare const PLAN_UPGRADE_URL: Readonly<Record<PlanId, string>>;
|
|
29
38
|
/** Single source of truth for plan ceilings. Every value finite and > 0. */
|
|
30
39
|
export declare const PLAN_LIMITS: Readonly<Record<PlanId, PlanLimits>>;
|
|
40
|
+
/**
|
|
41
|
+
* Whether a seat on the plan also unlocks the local Pro tools. A Record over PlanId, so adding a plan
|
|
42
|
+
* to PLAN_IDS without deciding this does not compile. The client never decides it: it asks the server
|
|
43
|
+
* (GET /v2/entitlement), so changing a plan here changes what every connected dev gets.
|
|
44
|
+
*/
|
|
45
|
+
export declare const PLAN_INCLUDES_PRO: Readonly<Record<PlanId, boolean>>;
|
|
31
46
|
export declare const DEFAULT_PLAN: PlanId;
|
|
47
|
+
/** The ceilings a founder's plan can raise. Seats are what a plan is sold by, so they are the plan's own. */
|
|
48
|
+
export type FounderLimits = Partial<Pick<PlanLimits, 'activeMemories' | 'dailyRequests' | 'monthlyRequests'>>;
|
|
49
|
+
/**
|
|
50
|
+
* What the founders (the first teams, who signed up before Cloud opened to everyone) keep. A founder gets,
|
|
51
|
+
* limit by limit, the HIGHER of this and the public plan: lowering a public plan later never reaches a
|
|
52
|
+
* founder, and raising one above these never leaves a founder behind. Only the paid plans have founder
|
|
53
|
+
* limits; a founder whose subscription ends is on `free` like anyone else (the flag stays, and comes back
|
|
54
|
+
* into force if they subscribe again). Like PLAN_LIMITS these numbers are not published: the landing only
|
|
55
|
+
* promises that founders keep better limits.
|
|
56
|
+
*/
|
|
57
|
+
export declare const FOUNDER_LIMITS: Readonly<Partial<Record<PlanId, FounderLimits>>>;
|
|
58
|
+
/** What, besides the plan, decides a tenant's limits. */
|
|
59
|
+
export interface LimitsContext {
|
|
60
|
+
founder?: boolean;
|
|
61
|
+
}
|
|
32
62
|
/**
|
|
33
63
|
* The `Infinity` elimination check, exported so tests can prove it (and the
|
|
34
64
|
* policy constructor refuses any non-finite/zero ceiling at startup).
|
|
35
65
|
*/
|
|
36
66
|
export declare function validatePlanLimits(limits: Record<string, PlanLimits>): string[];
|
|
67
|
+
/** Founder ceilings must be finite and positive too, and only for plans that exist. */
|
|
68
|
+
export declare function validateFounderLimits(founder: Partial<Record<string, FounderLimits>>): string[];
|
|
37
69
|
export type QuotaKind = 'memories' | 'seats';
|
|
38
70
|
export interface QuotaViolation {
|
|
39
71
|
kind: QuotaKind;
|
|
@@ -67,13 +99,17 @@ export interface QuotaErrorBody {
|
|
|
67
99
|
export declare function quotaErrorBody(violation: QuotaViolation, resetsAt?: number | null): QuotaErrorBody;
|
|
68
100
|
export declare class PlanPolicy {
|
|
69
101
|
private readonly limits;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
102
|
+
private readonly founder;
|
|
103
|
+
constructor(limits?: Record<string, PlanLimits>, founder?: Partial<Record<string, FounderLimits>>);
|
|
104
|
+
/**
|
|
105
|
+
* Limits for a plan; unknown plans conservatively fall back to `free`. With `founder`, each ceiling the
|
|
106
|
+
* founder table names is the higher of the two (see FOUNDER_LIMITS).
|
|
107
|
+
*/
|
|
108
|
+
limitsFor(plan: string, ctx?: LimitsContext): PlanLimits;
|
|
73
109
|
/** Memory quota: number of ACTIVE-VERIFIED memories the plan allows. */
|
|
74
|
-
checkMemoryQuota(planId: string, activeVerifiedMemories: number): QuotaCheck;
|
|
110
|
+
checkMemoryQuota(planId: string, activeVerifiedMemories: number, ctx?: LimitsContext): QuotaCheck;
|
|
75
111
|
/** Seat quota: number of seats (members/keys) the plan allows. */
|
|
76
|
-
checkSeatQuota(planId: string, seats: number): QuotaCheck;
|
|
112
|
+
checkSeatQuota(planId: string, seats: number, ctx?: LimitsContext): QuotaCheck;
|
|
77
113
|
private checkStatic;
|
|
78
114
|
}
|
|
79
115
|
//# sourceMappingURL=PlanPolicy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlanPolicy.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/PlanPolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"PlanPolicy.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/PlanPolicy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lemma API v2 — PlanPolicy (Lane D)
|
|
3
|
+
*
|
|
4
|
+
* Replaces `src/cloud/types.ts` PLAN_LIMITS. Quota is measured by ACTIVE-VERIFIED
|
|
5
|
+
* memories and by SEAT, not only by request count, and `Infinity` is gone —
|
|
6
|
+
* every plan has an explicit, positive ceiling. Exceeding a cap yields a 429
|
|
7
|
+
* with an actionable body: limit, current use, reset time and upgrade link.
|
|
8
|
+
*
|
|
9
|
+
* This module owns the plan table. The DB migration only stores tenancy; keeping
|
|
10
|
+
* a second copy of the limits in SQL would guarantee drift.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Cloud plans. `vinel` is the team tier (every seat also unlocks the local Pro tools) and `regnum`
|
|
14
|
+
* is the large-organisation tier. They used to be `pro` and `scale`; `pro` now means only the local
|
|
15
|
+
* Pro license, so the two are never confused. `internal` is not sold: it is for the maintainers' own
|
|
16
|
+
* accounts (huge but finite ceilings, because Infinity is banned), assigned only through the admin API,
|
|
17
|
+
* and the Stripe webhook never touches a tenant on it. Add a plan here and the type, the admin API validation
|
|
18
|
+
* and the SQL CHECK (a new migration) follow from this list.
|
|
19
|
+
*/
|
|
20
|
+
export const PLAN_IDS = ['free', 'vinel', 'regnum', 'internal'];
|
|
1
21
|
export const RATE_LIMIT_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
2
22
|
export const PLAN_UPGRADE_URL = Object.freeze({
|
|
3
23
|
free: 'https://lemma.dev/pricing',
|
|
4
|
-
|
|
5
|
-
|
|
24
|
+
vinel: 'https://lemma.dev/pricing',
|
|
25
|
+
regnum: 'https://lemma.dev/contact',
|
|
26
|
+
internal: 'https://lemma.dev/contact',
|
|
6
27
|
});
|
|
7
28
|
/** Single source of truth for plan ceilings. Every value finite and > 0. */
|
|
8
29
|
export const PLAN_LIMITS = Object.freeze({
|
|
@@ -14,24 +35,55 @@ export const PLAN_LIMITS = Object.freeze({
|
|
|
14
35
|
rateLimitWindowMs: RATE_LIMIT_WINDOW_MS,
|
|
15
36
|
upgradeUrl: PLAN_UPGRADE_URL.free,
|
|
16
37
|
}),
|
|
17
|
-
|
|
38
|
+
vinel: Object.freeze({
|
|
18
39
|
activeMemories: 10000,
|
|
19
40
|
seats: 10,
|
|
20
41
|
dailyRequests: 5000,
|
|
21
42
|
monthlyRequests: 60000,
|
|
22
43
|
rateLimitWindowMs: RATE_LIMIT_WINDOW_MS,
|
|
23
|
-
upgradeUrl: PLAN_UPGRADE_URL.
|
|
44
|
+
upgradeUrl: PLAN_UPGRADE_URL.vinel,
|
|
24
45
|
}),
|
|
25
|
-
|
|
46
|
+
regnum: Object.freeze({
|
|
26
47
|
activeMemories: 100000,
|
|
27
48
|
seats: 50,
|
|
28
49
|
dailyRequests: 20000,
|
|
29
50
|
monthlyRequests: 250000,
|
|
30
51
|
rateLimitWindowMs: RATE_LIMIT_WINDOW_MS,
|
|
31
|
-
upgradeUrl: PLAN_UPGRADE_URL.
|
|
52
|
+
upgradeUrl: PLAN_UPGRADE_URL.regnum,
|
|
32
53
|
}),
|
|
54
|
+
internal: Object.freeze({
|
|
55
|
+
activeMemories: 10000000,
|
|
56
|
+
seats: 25,
|
|
57
|
+
dailyRequests: 1000000,
|
|
58
|
+
monthlyRequests: 30000000,
|
|
59
|
+
rateLimitWindowMs: RATE_LIMIT_WINDOW_MS,
|
|
60
|
+
upgradeUrl: PLAN_UPGRADE_URL.internal,
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* Whether a seat on the plan also unlocks the local Pro tools. A Record over PlanId, so adding a plan
|
|
65
|
+
* to PLAN_IDS without deciding this does not compile. The client never decides it: it asks the server
|
|
66
|
+
* (GET /v2/entitlement), so changing a plan here changes what every connected dev gets.
|
|
67
|
+
*/
|
|
68
|
+
export const PLAN_INCLUDES_PRO = Object.freeze({
|
|
69
|
+
free: false,
|
|
70
|
+
vinel: true,
|
|
71
|
+
regnum: true,
|
|
72
|
+
internal: true,
|
|
33
73
|
});
|
|
34
74
|
export const DEFAULT_PLAN = 'free';
|
|
75
|
+
/**
|
|
76
|
+
* What the founders (the first teams, who signed up before Cloud opened to everyone) keep. A founder gets,
|
|
77
|
+
* limit by limit, the HIGHER of this and the public plan: lowering a public plan later never reaches a
|
|
78
|
+
* founder, and raising one above these never leaves a founder behind. Only the paid plans have founder
|
|
79
|
+
* limits; a founder whose subscription ends is on `free` like anyone else (the flag stays, and comes back
|
|
80
|
+
* into force if they subscribe again). Like PLAN_LIMITS these numbers are not published: the landing only
|
|
81
|
+
* promises that founders keep better limits.
|
|
82
|
+
*/
|
|
83
|
+
export const FOUNDER_LIMITS = Object.freeze({
|
|
84
|
+
vinel: Object.freeze({ activeMemories: 25000, dailyRequests: 10000, monthlyRequests: 150000 }),
|
|
85
|
+
regnum: Object.freeze({ activeMemories: 250000, dailyRequests: 40000, monthlyRequests: 600000 }),
|
|
86
|
+
});
|
|
35
87
|
const NUMERIC_LIMIT_KEYS = [
|
|
36
88
|
'activeMemories',
|
|
37
89
|
'seats',
|
|
@@ -57,6 +109,19 @@ export function validatePlanLimits(limits) {
|
|
|
57
109
|
}
|
|
58
110
|
return problems;
|
|
59
111
|
}
|
|
112
|
+
/** Founder ceilings must be finite and positive too, and only for plans that exist. */
|
|
113
|
+
export function validateFounderLimits(founder) {
|
|
114
|
+
const problems = [];
|
|
115
|
+
for (const [plan, l] of Object.entries(founder)) {
|
|
116
|
+
if (!PLAN_IDS.includes(plan))
|
|
117
|
+
problems.push(`founder.${plan}: unknown plan`);
|
|
118
|
+
for (const [key, value] of Object.entries(l ?? {})) {
|
|
119
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0)
|
|
120
|
+
problems.push(`founder.${plan}.${key} = ${value}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return problems;
|
|
124
|
+
}
|
|
60
125
|
export function quotaErrorBody(violation, resetsAt = null) {
|
|
61
126
|
return {
|
|
62
127
|
error: {
|
|
@@ -73,52 +138,66 @@ export function quotaErrorBody(violation, resetsAt = null) {
|
|
|
73
138
|
};
|
|
74
139
|
}
|
|
75
140
|
export class PlanPolicy {
|
|
76
|
-
constructor(limits = PLAN_LIMITS) {
|
|
77
|
-
const problems = validatePlanLimits(limits);
|
|
141
|
+
constructor(limits = PLAN_LIMITS, founder = FOUNDER_LIMITS) {
|
|
142
|
+
const problems = [...validatePlanLimits(limits), ...validateFounderLimits(founder)];
|
|
78
143
|
if (problems.length > 0) {
|
|
79
144
|
throw new Error(`PlanPolicy: invalid plan limits (${problems.join(', ')})`);
|
|
80
145
|
}
|
|
81
146
|
this.limits = limits;
|
|
147
|
+
this.founder = founder;
|
|
82
148
|
}
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Limits for a plan; unknown plans conservatively fall back to `free`. With `founder`, each ceiling the
|
|
151
|
+
* founder table names is the higher of the two (see FOUNDER_LIMITS).
|
|
152
|
+
*/
|
|
153
|
+
limitsFor(plan, ctx = {}) {
|
|
154
|
+
const base = this.limits[plan] ?? this.limits[DEFAULT_PLAN];
|
|
155
|
+
const raise = ctx.founder ? this.founder[plan in this.limits ? plan : DEFAULT_PLAN] : undefined;
|
|
156
|
+
if (!raise)
|
|
157
|
+
return base;
|
|
158
|
+
const out = { ...base };
|
|
159
|
+
for (const key of Object.keys(raise)) {
|
|
160
|
+
const v = raise[key];
|
|
161
|
+
if (typeof v === 'number')
|
|
162
|
+
out[key] = Math.max(base[key], v);
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
86
165
|
}
|
|
87
166
|
/** Memory quota: number of ACTIVE-VERIFIED memories the plan allows. */
|
|
88
|
-
checkMemoryQuota(planId, activeVerifiedMemories) {
|
|
89
|
-
return this.checkStatic(planId, 'memories', activeVerifiedMemories, (limit, plan) => ({
|
|
167
|
+
checkMemoryQuota(planId, activeVerifiedMemories, ctx = {}) {
|
|
168
|
+
return this.checkStatic(planId, 'memories', activeVerifiedMemories, ctx, (limit, plan) => ({
|
|
90
169
|
allowed: false,
|
|
91
170
|
violation: {
|
|
92
171
|
kind: 'memories',
|
|
93
172
|
plan,
|
|
94
173
|
limit,
|
|
95
174
|
current: activeVerifiedMemories,
|
|
96
|
-
upgradeUrl: this.limitsFor(planId).upgradeUrl,
|
|
175
|
+
upgradeUrl: this.limitsFor(planId, ctx).upgradeUrl,
|
|
97
176
|
message: `${plan} plan allows ${limit} active verified memories; ` +
|
|
98
177
|
`you currently have ${activeVerifiedMemories}. ` +
|
|
99
|
-
`Upgrade at ${this.limitsFor(planId).upgradeUrl}`,
|
|
178
|
+
`Upgrade at ${this.limitsFor(planId, ctx).upgradeUrl}`,
|
|
100
179
|
},
|
|
101
180
|
}));
|
|
102
181
|
}
|
|
103
182
|
/** Seat quota: number of seats (members/keys) the plan allows. */
|
|
104
|
-
checkSeatQuota(planId, seats) {
|
|
105
|
-
return this.checkStatic(planId, 'seats', seats, (limit, plan) => ({
|
|
183
|
+
checkSeatQuota(planId, seats, ctx = {}) {
|
|
184
|
+
return this.checkStatic(planId, 'seats', seats, ctx, (limit, plan) => ({
|
|
106
185
|
allowed: false,
|
|
107
186
|
violation: {
|
|
108
187
|
kind: 'seats',
|
|
109
188
|
plan,
|
|
110
189
|
limit,
|
|
111
190
|
current: seats,
|
|
112
|
-
upgradeUrl: this.limitsFor(planId).upgradeUrl,
|
|
191
|
+
upgradeUrl: this.limitsFor(planId, ctx).upgradeUrl,
|
|
113
192
|
message: `${plan} plan allows ${limit} seat(s); you currently have ${seats}. ` +
|
|
114
|
-
`Upgrade at ${this.limitsFor(planId).upgradeUrl}`,
|
|
193
|
+
`Upgrade at ${this.limitsFor(planId, ctx).upgradeUrl}`,
|
|
115
194
|
},
|
|
116
195
|
}));
|
|
117
196
|
}
|
|
118
|
-
checkStatic(planId, kind, current, makeViolation) {
|
|
197
|
+
checkStatic(planId, kind, current, ctx, makeViolation) {
|
|
119
198
|
const plan = (planId in this.limits ? planId : DEFAULT_PLAN);
|
|
120
199
|
const limitKey = kind === 'memories' ? 'activeMemories' : 'seats';
|
|
121
|
-
const limit = this.limitsFor(planId)[limitKey];
|
|
200
|
+
const limit = this.limitsFor(planId, ctx)[limitKey];
|
|
122
201
|
// El tope es exclusivo: en el límite (free con 1000 activas) la siguiente
|
|
123
202
|
// escritura ya está negada — "intenta crear la 1001 ⇒ 429".
|
|
124
203
|
if (current >= limit)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlanPolicy.js","sourceRoot":"","sources":["../../../../src/cloud/identity/PlanPolicy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PlanPolicy.js","sourceRoot":"","sources":["../../../../src/cloud/identity/PlanPolicy.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,13 +19,22 @@ export interface RateLimitDecision {
|
|
|
19
19
|
}
|
|
20
20
|
export interface RateLimiter {
|
|
21
21
|
consume(tenantId: string, limit: number, windowMs: number, now?: number): Promise<RateLimitDecision>;
|
|
22
|
+
/** Requests counted in the current window, WITHOUT counting this call. For reporting, never for enforcing. */
|
|
23
|
+
peek?(tenantId: string, windowMs: number, now?: number): Promise<number>;
|
|
24
|
+
/** One request against the tenant's calendar-month (UTC) allowance; resetAt is the first instant of the next month. */
|
|
25
|
+
consumeMonthly?(tenantId: string, limit: number, now?: number): Promise<RateLimitDecision>;
|
|
26
|
+
/** Requests counted this calendar month, WITHOUT counting this call. For reporting, never for enforcing. */
|
|
27
|
+
peekMonthly?(tenantId: string, now?: number): Promise<number>;
|
|
22
28
|
}
|
|
29
|
+
/** Which allowance a 429 came from. */
|
|
30
|
+
export type RateLimitWindow = 'day' | 'month';
|
|
23
31
|
/** The 429 body for rate_limited (additive to the LemmaApiError envelope). */
|
|
24
32
|
export interface RateLimitErrorBody {
|
|
25
33
|
error: {
|
|
26
34
|
code: 'rate_limited';
|
|
27
35
|
status: 429;
|
|
28
36
|
message: string;
|
|
37
|
+
window: RateLimitWindow;
|
|
29
38
|
limit: number;
|
|
30
39
|
used: number;
|
|
31
40
|
remaining: number;
|
|
@@ -34,16 +43,27 @@ export interface RateLimitErrorBody {
|
|
|
34
43
|
upgradeUrl: string;
|
|
35
44
|
};
|
|
36
45
|
}
|
|
37
|
-
export declare function rateLimitErrorBody(decision: RateLimitDecision, retryAfterSeconds: number, upgradeUrl: string): RateLimitErrorBody;
|
|
46
|
+
export declare function rateLimitErrorBody(decision: RateLimitDecision, retryAfterSeconds: number, upgradeUrl: string, window?: RateLimitWindow): RateLimitErrorBody;
|
|
47
|
+
/** Bucket id of the calendar month (UTC) that contains `now`, e.g. `m:2026-10`. Text, so it shares the daily buckets' table without clashing. */
|
|
48
|
+
export declare function monthBucket(now: number): string;
|
|
49
|
+
/** First instant (epoch ms) of the UTC month after the one containing `now`. */
|
|
50
|
+
export declare function nextMonthStart(now: number): number;
|
|
38
51
|
/** In-process fixed-window limiter. Suitable for single-instance dev and tests. */
|
|
39
52
|
export declare class InMemoryRateLimiter implements RateLimiter {
|
|
40
53
|
private readonly buckets;
|
|
41
54
|
consume(tenantId: string, limit: number, windowMs: number, now?: number): Promise<RateLimitDecision>;
|
|
55
|
+
peek(tenantId: string, windowMs: number, now?: number): Promise<number>;
|
|
56
|
+
private readonly months;
|
|
57
|
+
consumeMonthly(tenantId: string, limit: number, now?: number): Promise<RateLimitDecision>;
|
|
58
|
+
peekMonthly(tenantId: string, now?: number): Promise<number>;
|
|
42
59
|
}
|
|
43
60
|
/** Postgres-backed fixed-window limiter, atomic via a single upsert. */
|
|
44
61
|
export declare class PostgresRateLimiter implements RateLimiter {
|
|
45
62
|
private readonly pool;
|
|
46
63
|
constructor(pool: Pool);
|
|
47
64
|
consume(tenantId: string, limit: number, windowMs: number, now?: number): Promise<RateLimitDecision>;
|
|
65
|
+
peek(tenantId: string, windowMs: number, now?: number): Promise<number>;
|
|
66
|
+
consumeMonthly(tenantId: string, limit: number, now?: number): Promise<RateLimitDecision>;
|
|
67
|
+
peekMonthly(tenantId: string, now?: number): Promise<number>;
|
|
48
68
|
}
|
|
49
69
|
//# sourceMappingURL=RateLimiter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/RateLimiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/RateLimiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
export function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl) {
|
|
1
|
+
export function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl, window = 'day') {
|
|
2
|
+
const scope = window === 'month' ? 'requests this month' : 'requests in the current window';
|
|
2
3
|
return {
|
|
3
4
|
error: {
|
|
4
5
|
code: 'rate_limited',
|
|
5
6
|
status: 429,
|
|
6
|
-
message: `rate limit exceeded: ${decision.used}/${decision.limit}
|
|
7
|
+
message: `rate limit exceeded: ${decision.used}/${decision.limit} ${scope}. ` +
|
|
7
8
|
`Back off and retry after ${retryAfterSeconds}s, or upgrade at ${upgradeUrl}.`,
|
|
9
|
+
window,
|
|
8
10
|
limit: decision.limit,
|
|
9
11
|
used: decision.used,
|
|
10
12
|
remaining: decision.remaining,
|
|
@@ -14,10 +16,21 @@ export function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl) {
|
|
|
14
16
|
},
|
|
15
17
|
};
|
|
16
18
|
}
|
|
19
|
+
/** Bucket id of the calendar month (UTC) that contains `now`, e.g. `m:2026-10`. Text, so it shares the daily buckets' table without clashing. */
|
|
20
|
+
export function monthBucket(now) {
|
|
21
|
+
const d = new Date(now);
|
|
22
|
+
return `m:${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}`;
|
|
23
|
+
}
|
|
24
|
+
/** First instant (epoch ms) of the UTC month after the one containing `now`. */
|
|
25
|
+
export function nextMonthStart(now) {
|
|
26
|
+
const d = new Date(now);
|
|
27
|
+
return Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1);
|
|
28
|
+
}
|
|
17
29
|
/** In-process fixed-window limiter. Suitable for single-instance dev and tests. */
|
|
18
30
|
export class InMemoryRateLimiter {
|
|
19
31
|
constructor() {
|
|
20
32
|
this.buckets = new Map();
|
|
33
|
+
this.months = new Map();
|
|
21
34
|
}
|
|
22
35
|
async consume(tenantId, limit, windowMs, now = Date.now()) {
|
|
23
36
|
const bucket = Math.floor(now / windowMs);
|
|
@@ -42,6 +55,24 @@ export class InMemoryRateLimiter {
|
|
|
42
55
|
resetAt,
|
|
43
56
|
};
|
|
44
57
|
}
|
|
58
|
+
async peek(tenantId, windowMs, now = Date.now()) {
|
|
59
|
+
return this.buckets.get(`${tenantId}:${Math.floor(now / windowMs)}`)?.count ?? 0;
|
|
60
|
+
}
|
|
61
|
+
async consumeMonthly(tenantId, limit, now = Date.now()) {
|
|
62
|
+
const bucket = monthBucket(now);
|
|
63
|
+
// Keep only the current month, as the daily map does: no background timers.
|
|
64
|
+
for (const k of this.months.keys()) {
|
|
65
|
+
if (!k.endsWith(`:${bucket}`))
|
|
66
|
+
this.months.delete(k);
|
|
67
|
+
}
|
|
68
|
+
const key = `${tenantId}:${bucket}`;
|
|
69
|
+
const used = (this.months.get(key) ?? 0) + 1;
|
|
70
|
+
this.months.set(key, used);
|
|
71
|
+
return { allowed: used <= limit, used, limit, remaining: Math.max(0, limit - used), resetAt: nextMonthStart(now) };
|
|
72
|
+
}
|
|
73
|
+
async peekMonthly(tenantId, now = Date.now()) {
|
|
74
|
+
return this.months.get(`${tenantId}:${monthBucket(now)}`) ?? 0;
|
|
75
|
+
}
|
|
45
76
|
}
|
|
46
77
|
/** Postgres-backed fixed-window limiter, atomic via a single upsert. */
|
|
47
78
|
export class PostgresRateLimiter {
|
|
@@ -65,5 +96,29 @@ export class PostgresRateLimiter {
|
|
|
65
96
|
resetAt: (bucket + 1) * windowMs,
|
|
66
97
|
};
|
|
67
98
|
}
|
|
99
|
+
async peek(tenantId, windowMs, now = Date.now()) {
|
|
100
|
+
const { rows } = await this.pool.query('SELECT request_count FROM tenant_rate_limits WHERE tenant_id = $1 AND bucket = $2', [
|
|
101
|
+
tenantId,
|
|
102
|
+
String(Math.floor(now / windowMs)),
|
|
103
|
+
]);
|
|
104
|
+
return Number(rows[0]?.request_count ?? 0);
|
|
105
|
+
}
|
|
106
|
+
async consumeMonthly(tenantId, limit, now = Date.now()) {
|
|
107
|
+
const { rows } = await this.pool.query(`INSERT INTO tenant_rate_limits (tenant_id, bucket, request_count)
|
|
108
|
+
VALUES ($1, $2, 1)
|
|
109
|
+
ON CONFLICT (tenant_id, bucket) DO UPDATE
|
|
110
|
+
SET request_count = tenant_rate_limits.request_count + 1,
|
|
111
|
+
updated_at = CURRENT_TIMESTAMP
|
|
112
|
+
RETURNING request_count`, [tenantId, monthBucket(now)]);
|
|
113
|
+
const used = Number(rows[0]?.request_count ?? 1);
|
|
114
|
+
return { allowed: used <= limit, used, limit, remaining: Math.max(0, limit - used), resetAt: nextMonthStart(now) };
|
|
115
|
+
}
|
|
116
|
+
async peekMonthly(tenantId, now = Date.now()) {
|
|
117
|
+
const { rows } = await this.pool.query('SELECT request_count FROM tenant_rate_limits WHERE tenant_id = $1 AND bucket = $2', [
|
|
118
|
+
tenantId,
|
|
119
|
+
monthBucket(now),
|
|
120
|
+
]);
|
|
121
|
+
return Number(rows[0]?.request_count ?? 0);
|
|
122
|
+
}
|
|
68
123
|
}
|
|
69
124
|
//# sourceMappingURL=RateLimiter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../../../src/cloud/identity/RateLimiter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../../../src/cloud/identity/RateLimiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { IdentityStore } from './identityStore.js';
|
|
2
|
+
import type { PlanId } from './PlanPolicy.js';
|
|
2
3
|
export interface Tenant {
|
|
3
4
|
id: string;
|
|
4
|
-
plan:
|
|
5
|
+
plan: PlanId;
|
|
5
6
|
keyId: string;
|
|
7
|
+
/** Human label of the presented key (e.g. "dev-a"); recorded as the memory's author. */
|
|
8
|
+
keyName?: string;
|
|
9
|
+
/** The tenant signed up as a founder: PlanPolicy applies the founder limits. */
|
|
10
|
+
founder?: boolean;
|
|
6
11
|
}
|
|
7
12
|
export declare class TenantResolver {
|
|
8
13
|
private readonly store;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TenantResolver.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"TenantResolver.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,QAAQ,CAAC,IAAI,OAAO;gBAES,KAAK,EAAE,aAAa;IAEjD;;;;OAIG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAY3D;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -29,7 +29,7 @@ export class TenantResolver {
|
|
|
29
29
|
return null;
|
|
30
30
|
if (record.expiresAt !== null && Date.now() > record.expiresAt)
|
|
31
31
|
return null;
|
|
32
|
-
return { id: record.tenantId, plan: record.plan, keyId: record.id };
|
|
32
|
+
return { id: record.tenantId, plan: record.plan, keyId: record.id, keyName: record.name, ...(record.founder ? { founder: true } : {}) };
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
export default TenantResolver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TenantResolver.js","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"TenantResolver.js","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAcvD,MAAM,OAAO,cAAc;IAGzB,YAA6B,KAAoB;QAApB,UAAK,GAAL,KAAK,CAAe;QAFxC,SAAI,GAAG,GAAG,CAAC;IAEgC,CAAC;IAErD;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAE/C,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAChC,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5E,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC1I,CAAC;CACF;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticateV2.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,gEAAgE;YAChE,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB;KACF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBhE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"authenticateV2.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,gEAAgE;YAChE,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB;KACF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBhE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CA6CvE;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,eAAe,cAAc,CAAC"}
|
|
@@ -36,16 +36,19 @@ export function authenticateV2(deps) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
if (deps.rateLimiter) {
|
|
39
|
-
const
|
|
40
|
-
const
|
|
39
|
+
const limits = policy.limitsFor(tenant.plan, { founder: tenant.founder === true });
|
|
40
|
+
const daily = await deps.rateLimiter.consume(tenant.id, limits.dailyRequests, windowMs, now());
|
|
41
|
+
// A request the day already refused does not eat the month's allowance.
|
|
42
|
+
const decision = !daily.allowed || !deps.rateLimiter.consumeMonthly
|
|
43
|
+
? daily
|
|
44
|
+
: await deps.rateLimiter.consumeMonthly(tenant.id, limits.monthlyRequests, now());
|
|
41
45
|
if (!decision.allowed) {
|
|
42
46
|
const retryAfter = Math.max(1, Math.ceil((decision.resetAt - now()) / 1000));
|
|
43
|
-
const upgradeUrl = policy.limitsFor(tenant.plan).upgradeUrl;
|
|
44
47
|
res
|
|
45
48
|
.status(429)
|
|
46
49
|
.set('Retry-After', String(retryAfter))
|
|
47
50
|
.set('WWW-Authenticate', 'Bearer')
|
|
48
|
-
.json(rateLimitErrorBody(decision, retryAfter, upgradeUrl));
|
|
51
|
+
.json(rateLimitErrorBody(decision, retryAfter, limits.upgradeUrl, decision === daily ? 'day' : 'month'));
|
|
49
52
|
return;
|
|
50
53
|
}
|
|
51
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticateV2.js","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AA0BnD,SAAS,WAAW,CAAC,MAA0B;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO,IAAI,aAAa,CAAC;QACvB,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,4BAA4B;KACtC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,IAAI,oBAAoB,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAEjC,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC9B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAErD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;gBACxF,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;gBACxF,OAAO;YACT,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,
|
|
1
|
+
{"version":3,"file":"authenticateV2.js","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"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"}
|