mcp-usage-control-cloudflare 1.0.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.
@@ -0,0 +1,97 @@
1
+ const RESERVATION_ID_PATTERN = /^cf1\.[a-f0-9]{64}$/;
2
+ const HASH_PATTERN = /^[a-f0-9]{64}$/;
3
+ const LEASE_EXPIRED_REASON = 'lease_expired_after_execution_started';
4
+ /**
5
+ * Read-only lookup used only for ambiguous reserve acknowledgement recovery.
6
+ * It does not reserve, release, renew, settle, or otherwise change quota state.
7
+ */
8
+ export function lookupCloudflareReservation(storage, command, now = Date.now()) {
9
+ validateReservationId(command.reservationId);
10
+ const row = storage.sql
11
+ .exec(`SELECT id, state, reserved_units, expires_at, actual_units,
12
+ terminal_reason, tombstone_expires_at, budget_ids_json
13
+ FROM reservations WHERE id = ?`, command.reservationId)
14
+ .toArray()[0];
15
+ if (!row)
16
+ return { status: 'absent' };
17
+ const reservationId = String(row.id);
18
+ validateReservationId(reservationId);
19
+ const reservedUnits = integer(row.reserved_units, 'reservedUnits');
20
+ const budgetIds = parseBudgetIds(row.budget_ids_json);
21
+ const expiresAt = integer(row.expires_at, 'expiresAt');
22
+ if (row.state === 'pending' || row.state === 'liable') {
23
+ if (expiresAt <= now) {
24
+ return {
25
+ status: 'expired',
26
+ state: row.state,
27
+ reservationId,
28
+ reservedUnits,
29
+ expiredAt: expiresAt,
30
+ budgetIds,
31
+ };
32
+ }
33
+ return {
34
+ status: 'active',
35
+ state: row.state,
36
+ reservationId,
37
+ reservedUnits,
38
+ expiresAt,
39
+ budgetIds,
40
+ };
41
+ }
42
+ if (row.state !== 'settled')
43
+ throw new Error('Invalid stored reservation state');
44
+ if (row.terminal_reason === LEASE_EXPIRED_REASON) {
45
+ return {
46
+ status: 'expired',
47
+ state: 'liable',
48
+ reservationId,
49
+ reservedUnits,
50
+ expiredAt: expiresAt,
51
+ budgetIds,
52
+ };
53
+ }
54
+ const actualUnits = nullableInteger(row.actual_units, 'actualUnits');
55
+ const tombstoneExpiresAt = nullableInteger(row.tombstone_expires_at, 'tombstoneExpiresAt');
56
+ return {
57
+ status: 'settled',
58
+ reservationId,
59
+ reservedUnits,
60
+ actualUnits,
61
+ tombstoneExpiresAt,
62
+ budgetIds,
63
+ };
64
+ }
65
+ function validateReservationId(value) {
66
+ if (!RESERVATION_ID_PATTERN.test(value))
67
+ throw new RangeError('invalid reservationId');
68
+ }
69
+ function parseBudgetIds(raw) {
70
+ if (typeof raw !== 'string')
71
+ throw new Error('Invalid stored budget list');
72
+ let value;
73
+ try {
74
+ value = JSON.parse(raw);
75
+ }
76
+ catch {
77
+ throw new Error('Invalid stored budget list');
78
+ }
79
+ if (!Array.isArray(value) ||
80
+ value.length === 0 ||
81
+ !value.every(id => typeof id === 'string' && HASH_PATTERN.test(id))) {
82
+ throw new Error('Invalid stored budget list');
83
+ }
84
+ return value;
85
+ }
86
+ function integer(value, name) {
87
+ if (typeof value !== 'number' || !Number.isSafeInteger(value)) {
88
+ throw new Error(`Invalid stored ${name}`);
89
+ }
90
+ return value;
91
+ }
92
+ function nullableInteger(value, name) {
93
+ if (value === null)
94
+ throw new Error(`Invalid stored ${name}`);
95
+ return integer(value, name);
96
+ }
97
+ //# sourceMappingURL=reconciliation-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation-protocol.js","sourceRoot":"","sources":["../src/reconciliation-protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type UsageOperationReconciliation, type UsageOperationReconciliationInput } from 'mcp-usage-control';
2
+ import { type CloudflareUsageStoreGatewayOptions, type RemoteCloudflareUsageStoreOptions } from './index.js';
3
+ export type RemoteCloudflareReconciliationOptions = Pick<RemoteCloudflareUsageStoreOptions, 'endpoint' | 'headers' | 'fetch' | 'timeoutMs'>;
4
+ export type CloudflareReserveReconciliationInput = UsageOperationReconciliationInput;
5
+ export type CloudflareReserveReconciliation = UsageOperationReconciliation;
6
+ /**
7
+ * Drop-in gateway wrapper that preserves the normal usage-store protocol and
8
+ * adds one authenticated read-only `lookup` method for explicit reconciliation.
9
+ */
10
+ export declare function createReconciliableCloudflareUsageStoreGateway(options: CloudflareUsageStoreGatewayOptions): (request: Request) => Promise<Response>;
11
+ /**
12
+ * Reconciles one retained scalar logical operation. This function performs a
13
+ * single read-only lookup and never retries or creates a reservation. It is also
14
+ * the v0.8 generic entry point for ambiguous initial-reserve acknowledgement recovery.
15
+ */
16
+ export declare function reconcileRemoteCloudflareOperation(options: RemoteCloudflareReconciliationOptions, input: UsageOperationReconciliationInput): Promise<UsageOperationReconciliation>;
17
+ /** Backward-compatible v0.7 name for initial-reserve acknowledgement reconciliation. */
18
+ export declare function reconcileRemoteCloudflareReserve(options: RemoteCloudflareReconciliationOptions, input: CloudflareReserveReconciliationInput): Promise<CloudflareReserveReconciliation>;
19
+ //# sourceMappingURL=reconciliation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation.d.ts","sourceRoot":"","sources":["../src/reconciliation.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,4BAA4B,EACjC,KAAK,iCAAiC,EACvC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAIL,KAAK,kCAAkC,EACvC,KAAK,iCAAiC,EACvC,MAAM,YAAY,CAAC;AAepB,MAAM,MAAM,qCAAqC,GAAG,IAAI,CACtD,iCAAiC,EACjC,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAC/C,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG,iCAAiC,CAAC;AACrF,MAAM,MAAM,+BAA+B,GAAG,4BAA4B,CAAC;AAE3E;;;GAGG;AACH,wBAAgB,8CAA8C,CAC5D,OAAO,EAAE,kCAAkC,IAgBd,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAgDlE;AA+CD;;;;GAIG;AACH,wBAAsB,kCAAkC,CACtD,OAAO,EAAE,qCAAqC,EAC9C,KAAK,EAAE,iCAAiC,GACvC,OAAO,CAAC,4BAA4B,CAAC,CAgDvC;AAED,wFAAwF;AACxF,wBAAsB,gCAAgC,CACpD,OAAO,EAAE,qCAAqC,EAC9C,KAAK,EAAE,oCAAoC,GAC1C,OAAO,CAAC,+BAA+B,CAAC,CAE1C"}
@@ -0,0 +1,402 @@
1
+ import { UsageStateError, } from 'mcp-usage-control';
2
+ import { CloudflareUsageTransportError, createCloudflareUsageStoreGateway, } from './index.js';
3
+ const DEFAULT_PATH = '/v1/usage-store';
4
+ const MAX_GATEWAY_BODY_BYTES = 65_536;
5
+ const RESERVATION_ID_PATTERN = /^cf1\.[a-f0-9]{64}$/;
6
+ const HASH_PATTERN = /^[a-f0-9]{64}$/;
7
+ /**
8
+ * Drop-in gateway wrapper that preserves the normal usage-store protocol and
9
+ * adds one authenticated read-only `lookup` method for explicit reconciliation.
10
+ */
11
+ export function createReconciliableCloudflareUsageStoreGateway(options) {
12
+ // Normal usage requests still delegate to the base gateway. Cache only a
13
+ // successful decision for the exact Request object so a side-effectful
14
+ // application authorizer is never executed twice for one request.
15
+ const preauthorized = new WeakSet();
16
+ const baseHandler = createCloudflareUsageStoreGateway({
17
+ ...options,
18
+ authorize(request) {
19
+ if (preauthorized.has(request))
20
+ return true;
21
+ return options.authorize(request);
22
+ },
23
+ });
24
+ const path = options.path ?? DEFAULT_PATH;
25
+ const domainName = options.domainName ?? 'default';
26
+ return async function handle(request) {
27
+ const url = new URL(request.url);
28
+ if (url.pathname !== path || request.method !== 'POST')
29
+ return baseHandler(request);
30
+ let authorized = false;
31
+ try {
32
+ authorized = (await options.authorize(request)) === true;
33
+ }
34
+ catch {
35
+ authorized = false;
36
+ }
37
+ if (!authorized)
38
+ return responseJson({ error: 'unauthorized' }, 401);
39
+ preauthorized.add(request);
40
+ const contentLength = Number(request.headers.get('content-length') ?? '0');
41
+ if (Number.isFinite(contentLength) && contentLength > MAX_GATEWAY_BODY_BYTES) {
42
+ return responseJson({ error: 'payload_too_large' }, 413);
43
+ }
44
+ const buffered = await readBoundedRequestText(request.clone(), MAX_GATEWAY_BODY_BYTES);
45
+ if (buffered.status === 'too_large') {
46
+ return responseJson({ error: 'payload_too_large' }, 413);
47
+ }
48
+ if (buffered.status === 'error') {
49
+ return responseJson({ error: 'invalid_request' }, 400);
50
+ }
51
+ let body;
52
+ try {
53
+ body = JSON.parse(buffered.text);
54
+ }
55
+ catch {
56
+ return responseJson({ error: 'invalid_request' }, 400);
57
+ }
58
+ if (!isLookupHttpRequest(body))
59
+ return baseHandler(request);
60
+ let stub;
61
+ try {
62
+ stub = resolveLookupStub(options.namespace, domainName);
63
+ }
64
+ catch {
65
+ return responseJson({ error: 'store_unavailable' }, 503);
66
+ }
67
+ try {
68
+ const result = await stub.lookup(body.input);
69
+ return responseJson({ version: 1, result }, 200);
70
+ }
71
+ catch {
72
+ return responseJson({ error: 'store_unavailable' }, 503);
73
+ }
74
+ };
75
+ }
76
+ async function readBoundedRequestText(request, maxBytes) {
77
+ if (!request.body)
78
+ return { status: 'ok', text: '' };
79
+ const reader = request.body.getReader();
80
+ const chunks = [];
81
+ let totalBytes = 0;
82
+ try {
83
+ while (true) {
84
+ const { done, value } = await reader.read();
85
+ if (done)
86
+ break;
87
+ if (!value || value.byteLength === 0)
88
+ continue;
89
+ totalBytes += value.byteLength;
90
+ if (totalBytes > maxBytes) {
91
+ try {
92
+ await reader.cancel();
93
+ }
94
+ catch {
95
+ // Best-effort cancellation only; the response is already fail-closed.
96
+ }
97
+ return { status: 'too_large' };
98
+ }
99
+ chunks.push(value);
100
+ }
101
+ }
102
+ catch {
103
+ return { status: 'error' };
104
+ }
105
+ finally {
106
+ reader.releaseLock();
107
+ }
108
+ const bytes = new Uint8Array(totalBytes);
109
+ let offset = 0;
110
+ for (const chunk of chunks) {
111
+ bytes.set(chunk, offset);
112
+ offset += chunk.byteLength;
113
+ }
114
+ return { status: 'ok', text: new TextDecoder().decode(bytes) };
115
+ }
116
+ /**
117
+ * Reconciles one retained scalar logical operation. This function performs a
118
+ * single read-only lookup and never retries or creates a reservation. It is also
119
+ * the v0.8 generic entry point for ambiguous initial-reserve acknowledgement recovery.
120
+ */
121
+ export async function reconcileRemoteCloudflareOperation(options, input) {
122
+ const prepared = await prepareReconciliation(input);
123
+ const reply = await postLookup(options, prepared.reservationId);
124
+ if (reply.status === 'absent') {
125
+ return { status: 'absent', reservationId: prepared.reservationId };
126
+ }
127
+ verifyLookupIdentity(reply, prepared, input.units);
128
+ if (reply.status === 'active') {
129
+ return {
130
+ status: 'active',
131
+ state: reply.state,
132
+ reservation: {
133
+ id: prepared.reservationId,
134
+ operationId: input.request.operationId,
135
+ principalId: input.request.principal.id,
136
+ ...(input.request.principal.tenantId === undefined
137
+ ? {}
138
+ : { tenantId: input.request.principal.tenantId }),
139
+ ...(input.request.principal.plan === undefined
140
+ ? {}
141
+ : { plan: input.request.principal.plan }),
142
+ tool: input.request.tool,
143
+ budgetKeys: prepared.budgets.map(budget => budget.key),
144
+ reservedUnits: reply.reservedUnits,
145
+ expiresAt: reply.expiresAt,
146
+ },
147
+ };
148
+ }
149
+ if (reply.status === 'expired') {
150
+ return {
151
+ status: 'expired',
152
+ state: reply.state,
153
+ reservationId: prepared.reservationId,
154
+ expiredAt: reply.expiredAt,
155
+ };
156
+ }
157
+ return {
158
+ status: 'settled',
159
+ reservationId: prepared.reservationId,
160
+ reservedUnits: reply.reservedUnits,
161
+ actualUnits: reply.actualUnits,
162
+ tombstoneExpiresAt: reply.tombstoneExpiresAt,
163
+ };
164
+ }
165
+ /** Backward-compatible v0.7 name for initial-reserve acknowledgement reconciliation. */
166
+ export async function reconcileRemoteCloudflareReserve(options, input) {
167
+ return reconcileRemoteCloudflareOperation(options, input);
168
+ }
169
+ async function prepareReconciliation(input) {
170
+ validateRequestIdentity(input.request);
171
+ assertNonNegativeInteger(input.units, 'units');
172
+ const budgets = canonicalizeBudgets(input.budgets);
173
+ const operationHash = await digest(JSON.stringify([
174
+ input.request.principal.tenantId ?? null,
175
+ input.request.principal.id,
176
+ input.request.tool,
177
+ input.request.operationId,
178
+ ]));
179
+ const budgetIds = await Promise.all(budgets.map(budget => digest(budget.key)));
180
+ return { reservationId: `cf1.${operationHash}`, budgets, budgetIds };
181
+ }
182
+ async function postLookup(options, reservationId) {
183
+ const endpoint = new URL(options.endpoint);
184
+ const isLocalHttp = endpoint.protocol === 'http:' &&
185
+ (endpoint.hostname === '127.0.0.1' || endpoint.hostname === 'localhost');
186
+ if (endpoint.protocol !== 'https:' && !isLocalHttp) {
187
+ throw new RangeError('Cloudflare usage store endpoint must use HTTPS (local HTTP is test-only)');
188
+ }
189
+ if (endpoint.username || endpoint.password) {
190
+ throw new RangeError('Cloudflare usage store endpoint must not embed credentials');
191
+ }
192
+ const timeoutMs = options.timeoutMs ?? 10_000;
193
+ assertPositiveInteger(timeoutMs, 'timeoutMs');
194
+ assertPortableTimerDelay(timeoutMs, 'timeoutMs');
195
+ const controller = new AbortController();
196
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
197
+ try {
198
+ let resolvedHeaders;
199
+ try {
200
+ resolvedHeaders = await waitForAbort(resolveHeaders(options.headers), controller.signal);
201
+ }
202
+ catch (error) {
203
+ if (controller.signal.aborted)
204
+ throw new CloudflareUsageTransportError('timeout');
205
+ throw error;
206
+ }
207
+ const headers = new Headers(resolvedHeaders);
208
+ headers.set('content-type', 'application/json');
209
+ headers.set('accept', 'application/json');
210
+ let response;
211
+ try {
212
+ response = await waitForAbort((options.fetch ?? fetch)(endpoint, {
213
+ method: 'POST',
214
+ headers,
215
+ body: JSON.stringify({
216
+ version: 1,
217
+ method: 'lookup',
218
+ input: { reservationId },
219
+ }),
220
+ signal: controller.signal,
221
+ }), controller.signal);
222
+ }
223
+ catch (error) {
224
+ if (controller.signal.aborted)
225
+ throw new CloudflareUsageTransportError('timeout');
226
+ if (error instanceof CloudflareUsageTransportError)
227
+ throw error;
228
+ throw new CloudflareUsageTransportError('network');
229
+ }
230
+ if (response.status === 401 || response.status === 403) {
231
+ throw new CloudflareUsageTransportError('unauthorized', response.status);
232
+ }
233
+ if (!response.ok)
234
+ throw new CloudflareUsageTransportError('remote', response.status);
235
+ let payload;
236
+ try {
237
+ payload = await waitForAbort(response.json(), controller.signal);
238
+ }
239
+ catch (error) {
240
+ if (controller.signal.aborted)
241
+ throw new CloudflareUsageTransportError('timeout');
242
+ if (error instanceof CloudflareUsageTransportError)
243
+ throw error;
244
+ throw new CloudflareUsageTransportError('protocol', response.status);
245
+ }
246
+ if (!isLookupHttpResponse(payload)) {
247
+ throw new CloudflareUsageTransportError('protocol', response.status);
248
+ }
249
+ return payload.result;
250
+ }
251
+ finally {
252
+ clearTimeout(timer);
253
+ }
254
+ }
255
+ function verifyLookupIdentity(reply, prepared, units) {
256
+ if (reply.reservationId !== prepared.reservationId) {
257
+ throw new UsageStateError('Cloudflare reconciliation returned a different reservation');
258
+ }
259
+ if (reply.reservedUnits !== units) {
260
+ throw new UsageStateError('Cloudflare reconciliation reservedUnits did not match expected retained state');
261
+ }
262
+ if (reply.budgetIds.length !== prepared.budgetIds.length ||
263
+ reply.budgetIds.some((id, index) => id !== prepared.budgetIds[index])) {
264
+ throw new UsageStateError('Cloudflare reconciliation budgets did not match expected retained state');
265
+ }
266
+ }
267
+ function resolveLookupStub(namespace, domainName) {
268
+ const candidate = namespace.getByName
269
+ ? namespace.getByName(domainName)
270
+ : namespace.idFromName && namespace.get
271
+ ? namespace.get(namespace.idFromName(domainName))
272
+ : undefined;
273
+ if (!candidate)
274
+ throw new TypeError('Durable Object namespace is unavailable');
275
+ const lookup = candidate.lookup;
276
+ if (typeof lookup !== 'function') {
277
+ throw new TypeError('Durable Object does not expose reconciliation lookup');
278
+ }
279
+ return candidate;
280
+ }
281
+ function isLookupHttpRequest(value) {
282
+ return (isRecord(value) &&
283
+ value.version === 1 &&
284
+ value.method === 'lookup' &&
285
+ isRecord(value.input) &&
286
+ typeof value.input.reservationId === 'string' &&
287
+ RESERVATION_ID_PATTERN.test(value.input.reservationId));
288
+ }
289
+ function isLookupHttpResponse(value) {
290
+ return isRecord(value) && value.version === 1 && isLookupReply(value.result);
291
+ }
292
+ function isLookupReply(value) {
293
+ if (!isRecord(value) || typeof value.status !== 'string')
294
+ return false;
295
+ if (value.status === 'absent')
296
+ return true;
297
+ if (typeof value.reservationId !== 'string' ||
298
+ !RESERVATION_ID_PATTERN.test(value.reservationId) ||
299
+ !isNonNegativeInteger(value.reservedUnits) ||
300
+ !isHashArray(value.budgetIds)) {
301
+ return false;
302
+ }
303
+ if (value.status === 'active') {
304
+ return ((value.state === 'pending' || value.state === 'liable') &&
305
+ isNonNegativeInteger(value.expiresAt));
306
+ }
307
+ if (value.status === 'expired') {
308
+ return ((value.state === 'pending' || value.state === 'liable') &&
309
+ isNonNegativeInteger(value.expiredAt));
310
+ }
311
+ if (value.status === 'settled') {
312
+ return (isNonNegativeInteger(value.actualUnits) &&
313
+ isNonNegativeInteger(value.tombstoneExpiresAt));
314
+ }
315
+ return false;
316
+ }
317
+ function canonicalizeBudgets(budgets) {
318
+ if (budgets.length === 0)
319
+ throw new RangeError('budgets must contain at least one budget');
320
+ const normalized = budgets.map(budget => {
321
+ if (typeof budget.key !== 'string' || budget.key.length === 0) {
322
+ throw new RangeError('budget.key must be a non-empty string');
323
+ }
324
+ assertNonNegativeInteger(budget.limit, `budget.limit (${budget.key})`);
325
+ return { key: budget.key, limit: budget.limit };
326
+ });
327
+ normalized.sort((a, b) => a.key.localeCompare(b.key));
328
+ for (let index = 1; index < normalized.length; index += 1) {
329
+ if (normalized[index - 1].key === normalized[index].key) {
330
+ throw new RangeError(`duplicate budget key: ${normalized[index].key}`);
331
+ }
332
+ }
333
+ return normalized;
334
+ }
335
+ function validateRequestIdentity(request) {
336
+ if (!request.operationId)
337
+ throw new RangeError('operationId must be non-empty');
338
+ if (!request.principal.id)
339
+ throw new RangeError('principal.id must be non-empty');
340
+ if (!request.tool)
341
+ throw new RangeError('tool must be non-empty');
342
+ }
343
+ function assertNonNegativeInteger(value, name) {
344
+ if (!Number.isSafeInteger(value) || value < 0) {
345
+ throw new RangeError(`${name} must be a non-negative safe integer`);
346
+ }
347
+ }
348
+ function assertPortableTimerDelay(value, name) {
349
+ if (value > 2_147_483_647) {
350
+ throw new RangeError(`${name} must not exceed 2147483647ms`);
351
+ }
352
+ }
353
+ function assertPositiveInteger(value, name) {
354
+ if (!Number.isSafeInteger(value) || value <= 0) {
355
+ throw new RangeError(`${name} must be a positive safe integer`);
356
+ }
357
+ }
358
+ function isNonNegativeInteger(value) {
359
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
360
+ }
361
+ function isHashArray(value) {
362
+ return Array.isArray(value) && value.length > 0 && value.every(id => typeof id === 'string' && HASH_PATTERN.test(id));
363
+ }
364
+ async function digest(value) {
365
+ const bytes = new TextEncoder().encode(value);
366
+ const hash = await crypto.subtle.digest('SHA-256', bytes);
367
+ return Array.from(new Uint8Array(hash), byte => byte.toString(16).padStart(2, '0')).join('');
368
+ }
369
+ async function resolveHeaders(headers) {
370
+ if (typeof headers === 'function')
371
+ return headers();
372
+ return headers;
373
+ }
374
+ function waitForAbort(promise, signal) {
375
+ if (signal.aborted)
376
+ return Promise.reject(new Error('operation aborted'));
377
+ return new Promise((resolve, reject) => {
378
+ const onAbort = () => {
379
+ cleanup();
380
+ reject(new Error('operation aborted'));
381
+ };
382
+ const cleanup = () => signal.removeEventListener('abort', onAbort);
383
+ signal.addEventListener('abort', onAbort, { once: true });
384
+ void promise.then(value => {
385
+ cleanup();
386
+ resolve(value);
387
+ }, error => {
388
+ cleanup();
389
+ reject(error);
390
+ });
391
+ });
392
+ }
393
+ function responseJson(body, status) {
394
+ return new Response(JSON.stringify(body), {
395
+ status,
396
+ headers: { 'content-type': 'application/json; charset=utf-8' },
397
+ });
398
+ }
399
+ function isRecord(value) {
400
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
401
+ }
402
+ //# sourceMappingURL=reconciliation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation.js","sourceRoot":"","sources":["../src/reconciliation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { DurableObjectState } from 'cloudflare:workers';
2
+ export declare const CLOUDFLARE_USAGE_SCHEMA_VERSION = 3;
3
+ type DurableObjectStorage = DurableObjectState['storage'];
4
+ /**
5
+ * Initializes or validates the Cloudflare SQLite schema as one synchronous
6
+ * transaction. The first versioned release adopts the exact pre-versioning
7
+ * schema as v1 without rewriting accounting rows.
8
+ */
9
+ export declare function initializeCloudflareUsageSchema(storage: DurableObjectStorage): void;
10
+ export declare function readCloudflareUsageSchemaVersion(storage: DurableObjectStorage): number | undefined;
11
+ export {};
12
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,oBAAoB,CAAC;AAE9E,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAWjD,KAAK,oBAAoB,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;AA2D1D;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CA2CnF;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,oBAAoB,GAC5B,MAAM,GAAG,SAAS,CAEpB"}