@schematichq/schematic-typescript-node 1.4.8 → 1.5.1
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 +111 -6
- package/dist/Client.d.ts +8 -0
- package/dist/api/resources/credits/client/Client.d.ts +0 -48
- package/dist/api/resources/credits/client/requests/index.d.ts +0 -2
- package/dist/api/resources/credits/types/index.d.ts +0 -4
- package/dist/api/resources/plangroups/client/Client.d.ts +2 -0
- package/dist/api/resources/plangroups/client/requests/CreatePlanGroupRequestBody.d.ts +4 -0
- package/dist/api/resources/plangroups/client/requests/UpdatePlanGroupRequestBody.d.ts +4 -0
- package/dist/api/resources/plans/client/Client.d.ts +1 -5
- package/dist/api/resources/plans/client/requests/RetryCustomPlanBillingRequestBody.d.ts +1 -6
- package/dist/api/types/BillingCreditGrantZeroedOutReason.d.ts +1 -0
- package/dist/api/types/ChangeSubscriptionInternalRequestBody.d.ts +1 -0
- package/dist/api/types/ChangeSubscriptionRequestBody.d.ts +1 -0
- package/dist/api/types/CheckoutSettingsResponseData.d.ts +3 -0
- package/dist/api/types/FeatureEntitlement.d.ts +5 -1
- package/dist/api/types/PlanChangeResponseData.d.ts +2 -0
- package/dist/api/types/PreviewSubscriptionChangeResponseData.d.ts +3 -0
- package/dist/api/types/RulesengineFeatureEntitlement.d.ts +5 -1
- package/dist/api/types/index.d.ts +0 -2
- package/dist/cache/redis.d.ts +29 -2
- package/dist/credits/check.d.ts +49 -0
- package/dist/credits/index.d.ts +7 -0
- package/dist/credits/lease-manager.d.ts +68 -0
- package/dist/credits/lease-store.d.ts +133 -0
- package/dist/credits/redis-lease-store.d.ts +30 -0
- package/dist/credits/redis-reservation-store.d.ts +46 -0
- package/dist/credits/reservation-store.d.ts +64 -0
- package/dist/credits/track.d.ts +44 -0
- package/dist/credits/types.d.ts +175 -0
- package/dist/datastream/datastream-client.d.ts +19 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +85 -3
- package/dist/rules-engine.d.ts +3 -1
- package/dist/serialization/resources/credits/types/index.d.ts +0 -4
- package/dist/serialization/resources/plangroups/client/requests/CreatePlanGroupRequestBody.d.ts +3 -0
- package/dist/serialization/resources/plangroups/client/requests/UpdatePlanGroupRequestBody.d.ts +3 -0
- package/dist/serialization/resources/plans/client/requests/RetryCustomPlanBillingRequestBody.d.ts +0 -2
- package/dist/serialization/types/BillingCreditGrantZeroedOutReason.d.ts +1 -1
- package/dist/serialization/types/ChangeSubscriptionInternalRequestBody.d.ts +1 -0
- package/dist/serialization/types/ChangeSubscriptionRequestBody.d.ts +1 -0
- package/dist/serialization/types/CheckoutSettingsResponseData.d.ts +3 -0
- package/dist/serialization/types/FeatureEntitlement.d.ts +2 -0
- package/dist/serialization/types/PlanChangeResponseData.d.ts +1 -0
- package/dist/serialization/types/PreviewSubscriptionChangeResponseData.d.ts +3 -0
- package/dist/serialization/types/RulesengineFeatureEntitlement.d.ts +2 -0
- package/dist/serialization/types/index.d.ts +0 -2
- package/dist/wasm/rulesengine.js +4 -4
- package/dist/wrapper.d.ts +158 -6
- package/package.json +5 -4
- package/dist/api/resources/credits/client/requests/CountCreditLedgerRequest.d.ts +0 -26
- package/dist/api/resources/credits/client/requests/GetEnrichedCreditLedgerRequest.d.ts +0 -26
- package/dist/api/resources/credits/types/CountCreditLedgerParams.d.ts +0 -16
- package/dist/api/resources/credits/types/CountCreditLedgerResponse.d.ts +0 -6
- package/dist/api/resources/credits/types/GetEnrichedCreditLedgerParams.d.ts +0 -16
- package/dist/api/resources/credits/types/GetEnrichedCreditLedgerResponse.d.ts +0 -6
- package/dist/api/types/CreditLedgerEnrichedEntryResponseData.d.ts +0 -25
- package/dist/api/types/CreditLedgerPeriod.d.ts +0 -7
- package/dist/serialization/resources/credits/types/CountCreditLedgerParams.d.ts +0 -17
- package/dist/serialization/resources/credits/types/CountCreditLedgerResponse.d.ts +0 -12
- package/dist/serialization/resources/credits/types/GetEnrichedCreditLedgerParams.d.ts +0 -17
- package/dist/serialization/resources/credits/types/GetEnrichedCreditLedgerResponse.d.ts +0 -12
- package/dist/serialization/types/CreditLedgerEnrichedEntryResponseData.d.ts +0 -33
- package/dist/serialization/types/CreditLedgerPeriod.d.ts +0 -7
package/README.md
CHANGED
|
@@ -96,17 +96,17 @@ class CustomLogger implements Logger {
|
|
|
96
96
|
// Your custom error logging logic
|
|
97
97
|
console.error(`[ERROR] ${message}`, ...args);
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
warn(message: string, ...args: any[]): void {
|
|
101
101
|
// Your custom warning logging logic
|
|
102
102
|
console.warn(`[WARN] ${message}`, ...args);
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
info(message: string, ...args: any[]): void {
|
|
106
106
|
// Your custom info logging logic
|
|
107
107
|
console.info(`[INFO] ${message}`, ...args);
|
|
108
108
|
}
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
debug(message: string, ...args: any[]): void {
|
|
111
111
|
// Your custom debug logging logic
|
|
112
112
|
console.debug(`[DEBUG] ${message}`, ...args);
|
|
@@ -683,7 +683,7 @@ export default {
|
|
|
683
683
|
ttl: 1000 * 60 * 60, // 1 hour cache TTL
|
|
684
684
|
keyPrefix: 'schematic:', // Optional prefix for KV keys
|
|
685
685
|
});
|
|
686
|
-
|
|
686
|
+
|
|
687
687
|
// Initialize Schematic with the KV cache
|
|
688
688
|
const schematic = new SchematicClient({
|
|
689
689
|
apiKey: env.SCHEMATIC_API_KEY,
|
|
@@ -691,10 +691,10 @@ export default {
|
|
|
691
691
|
flagChecks: [cache],
|
|
692
692
|
}
|
|
693
693
|
});
|
|
694
|
-
|
|
694
|
+
|
|
695
695
|
// Your application logic...
|
|
696
696
|
// ...
|
|
697
|
-
|
|
697
|
+
|
|
698
698
|
// Don't forget to close the client when done
|
|
699
699
|
schematic.close();
|
|
700
700
|
}
|
|
@@ -798,6 +798,111 @@ const client = new SchematicClient({
|
|
|
798
798
|
| `replicatorHealthCheck` | `number` | 30000 | Health check polling interval in milliseconds |
|
|
799
799
|
| `cacheTTL` | `number` | 24 hours | Cache TTL in milliseconds |
|
|
800
800
|
|
|
801
|
+
## Credit Leases and Reservations
|
|
802
|
+
|
|
803
|
+
For features metered by credit burndown (e.g. inference tokens), the SDK can enforce credit balances locally — without a Schematic API call on every check — using a lease-and-reservation system:
|
|
804
|
+
|
|
805
|
+
- A **lease** is a tranche of credits acquired transactionally from Schematic's API. It functions as a hold against the company's credit balance until it is consumed, released, or expires.
|
|
806
|
+
- A **reservation** is a client-side hold carved out of the lease at check time, sized to the upper bound of the operation's usage. This protects against races and over-spend between the check and the eventual usage report.
|
|
807
|
+
- When the work completes, a track call reports actual usage; the difference between reserved and actual usage is refunded to the lease.
|
|
808
|
+
|
|
809
|
+
> **Requirements:** Credit leases require [DataStream](#datastream) (or [Replicator Mode](#replicator-mode)) — lease-bearing checks are evaluated locally against cached flag and company state. In a horizontally-scaled deployment, a shared Redis backend is also required so that all SDK instances gate against the same lease balance; without one, lease state is per-process.
|
|
810
|
+
|
|
811
|
+
### Setup
|
|
812
|
+
|
|
813
|
+
```ts
|
|
814
|
+
import { createClient } from "redis";
|
|
815
|
+
import { SchematicClient } from "@schematichq/schematic-typescript-node";
|
|
816
|
+
|
|
817
|
+
const redisClient = createClient({ url: "redis://localhost:6379" });
|
|
818
|
+
await redisClient.connect();
|
|
819
|
+
|
|
820
|
+
const client = new SchematicClient({
|
|
821
|
+
apiKey: process.env.SCHEMATIC_API_KEY,
|
|
822
|
+
useDataStream: true,
|
|
823
|
+
dataStream: {
|
|
824
|
+
redisClient, // also backs lease + reservation state automatically
|
|
825
|
+
},
|
|
826
|
+
creditLeases: {
|
|
827
|
+
defaultLeaseDuration: 5 * 60 * 1000, // lease lifetime (ms)
|
|
828
|
+
defaultReservationTTL: 60 * 1000, // how long a reservation is held if not settled by a track (ms)
|
|
829
|
+
defaultLeaseSize: 10_000, // credits requested per lease
|
|
830
|
+
lowWaterMark: 0.25, // extend the lease in the background when its balance dips below this fraction
|
|
831
|
+
},
|
|
832
|
+
});
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
When `dataStream.redisClient` is configured, lease and reservation state automatically lives in the same Redis, with atomic reservations driven by Lua scripts — no additional configuration needed. To point lease state at a *different* Redis, set `creditLeases.redisClient` explicitly.
|
|
836
|
+
|
|
837
|
+
### Checking and tracking
|
|
838
|
+
|
|
839
|
+
`check()` reserves the operation's upper-bound usage against the lease and returns a reservation handle; `trackWithReservation()` settles it with actual usage:
|
|
840
|
+
|
|
841
|
+
```ts
|
|
842
|
+
// Per-request: reserve up to maxTokens against the lease.
|
|
843
|
+
const result = await client.check(
|
|
844
|
+
{ company: { id: "your-company-id" } },
|
|
845
|
+
"inference",
|
|
846
|
+
{
|
|
847
|
+
usage: maxTokens, // upper bound for this operation
|
|
848
|
+
eventSubtype: "inference_tokens", // the metered event
|
|
849
|
+
},
|
|
850
|
+
);
|
|
851
|
+
if (!result.allowed) {
|
|
852
|
+
throw new Error("credit balance exceeded");
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
const inference = await runInference(/* ... */);
|
|
856
|
+
|
|
857
|
+
// Report actual usage; the unused slice of the reservation is refunded to the lease.
|
|
858
|
+
await client.trackWithReservation(result.reservation!, inference.tokensUsed);
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
If the caller never settles a reservation, it expires after `defaultReservationTTL` and its credits are returned to the lease. If the work outlives the reservation's TTL, `trackWithReservation` still bills the usage — the track event carries a deterministic idempotency key, so duplicate or recovery emits never double-bill. However, the local lease balance is not re-debited on that late settle (the expired reservation's hold was already swept back to the lease), so it reads high until the lease rolls over. **Set `defaultReservationTTL` above the longest expected gap between `check()` and `trackWithReservation()`** to keep the local balance accurate.
|
|
862
|
+
|
|
863
|
+
### Pre-warming
|
|
864
|
+
|
|
865
|
+
To avoid paying the lease-acquire round trip on a session's first check, pre-warm leases when the user is identified:
|
|
866
|
+
|
|
867
|
+
```ts
|
|
868
|
+
await client.identify(
|
|
869
|
+
{
|
|
870
|
+
keys: { userId: "your-user-id" },
|
|
871
|
+
company: { keys: { id: "your-company-id" } },
|
|
872
|
+
},
|
|
873
|
+
{ prewarm: ["credit-type-id"] }, // credit type IDs to acquire leases for
|
|
874
|
+
);
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
Or call `client.prewarm(evalCtx, creditTypeIds)` directly.
|
|
878
|
+
|
|
879
|
+
### Failure behavior
|
|
880
|
+
|
|
881
|
+
By default, a check that cannot be gated (API unreachable, Redis down, lease exhausted) **fails closed** (`allowed: false`). Override per check for callers where letting traffic through is preferable to a denial:
|
|
882
|
+
|
|
883
|
+
```ts
|
|
884
|
+
const result = await client.check(evalCtx, "inference", {
|
|
885
|
+
usage: maxTokens,
|
|
886
|
+
eventSubtype: "inference_tokens",
|
|
887
|
+
onAcquireFailure: "fail-open",
|
|
888
|
+
});
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
`fail-open` does not skip evaluation: the flag's rules still run with the credit balance assumed sufficient, so plan targeting, overrides, and all non-credit conditions still apply — only the credit gate is bypassed.
|
|
892
|
+
|
|
893
|
+
### Configuration options
|
|
894
|
+
|
|
895
|
+
| Option | Type | Default | Description |
|
|
896
|
+
|---|---|---|---|
|
|
897
|
+
| `defaultLeaseDuration` | `number` | 5 minutes | Lease lifetime in milliseconds |
|
|
898
|
+
| `defaultReservationTTL` | `number` | 60 seconds | How long an unsettled reservation is held (ms); set above your longest expected work duration |
|
|
899
|
+
| `defaultLeaseSize` | `number` | 10000 | Credits requested per lease acquire/extend |
|
|
900
|
+
| `lowWaterMark` | `number` | 0.25 | Extend in the background when the lease balance dips below this fraction |
|
|
901
|
+
| `sweepIntervalMs` | `number` | 1000 | Sweep interval for expired reservations (ms) |
|
|
902
|
+
| `redisClient` | `RedisClient` | `dataStream.redisClient` | Redis client for lease + reservation state |
|
|
903
|
+
| `redisKeyPrefix` | `string` | `dataStream.redisKeyPrefix` | Key prefix for lease + reservation keys |
|
|
904
|
+
| `overrides` | `object` | — | Per-credit-type overrides of the above (keyed by credit type ID) |
|
|
905
|
+
|
|
801
906
|
## Testing
|
|
802
907
|
|
|
803
908
|
### Offline mode
|
package/dist/Client.d.ts
CHANGED
|
@@ -69,6 +69,14 @@ export declare class SchematicClient {
|
|
|
69
69
|
get scheduledcheckout(): ScheduledcheckoutClient;
|
|
70
70
|
get accesstokens(): AccesstokensClient;
|
|
71
71
|
get webhooks(): WebhooksClient;
|
|
72
|
+
/**
|
|
73
|
+
* @param {SchematicClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* await client.getCreditLedger()
|
|
77
|
+
*/
|
|
78
|
+
getCreditLedger(requestOptions?: SchematicClient.RequestOptions): core.HttpResponsePromise<void>;
|
|
79
|
+
private __getCreditLedger;
|
|
72
80
|
/**
|
|
73
81
|
* Make a passthrough request using the SDK's configured auth, retry, logging, etc.
|
|
74
82
|
* This is useful for making requests to endpoints not yet supported in the SDK.
|
|
@@ -419,54 +419,6 @@ export declare class CreditsClient {
|
|
|
419
419
|
*/
|
|
420
420
|
releaseCreditLease(lease_id: string, request: Schematic.ReleaseCreditLeaseRequestBody, requestOptions?: CreditsClient.RequestOptions): core.HttpResponsePromise<Schematic.ReleaseCreditLeaseResponse>;
|
|
421
421
|
private __releaseCreditLease;
|
|
422
|
-
/**
|
|
423
|
-
* @param {Schematic.GetEnrichedCreditLedgerRequest} request
|
|
424
|
-
* @param {CreditsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
425
|
-
*
|
|
426
|
-
* @throws {@link Schematic.BadRequestError}
|
|
427
|
-
* @throws {@link Schematic.UnauthorizedError}
|
|
428
|
-
* @throws {@link Schematic.ForbiddenError}
|
|
429
|
-
* @throws {@link Schematic.NotFoundError}
|
|
430
|
-
* @throws {@link Schematic.InternalServerError}
|
|
431
|
-
*
|
|
432
|
-
* @example
|
|
433
|
-
* await client.credits.getEnrichedCreditLedger({
|
|
434
|
-
* companyId: "company_id",
|
|
435
|
-
* billingCreditId: "billing_credit_id",
|
|
436
|
-
* featureId: "feature_id",
|
|
437
|
-
* period: "daily",
|
|
438
|
-
* startTime: "start_time",
|
|
439
|
-
* endTime: "end_time",
|
|
440
|
-
* limit: 1000000,
|
|
441
|
-
* offset: 1000000
|
|
442
|
-
* })
|
|
443
|
-
*/
|
|
444
|
-
getEnrichedCreditLedger(request: Schematic.GetEnrichedCreditLedgerRequest, requestOptions?: CreditsClient.RequestOptions): core.HttpResponsePromise<Schematic.GetEnrichedCreditLedgerResponse>;
|
|
445
|
-
private __getEnrichedCreditLedger;
|
|
446
|
-
/**
|
|
447
|
-
* @param {Schematic.CountCreditLedgerRequest} request
|
|
448
|
-
* @param {CreditsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
449
|
-
*
|
|
450
|
-
* @throws {@link Schematic.BadRequestError}
|
|
451
|
-
* @throws {@link Schematic.UnauthorizedError}
|
|
452
|
-
* @throws {@link Schematic.ForbiddenError}
|
|
453
|
-
* @throws {@link Schematic.NotFoundError}
|
|
454
|
-
* @throws {@link Schematic.InternalServerError}
|
|
455
|
-
*
|
|
456
|
-
* @example
|
|
457
|
-
* await client.credits.countCreditLedger({
|
|
458
|
-
* companyId: "company_id",
|
|
459
|
-
* billingCreditId: "billing_credit_id",
|
|
460
|
-
* featureId: "feature_id",
|
|
461
|
-
* period: "daily",
|
|
462
|
-
* startTime: "start_time",
|
|
463
|
-
* endTime: "end_time",
|
|
464
|
-
* limit: 1000000,
|
|
465
|
-
* offset: 1000000
|
|
466
|
-
* })
|
|
467
|
-
*/
|
|
468
|
-
countCreditLedger(request: Schematic.CountCreditLedgerRequest, requestOptions?: CreditsClient.RequestOptions): core.HttpResponsePromise<Schematic.CountCreditLedgerResponse>;
|
|
469
|
-
private __countCreditLedger;
|
|
470
422
|
/**
|
|
471
423
|
* @param {Schematic.ListBillingPlanCreditGrantsRequest} request
|
|
472
424
|
* @param {CreditsClient.RequestOptions} requestOptions - Request-specific configuration.
|
|
@@ -5,13 +5,11 @@ export type { CountBillingPlanCreditGrantsRequest } from "./CountBillingPlanCred
|
|
|
5
5
|
export type { CountCompanyGrantsRequest } from "./CountCompanyGrantsRequest";
|
|
6
6
|
export type { CountCreditBundlesRequest } from "./CountCreditBundlesRequest";
|
|
7
7
|
export type { CountCreditEventLedgerRequest } from "./CountCreditEventLedgerRequest";
|
|
8
|
-
export type { CountCreditLedgerRequest } from "./CountCreditLedgerRequest";
|
|
9
8
|
export type { CreateBillingCreditRequestBody } from "./CreateBillingCreditRequestBody";
|
|
10
9
|
export type { CreateCompanyCreditGrant } from "./CreateCompanyCreditGrant";
|
|
11
10
|
export type { CreateCreditBundleRequestBody } from "./CreateCreditBundleRequestBody";
|
|
12
11
|
export type { DeleteBillingPlanCreditGrantRequest } from "./DeleteBillingPlanCreditGrantRequest";
|
|
13
12
|
export type { ExtendCreditLeaseRequestBody } from "./ExtendCreditLeaseRequestBody";
|
|
14
|
-
export type { GetEnrichedCreditLedgerRequest } from "./GetEnrichedCreditLedgerRequest";
|
|
15
13
|
export type { ListBillingCreditsRequest } from "./ListBillingCreditsRequest";
|
|
16
14
|
export type { ListBillingPlanCreditGrantsRequest } from "./ListBillingPlanCreditGrantsRequest";
|
|
17
15
|
export type { ListCompanyCreditBalancesRequest } from "./ListCompanyCreditBalancesRequest";
|
|
@@ -11,8 +11,6 @@ export * from "./CountCreditBundlesParams";
|
|
|
11
11
|
export * from "./CountCreditBundlesResponse";
|
|
12
12
|
export * from "./CountCreditEventLedgerParams";
|
|
13
13
|
export * from "./CountCreditEventLedgerResponse";
|
|
14
|
-
export * from "./CountCreditLedgerParams";
|
|
15
|
-
export * from "./CountCreditLedgerResponse";
|
|
16
14
|
export * from "./CreateBillingCreditResponse";
|
|
17
15
|
export * from "./CreateBillingPlanCreditGrantResponse";
|
|
18
16
|
export * from "./CreateCreditBundleResponse";
|
|
@@ -21,8 +19,6 @@ export * from "./DeleteBillingPlanCreditGrantResponse";
|
|
|
21
19
|
export * from "./DeleteCreditBundleResponse";
|
|
22
20
|
export * from "./ExtendCreditLeaseResponse";
|
|
23
21
|
export * from "./GetCreditBundleResponse";
|
|
24
|
-
export * from "./GetEnrichedCreditLedgerParams";
|
|
25
|
-
export * from "./GetEnrichedCreditLedgerResponse";
|
|
26
22
|
export * from "./GetSingleBillingCreditResponse";
|
|
27
23
|
export * from "./GetSingleBillingPlanCreditGrantResponse";
|
|
28
24
|
export * from "./GrantBillingCreditsToCompanyResponse";
|
|
@@ -43,6 +43,7 @@ export declare class PlangroupsClient {
|
|
|
43
43
|
* checkoutCollectEmail: true,
|
|
44
44
|
* checkoutCollectPhone: true,
|
|
45
45
|
* enableTaxCollection: true,
|
|
46
|
+
* optInEnabled: true,
|
|
46
47
|
* orderedAddOns: [{
|
|
47
48
|
* planId: "plan_id"
|
|
48
49
|
* }],
|
|
@@ -84,6 +85,7 @@ export declare class PlangroupsClient {
|
|
|
84
85
|
* checkoutCollectEmail: true,
|
|
85
86
|
* checkoutCollectPhone: true,
|
|
86
87
|
* enableTaxCollection: true,
|
|
88
|
+
* optInEnabled: true,
|
|
87
89
|
* orderedAddOns: [{
|
|
88
90
|
* planId: "plan_id"
|
|
89
91
|
* }],
|
|
@@ -7,6 +7,7 @@ import type * as Schematic from "../../../../index";
|
|
|
7
7
|
* checkoutCollectEmail: true,
|
|
8
8
|
* checkoutCollectPhone: true,
|
|
9
9
|
* enableTaxCollection: true,
|
|
10
|
+
* optInEnabled: true,
|
|
10
11
|
* orderedAddOns: [{
|
|
11
12
|
* planId: "plan_id"
|
|
12
13
|
* }],
|
|
@@ -42,6 +43,9 @@ export interface CreatePlanGroupRequestBody {
|
|
|
42
43
|
fallbackPlanId?: string;
|
|
43
44
|
initialPlanId?: string;
|
|
44
45
|
initialPlanPriceId?: string;
|
|
46
|
+
optInEnabled: boolean;
|
|
47
|
+
optInText?: string;
|
|
48
|
+
optInTitle?: string;
|
|
45
49
|
orderedAddOns: Schematic.OrderedPlansInGroup[];
|
|
46
50
|
orderedBundleList: Schematic.PlanGroupBundleOrder[];
|
|
47
51
|
orderedPlans: Schematic.OrderedPlansInGroup[];
|
|
@@ -7,6 +7,7 @@ import type * as Schematic from "../../../../index";
|
|
|
7
7
|
* checkoutCollectEmail: true,
|
|
8
8
|
* checkoutCollectPhone: true,
|
|
9
9
|
* enableTaxCollection: true,
|
|
10
|
+
* optInEnabled: true,
|
|
10
11
|
* orderedAddOns: [{
|
|
11
12
|
* planId: "plan_id"
|
|
12
13
|
* }],
|
|
@@ -42,6 +43,9 @@ export interface UpdatePlanGroupRequestBody {
|
|
|
42
43
|
fallbackPlanId?: string;
|
|
43
44
|
initialPlanId?: string;
|
|
44
45
|
initialPlanPriceId?: string;
|
|
46
|
+
optInEnabled: boolean;
|
|
47
|
+
optInText?: string;
|
|
48
|
+
optInTitle?: string;
|
|
45
49
|
orderedAddOns: Schematic.OrderedPlansInGroup[];
|
|
46
50
|
orderedBundleList: Schematic.PlanGroupBundleOrder[];
|
|
47
51
|
orderedPlans: Schematic.OrderedPlansInGroup[];
|
|
@@ -81,11 +81,7 @@ export declare class PlansClient {
|
|
|
81
81
|
*
|
|
82
82
|
* @example
|
|
83
83
|
* await client.plans.retryCustomPlanBilling("custom_plan_billing_id", {
|
|
84
|
-
* customerEmail: "customer_email"
|
|
85
|
-
* payInAdvance: [{
|
|
86
|
-
* priceId: "price_id",
|
|
87
|
-
* quantity: 1000000
|
|
88
|
-
* }]
|
|
84
|
+
* customerEmail: "customer_email"
|
|
89
85
|
* })
|
|
90
86
|
*/
|
|
91
87
|
retryCustomPlanBilling(custom_plan_billing_id: string, request: Schematic.RetryCustomPlanBillingRequestBody, requestOptions?: PlansClient.RequestOptions): core.HttpResponsePromise<Schematic.RetryCustomPlanBillingResponse>;
|
|
@@ -2,16 +2,11 @@ import type * as Schematic from "../../../../index";
|
|
|
2
2
|
/**
|
|
3
3
|
* @example
|
|
4
4
|
* {
|
|
5
|
-
* customerEmail: "customer_email"
|
|
6
|
-
* payInAdvance: [{
|
|
7
|
-
* priceId: "price_id",
|
|
8
|
-
* quantity: 1000000
|
|
9
|
-
* }]
|
|
5
|
+
* customerEmail: "customer_email"
|
|
10
6
|
* }
|
|
11
7
|
*/
|
|
12
8
|
export interface RetryCustomPlanBillingRequestBody {
|
|
13
9
|
activationStrategy?: Schematic.CustomPlanActivationStrategy;
|
|
14
10
|
customerEmail: string;
|
|
15
11
|
daysUntilDue?: number;
|
|
16
|
-
payInAdvance: Schematic.UpdatePayInAdvanceRequestBody[];
|
|
17
12
|
}
|
|
@@ -3,5 +3,6 @@ export declare const BillingCreditGrantZeroedOutReason: {
|
|
|
3
3
|
readonly Manual: "manual";
|
|
4
4
|
readonly PlanChange: "plan_change";
|
|
5
5
|
readonly PlanPeriodReset: "plan_period_reset";
|
|
6
|
+
readonly Reconciled: "reconciled";
|
|
6
7
|
};
|
|
7
8
|
export type BillingCreditGrantZeroedOutReason = (typeof BillingCreditGrantZeroedOutReason)[keyof typeof BillingCreditGrantZeroedOutReason];
|
|
@@ -8,6 +8,7 @@ export interface ChangeSubscriptionInternalRequestBody {
|
|
|
8
8
|
customFieldValues: Schematic.CheckoutFieldValue[];
|
|
9
9
|
newPlanId: string;
|
|
10
10
|
newPriceId: string;
|
|
11
|
+
optInAccepted?: boolean;
|
|
11
12
|
payInAdvance: Schematic.UpdatePayInAdvanceRequestBody[];
|
|
12
13
|
paymentMethodId?: string;
|
|
13
14
|
promoCode?: string;
|
|
@@ -7,6 +7,7 @@ export interface ChangeSubscriptionRequestBody {
|
|
|
7
7
|
customFieldValues: Schematic.CheckoutFieldValue[];
|
|
8
8
|
newPlanId: string;
|
|
9
9
|
newPriceId: string;
|
|
10
|
+
optInAccepted?: boolean;
|
|
10
11
|
payInAdvance: Schematic.UpdatePayInAdvanceRequestBody[];
|
|
11
12
|
paymentMethodId?: string;
|
|
12
13
|
promoCode?: string;
|
|
@@ -4,8 +4,12 @@ export interface FeatureEntitlement {
|
|
|
4
4
|
allocation?: number;
|
|
5
5
|
/** If the company has a credit-based entitlement for this feature, the ID of the credit */
|
|
6
6
|
creditId?: string;
|
|
7
|
-
/** If the company has a credit-based entitlement for this feature, the
|
|
7
|
+
/** If the company has a credit-based entitlement for this feature, the credit available to fund new consumption or a new lease hold — open lease holds are excluded. Clients that hold a lease should gate on this plus their own unspent hold; clients with no lease awareness should use credit_settled instead */
|
|
8
8
|
creditRemaining?: number;
|
|
9
|
+
/** If the company has a credit-based entitlement for this feature, the unspent amount held by an open credit lease. Returns to credit_remaining when the lease is released */
|
|
10
|
+
creditReserved?: number;
|
|
11
|
+
/** If the company has a credit-based entitlement for this feature, the balance net of actual consumption, unaffected by open lease holds (credit_remaining plus credit_reserved). The number to display to end users */
|
|
12
|
+
creditSettled?: number;
|
|
9
13
|
/** If the company has a credit-based entitlement for this feature, the total credit amount */
|
|
10
14
|
creditTotal?: number;
|
|
11
15
|
/** If the company has a credit-based entitlement for this feature, the amount of credit used */
|
|
@@ -16,6 +16,8 @@ export interface PlanChangeResponseData {
|
|
|
16
16
|
createdAt: Date;
|
|
17
17
|
environmentId: string;
|
|
18
18
|
id: string;
|
|
19
|
+
/** True when this change moved the company to a different version of the same plan (e.g. a plan version migration) rather than to a different plan. */
|
|
20
|
+
isVersionUpgrade: boolean;
|
|
19
21
|
previousBasePlan?: Schematic.PlanSnapshotView;
|
|
20
22
|
/** The plan version of the previous base plan before this change. */
|
|
21
23
|
previousBasePlanVersion?: Schematic.PlanVersionSnapshotView;
|
|
@@ -5,6 +5,9 @@ export interface PreviewSubscriptionChangeResponseData {
|
|
|
5
5
|
finance?: Schematic.PreviewSubscriptionFinanceResponseData;
|
|
6
6
|
isScheduledDowngrade: boolean;
|
|
7
7
|
newCharges: number;
|
|
8
|
+
optInRequired: boolean;
|
|
9
|
+
optInText?: string;
|
|
10
|
+
optInTitle?: string;
|
|
8
11
|
paymentMethodRequired: boolean;
|
|
9
12
|
percentOff: number;
|
|
10
13
|
periodStart: Date;
|
|
@@ -4,8 +4,12 @@ export interface RulesengineFeatureEntitlement {
|
|
|
4
4
|
allocation?: number;
|
|
5
5
|
/** If the company has a credit-based entitlement for this feature, the ID of the credit */
|
|
6
6
|
creditId?: string;
|
|
7
|
-
/** If the company has a credit-based entitlement for this feature, the
|
|
7
|
+
/** If the company has a credit-based entitlement for this feature, the credit available to fund new consumption or a new lease hold — open lease holds are excluded. Clients that hold a lease should gate on this plus their own unspent hold; clients with no lease awareness should use credit_settled instead */
|
|
8
8
|
creditRemaining?: number;
|
|
9
|
+
/** If the company has a credit-based entitlement for this feature, the unspent amount held by an open credit lease. Returns to credit_remaining when the lease is released */
|
|
10
|
+
creditReserved?: number;
|
|
11
|
+
/** If the company has a credit-based entitlement for this feature, the balance net of actual consumption, unaffected by open lease holds (credit_remaining plus credit_reserved). The number to display to end users */
|
|
12
|
+
creditSettled?: number;
|
|
9
13
|
/** If the company has a credit-based entitlement for this feature, the total credit amount */
|
|
10
14
|
creditTotal?: number;
|
|
11
15
|
/** If the company has a credit-based entitlement for this feature, the amount of credit used */
|
|
@@ -137,8 +137,6 @@ export * from "./CreditGrantDetail";
|
|
|
137
137
|
export * from "./CreditGrantExpiryRequestBody";
|
|
138
138
|
export * from "./CreditGrantSortOrder";
|
|
139
139
|
export * from "./CreditLeaseResponseData";
|
|
140
|
-
export * from "./CreditLedgerEnrichedEntryResponseData";
|
|
141
|
-
export * from "./CreditLedgerPeriod";
|
|
142
140
|
export * from "./CreditsAutoTopupCompanySummary";
|
|
143
141
|
export * from "./CreditsAutoTopupCreditSummary";
|
|
144
142
|
export * from "./CreditsAutoTopupHardFailure";
|
package/dist/cache/redis.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { CacheProvider, CacheOptions } from "./types";
|
|
2
2
|
/**
|
|
3
|
-
* Minimal interface describing the redis client methods used by
|
|
4
|
-
* Compatible with the 'redis' package's RedisClientType.
|
|
3
|
+
* Minimal interface describing the redis client methods used by the SDK.
|
|
4
|
+
* Compatible with the 'redis' package's RedisClientType (node-redis v4).
|
|
5
|
+
*
|
|
6
|
+
* Includes hash + sorted-set + eval surface used by the credit-lease and
|
|
7
|
+
* reservation stores to coordinate state across multiple SDK pods.
|
|
5
8
|
*/
|
|
6
9
|
export interface RedisClient {
|
|
7
10
|
get(key: string): Promise<string | null>;
|
|
@@ -12,6 +15,30 @@ export interface RedisClient {
|
|
|
12
15
|
MATCH: string;
|
|
13
16
|
COUNT: number;
|
|
14
17
|
}): AsyncIterable<string>;
|
|
18
|
+
hSet(key: string, field: string | Record<string, string | number>, value?: string | number): Promise<unknown>;
|
|
19
|
+
hGet(key: string, field: string): Promise<string | null | undefined>;
|
|
20
|
+
hGetAll(key: string): Promise<Record<string, string>>;
|
|
21
|
+
hDel(key: string, field: string | string[]): Promise<unknown>;
|
|
22
|
+
zAdd(key: string, members: {
|
|
23
|
+
score: number;
|
|
24
|
+
value: string;
|
|
25
|
+
} | {
|
|
26
|
+
score: number;
|
|
27
|
+
value: string;
|
|
28
|
+
}[]): Promise<unknown>;
|
|
29
|
+
zRangeByScore(key: string, min: number | string, max: number | string, options?: {
|
|
30
|
+
LIMIT: {
|
|
31
|
+
offset: number;
|
|
32
|
+
count: number;
|
|
33
|
+
};
|
|
34
|
+
}): Promise<string[]>;
|
|
35
|
+
zRem(key: string, member: string | string[]): Promise<unknown>;
|
|
36
|
+
zCard(key: string): Promise<number>;
|
|
37
|
+
eval(script: string, options: {
|
|
38
|
+
keys: string[];
|
|
39
|
+
arguments: string[];
|
|
40
|
+
}): Promise<unknown>;
|
|
41
|
+
pExpireAt(key: string, timestamp: number): Promise<unknown>;
|
|
15
42
|
}
|
|
16
43
|
export interface RedisOptions extends CacheOptions {
|
|
17
44
|
/** Pre-created, connected redis client */
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type * as api from "../api";
|
|
2
|
+
import type { DataStreamClient } from "../datastream";
|
|
3
|
+
import type { Logger } from "../logger";
|
|
4
|
+
import type { CheckFlagOptions } from "../wrapper";
|
|
5
|
+
import { CreditLeaseManager } from "./lease-manager";
|
|
6
|
+
import type { ILeaseStore } from "./lease-store";
|
|
7
|
+
import type { IReservationStore } from "./reservation-store";
|
|
8
|
+
import type { CheckOptions, CheckResult } from "./types";
|
|
9
|
+
/** Internal helper bundling everything needed to satisfy a lease-bearing check. */
|
|
10
|
+
export interface CreditCheckDeps {
|
|
11
|
+
leaseStore: ILeaseStore;
|
|
12
|
+
reservations: IReservationStore;
|
|
13
|
+
manager: CreditLeaseManager;
|
|
14
|
+
datastream: DataStreamClient | undefined;
|
|
15
|
+
logger: Logger;
|
|
16
|
+
/**
|
|
17
|
+
* Report a `flag_check` event for a check the lease path resolved itself.
|
|
18
|
+
* Mirrors the plain `checkFlag` paths (which enqueue one per check) so
|
|
19
|
+
* lease-gated checks stay visible to flag-check analytics and company
|
|
20
|
+
* last-seen. Fallback exits don't call this — the plain check they
|
|
21
|
+
* delegate to enqueues its own.
|
|
22
|
+
*/
|
|
23
|
+
enqueueFlagCheckEvent: (body: api.EventBodyFlagCheck) => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Drives a single `client.check` with `usage` set.
|
|
27
|
+
*
|
|
28
|
+
* Steps:
|
|
29
|
+
* 1. Resolve the matching credit-balance condition on the flag to get
|
|
30
|
+
* `creditId` + `consumptionRate`.
|
|
31
|
+
* 2. Acquire (or reuse) a lease for `(company, creditId)`.
|
|
32
|
+
* 3. Try to reserve `quantity × consumptionRate` from the lease.
|
|
33
|
+
* 4. Run the WASM rules engine against a substituted company snapshot
|
|
34
|
+
* (`credit_balances[creditId] = lease.localRemaining` *before* the
|
|
35
|
+
* reservation we just made was debited), plus `event_usage` options so
|
|
36
|
+
* the engine evaluates the post-call balance. The reservation we made
|
|
37
|
+
* in step 3 only sticks if the engine says allowed.
|
|
38
|
+
*/
|
|
39
|
+
export declare function checkWithLease(deps: CreditCheckDeps, key: string, evalCtx: api.CheckFlagRequestBody, options: CheckOptions, fallback: () => Promise<CheckResult>): Promise<CheckResult>;
|
|
40
|
+
/**
|
|
41
|
+
* Build the preflight options envelope for a client-side rules evaluation.
|
|
42
|
+
* With an `eventSubtype` the quantity goes out as the `event_usage` pair so
|
|
43
|
+
* the engine matches it to the subtype's condition; without one it goes out
|
|
44
|
+
* as the generic `usage` knob. Exported so `client.check`'s fallback path can
|
|
45
|
+
* thread the same preflight through a plain flag check — any client-side
|
|
46
|
+
* evaluation (datastream, replicator) honors it even when the lease path
|
|
47
|
+
* can't run.
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildPreflightOptions(options: CheckOptions): CheckFlagOptions | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { LeaseStore, leaseKey, type LeaseEntry, type ILeaseStore } from "./lease-store";
|
|
2
|
+
export { ReservationStore, type IReservationStore } from "./reservation-store";
|
|
3
|
+
export { CreditLeaseManager } from "./lease-manager";
|
|
4
|
+
export { RedisLeaseStore } from "./redis-lease-store";
|
|
5
|
+
export { RedisReservationStore } from "./redis-reservation-store";
|
|
6
|
+
export { DEFAULT_LEASE_DURATION_MS, DEFAULT_LEASE_SIZE, DEFAULT_LOW_WATER_MARK, DEFAULT_PREWARM_POLL_INTERVAL_MS, DEFAULT_PREWARM_RESOLVE_TIMEOUT_MS, DEFAULT_RESERVATION_TTL_MS, DEFAULT_SWEEP_INTERVAL_MS, } from "./types";
|
|
7
|
+
export type { CreditLeaseConfig, ResolvedLeaseConfig, Reservation, CheckOptions, CheckResult, OnAcquireFailure, TrackWithReservationOptions, } from "./types";
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { CreditsClient } from "../api/resources/credits/client/Client";
|
|
2
|
+
import type { Logger } from "../logger";
|
|
3
|
+
import { type ILeaseStore, type LeaseEntry } from "./lease-store";
|
|
4
|
+
import { type CreditLeaseConfig, type ResolvedLeaseConfig } from "./types";
|
|
5
|
+
/**
|
|
6
|
+
* Owns the lifecycle of `credit_lease` rows for a single client: acquire on
|
|
7
|
+
* first use or after expiry, extend when the local view dips below the low
|
|
8
|
+
* water mark, release on `client.close()`.
|
|
9
|
+
*
|
|
10
|
+
* Concurrency: each operation (acquire, extend) has its own best-effort
|
|
11
|
+
* single-flight map keyed by `(company, creditType)`. It's best-effort —
|
|
12
|
+
* callers racing ahead of the registration can still issue duplicate wire
|
|
13
|
+
* calls — which is safe because the server is idempotent for an active slot
|
|
14
|
+
* and `replace` keeps the first live lease.
|
|
15
|
+
*/
|
|
16
|
+
export declare class CreditLeaseManager {
|
|
17
|
+
private readonly creditsClient;
|
|
18
|
+
private readonly leaseStore;
|
|
19
|
+
private readonly logger;
|
|
20
|
+
private readonly config;
|
|
21
|
+
private readonly inflightAcquire;
|
|
22
|
+
private readonly inflightExtend;
|
|
23
|
+
constructor(opts: {
|
|
24
|
+
creditsClient: CreditsClient;
|
|
25
|
+
leaseStore: ILeaseStore;
|
|
26
|
+
logger: Logger;
|
|
27
|
+
config: CreditLeaseConfig;
|
|
28
|
+
});
|
|
29
|
+
resolveConfig(creditTypeId: string): ResolvedLeaseConfig;
|
|
30
|
+
/**
|
|
31
|
+
* Return the current lease entry, acquiring one (or replacing an expired
|
|
32
|
+
* one) if none is live. Best-effort single-flight: callers arriving after
|
|
33
|
+
* a request is registered share it (the first caller's `requestOptions`
|
|
34
|
+
* win); callers racing ahead of registration may duplicate the wire call,
|
|
35
|
+
* which the server's idempotent acquire absorbs.
|
|
36
|
+
* Never rejects: a store (Redis) failure is logged and reported as
|
|
37
|
+
* `undefined`, the same as a wire failure, so callers route it through
|
|
38
|
+
* their fail-open/fail-closed handling instead of an unhandled rejection.
|
|
39
|
+
*/
|
|
40
|
+
acquireIfNeeded(companyId: string, creditTypeId: string, requestOptions?: CreditsClient.RequestOptions): Promise<LeaseEntry | undefined>;
|
|
41
|
+
private acquire;
|
|
42
|
+
/**
|
|
43
|
+
* Single-flight: kick off a background extend when one is warranted.
|
|
44
|
+
* An extend is triggered if EITHER:
|
|
45
|
+
* - the local remaining is below the low-water-mark ratio (steady-state
|
|
46
|
+
* refresh), or
|
|
47
|
+
* - the caller passes `requiredCredits` and the local remaining is below
|
|
48
|
+
* that figure (a single check just failed a reserve for that many
|
|
49
|
+
* credits — extend opportunistically instead of waiting for the next
|
|
50
|
+
* sub-watermark check).
|
|
51
|
+
* Returns the in-flight promise so callers can await it or fire-and-forget.
|
|
52
|
+
* Never rejects (it is often fire-and-forget — a rejection would surface
|
|
53
|
+
* as an unhandled promise rejection).
|
|
54
|
+
*/
|
|
55
|
+
maybeExtendInBackground(companyId: string, creditTypeId: string, requiredCredits?: number, requestOptions?: CreditsClient.RequestOptions): Promise<LeaseEntry | undefined>;
|
|
56
|
+
private extend;
|
|
57
|
+
/**
|
|
58
|
+
* Release every live lease held in the store. ONLY safe when the store is
|
|
59
|
+
* per-process (in-memory): those leases are exclusively this process's, so
|
|
60
|
+
* releasing them on `close()` returns their unspent remainder to the
|
|
61
|
+
* company balance immediately instead of waiting out the lease expiry. A
|
|
62
|
+
* shared (Redis) store must never do this — sibling pods are still
|
|
63
|
+
* drawing on the same leases — and is excluded by the `list` capability
|
|
64
|
+
* check (only the in-memory store implements it). Best-effort: failures
|
|
65
|
+
* are logged and the lease falls back to server-side expiry.
|
|
66
|
+
*/
|
|
67
|
+
releaseAllLocalLeases(): Promise<void>;
|
|
68
|
+
}
|