@schematichq/schematic-typescript-node 1.4.7 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -6
- package/dist/api/resources/accounts/client/Client.d.ts +20 -0
- package/dist/api/resources/accounts/client/requests/CountAccountMembersRequest.d.ts +18 -0
- package/dist/api/resources/accounts/client/requests/index.d.ts +1 -0
- package/dist/api/resources/accounts/types/CountAccountMembersParams.d.ts +12 -0
- package/dist/api/resources/accounts/types/CountAccountMembersResponse.d.ts +6 -0
- package/dist/api/resources/accounts/types/index.d.ts +2 -0
- package/dist/api/resources/billing/client/Client.d.ts +6 -6
- package/dist/api/resources/billing/client/requests/CountBillingProductsRequest.d.ts +1 -1
- package/dist/api/resources/billing/client/requests/CountCustomersRequest.d.ts +1 -1
- package/dist/api/resources/billing/client/requests/ListBillingPricesRequest.d.ts +1 -1
- package/dist/api/resources/billing/client/requests/ListBillingProductPricesRequest.d.ts +1 -1
- package/dist/api/resources/billing/client/requests/ListBillingProductsRequest.d.ts +1 -1
- package/dist/api/resources/billing/client/requests/ListCustomersWithSubscriptionsRequest.d.ts +1 -1
- package/dist/api/resources/checkout/client/Client.d.ts +16 -0
- package/dist/api/resources/entitlements/client/Client.d.ts +3 -3
- package/dist/api/resources/entitlements/client/requests/CountFeatureUsageRequest.d.ts +1 -1
- package/dist/api/resources/entitlements/client/requests/CreateBillingLinkedPlanEntitlementRequestBody.d.ts +1 -1
- package/dist/api/resources/entitlements/client/requests/ListFeatureUsageRequest.d.ts +1 -1
- package/dist/api/resources/features/client/Client.d.ts +3 -3
- package/dist/api/resources/features/client/requests/CountFeaturesRequest.d.ts +1 -1
- package/dist/api/resources/features/client/requests/CreateBillingLinkedFeatureRequestBody.d.ts +1 -1
- package/dist/api/resources/features/client/requests/ListFeaturesRequest.d.ts +1 -1
- package/dist/api/resources/integrationsapi/client/Client.d.ts +54 -3
- package/dist/api/resources/integrationsapi/types/AssumeStripeInstalledResponse.d.ts +6 -0
- package/dist/api/resources/integrationsapi/types/InstallIntegrationResponse.d.ts +6 -0
- package/dist/api/resources/integrationsapi/types/InstallStripeResponse.d.ts +6 -0
- package/dist/api/resources/integrationsapi/types/{LoadSampleDataSetV2Response.d.ts → LoadSampleDataSetResponse.d.ts} +1 -1
- package/dist/api/resources/integrationsapi/types/index.d.ts +4 -1
- package/dist/api/resources/plangroups/client/requests/CreatePlanGroupRequestBody.d.ts +1 -0
- package/dist/api/resources/plangroups/client/requests/UpdatePlanGroupRequestBody.d.ts +1 -0
- package/dist/api/resources/plans/client/Client.d.ts +1 -1
- package/dist/api/resources/plans/client/requests/CreateBillingLinkedPlanRequestBody.d.ts +1 -1
- package/dist/api/types/AccountMemberResponseData.d.ts +2 -0
- package/dist/api/types/BillingCreditGrantReason.d.ts +1 -0
- package/dist/api/types/BillingCreditGrantResponseData.d.ts +4 -0
- package/dist/api/types/BillingCreditLedgerAuthority.d.ts +6 -0
- package/dist/api/types/BillingCreditView.d.ts +1 -0
- package/dist/api/types/BillingPlanCreditGrantResponseData.d.ts +2 -0
- package/dist/api/types/BillingProviderType.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/CheckoutDataResponseData.d.ts +1 -0
- package/dist/api/types/CheckoutFieldInput.d.ts +8 -0
- package/dist/api/types/CheckoutFieldResponseData.d.ts +12 -0
- package/dist/api/types/CheckoutFieldValue.d.ts +4 -0
- package/dist/api/types/CheckoutFieldWithValue.d.ts +9 -0
- package/dist/api/types/CompanyCreditBalanceResponseData.d.ts +2 -0
- package/dist/api/types/CompanyPlanCreditGrantView.d.ts +1 -0
- package/dist/api/types/ComponentHydrateResponseData.d.ts +1 -0
- package/dist/api/types/ComponentPreviewResponseData.d.ts +1 -0
- package/dist/api/types/CreateBillingPlanCreditGrantRequestBody.d.ts +2 -0
- package/dist/api/types/CreditCompanyGrantView.d.ts +3 -0
- package/dist/api/types/CreditEventLedgerResponseData.d.ts +1 -0
- package/dist/api/types/CreditUsageReason.d.ts +8 -0
- package/dist/api/types/EventDetailResponseData.d.ts +1 -0
- package/dist/api/types/EventResponseData.d.ts +1 -0
- package/dist/api/types/InstallIntegrationRequestBody.d.ts +9 -0
- package/dist/api/types/IntegrationConfig.d.ts +4 -1
- package/dist/api/types/IntegrationInstallConfig.d.ts +13 -0
- package/dist/api/types/IntegrationInstallResponseData.d.ts +6 -0
- package/dist/api/types/IntegrationType.d.ts +1 -0
- package/dist/api/types/ManagePlanRequest.d.ts +1 -0
- package/dist/api/types/MetronomeIntegrationConfig.d.ts +1 -0
- package/dist/api/types/MigrationErrorCode.d.ts +1 -0
- package/dist/api/types/PlanCreditGrantView.d.ts +1 -0
- package/dist/api/types/PlanGroupDetailResponseData.d.ts +1 -0
- package/dist/api/types/UpdateBillingPlanCreditGrantRequestBody.d.ts +2 -0
- package/dist/api/types/index.d.ts +10 -0
- 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/datastream/merge.d.ts +5 -11
- 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/accounts/types/CountAccountMembersParams.d.ts +12 -0
- package/dist/serialization/resources/accounts/types/CountAccountMembersResponse.d.ts +12 -0
- package/dist/serialization/resources/accounts/types/index.d.ts +2 -0
- package/dist/serialization/resources/integrationsapi/types/AssumeStripeInstalledResponse.d.ts +11 -0
- package/dist/serialization/resources/integrationsapi/types/InstallIntegrationResponse.d.ts +11 -0
- package/dist/serialization/resources/integrationsapi/types/InstallStripeResponse.d.ts +11 -0
- package/dist/serialization/resources/integrationsapi/types/{LoadSampleDataSetV2Response.d.ts → LoadSampleDataSetResponse.d.ts} +2 -2
- package/dist/serialization/resources/integrationsapi/types/index.d.ts +4 -1
- package/dist/serialization/resources/plangroups/client/requests/CreatePlanGroupRequestBody.d.ts +2 -0
- package/dist/serialization/resources/plangroups/client/requests/UpdatePlanGroupRequestBody.d.ts +2 -0
- package/dist/serialization/types/AccountMemberResponseData.d.ts +2 -0
- package/dist/serialization/types/BillingCreditGrantReason.d.ts +1 -1
- package/dist/serialization/types/BillingCreditGrantResponseData.d.ts +3 -0
- package/dist/serialization/types/BillingCreditLedgerAuthority.d.ts +7 -0
- package/dist/serialization/types/BillingCreditView.d.ts +2 -0
- package/dist/serialization/types/BillingPlanCreditGrantResponseData.d.ts +1 -0
- package/dist/serialization/types/BillingProviderType.d.ts +1 -1
- package/dist/serialization/types/ChangeSubscriptionInternalRequestBody.d.ts +2 -0
- package/dist/serialization/types/ChangeSubscriptionRequestBody.d.ts +2 -0
- package/dist/serialization/types/CheckoutDataResponseData.d.ts +2 -0
- package/dist/serialization/types/CheckoutFieldInput.d.ts +14 -0
- package/dist/serialization/types/CheckoutFieldResponseData.d.ts +18 -0
- package/dist/serialization/types/CheckoutFieldValue.d.ts +10 -0
- package/dist/serialization/types/CheckoutFieldWithValue.d.ts +15 -0
- package/dist/serialization/types/CompanyCreditBalanceResponseData.d.ts +2 -0
- package/dist/serialization/types/CompanyPlanCreditGrantView.d.ts +1 -0
- package/dist/serialization/types/ComponentHydrateResponseData.d.ts +2 -0
- package/dist/serialization/types/ComponentPreviewResponseData.d.ts +2 -0
- package/dist/serialization/types/CreateBillingPlanCreditGrantRequestBody.d.ts +1 -0
- package/dist/serialization/types/CreditCompanyGrantView.d.ts +3 -0
- package/dist/serialization/types/CreditEventLedgerResponseData.d.ts +2 -0
- package/dist/serialization/types/CreditUsageReason.d.ts +7 -0
- package/dist/serialization/types/EventDetailResponseData.d.ts +1 -0
- package/dist/serialization/types/EventResponseData.d.ts +1 -0
- package/dist/serialization/types/InstallIntegrationRequestBody.d.ts +16 -0
- package/dist/serialization/types/IntegrationConfig.d.ts +5 -1
- package/dist/serialization/types/IntegrationInstallConfig.d.ts +20 -0
- package/dist/serialization/types/IntegrationInstallResponseData.d.ts +14 -0
- package/dist/serialization/types/IntegrationType.d.ts +1 -1
- package/dist/serialization/types/ManagePlanRequest.d.ts +2 -0
- package/dist/serialization/types/MetronomeIntegrationConfig.d.ts +7 -0
- package/dist/serialization/types/MigrationErrorCode.d.ts +1 -1
- package/dist/serialization/types/PlanCreditGrantView.d.ts +1 -0
- package/dist/serialization/types/PlanGroupDetailResponseData.d.ts +2 -0
- package/dist/serialization/types/UpdateBillingPlanCreditGrantRequestBody.d.ts +1 -0
- package/dist/serialization/types/index.d.ts +10 -0
- package/dist/wasm/rulesengine.js +5 -5
- package/dist/wrapper.d.ts +158 -6
- package/package.json +5 -4
- package/dist/wasm/rulesengine_bg.wasm +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory lease store, keyed by `${companyId}:${creditTypeId}`.
|
|
3
|
+
*
|
|
4
|
+
* Holds the lease ID, original granted amount, expiry, and the SDK's local
|
|
5
|
+
* view of `localRemainingCredits` — the portion of the lease not yet reserved
|
|
6
|
+
* by an outstanding reservation. Per-key serialization (Promise chain) keeps
|
|
7
|
+
* reserve / refund / replace atomic without external locking.
|
|
8
|
+
*
|
|
9
|
+
* The store doesn't talk to the API directly; `CreditLeaseManager` drives
|
|
10
|
+
* acquire/extend/release through the wire client and uses these methods to
|
|
11
|
+
* mirror remote state locally.
|
|
12
|
+
*
|
|
13
|
+
* For cross-pod deployments, swap this for `RedisLeaseStore` — both
|
|
14
|
+
* implement `ILeaseStore`.
|
|
15
|
+
*/
|
|
16
|
+
export interface LeaseEntry {
|
|
17
|
+
leaseId: string;
|
|
18
|
+
companyId: string;
|
|
19
|
+
creditTypeId: string;
|
|
20
|
+
grantedAmount: number;
|
|
21
|
+
localRemainingCredits: number;
|
|
22
|
+
expiresAt: Date;
|
|
23
|
+
}
|
|
24
|
+
/** Backing-store contract shared by `LeaseStore` (in-memory) and `RedisLeaseStore` (shared). */
|
|
25
|
+
export interface ILeaseStore {
|
|
26
|
+
get(companyId: string, creditTypeId: string): Promise<LeaseEntry | undefined> | LeaseEntry | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Install a fresh lease for the slot, but only if no live lease already
|
|
29
|
+
* occupies it. Implementations must be safe against concurrent writers
|
|
30
|
+
* sharing the backend: if a live (unexpired) lease is already present —
|
|
31
|
+
* even one with a different `leaseId`, e.g. acquired by a sibling pod that
|
|
32
|
+
* raced this one — leave it untouched so its already-debited
|
|
33
|
+
* `localRemainingCredits` wins. Returns `true` if it wrote a fresh row,
|
|
34
|
+
* `false` if it kept an existing live lease (the caller should release the
|
|
35
|
+
* lease it acquired ONLY if its ID differs from the installed one — the
|
|
36
|
+
* server hands a racing acquire the same active lease back, and releasing
|
|
37
|
+
* that would pull the shared lease out from under every sibling).
|
|
38
|
+
*/
|
|
39
|
+
replace(entry: Omit<LeaseEntry, "localRemainingCredits">): Promise<boolean>;
|
|
40
|
+
/**
|
|
41
|
+
* Reconcile the slot's lease to the server-authoritative `grantedAmount`
|
|
42
|
+
* total (after a remote extend), crediting the difference to
|
|
43
|
+
* `localRemainingCredits`. The delta MUST be computed atomically inside
|
|
44
|
+
* the store against the *current* stored total — never by the caller from
|
|
45
|
+
* a pre-wire-call read: with a shared backend, two pods extending the same
|
|
46
|
+
* lease concurrently would each apply a delta against the same stale read
|
|
47
|
+
* and mint phantom credits. Reconciling to the absolute total converges
|
|
48
|
+
* regardless of arrival order (a total a sibling already applied lands as
|
|
49
|
+
* a no-op). `newExpiresAt` only ever moves the expiry forward, so an
|
|
50
|
+
* out-of-order apply can't shorten a lease a sibling just extended. When
|
|
51
|
+
* `leaseId` is supplied, the extend applies ONLY if the slot still holds
|
|
52
|
+
* that lease: the server extended lease A, so its credits must not land on
|
|
53
|
+
* a successor lease B that replaced A after it expired mid-extend —
|
|
54
|
+
* crediting B would mint credits locally that the server granted to A
|
|
55
|
+
* (whose remainder it refunds at A's expiry). Mirrors the pin on `refund`.
|
|
56
|
+
*/
|
|
57
|
+
extend(companyId: string, creditTypeId: string, grantedAmount: number, newExpiresAt?: Date, leaseId?: string): Promise<void>;
|
|
58
|
+
drop(companyId: string, creditTypeId: string): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Atomically check-and-debit `credits` from the lease's remaining balance.
|
|
61
|
+
* Returns the post-debit `localRemainingCredits` on success, or `null` if
|
|
62
|
+
* there is no live lease, the balance is insufficient, or `credits` is not
|
|
63
|
+
* a finite non-negative number (NaN must never reach the debit — it slips
|
|
64
|
+
* through every numeric comparison and would poison the balance into
|
|
65
|
+
* allowing everything). Returning the balance rather than a boolean lets
|
|
66
|
+
* the caller derive the pre-debit figure (`returned + credits`) without a
|
|
67
|
+
* follow-up read.
|
|
68
|
+
*/
|
|
69
|
+
tryReserve(companyId: string, creditTypeId: string, credits: number): Promise<number | null>;
|
|
70
|
+
/**
|
|
71
|
+
* Refund credits to the slot's lease balance (clamped at `grantedAmount`).
|
|
72
|
+
* When `leaseId` is supplied, the refund applies ONLY if the slot still
|
|
73
|
+
* holds that lease: a reservation carved out of lease A must never inflate
|
|
74
|
+
* a successor lease B that replaced it after A expired — A's unspent
|
|
75
|
+
* remainder (including this slice) was already refunded to the company
|
|
76
|
+
* balance server-side when A expired, so crediting B would double-count.
|
|
77
|
+
*/
|
|
78
|
+
refund(companyId: string, creditTypeId: string, credits: number, leaseId?: string): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Snapshot of all current entries. Only meaningful (and only implemented)
|
|
81
|
+
* for the per-process in-memory store, where `close()` releases this
|
|
82
|
+
* process's exclusively-held leases; a shared backend must NOT enumerate —
|
|
83
|
+
* sibling pods may still be drawing on those leases.
|
|
84
|
+
*/
|
|
85
|
+
list?(): LeaseEntry[];
|
|
86
|
+
}
|
|
87
|
+
export declare function leaseKey(companyId: string, creditTypeId: string): string;
|
|
88
|
+
export declare class LeaseStore implements ILeaseStore {
|
|
89
|
+
private leases;
|
|
90
|
+
/**
|
|
91
|
+
* Per-key serializer chain. Each `withLock` appends to the tail so
|
|
92
|
+
* reserve / refund / replace see consistent intermediate state.
|
|
93
|
+
*/
|
|
94
|
+
private locks;
|
|
95
|
+
/** Snapshot of the current entry, or undefined if no active lease. */
|
|
96
|
+
get(companyId: string, creditTypeId: string): LeaseEntry | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Replace (or insert) the lease for the given (company, creditType).
|
|
99
|
+
* Resets `localRemainingCredits` to `grantedAmount` for a new lease.
|
|
100
|
+
* If a live lease already occupies the slot — regardless of `leaseId` — it
|
|
101
|
+
* is left alone so any already-debited `localRemainingCredits` wins.
|
|
102
|
+
* Returns `true` if a fresh row was written, `false` if an existing live
|
|
103
|
+
* lease was kept.
|
|
104
|
+
*/
|
|
105
|
+
replace(entry: Omit<LeaseEntry, "localRemainingCredits">): Promise<boolean>;
|
|
106
|
+
/**
|
|
107
|
+
* Reconcile an existing lease to the server-authoritative `grantedAmount`
|
|
108
|
+
* total (after a remote extend), crediting the difference to
|
|
109
|
+
* `localRemainingCredits`. The delta is computed against the CURRENT
|
|
110
|
+
* stored total under the key lock, so concurrent extends converge instead
|
|
111
|
+
* of double-counting (see `ILeaseStore.extend`). If no lease exists for
|
|
112
|
+
* the key, this is a no-op (caller should have replaced). When `leaseId`
|
|
113
|
+
* is given, the extend is dropped if the slot now holds a different lease.
|
|
114
|
+
*/
|
|
115
|
+
extend(companyId: string, creditTypeId: string, grantedAmount: number, newExpiresAt?: Date, leaseId?: string): Promise<void>;
|
|
116
|
+
/** Drop the lease entry (after a remote release or lazy expiry). */
|
|
117
|
+
drop(companyId: string, creditTypeId: string): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Attempt to reserve `credits` from the local remaining balance.
|
|
120
|
+
* Returns the post-debit balance on success, `null` if there isn't enough
|
|
121
|
+
* remaining (see `ILeaseStore.tryReserve`).
|
|
122
|
+
*/
|
|
123
|
+
tryReserve(companyId: string, creditTypeId: string, credits: number): Promise<number | null>;
|
|
124
|
+
/**
|
|
125
|
+
* Refund credits back to the local balance (capped at grantedAmount).
|
|
126
|
+
* When `leaseId` is given, the refund is dropped if the slot now holds a
|
|
127
|
+
* different lease (see `ILeaseStore.refund`).
|
|
128
|
+
*/
|
|
129
|
+
refund(companyId: string, creditTypeId: string, credits: number, leaseId?: string): Promise<void>;
|
|
130
|
+
/** Snapshot of all current entries (see `ILeaseStore.list`). */
|
|
131
|
+
list(): LeaseEntry[];
|
|
132
|
+
private withLock;
|
|
133
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { RedisClient } from "../cache/redis";
|
|
2
|
+
import { type ILeaseStore, type LeaseEntry } from "./lease-store";
|
|
3
|
+
/**
|
|
4
|
+
* Redis-backed lease store. One hash per `(companyId, creditTypeId)` slot, with
|
|
5
|
+
* atomic mutations via single-key Lua scripts so it stays correct on both
|
|
6
|
+
* standalone and clustered Redis.
|
|
7
|
+
*/
|
|
8
|
+
export declare class RedisLeaseStore implements ILeaseStore {
|
|
9
|
+
private readonly client;
|
|
10
|
+
private readonly keyPrefix;
|
|
11
|
+
private readonly defaultLeaseDurationMs;
|
|
12
|
+
constructor(opts: {
|
|
13
|
+
client: RedisClient;
|
|
14
|
+
keyPrefix?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Defensive fallback used by `extend()` when the caller doesn't supply
|
|
17
|
+
* `newExpiresAt`. The lease manager always passes one today, so this
|
|
18
|
+
* only matters for direct callers. Default `DEFAULT_LEASE_DURATION_MS`.
|
|
19
|
+
*/
|
|
20
|
+
defaultLeaseDurationMs?: number;
|
|
21
|
+
});
|
|
22
|
+
/** Public so the reservation store can target the same lease hash for refunds. */
|
|
23
|
+
hashKey(companyId: string, creditTypeId: string): string;
|
|
24
|
+
get(companyId: string, creditTypeId: string): Promise<LeaseEntry | undefined>;
|
|
25
|
+
replace(entry: Omit<LeaseEntry, "localRemainingCredits">): Promise<boolean>;
|
|
26
|
+
extend(companyId: string, creditTypeId: string, grantedAmount: number, newExpiresAt?: Date, leaseId?: string): Promise<void>;
|
|
27
|
+
drop(companyId: string, creditTypeId: string): Promise<void>;
|
|
28
|
+
tryReserve(companyId: string, creditTypeId: string, credits: number): Promise<number | null>;
|
|
29
|
+
refund(companyId: string, creditTypeId: string, credits: number, leaseId?: string): Promise<void>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { RedisClient } from "../cache/redis";
|
|
2
|
+
import type { ILeaseStore } from "./lease-store";
|
|
3
|
+
import type { IReservationStore } from "./reservation-store";
|
|
4
|
+
import type { Reservation } from "./types";
|
|
5
|
+
/**
|
|
6
|
+
* Redis-backed reservation table. Each reservation is a hash, indexed by
|
|
7
|
+
* `expiresAt` in a sorted set so the sweeper can pop expired entries in
|
|
8
|
+
* O(log n), and by `(company, credit)` so the balance display can sum a
|
|
9
|
+
* tenant's open holds. All mutations use single-key operations (or single-key
|
|
10
|
+
* Lua), so the store is correct on standalone and clustered Redis alike — the
|
|
11
|
+
* unspent-slice refund is delegated to the lease store rather than reaching
|
|
12
|
+
* across to the lease hash inside a multi-key script.
|
|
13
|
+
*/
|
|
14
|
+
export declare class RedisReservationStore implements IReservationStore {
|
|
15
|
+
private readonly client;
|
|
16
|
+
private readonly leaseStore;
|
|
17
|
+
private readonly sweepIntervalMs;
|
|
18
|
+
private readonly keyPrefix;
|
|
19
|
+
private sweepInterval;
|
|
20
|
+
private stopped;
|
|
21
|
+
constructor(opts: {
|
|
22
|
+
client: RedisClient;
|
|
23
|
+
leaseStore: ILeaseStore;
|
|
24
|
+
sweepIntervalMs?: number;
|
|
25
|
+
keyPrefix?: string;
|
|
26
|
+
});
|
|
27
|
+
private hashKey;
|
|
28
|
+
private indexKey;
|
|
29
|
+
private byCreditKey;
|
|
30
|
+
add(reservation: Reservation): Promise<void>;
|
|
31
|
+
get(id: string): Promise<Reservation | undefined>;
|
|
32
|
+
/**
|
|
33
|
+
* Sum open reservations for a (company, credit) with a single `HGETALL` on
|
|
34
|
+
* the per-tenant index hash — one round trip, one key (Cluster-safe), no
|
|
35
|
+
* per-reservation fan-out. The hash values are the authoritative
|
|
36
|
+
* `creditsReserved` figures; a field is present iff its reservation is open
|
|
37
|
+
* and unrefunded (consume removes the field and refunds in the same call),
|
|
38
|
+
* so summing them is exact. Display-path call, not a hot path.
|
|
39
|
+
*/
|
|
40
|
+
reservedCredits(companyId: string, creditTypeId: string): Promise<number>;
|
|
41
|
+
consume(id: string, creditsConsumed: number): Promise<number | null>;
|
|
42
|
+
startSweep(): void;
|
|
43
|
+
sweepExpired(now?: Date): Promise<number>;
|
|
44
|
+
stop(): void;
|
|
45
|
+
size(): Promise<number>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Reservation } from "./types";
|
|
2
|
+
import type { ILeaseStore } from "./lease-store";
|
|
3
|
+
/** Backing-store contract for the reservation table. */
|
|
4
|
+
export interface IReservationStore {
|
|
5
|
+
add(reservation: Reservation): Promise<void> | void;
|
|
6
|
+
get(id: string): Promise<Reservation | undefined> | Reservation | undefined;
|
|
7
|
+
consume(id: string, creditsConsumed: number): Promise<number | null>;
|
|
8
|
+
/**
|
|
9
|
+
* Sum of `creditsReserved` across open reservations for a (company, credit).
|
|
10
|
+
* These credits are carved out of the lease's `localRemainingCredits` but
|
|
11
|
+
* aren't spent yet, so a balance display can add them back to ignore
|
|
12
|
+
* in-flight holds.
|
|
13
|
+
*/
|
|
14
|
+
reservedCredits(companyId: string, creditTypeId: string): Promise<number> | number;
|
|
15
|
+
startSweep(): void;
|
|
16
|
+
sweepExpired(now?: Date): Promise<number>;
|
|
17
|
+
stop(): void;
|
|
18
|
+
size(): Promise<number> | number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* In-memory reservation table, paired with a sweep loop that returns expired
|
|
22
|
+
* reservations to their underlying lease.
|
|
23
|
+
*
|
|
24
|
+
* For cross-pod deployments, swap this for `RedisReservationStore` — both
|
|
25
|
+
* implement `IReservationStore`.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ReservationStore implements IReservationStore {
|
|
28
|
+
private readonly leaseStore;
|
|
29
|
+
private readonly sweepIntervalMs;
|
|
30
|
+
private reservations;
|
|
31
|
+
private sweepInterval;
|
|
32
|
+
private stopped;
|
|
33
|
+
constructor(leaseStore: ILeaseStore, sweepIntervalMs?: number);
|
|
34
|
+
/** Register a new reservation. Idempotent on `id`. */
|
|
35
|
+
add(reservation: Reservation): void;
|
|
36
|
+
/** Look up a reservation by ID. */
|
|
37
|
+
get(id: string): Reservation | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Sum open reservations for a (company, credit). Counts every reservation
|
|
40
|
+
* still in the table: its credits stay carved out of the lease's
|
|
41
|
+
* `localRemainingCredits` until `consume`/`sweepExpired` removes it and
|
|
42
|
+
* refunds the unspent remainder in the same step, so summing by presence
|
|
43
|
+
* keeps `localRemainingCredits + reservedCredits` exact.
|
|
44
|
+
*/
|
|
45
|
+
reservedCredits(companyId: string, creditTypeId: string): number;
|
|
46
|
+
/**
|
|
47
|
+
* Consume a reservation — removes it from the table and refunds
|
|
48
|
+
* `creditsReserved - creditsConsumed` back to the underlying lease.
|
|
49
|
+
* Returns the credits actually consumed (clamped to `creditsReserved`)
|
|
50
|
+
* or `null` if the reservation is missing/already consumed.
|
|
51
|
+
*/
|
|
52
|
+
consume(id: string, creditsConsumed: number): Promise<number | null>;
|
|
53
|
+
/** Start the background sweep loop. Safe to call repeatedly. */
|
|
54
|
+
startSweep(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Scan for expired reservations, remove them, and refund their credits to
|
|
57
|
+
* the lease.
|
|
58
|
+
*/
|
|
59
|
+
sweepExpired(now?: Date): Promise<number>;
|
|
60
|
+
/** Stop the sweep loop. */
|
|
61
|
+
stop(): void;
|
|
62
|
+
/** Test/debug: current reservation count. */
|
|
63
|
+
size(): number;
|
|
64
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as api from "../api";
|
|
2
|
+
import type { IReservationStore } from "./reservation-store";
|
|
3
|
+
import type { Reservation, TrackWithReservationOptions } from "./types";
|
|
4
|
+
/** Outcome of consuming a reservation and building its Track event. */
|
|
5
|
+
export interface ReservationConsumeResult {
|
|
6
|
+
/** The Track event to emit. Always carries the `leaseId`. */
|
|
7
|
+
track: api.EventBodyTrack;
|
|
8
|
+
/**
|
|
9
|
+
* `true` when the reservation was still live and `consume` debited/refunded
|
|
10
|
+
* the local lease in this call. `false` when the reservation was already
|
|
11
|
+
* gone from the store (swept after its TTL, or already consumed): the local
|
|
12
|
+
* lease balance was *not* touched here, and the returned `track` is a
|
|
13
|
+
* recovery event so the server still bills the actual usage. The caller is
|
|
14
|
+
* responsible for de-duping recovery emits (see `trackWithReservation`).
|
|
15
|
+
*/
|
|
16
|
+
settledLocally: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build the `EventBodyTrack` payload for a Track event that consumes a
|
|
20
|
+
* reservation, and consume the reservation against the lease (refunding the
|
|
21
|
+
* unused slice locally).
|
|
22
|
+
*
|
|
23
|
+
* The Track is built from the caller-held `reservation` handle, so it can be
|
|
24
|
+
* emitted even when the reservation has already been swept out of the store —
|
|
25
|
+
* the server is the source of truth for actual consumption. When the lease is
|
|
26
|
+
* still live server-side the `leaseId` routes the spend through its sub-ledger;
|
|
27
|
+
* when the server lease has itself expired/released, the server falls through
|
|
28
|
+
* to a direct grant decrement. Either way the usage is billed, so a hold that
|
|
29
|
+
* outlives its (client-side) reservation TTL is no longer dropped on the floor.
|
|
30
|
+
*
|
|
31
|
+
* On the recovery path (`settledLocally: false`) the sweeper already refunded
|
|
32
|
+
* the full hold and nothing re-debits the consumed slice, so the local lease
|
|
33
|
+
* reads high until rollover — hence `reservationTTL` should exceed the longest
|
|
34
|
+
* expected work duration (see `CreditLeaseConfig.defaultReservationTTL`).
|
|
35
|
+
*/
|
|
36
|
+
export declare function consumeReservationAndBuildEvent(reservations: IReservationStore, reservation: Reservation, actualQuantity: number, options?: TrackWithReservationOptions): Promise<ReservationConsumeResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Build the Track event for a reservation purely from the caller-held handle —
|
|
39
|
+
* no store access. Split out so `trackWithReservation` can still emit the
|
|
40
|
+
* billing event when the local settle (`consume`) fails on an unreachable
|
|
41
|
+
* store: the server is the source of truth for actual consumption, so the
|
|
42
|
+
* usage must be reported regardless of local bookkeeping.
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildReservationTrackEvent(reservation: Reservation, actualQuantity: number, options?: TrackWithReservationOptions): api.EventBodyTrack;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type * as api from "../api";
|
|
2
|
+
import type { RedisClient } from "../cache/redis";
|
|
3
|
+
/**
|
|
4
|
+
* Behavior when a lease cannot be acquired or reserved against (API error,
|
|
5
|
+
* lease/reservation store unreachable, insufficient balance).
|
|
6
|
+
* - `fail-open`: err on the side of assuming the credits are there — the rules
|
|
7
|
+
* engine still evaluates the flag (plan targeting, overrides, and all
|
|
8
|
+
* non-credit conditions apply) with the credit balance substituted to an
|
|
9
|
+
* effectively unlimited value, so only the credit gate is bypassed. No
|
|
10
|
+
* reservation is issued.
|
|
11
|
+
* - `fail-closed`: `check()` returns `{ allowed: false }` so the caller blocks the action
|
|
12
|
+
*/
|
|
13
|
+
export type OnAcquireFailure = "fail-open" | "fail-closed";
|
|
14
|
+
export declare const DEFAULT_LEASE_DURATION_MS: number;
|
|
15
|
+
export declare const DEFAULT_RESERVATION_TTL_MS: number;
|
|
16
|
+
export declare const DEFAULT_LEASE_SIZE: number;
|
|
17
|
+
export declare const DEFAULT_LOW_WATER_MARK: number;
|
|
18
|
+
export declare const DEFAULT_SWEEP_INTERVAL_MS: number;
|
|
19
|
+
export declare const DEFAULT_PREWARM_RESOLVE_TIMEOUT_MS: number;
|
|
20
|
+
export declare const DEFAULT_PREWARM_POLL_INTERVAL_MS: number;
|
|
21
|
+
/**
|
|
22
|
+
* Configuration block enabling client-side lease + reservation behavior on
|
|
23
|
+
* `client.check` / `client.trackWithReservation`. Omit to keep the SDK
|
|
24
|
+
* lease-unaware (`check` falls back to a plain flag check).
|
|
25
|
+
*/
|
|
26
|
+
export interface CreditLeaseConfig {
|
|
27
|
+
/** Default lease duration in milliseconds. Default `DEFAULT_LEASE_DURATION_MS` (5 minutes). */
|
|
28
|
+
defaultLeaseDuration?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Default reservation TTL in milliseconds. Default `DEFAULT_RESERVATION_TTL_MS`
|
|
31
|
+
* (60 seconds). Size this above the longest expected gap between `check()`
|
|
32
|
+
* and `trackWithReservation()`: a settle arriving after the TTL still bills
|
|
33
|
+
* the server but doesn't re-debit the local lease (its hold was already
|
|
34
|
+
* swept back), so the local balance reads high until the lease rolls over.
|
|
35
|
+
*/
|
|
36
|
+
defaultReservationTTL?: number;
|
|
37
|
+
/** Default lease size (credit amount requested). Default `DEFAULT_LEASE_SIZE` (10000). */
|
|
38
|
+
defaultLeaseSize?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Fraction of remaining lease balance below which the SDK kicks off a
|
|
41
|
+
* background extend. Default `DEFAULT_LOW_WATER_MARK` (0.25).
|
|
42
|
+
*/
|
|
43
|
+
lowWaterMark?: number;
|
|
44
|
+
/** Sweep interval (ms) for expired reservations. Default `DEFAULT_SWEEP_INTERVAL_MS` (1000). */
|
|
45
|
+
sweepIntervalMs?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Max time `prewarm()` will wait for a freshly-identified company to
|
|
48
|
+
* surface in the datastream cache when only secondary keys are passed.
|
|
49
|
+
* Set to 0 to skip waiting entirely (prewarm bails immediately if the
|
|
50
|
+
* company isn't already cached). Default `DEFAULT_PREWARM_RESOLVE_TIMEOUT_MS`
|
|
51
|
+
* (5000ms).
|
|
52
|
+
*/
|
|
53
|
+
prewarmResolveTimeoutMs?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Pre-connected Redis client for lease + reservation state. Optional: when
|
|
56
|
+
* omitted, the SDK reuses the DataStream cache's Redis client
|
|
57
|
+
* (`dataStream.redisClient`) if one is configured, so an existing Redis
|
|
58
|
+
* setup backs leases automatically. Set this only to point lease state at a
|
|
59
|
+
* *different* Redis than the DataStream cache.
|
|
60
|
+
*
|
|
61
|
+
* When neither this nor `dataStream.redisClient` is configured, the SDK
|
|
62
|
+
* falls back to per-process in-memory stores — single-pod only, since
|
|
63
|
+
* cross-pod gating is lost (a warning is logged). With a Redis client
|
|
64
|
+
* present, the Lua-driven `tryReserve` / `consume` paths give atomic
|
|
65
|
+
* cross-pod gating.
|
|
66
|
+
*/
|
|
67
|
+
redisClient?: RedisClient;
|
|
68
|
+
/**
|
|
69
|
+
* Optional Redis key prefix. Falls back to `dataStream.redisKeyPrefix` when
|
|
70
|
+
* unset, then to `schematic:`.
|
|
71
|
+
*/
|
|
72
|
+
redisKeyPrefix?: string;
|
|
73
|
+
/** Per-credit-type overrides (keyed by credit type ID). */
|
|
74
|
+
overrides?: Record<string, Partial<Omit<CreditLeaseConfig, "overrides" | "sweepIntervalMs" | "redisClient" | "redisKeyPrefix">>>;
|
|
75
|
+
}
|
|
76
|
+
/** Resolved config for a single credit type after applying defaults + overrides. */
|
|
77
|
+
export interface ResolvedLeaseConfig {
|
|
78
|
+
leaseDuration: number;
|
|
79
|
+
reservationTTL: number;
|
|
80
|
+
leaseSize: number;
|
|
81
|
+
lowWaterMark: number;
|
|
82
|
+
}
|
|
83
|
+
/** Handle returned by `client.check` when a reservation is issued. Pass to `client.trackWithReservation`. */
|
|
84
|
+
export interface Reservation {
|
|
85
|
+
/** Opaque reservation ID. */
|
|
86
|
+
id: string;
|
|
87
|
+
/** Underlying lease ID this reservation draws from. */
|
|
88
|
+
leaseId: string;
|
|
89
|
+
/** Company that owns the lease. */
|
|
90
|
+
companyId: string;
|
|
91
|
+
/** Credit type the reservation reserves against. */
|
|
92
|
+
creditTypeId: string;
|
|
93
|
+
/** Event subtype to record on the Track event when consumed. */
|
|
94
|
+
eventSubtype: string;
|
|
95
|
+
/** Quantity (in event units) the caller declared upfront. */
|
|
96
|
+
quantityReserved: number;
|
|
97
|
+
/** Credits reserved = `quantityReserved * consumptionRate`. */
|
|
98
|
+
creditsReserved: number;
|
|
99
|
+
/** Consumption rate at the time the reservation was issued. */
|
|
100
|
+
consumptionRate: number;
|
|
101
|
+
/** When the reservation expires and gets swept back to the lease. */
|
|
102
|
+
expiresAt: Date;
|
|
103
|
+
/**
|
|
104
|
+
* Evaluation context used to issue this reservation. Threaded into the
|
|
105
|
+
* Track event in `trackWithReservation` so the server can attribute usage
|
|
106
|
+
* to the same company/user.
|
|
107
|
+
*/
|
|
108
|
+
evalCtx: api.CheckFlagRequestBody;
|
|
109
|
+
}
|
|
110
|
+
/** Options accepted by `client.check`. */
|
|
111
|
+
export interface CheckOptions {
|
|
112
|
+
/**
|
|
113
|
+
* Quantity (in event units) to gate the check on — the check reserves
|
|
114
|
+
* `usage × consumption_rate` credits from the lease. A check issues at
|
|
115
|
+
* most ONE reservation, against a single event subtype.
|
|
116
|
+
*/
|
|
117
|
+
usage?: number;
|
|
118
|
+
/**
|
|
119
|
+
* Event subtype the `usage` applies to (e.g. `"inference_tokens"`).
|
|
120
|
+
* Disambiguates which credit condition to gate on when the flag meters
|
|
121
|
+
* more than one event. Optional when the flag's credit condition is
|
|
122
|
+
* unambiguous.
|
|
123
|
+
*/
|
|
124
|
+
eventSubtype?: string;
|
|
125
|
+
/**
|
|
126
|
+
* What to do when a lease cannot be acquired (API error, store
|
|
127
|
+
* unreachable, insufficient remote balance). Default: `fail-closed`
|
|
128
|
+
* (`allowed = false`, no reservation) — deny when the gate can't gate.
|
|
129
|
+
* Override to `fail-open` for trusted/known customers where letting
|
|
130
|
+
* traffic through is preferable to a denial; the flag's rules are still
|
|
131
|
+
* evaluated with an assumed-sufficient credit balance, so only the credit
|
|
132
|
+
* gate is bypassed (see `OnAcquireFailure`).
|
|
133
|
+
*/
|
|
134
|
+
onAcquireFailure?: OnAcquireFailure;
|
|
135
|
+
/** Default value to return on error. */
|
|
136
|
+
defaultValue?: boolean | (() => boolean);
|
|
137
|
+
/** Custom timeout for API calls within this check (ms). */
|
|
138
|
+
timeoutMs?: number;
|
|
139
|
+
}
|
|
140
|
+
/** Result of `client.check`. */
|
|
141
|
+
export interface CheckResult {
|
|
142
|
+
/** Whether the caller is permitted to proceed. */
|
|
143
|
+
allowed: boolean;
|
|
144
|
+
/** Boolean flag value (`allowed` mirrors this in non-lease paths). */
|
|
145
|
+
value: boolean;
|
|
146
|
+
/** Reservation handle when a lease-bearing check passed. */
|
|
147
|
+
reservation?: Reservation;
|
|
148
|
+
/** Human-readable reason (from the rules engine or the SDK). */
|
|
149
|
+
reason: string;
|
|
150
|
+
/**
|
|
151
|
+
* Entitlement payload from the check.
|
|
152
|
+
*
|
|
153
|
+
* NOTE: `entitlement.creditRemaining` (and `creditTotal` / `creditUsed`) is
|
|
154
|
+
* NOT lease-aware and must not be used as a user-facing balance when credit
|
|
155
|
+
* leases are enabled. The WASM derives those fields from the company's
|
|
156
|
+
* server `creditBalances`, which a lease distorts: a plain `checkFlag` sees
|
|
157
|
+
* the balance net of the whole lease tranche (reads low/~0), and a
|
|
158
|
+
* lease-bearing `check()` sees the substituted *tranche-local* balance, not
|
|
159
|
+
* the company total. For any "credits remaining" display use
|
|
160
|
+
* `client.getCreditBalance(...).settled` (`B − spent`), which speaks the
|
|
161
|
+
* server's `remaining`/`reserved`/`settled` vocabulary.
|
|
162
|
+
*/
|
|
163
|
+
entitlement?: api.RulesengineFeatureEntitlement;
|
|
164
|
+
/** Flag key checked. */
|
|
165
|
+
flagKey: string;
|
|
166
|
+
/** Flag ID if known. */
|
|
167
|
+
flagId?: string;
|
|
168
|
+
/** Optional error string (populated when the SDK fell back to a default). */
|
|
169
|
+
err?: string;
|
|
170
|
+
}
|
|
171
|
+
/** Extras accepted by `trackWithReservation`. */
|
|
172
|
+
export interface TrackWithReservationOptions {
|
|
173
|
+
/** Optional traits to attach to the emitted Track event. */
|
|
174
|
+
traits?: Record<string, unknown>;
|
|
175
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as Schematic from '../api/types';
|
|
2
|
+
import { RulesEngineClient } from '../rules-engine';
|
|
3
|
+
import type { CheckFlagOptions } from '../wrapper';
|
|
2
4
|
import { Logger } from '../logger';
|
|
3
5
|
import { LazyEmitter } from './emitter';
|
|
4
6
|
import type { CacheProvider } from '../cache/types';
|
|
@@ -9,7 +11,11 @@ import { type RedisClient } from '../cache/redis';
|
|
|
9
11
|
export interface DataStreamClientOptions {
|
|
10
12
|
/** Schematic API key for authentication */
|
|
11
13
|
apiKey: string;
|
|
12
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Base URL for the API, converted to its WebSocket counterpart (e.g.
|
|
16
|
+
* https://api.schematichq.com -> wss://datastream.schematichq.com).
|
|
17
|
+
* Defaults to the standard Schematic API environment.
|
|
18
|
+
*/
|
|
13
19
|
baseURL?: string;
|
|
14
20
|
/** Logger for debug/info/error messages */
|
|
15
21
|
logger: Logger;
|
|
@@ -38,7 +44,7 @@ export interface DataStreamClientOptions {
|
|
|
38
44
|
*/
|
|
39
45
|
export declare class DataStreamClient extends LazyEmitter {
|
|
40
46
|
private readonly apiKey;
|
|
41
|
-
private readonly baseURL
|
|
47
|
+
private readonly baseURL;
|
|
42
48
|
private readonly logger;
|
|
43
49
|
private readonly cacheTTL;
|
|
44
50
|
private readonly companyCacheProvider;
|
|
@@ -106,7 +112,17 @@ export declare class DataStreamClient extends LazyEmitter {
|
|
|
106
112
|
checkFlag(evalCtx: {
|
|
107
113
|
company?: Record<string, string>;
|
|
108
114
|
user?: Record<string, string>;
|
|
109
|
-
}, flagKey: string): Promise<Schematic.RulesengineCheckFlagResult>;
|
|
115
|
+
}, flagKey: string, options?: CheckFlagOptions): Promise<Schematic.RulesengineCheckFlagResult>;
|
|
116
|
+
/**
|
|
117
|
+
* Public accessor for the cached company snapshot. Used by credit-lease
|
|
118
|
+
* callers that need the company's `credit_balances` so they can substitute
|
|
119
|
+
* a lease-bound view before calling the rules engine.
|
|
120
|
+
*/
|
|
121
|
+
getCachedCompany(keys: Record<string, string>): Promise<Schematic.RulesengineCompany | null>;
|
|
122
|
+
/** Public accessor for the cached user snapshot. */
|
|
123
|
+
getCachedUser(keys: Record<string, string>): Promise<Schematic.RulesengineUser | null>;
|
|
124
|
+
/** Public accessor for the rules engine. Used by credit-lease eval. */
|
|
125
|
+
getRulesEngine(): RulesEngineClient;
|
|
110
126
|
/**
|
|
111
127
|
* UpdateCompanyMetrics updates company metrics locally (for track events)
|
|
112
128
|
*/
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type * as Schematic from "../api/types";
|
|
2
|
-
/**
|
|
3
|
-
* Creates a complete deep copy of a Company object.
|
|
4
|
-
*/
|
|
5
2
|
export declare function deepCopyCompany(c: Schematic.RulesengineCompany): Schematic.RulesengineCompany;
|
|
6
|
-
/**
|
|
7
|
-
* Creates a complete deep copy of a User object.
|
|
8
|
-
*/
|
|
9
3
|
export declare function deepCopyUser(u: Schematic.RulesengineUser): Schematic.RulesengineUser;
|
|
10
4
|
/**
|
|
11
5
|
* Merges a partial update into an existing Company.
|
|
@@ -17,13 +11,13 @@ export declare function deepCopyUser(u: Schematic.RulesengineUser): Schematic.Ru
|
|
|
17
11
|
* Partials don't carry refreshed entitlements, so when their derived fields
|
|
18
12
|
* change in another part of the company we sync them here to match server
|
|
19
13
|
* behavior:
|
|
20
|
-
* -
|
|
21
|
-
* - usage ← metric value matching (
|
|
14
|
+
* - creditRemaining ← credit_balances[credit_id]
|
|
15
|
+
* - usage ← metric value matching (eventName, metricPeriod, monthReset)
|
|
22
16
|
* Both are skipped when the partial also sends entitlements wholesale.
|
|
23
17
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
18
|
+
* Partial updates arrive as raw wire payloads (snake_case keys) and are merged
|
|
19
|
+
* into an existing camelCase-canonicalized entity; each case writes the
|
|
20
|
+
* corresponding camelCase field so the cached entity stays in a single shape.
|
|
27
21
|
*/
|
|
28
22
|
export declare function partialCompany(existing: Schematic.RulesengineCompany, partial: Record<string, unknown>): Schematic.RulesengineCompany;
|
|
29
23
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export { ConsoleLogger, LogLevel, type Logger } from "./logger";
|
|
|
6
6
|
export { SchematicEnvironment } from "./environments";
|
|
7
7
|
export { SchematicError, SchematicTimeoutError } from "./errors";
|
|
8
8
|
export { RulesEngineClient } from "./rules-engine";
|
|
9
|
+
export type { CheckOptions, CheckResult, CreditLeaseConfig, OnAcquireFailure, Reservation, TrackWithReservationOptions, } from "./credits";
|
|
9
10
|
export { verifyWebhookSignature, verifySignature, computeSignature, computeHexSignature, WebhookSignatureError, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER } from "./webhooks";
|