@noodleseed/one 0.61.0 → 0.63.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/bin.js +8 -2
- package/dist/bin.js.map +1 -1
- package/dist/browser.d.ts +10 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +18 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/apps-ops.js +1 -1
- package/dist/commands/apps-ops.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts +2 -3
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +5 -17
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/commands/github-ops.d.ts +3 -2
- package/dist/commands/github-ops.d.ts.map +1 -1
- package/dist/commands/github-ops.js +7 -4
- package/dist/commands/github-ops.js.map +1 -1
- package/dist/control-plane.d.ts +2 -1
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +31 -10
- package/dist/control-plane.js.map +1 -1
- package/dist/device-login.d.ts +30 -0
- package/dist/device-login.d.ts.map +1 -0
- package/dist/device-login.js +162 -0
- package/dist/device-login.js.map +1 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +11 -0
- package/dist/doctor.js.map +1 -1
- package/dist/platform-support.d.ts +22 -0
- package/dist/platform-support.d.ts.map +1 -0
- package/dist/platform-support.js +118 -0
- package/dist/platform-support.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.js +2 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-overage-schema.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-overage-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-overage-schema.js +74 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-overage-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-overage-store.d.ts +31 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-overage-store.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-overage-store.js +295 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-overage-store.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-schema.js +13 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-schema.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-store.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-store.js +4 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-stripe-store.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/stripe-config.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-config.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/stripe-config.js +12 -1
- package/node_modules/@noodle-borg/service/dist/billing/stripe-config.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/stripe-integration-loader.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-integration-loader.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/stripe-integration-loader.js +14 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-integration-loader.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/stripe-integration.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-integration.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/stripe-integration.js +38 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-integration.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-provider-validation.d.ts +49 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-provider-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-provider-validation.js +241 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-provider-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-provider.d.ts +28 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-provider.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-provider.js +133 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-provider.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-service.d.ts +23 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-service.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-service.js +171 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-service.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-store.d.ts +51 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-store.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-store.js +2 -0
- package/node_modules/@noodle-borg/service/dist/billing/stripe-overage-store.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/app.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/app.js +65 -0
- package/node_modules/@noodle-borg/service/dist/oauth/app.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/device-flow.d.ts +20 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-flow.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-flow.js +239 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-flow.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-provider.d.ts +15 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-provider.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-provider.js +45 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-provider.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-schema.d.ts +3 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-schema.js +33 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-types.d.ts +30 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-types.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-types.js +31 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-types.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store.d.ts +66 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store.js +2 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/paths.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/paths.js +3 -0
- package/node_modules/@noodle-borg/service/dist/oauth/paths.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/oauth/provider.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.js +36 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.d.ts +14 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.js +122 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts +15 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store.js +83 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve.js +14 -1
- package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js +3 -0
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js.map +1 -1
- package/node_modules/bundle-name/index.js +5 -0
- package/node_modules/bundle-name/license +9 -0
- package/node_modules/bundle-name/package.json +45 -0
- package/node_modules/bundle-name/readme.md +23 -0
- package/node_modules/default-browser/index.d.ts +29 -0
- package/node_modules/default-browser/index.js +34 -0
- package/node_modules/default-browser/license +9 -0
- package/node_modules/default-browser/package.json +54 -0
- package/node_modules/default-browser/readme.md +24 -0
- package/node_modules/default-browser/windows.js +57 -0
- package/node_modules/default-browser-id/index.js +25 -0
- package/node_modules/default-browser-id/license +9 -0
- package/node_modules/default-browser-id/package.json +41 -0
- package/node_modules/default-browser-id/readme.md +19 -0
- package/node_modules/define-lazy-prop/index.d.ts +31 -0
- package/node_modules/define-lazy-prop/index.js +18 -0
- package/node_modules/define-lazy-prop/license +9 -0
- package/node_modules/define-lazy-prop/package.json +51 -0
- package/node_modules/define-lazy-prop/readme.md +55 -0
- package/node_modules/is-docker/cli.js +5 -0
- package/node_modules/is-docker/index.d.ts +13 -0
- package/node_modules/is-docker/index.js +29 -0
- package/node_modules/is-docker/license +9 -0
- package/node_modules/is-docker/package.json +44 -0
- package/node_modules/is-docker/readme.md +27 -0
- package/node_modules/is-in-ssh/index.d.ts +15 -0
- package/node_modules/is-in-ssh/index.js +7 -0
- package/node_modules/is-in-ssh/license +9 -0
- package/node_modules/is-in-ssh/package.json +43 -0
- package/node_modules/is-in-ssh/readme.md +43 -0
- package/node_modules/is-inside-container/cli.js +5 -0
- package/node_modules/is-inside-container/index.d.ts +13 -0
- package/node_modules/is-inside-container/index.js +23 -0
- package/node_modules/is-inside-container/license +9 -0
- package/node_modules/is-inside-container/package.json +51 -0
- package/node_modules/is-inside-container/readme.md +36 -0
- package/node_modules/is-wsl/index.d.ts +15 -0
- package/node_modules/is-wsl/index.js +36 -0
- package/node_modules/is-wsl/license +9 -0
- package/node_modules/is-wsl/package.json +58 -0
- package/node_modules/is-wsl/readme.md +21 -0
- package/node_modules/open/index.d.ts +158 -0
- package/node_modules/open/index.js +417 -0
- package/node_modules/open/license +9 -0
- package/node_modules/open/package.json +70 -0
- package/node_modules/open/readme.md +197 -0
- package/node_modules/open/xdg-open +1267 -0
- package/node_modules/powershell-utils/index.d.ts +122 -0
- package/node_modules/powershell-utils/index.js +58 -0
- package/node_modules/powershell-utils/license +9 -0
- package/node_modules/powershell-utils/package.json +47 -0
- package/node_modules/powershell-utils/readme.md +153 -0
- package/node_modules/run-applescript/index.d.ts +66 -0
- package/node_modules/run-applescript/index.js +37 -0
- package/node_modules/run-applescript/license +9 -0
- package/node_modules/run-applescript/package.json +42 -0
- package/node_modules/run-applescript/readme.md +78 -0
- package/node_modules/wsl-utils/index.d.ts +81 -0
- package/node_modules/wsl-utils/index.js +98 -0
- package/node_modules/wsl-utils/license +9 -0
- package/node_modules/wsl-utils/package.json +48 -0
- package/node_modules/wsl-utils/readme.md +111 -0
- package/node_modules/wsl-utils/utilities.js +19 -0
- package/package.json +14 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BillingStripeConfig } from './stripe-config.js';
|
|
2
|
+
import { type BillingStripeOverageInvoice, type BillingStripeOverageInvoiceItem } from './stripe-overage-provider-validation.js';
|
|
3
|
+
import type { BillingStripeOverageSettlementClaim } from './stripe-overage-store.js';
|
|
4
|
+
export type { BillingStripeOverageInvoice, BillingStripeOverageInvoiceItem, BillingStripeOverageInvoiceStatus, } from './stripe-overage-provider-validation.js';
|
|
5
|
+
export interface BillingStripeOverageApi {
|
|
6
|
+
readonly subscriptions: {
|
|
7
|
+
retrieve(id: string): Promise<unknown>;
|
|
8
|
+
};
|
|
9
|
+
readonly invoices: {
|
|
10
|
+
search(params: unknown): Promise<unknown>;
|
|
11
|
+
create(params: unknown, options?: unknown): Promise<unknown>;
|
|
12
|
+
retrieve(id: string): Promise<unknown>;
|
|
13
|
+
finalizeInvoice(id: string, params: unknown, options?: unknown): Promise<unknown>;
|
|
14
|
+
};
|
|
15
|
+
readonly invoiceItems: {
|
|
16
|
+
create(params: unknown, options?: unknown): Promise<unknown>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare class StripeOverageBillingProvider {
|
|
20
|
+
#private;
|
|
21
|
+
constructor(config: BillingStripeConfig, api?: BillingStripeOverageApi);
|
|
22
|
+
findInvoice(claim: BillingStripeOverageSettlementClaim): Promise<BillingStripeOverageInvoice | undefined>;
|
|
23
|
+
createDraftInvoice(claim: BillingStripeOverageSettlementClaim): Promise<BillingStripeOverageInvoice>;
|
|
24
|
+
createInvoiceItem(claim: BillingStripeOverageSettlementClaim, invoiceId: string): Promise<BillingStripeOverageInvoiceItem>;
|
|
25
|
+
retrieveInvoice(claim: BillingStripeOverageSettlementClaim, invoiceId: string): Promise<BillingStripeOverageInvoice>;
|
|
26
|
+
finalizeInvoice(claim: BillingStripeOverageSettlementClaim, invoiceId: string): Promise<BillingStripeOverageInvoice>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=stripe-overage-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-overage-provider.d.ts","sourceRoot":"","sources":["../../src/billing/stripe-overage-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAqB,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAEL,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EAarC,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,2BAA2B,CAAC;AAErF,YAAY,EACV,2BAA2B,EAC3B,+BAA+B,EAC/B,iCAAiC,GAClC,MAAM,yCAAyC,CAAC;AAEjD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,aAAa,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC;IACnE,QAAQ,CAAC,QAAQ,EAAE;QACjB,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7D,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACvC,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KACnF,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE;QACrB,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC9D,CAAC;CACH;AAED,qBAAa,4BAA4B;;gBAI3B,MAAM,EAAE,mBAAmB,EAAE,GAAG,CAAC,EAAE,uBAAuB;IAKhE,WAAW,CACf,KAAK,EAAE,mCAAmC,GACzC,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC;IAiB7C,kBAAkB,CACtB,KAAK,EAAE,mCAAmC,GACzC,OAAO,CAAC,2BAA2B,CAAC;IAgCjC,iBAAiB,CACrB,KAAK,EAAE,mCAAmC,EAC1C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,+BAA+B,CAAC;IA8BrC,eAAe,CACnB,KAAK,EAAE,mCAAmC,EAC1C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,2BAA2B,CAAC;IAWjC,eAAe,CACnB,KAAK,EAAE,mCAAmC,EAC1C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,2BAA2B,CAAC;CA+CxC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import Stripe from 'stripe';
|
|
2
|
+
import { assertExpectedInvoiceId, normalizeStripeOverageInvoice, normalizeStripeOverageInvoiceItem, requireStripeMode, safePositiveInteger, stripeArray, stripeBoolean, stripeId, stripeOverageMetadata, stripePeriod, stripeRecord, stripeReference, stripeString, } from './stripe-overage-provider-validation.js';
|
|
3
|
+
export class StripeOverageBillingProvider {
|
|
4
|
+
#config;
|
|
5
|
+
#api;
|
|
6
|
+
constructor(config, api) {
|
|
7
|
+
this.#config = config;
|
|
8
|
+
this.#api = api ?? createStripeOverageApi(config.secretKey);
|
|
9
|
+
}
|
|
10
|
+
async findInvoice(claim) {
|
|
11
|
+
const result = stripeRecord('Stripe invoice search', await this.#api.invoices.search({
|
|
12
|
+
query: `metadata['noodle_overage_closure_id']:'${claim.closure.closureId}'`,
|
|
13
|
+
limit: 2,
|
|
14
|
+
}));
|
|
15
|
+
const data = stripeArray('Stripe invoice search data', result.data);
|
|
16
|
+
if (data.length > 1 || result.has_more === true) {
|
|
17
|
+
throw new Error('multiple Stripe invoices match one overage closure');
|
|
18
|
+
}
|
|
19
|
+
const value = data[0];
|
|
20
|
+
if (value === undefined)
|
|
21
|
+
return undefined;
|
|
22
|
+
return normalizeStripeOverageInvoice(this.#config, claim, value);
|
|
23
|
+
}
|
|
24
|
+
async createDraftInvoice(claim) {
|
|
25
|
+
const defaultPaymentMethod = await this.#defaultPaymentMethod(claim);
|
|
26
|
+
const value = await this.#api.invoices.create({
|
|
27
|
+
customer: claim.customerId,
|
|
28
|
+
auto_advance: false,
|
|
29
|
+
collection_method: 'charge_automatically',
|
|
30
|
+
automatic_tax: { enabled: false },
|
|
31
|
+
default_tax_rates: [],
|
|
32
|
+
pending_invoice_items_behavior: 'exclude',
|
|
33
|
+
discounts: '',
|
|
34
|
+
...(defaultPaymentMethod === undefined
|
|
35
|
+
? {}
|
|
36
|
+
: { default_payment_method: defaultPaymentMethod }),
|
|
37
|
+
description: invoiceDescription(claim.closure.windowStart),
|
|
38
|
+
metadata: stripeOverageMetadata(claim),
|
|
39
|
+
}, { idempotencyKey: operationKey(claim.mode, claim.closure.closureId, 'invoice') });
|
|
40
|
+
const invoice = normalizeStripeOverageInvoice(this.#config, claim, value);
|
|
41
|
+
if (invoice.status !== 'draft' ||
|
|
42
|
+
invoice.autoAdvance ||
|
|
43
|
+
invoice.lines.length !== 0 ||
|
|
44
|
+
invoice.subtotalMinor !== 0 ||
|
|
45
|
+
invoice.totalMinor !== 0) {
|
|
46
|
+
throw new Error('Stripe overage invoice draft is not empty and isolated');
|
|
47
|
+
}
|
|
48
|
+
return invoice;
|
|
49
|
+
}
|
|
50
|
+
async createInvoiceItem(claim, invoiceId) {
|
|
51
|
+
const quantity = safePositiveInteger('Stripe overage billable blocks', claim.closure.billableBlocks);
|
|
52
|
+
safePositiveInteger('Stripe overage amount', claim.closure.amountMinor);
|
|
53
|
+
const period = stripePeriod(claim.closure.windowStart, claim.closure.windowEnd);
|
|
54
|
+
const expectedInvoiceId = stripeId('invoice', 'in_', invoiceId);
|
|
55
|
+
const item = normalizeStripeOverageInvoiceItem(this.#config, claim, expectedInvoiceId, await this.#api.invoiceItems.create({
|
|
56
|
+
customer: claim.customerId,
|
|
57
|
+
invoice: expectedInvoiceId,
|
|
58
|
+
pricing: { price: claim.overagePriceId },
|
|
59
|
+
quantity,
|
|
60
|
+
discountable: false,
|
|
61
|
+
discounts: '',
|
|
62
|
+
description: `${quantity} started-million MCP overage ${quantity === 1 ? 'block' : 'blocks'}`,
|
|
63
|
+
metadata: stripeOverageMetadata(claim),
|
|
64
|
+
period,
|
|
65
|
+
}, { idempotencyKey: operationKey(claim.mode, claim.closure.closureId, 'item') }));
|
|
66
|
+
return item;
|
|
67
|
+
}
|
|
68
|
+
async retrieveInvoice(claim, invoiceId) {
|
|
69
|
+
const expectedInvoiceId = stripeId('invoice', 'in_', invoiceId);
|
|
70
|
+
const invoice = normalizeStripeOverageInvoice(this.#config, claim, await this.#api.invoices.retrieve(expectedInvoiceId));
|
|
71
|
+
assertExpectedInvoiceId(invoice, expectedInvoiceId);
|
|
72
|
+
return invoice;
|
|
73
|
+
}
|
|
74
|
+
async finalizeInvoice(claim, invoiceId) {
|
|
75
|
+
const expectedInvoiceId = stripeId('invoice', 'in_', invoiceId);
|
|
76
|
+
const invoice = normalizeStripeOverageInvoice(this.#config, claim, await this.#api.invoices.finalizeInvoice(expectedInvoiceId, { auto_advance: true }, { idempotencyKey: operationKey(claim.mode, claim.closure.closureId, 'finalize') }));
|
|
77
|
+
assertExpectedInvoiceId(invoice, expectedInvoiceId);
|
|
78
|
+
if (invoice.status === 'draft') {
|
|
79
|
+
throw new Error('Stripe overage invoice did not finalize');
|
|
80
|
+
}
|
|
81
|
+
return invoice;
|
|
82
|
+
}
|
|
83
|
+
async #defaultPaymentMethod(claim) {
|
|
84
|
+
if (claim.providerSubscriptionIds.length === 0) {
|
|
85
|
+
throw new Error('Stripe overage settlement requires provider subscription provenance');
|
|
86
|
+
}
|
|
87
|
+
for (const subscriptionId of [...claim.providerSubscriptionIds].reverse()) {
|
|
88
|
+
const subscription = stripeRecord('Stripe overage source subscription', await this.#api.subscriptions.retrieve(stripeId('subscription', 'sub_', subscriptionId)));
|
|
89
|
+
if (stripeId('subscription', 'sub_', stripeString(subscription, 'id')) !== subscriptionId) {
|
|
90
|
+
throw new Error('Stripe overage source subscription identity does not match request');
|
|
91
|
+
}
|
|
92
|
+
requireStripeMode(this.#config.mode, stripeBoolean(subscription, 'livemode'));
|
|
93
|
+
if (stripeReference('Stripe subscription customer', 'cus_', subscription.customer) !==
|
|
94
|
+
claim.customerId) {
|
|
95
|
+
throw new Error('Stripe overage source subscription customer does not match closure binding');
|
|
96
|
+
}
|
|
97
|
+
const paymentMethod = subscription.default_payment_method;
|
|
98
|
+
if (paymentMethod === null || paymentMethod === undefined)
|
|
99
|
+
continue;
|
|
100
|
+
return stripeReference('Stripe default payment method', 'pm_', paymentMethod);
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function createStripeOverageApi(secretKey) {
|
|
106
|
+
const stripe = new Stripe(secretKey, { maxNetworkRetries: 2, timeout: 10_000 });
|
|
107
|
+
return {
|
|
108
|
+
subscriptions: { retrieve: (id) => stripe.subscriptions.retrieve(id) },
|
|
109
|
+
invoices: {
|
|
110
|
+
search: (params) => stripe.invoices.search(params),
|
|
111
|
+
create: (params, options) => stripe.invoices.create(params, options),
|
|
112
|
+
retrieve: (id) => stripe.invoices.retrieve(id),
|
|
113
|
+
finalizeInvoice: (id, params, options) => stripe.invoices.finalizeInvoice(id, params, options),
|
|
114
|
+
},
|
|
115
|
+
invoiceItems: {
|
|
116
|
+
create: (params, options) => stripe.invoiceItems.create(params, options),
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function invoiceDescription(windowStart) {
|
|
121
|
+
const date = new Date(windowStart);
|
|
122
|
+
if (Number.isNaN(date.getTime()))
|
|
123
|
+
throw new Error('Stripe overage invoice window is invalid');
|
|
124
|
+
return `Noodle Seed MCP overage for ${new Intl.DateTimeFormat('en-US', {
|
|
125
|
+
month: 'long',
|
|
126
|
+
year: 'numeric',
|
|
127
|
+
timeZone: 'UTC',
|
|
128
|
+
}).format(date)}`;
|
|
129
|
+
}
|
|
130
|
+
function operationKey(mode, closureId, operation) {
|
|
131
|
+
return `noodle:stripe:${mode}:overage:${closureId}:${operation}`;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=stripe-overage-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-overage-provider.js","sourceRoot":"","sources":["../../src/billing/stripe-overage-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { BillingStripeConfig } from './stripe-config.js';
|
|
2
|
+
import type { StripeOverageBillingProvider } from './stripe-overage-provider.js';
|
|
3
|
+
import type { BillingStripeOverageStore } from './stripe-overage-store.js';
|
|
4
|
+
type OverageProvider = Pick<StripeOverageBillingProvider, 'findInvoice' | 'createDraftInvoice' | 'createInvoiceItem' | 'retrieveInvoice' | 'finalizeInvoice'>;
|
|
5
|
+
export interface BillingStripeOverageSettlementResult {
|
|
6
|
+
readonly checked: number;
|
|
7
|
+
readonly finalized: number;
|
|
8
|
+
readonly review: number;
|
|
9
|
+
readonly failed: number;
|
|
10
|
+
}
|
|
11
|
+
/** Settle immutable overage closures without coupling provider calls to database transactions. */
|
|
12
|
+
export declare class BillingStripeOverageService {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(input: {
|
|
15
|
+
readonly config: BillingStripeConfig;
|
|
16
|
+
readonly store: BillingStripeOverageStore;
|
|
17
|
+
readonly provider: OverageProvider;
|
|
18
|
+
readonly clock?: () => Date;
|
|
19
|
+
});
|
|
20
|
+
settleOverageClosures(limit: number): Promise<BillingStripeOverageSettlementResult>;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=stripe-overage-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-overage-service.d.ts","sourceRoot":"","sources":["../../src/billing/stripe-overage-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAEV,4BAA4B,EAC7B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAEV,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AAKnC,KAAK,eAAe,GAAG,IAAI,CACzB,4BAA4B,EAC5B,aAAa,GAAG,oBAAoB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,iBAAiB,CACnG,CAAC;AAEF,MAAM,WAAW,oCAAoC;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,kGAAkG;AAClG,qBAAa,2BAA2B;;gBAM1B,KAAK,EAAE;QACjB,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;QACrC,QAAQ,CAAC,KAAK,EAAE,yBAAyB,CAAC;QAC1C,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;QACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;KAC7B;IAOK,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,oCAAoC,CAAC;CA0I1F"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const INVOICE_CREATE_SAFETY_WINDOW_MS = 23 * 60 * 60 * 1_000;
|
|
2
|
+
const SETTLEMENT_RETRY_DELAY_MS = 5 * 60 * 1_000;
|
|
3
|
+
/** Settle immutable overage closures without coupling provider calls to database transactions. */
|
|
4
|
+
export class BillingStripeOverageService {
|
|
5
|
+
#config;
|
|
6
|
+
#store;
|
|
7
|
+
#provider;
|
|
8
|
+
#clock;
|
|
9
|
+
constructor(input) {
|
|
10
|
+
this.#config = input.config;
|
|
11
|
+
this.#store = input.store;
|
|
12
|
+
this.#provider = input.provider;
|
|
13
|
+
this.#clock = input.clock ?? (() => new Date());
|
|
14
|
+
}
|
|
15
|
+
async settleOverageClosures(limit) {
|
|
16
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100) {
|
|
17
|
+
throw new Error('Stripe overage settlement limit must be between 1 and 100');
|
|
18
|
+
}
|
|
19
|
+
let checked = 0;
|
|
20
|
+
let finalized = 0;
|
|
21
|
+
let review = 0;
|
|
22
|
+
let failed = 0;
|
|
23
|
+
while (checked < limit) {
|
|
24
|
+
const now = this.#clock();
|
|
25
|
+
const claimedAt = now.toISOString();
|
|
26
|
+
const claim = await this.#store.claimNext({
|
|
27
|
+
mode: this.#config.mode,
|
|
28
|
+
overageProductId: this.#config.products.overage,
|
|
29
|
+
overagePriceId: this.#config.overageBlockPriceId,
|
|
30
|
+
claimedAt,
|
|
31
|
+
});
|
|
32
|
+
if (claim === undefined)
|
|
33
|
+
break;
|
|
34
|
+
checked += 1;
|
|
35
|
+
try {
|
|
36
|
+
const outcome = await this.#settleClaim(claim, now);
|
|
37
|
+
if (outcome === 'review')
|
|
38
|
+
review += 1;
|
|
39
|
+
else
|
|
40
|
+
finalized += 1;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
failed += 1;
|
|
44
|
+
await this.#recordFailure(claim, failureCode(error), now);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { checked, finalized, review, failed };
|
|
48
|
+
}
|
|
49
|
+
async #settleClaim(initialClaim, now) {
|
|
50
|
+
let claim = initialClaim;
|
|
51
|
+
let invoice;
|
|
52
|
+
if (claim.stage === 'invoice_pending') {
|
|
53
|
+
invoice = await phase('invoice_recovery_failed', () => this.#provider.findInvoice(claim));
|
|
54
|
+
if (invoice === undefined) {
|
|
55
|
+
if (now.getTime() - new Date(claim.firstClaimedAt).getTime() >=
|
|
56
|
+
INVOICE_CREATE_SAFETY_WINDOW_MS) {
|
|
57
|
+
await phase('review_record_failed', () => this.#store.requireReview(claim, {
|
|
58
|
+
errorCode: 'invoice_create_outcome_unknown',
|
|
59
|
+
reviewedAt: now.toISOString(),
|
|
60
|
+
}));
|
|
61
|
+
return 'review';
|
|
62
|
+
}
|
|
63
|
+
invoice = await phase('invoice_create_failed', () => this.#provider.createDraftInvoice(claim));
|
|
64
|
+
}
|
|
65
|
+
claim = await phase('invoice_record_failed', () => this.#store.recordInvoice(claim, {
|
|
66
|
+
invoiceId: invoiceId(invoice),
|
|
67
|
+
recordedAt: now.toISOString(),
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
if (claim.stage === 'invoice_created') {
|
|
71
|
+
invoice ??= await phase('item_recovery_failed', () => this.#provider.retrieveInvoice(claim, requiredInvoiceId(claim)));
|
|
72
|
+
assertInvoiceIdentity(claim, invoice);
|
|
73
|
+
let invoiceItemId = invoice.lines[0]?.id;
|
|
74
|
+
let createdItem = false;
|
|
75
|
+
if (invoiceItemId === undefined) {
|
|
76
|
+
if (invoice.status !== 'draft') {
|
|
77
|
+
throw settlementError('item_recovery_failed', 'finalized Stripe overage invoice is missing its line');
|
|
78
|
+
}
|
|
79
|
+
const item = await phase('item_create_failed', () => this.#provider.createInvoiceItem(claim, requiredInvoiceId(claim)));
|
|
80
|
+
invoiceItemId = item.id;
|
|
81
|
+
createdItem = true;
|
|
82
|
+
}
|
|
83
|
+
claim = await phase('item_record_failed', () => this.#store.recordItem(claim, {
|
|
84
|
+
invoiceItemId,
|
|
85
|
+
recordedAt: now.toISOString(),
|
|
86
|
+
}));
|
|
87
|
+
if (createdItem)
|
|
88
|
+
invoice = undefined;
|
|
89
|
+
}
|
|
90
|
+
if (claim.stage !== 'item_created') {
|
|
91
|
+
throw settlementError('settlement_state_invalid', 'Stripe overage claim stage is invalid');
|
|
92
|
+
}
|
|
93
|
+
invoice ??= await phase('invoice_finalize_recovery_failed', () => this.#provider.retrieveInvoice(claim, requiredInvoiceId(claim)));
|
|
94
|
+
assertInvoiceIdentity(claim, invoice);
|
|
95
|
+
if (invoice.status === 'draft') {
|
|
96
|
+
invoice = await phase('invoice_finalize_failed', () => this.#provider.finalizeInvoice(claim, requiredInvoiceId(claim)));
|
|
97
|
+
assertInvoiceIdentity(claim, invoice);
|
|
98
|
+
}
|
|
99
|
+
if (invoice.status === 'draft') {
|
|
100
|
+
throw settlementError('invoice_finalize_failed', 'Stripe overage invoice remains a draft');
|
|
101
|
+
}
|
|
102
|
+
const providerStatus = finalizedStatus(invoice.status);
|
|
103
|
+
await phase('settlement_complete_failed', () => this.#store.complete(claim, {
|
|
104
|
+
providerStatus,
|
|
105
|
+
amountDueMinor: invoice.amountDueMinor,
|
|
106
|
+
amountPaidMinor: invoice.amountPaidMinor,
|
|
107
|
+
completedAt: now.toISOString(),
|
|
108
|
+
}));
|
|
109
|
+
return 'finalized';
|
|
110
|
+
}
|
|
111
|
+
async #recordFailure(claim, errorCode, now) {
|
|
112
|
+
try {
|
|
113
|
+
await this.#store.fail(claim, {
|
|
114
|
+
errorCode,
|
|
115
|
+
failedAt: now.toISOString(),
|
|
116
|
+
retryAt: new Date(now.getTime() + SETTLEMENT_RETRY_DELAY_MS).toISOString(),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// A lost database acknowledgement is recovered by the expired claim lease.
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function phase(code, operation) {
|
|
125
|
+
try {
|
|
126
|
+
return await operation();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (error instanceof SettlementPhaseError)
|
|
130
|
+
throw error;
|
|
131
|
+
throw new SettlementPhaseError(code, error);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
class SettlementPhaseError extends Error {
|
|
135
|
+
code;
|
|
136
|
+
constructor(code, cause) {
|
|
137
|
+
super(code, { cause });
|
|
138
|
+
this.name = 'SettlementPhaseError';
|
|
139
|
+
this.code = code;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function settlementError(code, message) {
|
|
143
|
+
return new SettlementPhaseError(code, new Error(message));
|
|
144
|
+
}
|
|
145
|
+
function failureCode(error) {
|
|
146
|
+
return error instanceof SettlementPhaseError ? error.code : 'settlement_failed';
|
|
147
|
+
}
|
|
148
|
+
function requiredInvoiceId(claim) {
|
|
149
|
+
if (claim.invoiceId === null) {
|
|
150
|
+
throw settlementError('settlement_state_invalid', 'Stripe overage claim has no invoice');
|
|
151
|
+
}
|
|
152
|
+
return claim.invoiceId;
|
|
153
|
+
}
|
|
154
|
+
function invoiceId(invoice) {
|
|
155
|
+
if (invoice === undefined) {
|
|
156
|
+
throw settlementError('invoice_recovery_failed', 'Stripe overage invoice is unavailable');
|
|
157
|
+
}
|
|
158
|
+
return invoice.id;
|
|
159
|
+
}
|
|
160
|
+
function assertInvoiceIdentity(claim, invoice) {
|
|
161
|
+
if (invoice.id !== requiredInvoiceId(claim)) {
|
|
162
|
+
throw settlementError('invoice_identity_mismatch', 'Stripe overage invoice identity changed');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function finalizedStatus(status) {
|
|
166
|
+
if (status === 'draft') {
|
|
167
|
+
throw settlementError('invoice_finalize_failed', 'Stripe overage invoice remains a draft');
|
|
168
|
+
}
|
|
169
|
+
return status;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=stripe-overage-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-overage-service.js","sourceRoot":"","sources":["../../src/billing/stripe-overage-service.ts"],"names":[],"mappings":"AAUA,MAAM,+BAA+B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AAC7D,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;AAcjD,kGAAkG;AAClG,MAAM,OAAO,2BAA2B;IAC7B,OAAO,CAAsB;IAC7B,MAAM,CAA4B;IAClC,SAAS,CAAkB;IAC3B,MAAM,CAAa;IAE5B,YAAY,KAKX;QACC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,KAAa;QACvC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,OAAO,OAAO,GAAG,KAAK,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;gBACxC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;gBACvB,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAC/C,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB;gBAChD,SAAS;aACV,CAAC,CAAC;YACH,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM;YAC/B,OAAO,IAAI,CAAC,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBACpD,IAAI,OAAO,KAAK,QAAQ;oBAAE,MAAM,IAAI,CAAC,CAAC;;oBACjC,SAAS,IAAI,CAAC,CAAC;YACtB,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,CAAC;gBACZ,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,YAAiD,EACjD,GAAS;QAET,IAAI,KAAK,GAAG,YAAY,CAAC;QACzB,IAAI,OAAgD,CAAC;QAErD,IAAI,KAAK,CAAC,KAAK,KAAK,iBAAiB,EAAE,CAAC;YACtC,OAAO,GAAG,MAAM,KAAK,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1F,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,IACE,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE;oBACxD,+BAA+B,EAC/B,CAAC;oBACD,MAAM,KAAK,CAAC,sBAAsB,EAAE,GAAG,EAAE,CACvC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE;wBAC/B,SAAS,EAAE,gCAAgC;wBAC3C,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE;qBAC9B,CAAC,CACH,CAAC;oBACF,OAAO,QAAQ,CAAC;gBAClB,CAAC;gBACD,OAAO,GAAG,MAAM,KAAK,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAClD,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,KAAK,CAAC,CACzC,CAAC;YACJ,CAAC;YACD,KAAK,GAAG,MAAM,KAAK,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAChD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE;gBAC/B,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC;gBAC7B,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE;aAC9B,CAAC,CACH,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,KAAK,iBAAiB,EAAE,CAAC;YACtC,OAAO,KAAK,MAAM,KAAK,CAAC,sBAAsB,EAAE,GAAG,EAAE,CACnD,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAChE,CAAC;YACF,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACtC,IAAI,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;gBAChC,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;oBAC/B,MAAM,eAAe,CACnB,sBAAsB,EACtB,sDAAsD,CACvD,CAAC;gBACJ,CAAC;gBACD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAClD,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAClE,CAAC;gBACF,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC;gBACxB,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;YACD,KAAK,GAAG,MAAM,KAAK,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAC7C,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE;gBAC5B,aAAa;gBACb,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE;aAC9B,CAAC,CACH,CAAC;YACF,IAAI,WAAW;gBAAE,OAAO,GAAG,SAAS,CAAC;QACvC,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,KAAK,cAAc,EAAE,CAAC;YACnC,MAAM,eAAe,CAAC,0BAA0B,EAAE,uCAAuC,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO,KAAK,MAAM,KAAK,CAAC,kCAAkC,EAAE,GAAG,EAAE,CAC/D,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAChE,CAAC;QACF,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC/B,OAAO,GAAG,MAAM,KAAK,CAAC,yBAAyB,EAAE,GAAG,EAAE,CACpD,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAChE,CAAC;YACF,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,eAAe,CAAC,yBAAyB,EAAE,wCAAwC,CAAC,CAAC;QAC7F,CAAC;QACD,MAAM,cAAc,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,KAAK,CAAC,4BAA4B,EAAE,GAAG,EAAE,CAC7C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE;YAC1B,cAAc;YACd,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE;SAC/B,CAAC,CACH,CAAC;QACF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAA0C,EAC1C,SAAiB,EACjB,GAAS;QAET,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE;gBAC5B,SAAS;gBACT,QAAQ,EAAE,GAAG,CAAC,WAAW,EAAE;gBAC3B,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,yBAAyB,CAAC,CAAC,WAAW,EAAE;aAC3E,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,2EAA2E;QAC7E,CAAC;IACH,CAAC;CACF;AAED,KAAK,UAAU,KAAK,CAAI,IAAY,EAAE,SAA2B;IAC/D,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,oBAAoB;YAAE,MAAM,KAAK,CAAC;QACvD,MAAM,IAAI,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,MAAM,oBAAqB,SAAQ,KAAK;IAC7B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,KAAc;QACtC,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,OAAe;IACpD,OAAO,IAAI,oBAAoB,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,YAAY,oBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC;AAClF,CAAC;AAED,SAAS,iBAAiB,CAAC,KAA0C;IACnE,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,eAAe,CAAC,0BAA0B,EAAE,qCAAqC,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,KAAK,CAAC,SAAS,CAAC;AACzB,CAAC;AAED,SAAS,SAAS,CAAC,OAAgD;IACjE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,eAAe,CAAC,yBAAyB,EAAE,uCAAuC,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,OAAO,CAAC,EAAE,CAAC;AACpB,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAA0C,EAC1C,OAAoC;IAEpC,IAAI,OAAO,CAAC,EAAE,KAAK,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,MAAM,eAAe,CAAC,2BAA2B,EAAE,yCAAyC,CAAC,CAAC;IAChG,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CACtB,MAA6C;IAE7C,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,MAAM,eAAe,CAAC,yBAAyB,EAAE,wCAAwC,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { BillingOverageWindowClosure } from './overage-window-closure.js';
|
|
2
|
+
import type { BillingStripeMode } from './stripe-config.js';
|
|
3
|
+
export type BillingStripeOverageStage = 'invoice_pending' | 'invoice_created' | 'item_created' | 'finalized' | 'review_required';
|
|
4
|
+
export type BillingStripeOverageProviderStatus = 'draft' | 'open' | 'paid' | 'void' | 'uncollectible';
|
|
5
|
+
export interface BillingStripeOverageSettlementClaim {
|
|
6
|
+
readonly mode: BillingStripeMode;
|
|
7
|
+
readonly closure: BillingOverageWindowClosure;
|
|
8
|
+
readonly customerId: string;
|
|
9
|
+
readonly overageProductId: string;
|
|
10
|
+
readonly overagePriceId: string;
|
|
11
|
+
/** Distinct source subscriptions ordered oldest to newest for transient payment-method fallback. */
|
|
12
|
+
readonly providerSubscriptionIds: readonly string[];
|
|
13
|
+
readonly stage: BillingStripeOverageStage;
|
|
14
|
+
readonly attempt: number;
|
|
15
|
+
readonly firstClaimedAt: string;
|
|
16
|
+
readonly invoiceId: string | null;
|
|
17
|
+
readonly invoiceItemId: string | null;
|
|
18
|
+
readonly providerStatus: BillingStripeOverageProviderStatus | null;
|
|
19
|
+
}
|
|
20
|
+
export interface BillingStripeOverageStore {
|
|
21
|
+
claimNext(input: {
|
|
22
|
+
readonly mode: BillingStripeMode;
|
|
23
|
+
readonly overageProductId: string;
|
|
24
|
+
readonly overagePriceId: string;
|
|
25
|
+
readonly claimedAt: string;
|
|
26
|
+
}): Promise<BillingStripeOverageSettlementClaim | undefined>;
|
|
27
|
+
recordInvoice(claim: BillingStripeOverageSettlementClaim, input: {
|
|
28
|
+
readonly invoiceId: string;
|
|
29
|
+
readonly recordedAt: string;
|
|
30
|
+
}): Promise<BillingStripeOverageSettlementClaim>;
|
|
31
|
+
recordItem(claim: BillingStripeOverageSettlementClaim, input: {
|
|
32
|
+
readonly invoiceItemId: string;
|
|
33
|
+
readonly recordedAt: string;
|
|
34
|
+
}): Promise<BillingStripeOverageSettlementClaim>;
|
|
35
|
+
complete(claim: BillingStripeOverageSettlementClaim, input: {
|
|
36
|
+
readonly providerStatus: Exclude<BillingStripeOverageProviderStatus, 'draft'>;
|
|
37
|
+
readonly amountDueMinor: number;
|
|
38
|
+
readonly amountPaidMinor: number;
|
|
39
|
+
readonly completedAt: string;
|
|
40
|
+
}): Promise<BillingStripeOverageSettlementClaim>;
|
|
41
|
+
fail(claim: BillingStripeOverageSettlementClaim, input: {
|
|
42
|
+
readonly errorCode: string;
|
|
43
|
+
readonly failedAt: string;
|
|
44
|
+
readonly retryAt: string;
|
|
45
|
+
}): Promise<void>;
|
|
46
|
+
requireReview(claim: BillingStripeOverageSettlementClaim, input: {
|
|
47
|
+
readonly errorCode: string;
|
|
48
|
+
readonly reviewedAt: string;
|
|
49
|
+
}): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=stripe-overage-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-overage-store.d.ts","sourceRoot":"","sources":["../../src/billing/stripe-overage-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,MAAM,yBAAyB,GACjC,iBAAiB,GACjB,iBAAiB,GACjB,cAAc,GACd,WAAW,GACX,iBAAiB,CAAC;AAEtB,MAAM,MAAM,kCAAkC,GAC1C,OAAO,GACP,MAAM,GACN,MAAM,GACN,MAAM,GACN,eAAe,CAAC;AAEpB,MAAM,WAAW,mCAAmC;IAClD,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,oGAAoG;IACpG,QAAQ,CAAC,uBAAuB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,yBAAyB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,kCAAkC,GAAG,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,KAAK,EAAE;QACf,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;QACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;QAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,mCAAmC,GAAG,SAAS,CAAC,CAAC;IAC7D,aAAa,CACX,KAAK,EAAE,mCAAmC,EAC1C,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACjE,OAAO,CAAC,mCAAmC,CAAC,CAAC;IAChD,UAAU,CACR,KAAK,EAAE,mCAAmC,EAC1C,KAAK,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACrE,OAAO,CAAC,mCAAmC,CAAC,CAAC;IAChD,QAAQ,CACN,KAAK,EAAE,mCAAmC,EAC1C,KAAK,EAAE;QACL,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;QAC9E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;QACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;KAC9B,GACA,OAAO,CAAC,mCAAmC,CAAC,CAAC;IAChD,IAAI,CACF,KAAK,EAAE,mCAAmC,EAC1C,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GACzF,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,aAAa,CACX,KAAK,EAAE,mCAAmC,EAC1C,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACjE,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-overage-store.js","sourceRoot":"","sources":["../../src/billing/stripe-overage-store.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/oauth/app.ts"],"names":[],"mappings":"AAIA,OAAgB,EAAE,KAAK,OAAO,EAA+B,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/oauth/app.ts"],"names":[],"mappings":"AAIA,OAAgB,EAAE,KAAK,OAAO,EAA+B,MAAM,SAAS,CAAC;AAG7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAuIT;AA0CD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { clientRegistrationHandler } from '@modelcontextprotocol/sdk/server/auth
|
|
|
3
3
|
import { revocationHandler } from '@modelcontextprotocol/sdk/server/auth/handlers/revoke.js';
|
|
4
4
|
import { tokenHandler } from '@modelcontextprotocol/sdk/server/auth/handlers/token.js';
|
|
5
5
|
import express, {} from 'express';
|
|
6
|
+
import { rateLimit as createRateLimit } from 'express-rate-limit';
|
|
6
7
|
import { renderOAuthErrorPage } from './branding.js';
|
|
7
8
|
export function createOAuthApp(provider, options = {}) {
|
|
8
9
|
const app = express();
|
|
@@ -17,7 +18,64 @@ export function createOAuthApp(provider, options = {}) {
|
|
|
17
18
|
xForwardedForHeader: false,
|
|
18
19
|
},
|
|
19
20
|
};
|
|
21
|
+
app.use(['/device_authorization', '/device', '/oauth/device/callback'], createRateLimit({
|
|
22
|
+
windowMs: 60_000,
|
|
23
|
+
limit: 30,
|
|
24
|
+
standardHeaders: true,
|
|
25
|
+
legacyHeaders: false,
|
|
26
|
+
...rateLimit,
|
|
27
|
+
}), createRateLimit({
|
|
28
|
+
windowMs: 60_000,
|
|
29
|
+
limit: 600,
|
|
30
|
+
standardHeaders: false,
|
|
31
|
+
legacyHeaders: false,
|
|
32
|
+
keyGenerator: transportRateLimitKey,
|
|
33
|
+
validate: rateLimit.validate,
|
|
34
|
+
}));
|
|
35
|
+
const deviceTokenRateLimit = createRateLimit({
|
|
36
|
+
windowMs: 60_000,
|
|
37
|
+
limit: 30,
|
|
38
|
+
standardHeaders: true,
|
|
39
|
+
legacyHeaders: false,
|
|
40
|
+
...rateLimit,
|
|
41
|
+
});
|
|
42
|
+
const deviceTokenTransportRateLimit = createRateLimit({
|
|
43
|
+
windowMs: 60_000,
|
|
44
|
+
limit: 600,
|
|
45
|
+
standardHeaders: false,
|
|
46
|
+
legacyHeaders: false,
|
|
47
|
+
keyGenerator: transportRateLimitKey,
|
|
48
|
+
validate: rateLimit.validate,
|
|
49
|
+
});
|
|
20
50
|
app.use('/authorize', authorizationHandler({ provider, rateLimit }));
|
|
51
|
+
app.post('/device_authorization', express.urlencoded({ extended: false }), (req, res) => {
|
|
52
|
+
void provider.deviceAuthorizationFlow
|
|
53
|
+
.handleAuthorization(req, res)
|
|
54
|
+
.catch(() => failJson(res));
|
|
55
|
+
});
|
|
56
|
+
app.get('/device', (req, res) => {
|
|
57
|
+
provider.deviceAuthorizationFlow.handleVerificationPage(req, res);
|
|
58
|
+
});
|
|
59
|
+
app.post('/device', express.urlencoded({ extended: false }), (req, res) => {
|
|
60
|
+
void provider.deviceAuthorizationFlow.handleVerification(req, res).catch(() => failPlain(res));
|
|
61
|
+
});
|
|
62
|
+
app.get('/oauth/device/callback', (req, res) => {
|
|
63
|
+
void provider.deviceAuthorizationFlow.handleCallback(req, res).catch(() => failPlain(res));
|
|
64
|
+
});
|
|
65
|
+
app.use(express.urlencoded({ extended: false }));
|
|
66
|
+
app.use('/token', allowCors);
|
|
67
|
+
app.use('/token', (req, res, next) => {
|
|
68
|
+
const body = (req.body ?? {});
|
|
69
|
+
if (body.grant_type !== 'urn:ietf:params:oauth:grant-type:device_code') {
|
|
70
|
+
next();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
deviceTokenTransportRateLimit(req, res, () => {
|
|
74
|
+
deviceTokenRateLimit(req, res, () => {
|
|
75
|
+
void provider.deviceAuthorizationFlow.handleToken(req, res).catch(() => failJson(res));
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
21
79
|
app.use('/token', tokenHandler({ provider, rateLimit }));
|
|
22
80
|
app.use('/revoke', revocationHandler({ provider, rateLimit }));
|
|
23
81
|
app.use('/register', clientRegistrationHandler({ clientsStore: provider.clientsStore, rateLimit }));
|
|
@@ -63,6 +121,10 @@ function failPlain(res) {
|
|
|
63
121
|
if (!res.headersSent)
|
|
64
122
|
res.status(500).type('text/html').send(renderOAuthErrorPage());
|
|
65
123
|
}
|
|
124
|
+
function failJson(res) {
|
|
125
|
+
if (!res.headersSent)
|
|
126
|
+
res.status(500).json({ error: 'server_error' });
|
|
127
|
+
}
|
|
66
128
|
function rateLimitKey(req, trustProxy) {
|
|
67
129
|
if (trustProxy) {
|
|
68
130
|
const forwarded = firstForwardedFor(req.headers.forwarded);
|
|
@@ -74,6 +136,9 @@ function rateLimitKey(req, trustProxy) {
|
|
|
74
136
|
}
|
|
75
137
|
return req.ip ?? req.socket.remoteAddress ?? 'unknown';
|
|
76
138
|
}
|
|
139
|
+
function transportRateLimitKey(req) {
|
|
140
|
+
return req.socket.remoteAddress ?? 'unknown';
|
|
141
|
+
}
|
|
77
142
|
function firstForwardedFor(value) {
|
|
78
143
|
const raw = firstHeaderValue(value);
|
|
79
144
|
if (!raw)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/oauth/app.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/oauth/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6DAA6D,CAAC;AACnG,OAAO,EAAE,yBAAyB,EAAE,MAAM,4DAA4D,CAAC;AACvG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,MAAM,yDAAyD,CAAC;AACvF,OAAO,OAAO,EAAE,EAA6C,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAgBrD,MAAM,UAAU,cAAc,CAC5B,QAA6B,EAC7B,UAA2B,EAAE;IAE7B,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5B,IAAI,OAAO,CAAC,UAAU;QAAE,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAErD,MAAM,SAAS,GAAG;QAChB,YAAY,EAAE,CAAC,GAAY,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC;QAC9E,QAAQ,EAAE;YACR,eAAe,EAAE,KAAK;YACtB,sBAAsB,EAAE,KAAK;YAC7B,mBAAmB,EAAE,KAAK;SAC3B;KACF,CAAC;IAEF,GAAG,CAAC,GAAG,CACL,CAAC,uBAAuB,EAAE,SAAS,EAAE,wBAAwB,CAAC,EAC9D,eAAe,CAAC;QACd,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,EAAE;QACT,eAAe,EAAE,IAAI;QACrB,aAAa,EAAE,KAAK;QACpB,GAAG,SAAS;KACb,CAAC,EACF,eAAe,CAAC;QACd,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,GAAG;QACV,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,qBAAqB;QACnC,QAAQ,EAAE,SAAS,CAAC,QAAQ;KAC7B,CAAC,CACH,CAAC;IACF,MAAM,oBAAoB,GAAG,eAAe,CAAC;QAC3C,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,EAAE;QACT,eAAe,EAAE,IAAI;QACrB,aAAa,EAAE,KAAK;QACpB,GAAG,SAAS;KACb,CAAC,CAAC;IACH,MAAM,6BAA6B,GAAG,eAAe,CAAC;QACpD,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,GAAG;QACV,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,qBAAqB;QACnC,QAAQ,EAAE,SAAS,CAAC,QAAQ;KAC7B,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,oBAAoB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IACrE,GAAG,CAAC,IAAI,CACN,uBAAuB,EACvB,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EACvC,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC9B,KAAK,QAAQ,CAAC,uBAAuB;aAClC,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC;aAC7B,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,CAAC,CACF,CAAC;IACF,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QACjD,QAAQ,CAAC,uBAAuB,CAAC,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC3F,KAAK,QAAQ,CAAC,uBAAuB,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAChE,KAAK,QAAQ,CAAC,uBAAuB,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACjD,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC7B,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,IAAgB,EAAE,EAAE;QAClE,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QACzD,IAAI,IAAI,CAAC,UAAU,KAAK,8CAA8C,EAAE,CAAC;YACvE,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,6BAA6B,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;YAC3C,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;gBAClC,KAAK,QAAQ,CAAC,uBAAuB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YACzF,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IACzD,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAC/D,GAAG,CAAC,GAAG,CACL,WAAW,EACX,yBAAyB,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,SAAS,EAAE,CAAC,CAC9E,CAAC;IAEF,8FAA8F;IAC9F,GAAG,CAAC,GAAG,CAAC,yCAAyC,EAAE,SAAS,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QAC7F,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,wBAAwB,EAAE,SAAS,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QAC5E,KAAK,QAAQ;aACV,IAAI,EAAE;aACN,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC9B,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,4FAA4F;IAC5F,GAAG,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAChE,KAAK,QAAQ,CAAC,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,CACN,gBAAgB,EAChB,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EACvC,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC9B,KAAK,QAAQ,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC,CACF,CAAC;IACF,GAAG,CAAC,IAAI,CACN,wBAAwB,EACxB,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EACvC,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC9B,KAAK,QAAQ,CAAC,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,CAAC,CACF,CAAC;IACF,GAAG,CAAC,IAAI,CACN,mCAAmC,EACnC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EACvC,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC9B,KAAK,QAAQ,CAAC,8BAA8B,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACrF,CAAC,CACF,CAAC;IACF,GAAG,CAAC,GAAG,CAAC,oCAAoC,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC5E,KAAK,QAAQ,CAAC,+BAA+B,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,mCAAmC,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC3E,KAAK,QAAQ,CAAC,8BAA8B,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,oCAAoC,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC5E,KAAK,QAAQ,CAAC,+BAA+B,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAAC,IAAa,EAAE,GAAa,EAAE,IAAgB;IAC/D,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;IAClD,IAAI,EAAE,CAAC;AACT,CAAC;AAED,SAAS,SAAS,CAAC,GAAa;IAC9B,IAAI,CAAC,GAAG,CAAC,WAAW;QAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;AACvF,CAAC;AAED,SAAS,QAAQ,CAAC,GAAa;IAC7B,IAAI,CAAC,GAAG,CAAC,WAAW;QAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,YAAY,CAAC,GAAY,EAAE,UAAmB;IACrD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC3D,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAChC,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACvE,IAAI,aAAa;YAAE,OAAO,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,aAAa,CAAC;IACjF,CAAC;IACD,OAAO,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;AACzD,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAY;IACzC,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;AAC/C,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAoC;IAC7D,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IACvC,MAAM,KAAK,GAAG,+BAA+B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1D,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAoC;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Request, Response } from 'express';
|
|
2
|
+
import type { NoodleOAuthProvider } from './provider.js';
|
|
3
|
+
import type { OAuthStore } from './store.js';
|
|
4
|
+
export declare const DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
5
|
+
/** RFC 8628 endpoints, backed by the existing authorization-code consent path in the browser. */
|
|
6
|
+
export declare class DeviceAuthorizationFlow {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(input: {
|
|
9
|
+
readonly issuer: string;
|
|
10
|
+
readonly store: OAuthStore;
|
|
11
|
+
readonly provider: NoodleOAuthProvider;
|
|
12
|
+
readonly now?: () => number;
|
|
13
|
+
});
|
|
14
|
+
handleAuthorization(req: Request, res: Response): Promise<void>;
|
|
15
|
+
handleVerificationPage(req: Request, res: Response): void;
|
|
16
|
+
handleVerification(req: Request, res: Response): Promise<void>;
|
|
17
|
+
handleCallback(req: Request, res: Response): Promise<void>;
|
|
18
|
+
handleToken(req: Request, res: Response): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=device-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../src/oauth/device-flow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,eAAO,MAAM,YAAY,iDAAiD,CAAC;AAI3E,iGAAiG;AACjG,qBAAa,uBAAuB;;gBAMtB,KAAK,EAAE;QACjB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;QAC3B,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;QACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;KAC7B;IAOK,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDrE,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAKnD,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAqC9D,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB1D,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAwD9D"}
|