usage-sdk-test 0.1.0 → 0.1.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.
Files changed (96) hide show
  1. package/README.md +2 -1
  2. package/dist/errors.d.ts +20 -0
  3. package/dist/errors.d.ts.map +1 -0
  4. package/dist/errors.js +35 -0
  5. package/dist/errors.js.map +1 -0
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +24 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/persistence/MemoryPersistenceProvider.d.ts +4 -0
  11. package/dist/persistence/MemoryPersistenceProvider.js +19 -0
  12. package/dist/persistence/MemoryPersistenceProvider.js.map +1 -0
  13. package/dist/persistence/PersistenceProvider.d.ts +22 -0
  14. package/dist/persistence/PersistenceProvider.js +3 -0
  15. package/dist/persistence/PersistenceProvider.js.map +1 -0
  16. package/dist/pricing/matchRule.d.ts +2 -0
  17. package/dist/pricing/matchRule.d.ts.map +1 -0
  18. package/dist/pricing/matchRule.js +47 -0
  19. package/dist/pricing/matchRule.js.map +1 -0
  20. package/dist/pricing/quote.d.ts +2 -0
  21. package/dist/pricing/quote.d.ts.map +1 -0
  22. package/dist/pricing/quote.js +35 -0
  23. package/dist/pricing/quote.js.map +1 -0
  24. package/dist/providers/memory/MemoryLedgerStore.d.ts +16 -0
  25. package/dist/providers/memory/MemoryLedgerStore.d.ts.map +1 -0
  26. package/dist/providers/memory/MemoryLedgerStore.js +80 -0
  27. package/dist/providers/memory/MemoryLedgerStore.js.map +1 -0
  28. package/dist/providers/memory/MemoryLimitStore.d.ts +24 -0
  29. package/dist/providers/memory/MemoryLimitStore.d.ts.map +1 -0
  30. package/dist/providers/memory/MemoryLimitStore.js +88 -0
  31. package/dist/providers/memory/MemoryLimitStore.js.map +1 -0
  32. package/dist/providers/memory/MemoryPlanStore.d.ts +7 -0
  33. package/dist/providers/memory/MemoryPlanStore.d.ts.map +1 -0
  34. package/dist/providers/memory/MemoryPlanStore.js +15 -0
  35. package/dist/providers/memory/MemoryPlanStore.js.map +1 -0
  36. package/dist/providers/memory/MemoryUsageStore.d.ts +11 -0
  37. package/dist/providers/memory/MemoryUsageStore.d.ts.map +1 -0
  38. package/dist/providers/memory/MemoryUsageStore.js +16 -0
  39. package/dist/providers/memory/MemoryUsageStore.js.map +1 -0
  40. package/dist/sdk/UsageSdk.d.ts +40 -0
  41. package/dist/sdk/UsageSdk.d.ts.map +1 -0
  42. package/dist/sdk/UsageSdk.js +156 -0
  43. package/dist/sdk/UsageSdk.js.map +1 -0
  44. package/dist/sdk/createUsageSdk.d.ts +41 -0
  45. package/dist/sdk/createUsageSdk.d.ts.map +1 -0
  46. package/dist/sdk/createUsageSdk.js +24 -0
  47. package/dist/sdk/createUsageSdk.js.map +1 -0
  48. package/dist/stores/LedgerStore.d.ts +29 -0
  49. package/dist/stores/LedgerStore.d.ts.map +1 -0
  50. package/dist/stores/LedgerStore.js +3 -0
  51. package/dist/stores/LedgerStore.js.map +1 -0
  52. package/dist/stores/LimitStore.d.ts +20 -0
  53. package/dist/stores/LimitStore.d.ts.map +1 -0
  54. package/dist/stores/LimitStore.js +3 -0
  55. package/dist/stores/LimitStore.js.map +1 -0
  56. package/dist/stores/PlanStore.d.ts +4 -0
  57. package/dist/stores/PlanStore.d.ts.map +1 -0
  58. package/dist/stores/PlanStore.js +3 -0
  59. package/dist/stores/PlanStore.js.map +1 -0
  60. package/dist/stores/UsageStore.d.ts +9 -0
  61. package/dist/stores/UsageStore.d.ts.map +1 -0
  62. package/dist/stores/UsageStore.js +3 -0
  63. package/dist/stores/UsageStore.js.map +1 -0
  64. package/dist/types.d.ts +115 -0
  65. package/dist/types.d.ts.map +1 -0
  66. package/dist/types.js +3 -0
  67. package/dist/types.js.map +1 -0
  68. package/dist/utils/fingerprint.d.ts +2 -0
  69. package/dist/utils/fingerprint.d.ts.map +1 -0
  70. package/dist/utils/fingerprint.js +20 -0
  71. package/dist/utils/fingerprint.js.map +1 -0
  72. package/dist/utils/guards.d.ts +5 -0
  73. package/dist/utils/guards.d.ts.map +1 -0
  74. package/dist/utils/guards.js +32 -0
  75. package/dist/utils/guards.js.map +1 -0
  76. package/package.json +9 -9
  77. package/examples/basic.ts +0 -35
  78. package/src/errors.ts +0 -19
  79. package/src/index.ts +0 -3
  80. package/src/pricing/matchRule.ts +0 -36
  81. package/src/pricing/quote.ts +0 -38
  82. package/src/providers/memory/MemoryLedgerStore.ts +0 -90
  83. package/src/providers/memory/MemoryLimitStore.ts +0 -102
  84. package/src/providers/memory/MemoryPlanStore.ts +0 -14
  85. package/src/providers/memory/MemoryUsageStore.ts +0 -10
  86. package/src/sdk/UsageSdk.ts +0 -117
  87. package/src/sdk/createUsageSdk.ts +0 -38
  88. package/src/stores/LedgerStore.ts +0 -30
  89. package/src/stores/LimitStore.ts +0 -5
  90. package/src/stores/PlanStore.ts +0 -5
  91. package/src/stores/UsageStore.ts +0 -5
  92. package/src/types.ts +0 -116
  93. package/src/utils/fingerprint.ts +0 -14
  94. package/src/utils/guards.ts +0 -23
  95. package/tsconfig.build.json +0 -14
  96. package/tsconfig.json +0 -13
@@ -0,0 +1,40 @@
1
+ import type { LedgerStore } from "../stores/LedgerStore";
2
+ import type { LimitStore } from "../stores/LimitStore";
3
+ import type { PlanStore } from "../stores/PlanStore";
4
+ import type { UsageStore } from "../stores/UsageStore";
5
+ import type { CheckResult, EnforceInput, EnforceResult, GrantResult, Money, Quote, QuoteInput } from "../types";
6
+ export type UsageSdkDeps = {
7
+ planStore: PlanStore;
8
+ ledgerStore: LedgerStore;
9
+ limitStore: LimitStore;
10
+ usageStore: UsageStore;
11
+ };
12
+ export declare class UsageSdk {
13
+ private readonly deps;
14
+ constructor(deps: UsageSdkDeps);
15
+ quote(input: QuoteInput): Promise<Quote>;
16
+ getBalance(input: {
17
+ accountId: string;
18
+ currency: Money["currency"];
19
+ }): Promise<Money>;
20
+ consumeRpm(input: {
21
+ accountId: string;
22
+ rpm: number;
23
+ requestCount?: number;
24
+ nowMs?: number;
25
+ }): Promise<CheckResult>;
26
+ grant(input: {
27
+ accountId: string;
28
+ money: Money;
29
+ idempotencyKey: string;
30
+ nowMs?: number;
31
+ metadata?: Record<string, unknown>;
32
+ }): Promise<GrantResult>;
33
+ getUsageCostSum(input: {
34
+ accountId: string;
35
+ currency: Money["currency"];
36
+ fromMs?: number;
37
+ toMs?: number;
38
+ }): Promise<Money>;
39
+ enforce(input: EnforceInput): Promise<EnforceResult>;
40
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsageSdk.d.ts","sourceRoot":"","sources":["../../src/sdk/UsageSdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzF,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,YAAY;IAEzC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;IAMxC,UAAU,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IAIrF,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAsF3D"}
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UsageSdk = void 0;
4
+ const errors_1 = require("../errors");
5
+ const quote_1 = require("../pricing/quote");
6
+ const guards_1 = require("../utils/guards");
7
+ const fingerprint_1 = require("../utils/fingerprint");
8
+ class UsageSdk {
9
+ deps;
10
+ constructor(deps) {
11
+ this.deps = deps;
12
+ }
13
+ async quote(input) {
14
+ const plan = await this.deps.planStore.getPlan(input.planId);
15
+ if (!plan)
16
+ throw new errors_1.UsageError("INVALID_ARGUMENT", `unknown planId: ${input.planId}`);
17
+ return (0, quote_1.quoteWithPlan)(input, plan);
18
+ }
19
+ async getBalance(input) {
20
+ return this.deps.ledgerStore.getBalance(input);
21
+ }
22
+ async consumeRpm(input) {
23
+ try {
24
+ const nowMs = input.nowMs ?? Date.now();
25
+ const requestCount = input.requestCount ?? 1;
26
+ (0, guards_1.assertNonNegativeInteger)(nowMs, "nowMs");
27
+ (0, guards_1.assertNonNegativeInteger)(requestCount, "requestCount");
28
+ await this.deps.limitStore.consumeRpm({ accountId: input.accountId, rpm: input.rpm, requestCount, nowMs });
29
+ return { ok: true };
30
+ }
31
+ catch (err) {
32
+ return (0, errors_1.toCheckResultError)(err);
33
+ }
34
+ }
35
+ async grant(input) {
36
+ try {
37
+ if (!input.idempotencyKey)
38
+ throw new errors_1.UsageError("INVALID_ARGUMENT", "idempotencyKey is required");
39
+ const nowMs = input.nowMs ?? Date.now();
40
+ (0, guards_1.assertNonNegativeInteger)(nowMs, "nowMs");
41
+ const fingerprint = (0, fingerprint_1.makeFingerprint)({
42
+ op: "credit",
43
+ accountId: input.accountId,
44
+ idempotencyKey: input.idempotencyKey,
45
+ money: input.money,
46
+ });
47
+ const result = await this.deps.ledgerStore.credit({
48
+ accountId: input.accountId,
49
+ money: input.money,
50
+ idempotencyKey: input.idempotencyKey,
51
+ fingerprint,
52
+ metadata: input.metadata,
53
+ nowMs,
54
+ });
55
+ return { ok: true, txId: result.txId, balanceAfter: result.balanceAfter };
56
+ }
57
+ catch (err) {
58
+ return (0, errors_1.toGrantResultError)(err);
59
+ }
60
+ }
61
+ async getUsageCostSum(input) {
62
+ const records = await this.deps.usageStore.list({ accountId: input.accountId, fromMs: input.fromMs, toMs: input.toMs });
63
+ let sum = 0;
64
+ for (const r of records) {
65
+ if (r.cost.currency !== input.currency)
66
+ continue;
67
+ sum += Math.max(0, r.cost.amountMinor);
68
+ }
69
+ return { currency: input.currency, amountMinor: sum };
70
+ }
71
+ async enforce(input) {
72
+ try {
73
+ if (!input.idempotencyKey)
74
+ throw new errors_1.UsageError("INVALID_ARGUMENT", "idempotencyKey is required");
75
+ const nowMs = input.nowMs ?? Date.now();
76
+ (0, guards_1.assertNonNegativeInteger)(nowMs, "nowMs");
77
+ const quote = await this.quote(input);
78
+ const debitFingerprint = (0, fingerprint_1.makeFingerprint)({
79
+ op: "debit",
80
+ accountId: input.accountId,
81
+ planId: input.planId,
82
+ idempotencyKey: input.idempotencyKey,
83
+ total: quote.total,
84
+ events: quote.items.map((i) => ({ meter: i.event.meter, quantity: i.event.quantity, dimensions: i.event.dimensions ?? {} })),
85
+ limits: input.limits ?? null,
86
+ });
87
+ const debitResult = await this.deps.ledgerStore.debit({
88
+ accountId: input.accountId,
89
+ money: quote.total,
90
+ idempotencyKey: input.idempotencyKey,
91
+ fingerprint: debitFingerprint,
92
+ metadata: input.metadata,
93
+ nowMs,
94
+ });
95
+ try {
96
+ const requestCount = input.requestCount ?? 1;
97
+ (0, guards_1.assertNonNegativeInteger)(requestCount, "requestCount");
98
+ const limits = input.limits;
99
+ if (limits?.rpm !== undefined) {
100
+ await this.deps.limitStore.consumeRpm({ accountId: input.accountId, rpm: limits.rpm, requestCount, nowMs });
101
+ }
102
+ if (limits?.dailyLimitMinor !== undefined) {
103
+ await this.deps.limitStore.consumeDailyMinor({
104
+ accountId: input.accountId,
105
+ amountMinor: quote.total.amountMinor,
106
+ limitMinor: limits.dailyLimitMinor,
107
+ nowMs,
108
+ });
109
+ }
110
+ if (limits?.monthlyLimitMinor !== undefined) {
111
+ await this.deps.limitStore.consumeMonthlyMinor({
112
+ accountId: input.accountId,
113
+ amountMinor: quote.total.amountMinor,
114
+ limitMinor: limits.monthlyLimitMinor,
115
+ nowMs,
116
+ });
117
+ }
118
+ }
119
+ catch (limitErr) {
120
+ const refundKey = `${input.idempotencyKey}::refund`;
121
+ const refundFingerprint = (0, fingerprint_1.makeFingerprint)({
122
+ op: "refund",
123
+ accountId: input.accountId,
124
+ currency: quote.total.currency,
125
+ amountMinor: quote.total.amountMinor,
126
+ for: input.idempotencyKey,
127
+ });
128
+ await this.deps.ledgerStore.credit({
129
+ accountId: input.accountId,
130
+ money: quote.total,
131
+ idempotencyKey: refundKey,
132
+ fingerprint: refundFingerprint,
133
+ metadata: { reason: "limits_failed", for: input.idempotencyKey },
134
+ nowMs,
135
+ });
136
+ throw limitErr;
137
+ }
138
+ await this.deps.usageStore.append({
139
+ accountId: input.accountId,
140
+ planId: input.planId,
141
+ idempotencyKey: input.idempotencyKey,
142
+ txId: debitResult.txId,
143
+ cost: quote.total,
144
+ events: input.events,
145
+ tsMs: nowMs,
146
+ metadata: input.metadata,
147
+ });
148
+ return { ok: true, txId: debitResult.txId, cost: quote.total, balanceAfter: debitResult.balanceAfter };
149
+ }
150
+ catch (err) {
151
+ return (0, errors_1.toEnforceResultError)(err);
152
+ }
153
+ }
154
+ }
155
+ exports.UsageSdk = UsageSdk;
156
+ //# sourceMappingURL=UsageSdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsageSdk.js","sourceRoot":"","sources":["../../src/sdk/UsageSdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { Limits, Money, PricePlan } from "../types";
2
+ import type { PersistenceProvider } from "../persistence/PersistenceProvider";
3
+ export type CreateUsageSdkInput = {
4
+ plans: PricePlan[];
5
+ persistence: PersistenceProvider;
6
+ initialBalances?: Array<{
7
+ accountId: string;
8
+ money: Money;
9
+ }>;
10
+ /**
11
+ * Optional: default limits applied by callers (you can also pass per-call limits in enforce()).
12
+ */
13
+ defaultLimits?: Limits;
14
+ };
15
+ export declare const createUsageSdk: (input: CreateUsageSdkInput) => {
16
+ quote: (input: import("../types").QuoteInput) => Promise<import("../types").Quote>;
17
+ enforce: (enforceInput: Parameters<(input: import("../types").EnforceInput) => Promise<import("../types").EnforceResult>>[0]) => Promise<import("../types").EnforceResult>;
18
+ getBalance: (input: {
19
+ accountId: string;
20
+ currency: Money["currency"];
21
+ }) => Promise<Money>;
22
+ consumeRpm: (input: {
23
+ accountId: string;
24
+ rpm: number;
25
+ requestCount?: number;
26
+ nowMs?: number;
27
+ }) => Promise<import("../types").CheckResult>;
28
+ grant: (input: {
29
+ accountId: string;
30
+ money: Money;
31
+ idempotencyKey: string;
32
+ nowMs?: number;
33
+ metadata?: Record<string, unknown>;
34
+ }) => Promise<import("../types").GrantResult>;
35
+ getUsageCostSum: (input: {
36
+ accountId: string;
37
+ currency: Money["currency"];
38
+ fromMs?: number;
39
+ toMs?: number;
40
+ }) => Promise<Money>;
41
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createUsageSdk.d.ts","sourceRoot":"","sources":["../../src/sdk/createUsageSdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAG3E,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IAC7D;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,mBAAmB;;4BAUvB,UAAU,6FAAoB,CAAC,CAAC,CAAC;;;;;IAM/D;;OAEG;;;;;;;CAGN,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createUsageSdk = void 0;
4
+ const UsageSdk_1 = require("./UsageSdk");
5
+ const createUsageSdk = (input) => {
6
+ const { planStore, ledgerStore, limitStore, usageStore } = input.persistence.create({
7
+ plans: input.plans,
8
+ initialBalances: input.initialBalances,
9
+ });
10
+ const sdk = new UsageSdk_1.UsageSdk({ planStore, ledgerStore, limitStore, usageStore });
11
+ return {
12
+ quote: sdk.quote.bind(sdk),
13
+ enforce: async (enforceInput) => sdk.enforce({
14
+ ...enforceInput,
15
+ limits: enforceInput.limits ?? input.defaultLimits,
16
+ }),
17
+ getBalance: sdk.getBalance.bind(sdk),
18
+ consumeRpm: sdk.consumeRpm.bind(sdk),
19
+ grant: sdk.grant.bind(sdk),
20
+ getUsageCostSum: sdk.getUsageCostSum.bind(sdk),
21
+ };
22
+ };
23
+ exports.createUsageSdk = createUsageSdk;
24
+ //# sourceMappingURL=createUsageSdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createUsageSdk.js","sourceRoot":"","sources":["../../src/sdk/createUsageSdk.ts"],"names":[],"mappings":";;;AACA,yCAAsC;AAa/B,MAAM,cAAc,GAAG,CAAC,KAA0B,EAAE,EAAE;IAC3D,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;QAClF,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,eAAe,EAAE,KAAK,CAAC,eAAe;KACvC,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,IAAI,mBAAQ,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;IAE7E,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,YAA+C,EAAE,EAAE,CACjE,GAAG,CAAC,OAAO,CAAC;YACV,GAAG,YAAY;YACf,MAAM,EAAE,YAAY,CAAC,MAAM,IAAI,KAAK,CAAC,aAAa;SACnD,CAAC;QACJ,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;QACpC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;QACpC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QAC1B,eAAe,EAAE,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;KAC/C,CAAC;AACJ,CAAC,CAAC;AApBW,QAAA,cAAc,kBAoBzB"}
@@ -0,0 +1,29 @@
1
+ import type { Money } from "../types";
2
+ export type LedgerDebitInput = {
3
+ accountId: string;
4
+ money: Money;
5
+ idempotencyKey: string;
6
+ fingerprint: string;
7
+ metadata?: Record<string, unknown>;
8
+ nowMs: number;
9
+ };
10
+ export type LedgerCreditInput = {
11
+ accountId: string;
12
+ money: Money;
13
+ idempotencyKey: string;
14
+ fingerprint: string;
15
+ metadata?: Record<string, unknown>;
16
+ nowMs: number;
17
+ };
18
+ export type LedgerApplyResult = {
19
+ txId: string;
20
+ balanceAfter: Money;
21
+ };
22
+ export interface LedgerStore {
23
+ getBalance(input: {
24
+ accountId: string;
25
+ currency: Money["currency"];
26
+ }): Promise<Money>;
27
+ debit(input: LedgerDebitInput): Promise<LedgerApplyResult>;
28
+ credit(input: LedgerCreditInput): Promise<LedgerApplyResult>;
29
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LedgerStore.d.ts","sourceRoot":"","sources":["../../src/stores/LedgerStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,KAAK,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACtF,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC9D"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=LedgerStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LedgerStore.js","sourceRoot":"","sources":["../../src/stores/LedgerStore.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ export interface LimitStore {
2
+ consumeRpm(input: {
3
+ accountId: string;
4
+ rpm: number;
5
+ requestCount: number;
6
+ nowMs: number;
7
+ }): Promise<void>;
8
+ consumeDailyMinor(input: {
9
+ accountId: string;
10
+ amountMinor: number;
11
+ limitMinor: number;
12
+ nowMs: number;
13
+ }): Promise<void>;
14
+ consumeMonthlyMinor(input: {
15
+ accountId: string;
16
+ amountMinor: number;
17
+ limitMinor: number;
18
+ nowMs: number;
19
+ }): Promise<void>;
20
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LimitStore.d.ts","sourceRoot":"","sources":["../../src/stores/LimitStore.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1G,iBAAiB,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvH,mBAAmB,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1H"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=LimitStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LimitStore.js","sourceRoot":"","sources":["../../src/stores/LimitStore.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { PricePlan } from "../types";
2
+ export interface PlanStore {
3
+ getPlan(planId: string): Promise<PricePlan | null>;
4
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanStore.d.ts","sourceRoot":"","sources":["../../src/stores/PlanStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACpD"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=PlanStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanStore.js","sourceRoot":"","sources":["../../src/stores/PlanStore.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { UsageRecord } from "../types";
2
+ export interface UsageStore {
3
+ append(record: UsageRecord): Promise<void>;
4
+ list(input: {
5
+ accountId: string;
6
+ fromMs?: number;
7
+ toMs?: number;
8
+ }): Promise<UsageRecord[]>;
9
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsageStore.d.ts","sourceRoot":"","sources":["../../src/stores/UsageStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=UsageStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsageStore.js","sourceRoot":"","sources":["../../src/stores/UsageStore.ts"],"names":[],"mappings":""}
@@ -0,0 +1,115 @@
1
+ export type Currency = "CNY" | (string & {});
2
+ export type Money = {
3
+ currency: Currency;
4
+ /**
5
+ * Minor units (e.g. CNY=分). Integer only.
6
+ */
7
+ amountMinor: number;
8
+ };
9
+ export type UsageEvent = {
10
+ meter: string;
11
+ quantity: number;
12
+ dimensions?: Record<string, string>;
13
+ ts?: number;
14
+ };
15
+ export type PriceRule = {
16
+ /**
17
+ * A logical meter name, e.g. "tokens.input", "tokens.output", "requests".
18
+ */
19
+ meter: string;
20
+ /**
21
+ * Dimension matchers. v0 supports:
22
+ * - "*" wildcard
23
+ * - string equality
24
+ * - string[] membership
25
+ */
26
+ when?: Record<string, "*" | string | string[]>;
27
+ /**
28
+ * Price per unit in minor units (e.g. 分). Integer only.
29
+ */
30
+ unitPriceMinor: number;
31
+ currency: Currency;
32
+ priority?: number;
33
+ ruleId?: string;
34
+ };
35
+ export type PricePlan = {
36
+ planId: string;
37
+ rules: PriceRule[];
38
+ };
39
+ export type Limits = {
40
+ /**
41
+ * Requests per minute. v0: each `enforce()` call consumes 1 request by default.
42
+ */
43
+ rpm?: number;
44
+ /**
45
+ * Daily spending limit in minor units.
46
+ */
47
+ dailyLimitMinor?: number;
48
+ /**
49
+ * Monthly spending limit in minor units.
50
+ */
51
+ monthlyLimitMinor?: number;
52
+ };
53
+ export type QuoteInput = {
54
+ accountId: string;
55
+ planId: string;
56
+ events: UsageEvent[];
57
+ };
58
+ export type QuoteItem = {
59
+ event: UsageEvent;
60
+ costMinor: number;
61
+ ruleId?: string;
62
+ };
63
+ export type Quote = {
64
+ total: Money;
65
+ items: QuoteItem[];
66
+ };
67
+ export type EnforceInput = QuoteInput & {
68
+ idempotencyKey: string;
69
+ limits?: Limits;
70
+ /**
71
+ * Overrides RPM consumption for this call. Defaults to 1.
72
+ */
73
+ requestCount?: number;
74
+ nowMs?: number;
75
+ metadata?: Record<string, unknown>;
76
+ };
77
+ export type EnforceErrorCode = "INSUFFICIENT_BALANCE" | "RPM_LIMIT_EXCEEDED" | "DAILY_LIMIT_EXCEEDED" | "MONTHLY_LIMIT_EXCEEDED" | "NO_PRICE_RULE" | "CURRENCY_MISMATCH" | "IDEMPOTENCY_CONFLICT" | "INVALID_ARGUMENT";
78
+ export type EnforceResult = {
79
+ ok: true;
80
+ txId: string;
81
+ cost: Money;
82
+ balanceAfter: Money;
83
+ } | {
84
+ ok: false;
85
+ code: EnforceErrorCode;
86
+ message?: string;
87
+ retryAfterMs?: number;
88
+ };
89
+ export type CheckResult = {
90
+ ok: true;
91
+ } | {
92
+ ok: false;
93
+ code: EnforceErrorCode;
94
+ message?: string;
95
+ retryAfterMs?: number;
96
+ };
97
+ export type GrantResult = {
98
+ ok: true;
99
+ txId: string;
100
+ balanceAfter: Money;
101
+ } | {
102
+ ok: false;
103
+ code: EnforceErrorCode;
104
+ message?: string;
105
+ };
106
+ export type UsageRecord = {
107
+ accountId: string;
108
+ planId: string;
109
+ idempotencyKey: string;
110
+ txId: string;
111
+ cost: Money;
112
+ events: UsageEvent[];
113
+ tsMs: number;
114
+ metadata?: Record<string, unknown>;
115
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare const stableStringify: (value: unknown) => string;
2
+ export declare const makeFingerprint: (value: unknown) => string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/utils/fingerprint.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,WAAgD,CAAC;AAE/F,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,WAA2B,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeFingerprint = exports.stableStringify = void 0;
4
+ const stableStringifyValue = (value) => {
5
+ if (Array.isArray(value))
6
+ return value.map(stableStringifyValue);
7
+ if (!value || typeof value !== "object")
8
+ return value;
9
+ const record = value;
10
+ const keys = Object.keys(record).sort();
11
+ const out = {};
12
+ for (const key of keys)
13
+ out[key] = stableStringifyValue(record[key]);
14
+ return out;
15
+ };
16
+ const stableStringify = (value) => JSON.stringify(stableStringifyValue(value));
17
+ exports.stableStringify = stableStringify;
18
+ const makeFingerprint = (value) => (0, exports.stableStringify)(value);
19
+ exports.makeFingerprint = makeFingerprint;
20
+ //# sourceMappingURL=fingerprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/utils/fingerprint.ts"],"names":[],"mappings":";;;AAAA,MAAM,oBAAoB,GAAG,CAAC,KAAc,EAAW,EAAE;IACvD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACjE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,GAAG,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEK,MAAM,eAAe,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;AAAlF,QAAA,eAAe,mBAAmE;AAExF,MAAM,eAAe,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,IAAA,uBAAe,EAAC,KAAK,CAAC,CAAC;AAA7D,QAAA,eAAe,mBAA8C"}
@@ -0,0 +1,5 @@
1
+ import type { Money, UsageEvent } from "../types";
2
+ export declare const assertInteger: (value: number, field: string) => void;
3
+ export declare const assertNonNegativeInteger: (value: number, field: string) => void;
4
+ export declare const assertMoney: (money: Money, field: string) => void;
5
+ export declare const assertUsageEvent: (event: UsageEvent, field: string) => void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErD,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,SAEzD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,SAGpE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,EAAE,OAAO,MAAM,SAItD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,OAAO,UAAU,EAAE,OAAO,MAAM,SAIhE,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertUsageEvent = exports.assertMoney = exports.assertNonNegativeInteger = exports.assertInteger = void 0;
4
+ const errors_1 = require("../errors");
5
+ const assertInteger = (value, field) => {
6
+ if (!Number.isInteger(value))
7
+ throw new errors_1.UsageError("INVALID_ARGUMENT", `${field} must be an integer`);
8
+ };
9
+ exports.assertInteger = assertInteger;
10
+ const assertNonNegativeInteger = (value, field) => {
11
+ (0, exports.assertInteger)(value, field);
12
+ if (value < 0)
13
+ throw new errors_1.UsageError("INVALID_ARGUMENT", `${field} must be >= 0`);
14
+ };
15
+ exports.assertNonNegativeInteger = assertNonNegativeInteger;
16
+ const assertMoney = (money, field) => {
17
+ if (!money || typeof money !== "object")
18
+ throw new errors_1.UsageError("INVALID_ARGUMENT", `${field} is required`);
19
+ if (!money.currency)
20
+ throw new errors_1.UsageError("INVALID_ARGUMENT", `${field}.currency is required`);
21
+ (0, exports.assertNonNegativeInteger)(money.amountMinor, `${field}.amountMinor`);
22
+ };
23
+ exports.assertMoney = assertMoney;
24
+ const assertUsageEvent = (event, field) => {
25
+ if (!event || typeof event !== "object")
26
+ throw new errors_1.UsageError("INVALID_ARGUMENT", `${field} is required`);
27
+ if (!event.meter)
28
+ throw new errors_1.UsageError("INVALID_ARGUMENT", `${field}.meter is required`);
29
+ (0, exports.assertNonNegativeInteger)(event.quantity, `${field}.quantity`);
30
+ };
31
+ exports.assertUsageEvent = assertUsageEvent;
32
+ //# sourceMappingURL=guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":";;;AAAA,sCAAuC;AAGhC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAE,KAAa,EAAE,EAAE;IAC5D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,mBAAU,CAAC,kBAAkB,EAAE,GAAG,KAAK,qBAAqB,CAAC,CAAC;AACxG,CAAC,CAAC;AAFW,QAAA,aAAa,iBAExB;AAEK,MAAM,wBAAwB,GAAG,CAAC,KAAa,EAAE,KAAa,EAAE,EAAE;IACvE,IAAA,qBAAa,EAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,mBAAU,CAAC,kBAAkB,EAAE,GAAG,KAAK,eAAe,CAAC,CAAC;AACnF,CAAC,CAAC;AAHW,QAAA,wBAAwB,4BAGnC;AAEK,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,KAAa,EAAE,EAAE;IACzD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,mBAAU,CAAC,kBAAkB,EAAE,GAAG,KAAK,cAAc,CAAC,CAAC;IAC1G,IAAI,CAAC,KAAK,CAAC,QAAQ;QAAE,MAAM,IAAI,mBAAU,CAAC,kBAAkB,EAAE,GAAG,KAAK,uBAAuB,CAAC,CAAC;IAC/F,IAAA,gCAAwB,EAAC,KAAK,CAAC,WAAW,EAAE,GAAG,KAAK,cAAc,CAAC,CAAC;AACtE,CAAC,CAAC;AAJW,QAAA,WAAW,eAItB;AAEK,MAAM,gBAAgB,GAAG,CAAC,KAAiB,EAAE,KAAa,EAAE,EAAE;IACnE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,mBAAU,CAAC,kBAAkB,EAAE,GAAG,KAAK,cAAc,CAAC,CAAC;IAC1G,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,MAAM,IAAI,mBAAU,CAAC,kBAAkB,EAAE,GAAG,KAAK,oBAAoB,CAAC,CAAC;IACzF,IAAA,gCAAwB,EAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,KAAK,WAAW,CAAC,CAAC;AAChE,CAAC,CAAC;AAJW,QAAA,gBAAgB,oBAI3B"}