@substrat-run/adapter-cloudflare 0.2.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,339 @@
1
+ import { DurableObject } from 'cloudflare:workers';
2
+ import { domainEvent, domainEventInput, eventId, instant, objectRef, principalId, } from '@substrat-run/contracts';
3
+ import { ulid, } from '@substrat-run/kernel';
4
+ import { OperationQueue } from './serialization.js';
5
+ import { doScopedSql } from './sql.js';
6
+ import { createDoTupleChecker } from './checker.js';
7
+ const KERNEL_DDL = `
8
+ CREATE TABLE IF NOT EXISTS _substrat_outbox (
9
+ id TEXT PRIMARY KEY,
10
+ type TEXT NOT NULL,
11
+ schema_version INTEGER NOT NULL,
12
+ occurred_at TEXT NOT NULL,
13
+ tenant_id TEXT NOT NULL,
14
+ scope_id TEXT NOT NULL,
15
+ actor TEXT NOT NULL,
16
+ entity_type TEXT NOT NULL,
17
+ entity_id TEXT NOT NULL,
18
+ pii_class TEXT NOT NULL,
19
+ subject_id TEXT,
20
+ payload TEXT,
21
+ drained_at TEXT
22
+ );
23
+ CREATE TABLE IF NOT EXISTS _substrat_migrations (
24
+ module_id TEXT NOT NULL,
25
+ version TEXT NOT NULL,
26
+ applied_at TEXT NOT NULL,
27
+ PRIMARY KEY (module_id, version)
28
+ );
29
+ CREATE TABLE IF NOT EXISTS _substrat_tuples (
30
+ subject TEXT NOT NULL,
31
+ relation TEXT NOT NULL,
32
+ object TEXT NOT NULL,
33
+ expires_at TEXT,
34
+ PRIMARY KEY (subject, relation, object)
35
+ );
36
+ CREATE TABLE IF NOT EXISTS _substrat_deliveries (
37
+ event_id TEXT NOT NULL,
38
+ consumer_module TEXT NOT NULL,
39
+ delivered_at TEXT NOT NULL,
40
+ error TEXT,
41
+ PRIMARY KEY (event_id, consumer_module)
42
+ );
43
+ `;
44
+ /**
45
+ * Workers RPC carries only a plain `Error`'s message/name/stack faithfully; a
46
+ * custom subclass (e.g. Zod's `ZodError`, whose `message` is a getter over its
47
+ * issues) arrives on the coordinator side as just its class name. Contract
48
+ * matchers assert on the message (`/subjectId/`, `/boom/`, …), so re-wrap any
49
+ * non-plain error as a plain `Error` before it crosses the boundary — the
50
+ * message (which for a ZodError includes the failing path/detail) survives.
51
+ */
52
+ function toRpcError(err) {
53
+ if (err instanceof Error) {
54
+ return err.constructor === Error ? err : new Error(err.message);
55
+ }
56
+ return new Error(String(err));
57
+ }
58
+ export function defineScopeDO(modules, bareOps) {
59
+ return class ScopeDO extends DurableObject {
60
+ sql;
61
+ queue = new OperationQueue();
62
+ operations = new Map();
63
+ modules = new Map();
64
+ guards = new Map();
65
+ predicates = new Map();
66
+ withdrawn = new Map();
67
+ relations = new Map();
68
+ checker;
69
+ systemPrincipal = principalId.parse(ulid());
70
+ applied = new Set();
71
+ migrationPromise;
72
+ constructor(ctx, env) {
73
+ super(ctx, env);
74
+ this.sql = ctx.storage.sql;
75
+ for (const stmt of KERNEL_DDL.split(';')) {
76
+ const s = stmt.trim();
77
+ if (s)
78
+ this.sql.exec(s);
79
+ }
80
+ for (const registration of modules)
81
+ this.registerModule(registration);
82
+ for (const [name, handler] of Object.entries(bareOps))
83
+ this.defineOperation(name, handler);
84
+ // Which migrations have already run (a warm DO wakes with rows here).
85
+ for (const row of this.sql
86
+ .exec('SELECT module_id, version FROM _substrat_migrations')
87
+ .toArray()) {
88
+ this.applied.add(`${row.module_id}@${row.version}`);
89
+ }
90
+ const controlPlane = this.controlPlaneReader();
91
+ this.checker = createDoTupleChecker({ scopeSql: this.sql, controlPlane });
92
+ }
93
+ // -- module registration (port of SqliteScopeHost.registerModule) ---------
94
+ registerModule(registration) {
95
+ const manifest = registration.manifest;
96
+ this.modules.set(manifest.id, {
97
+ id: manifest.id,
98
+ migrations: registration.migrations ?? [],
99
+ consumers: Object.entries(registration.consumers ?? {}).map(([eventType, handler]) => ({
100
+ eventType,
101
+ handler,
102
+ })),
103
+ });
104
+ for (const [name, handler] of Object.entries(registration.predicates ?? {})) {
105
+ this.predicates.set(name, { module: manifest.id, handler });
106
+ }
107
+ for (const guard of manifest.guards ?? []) {
108
+ const forOperation = this.guards.get(guard.before) ?? [];
109
+ forOperation.push({ predicate: guard.predicate, config: guard.config, declaredBy: manifest.id });
110
+ this.guards.set(guard.before, forOperation);
111
+ }
112
+ for (const rel of manifest.entityRelations ?? []) {
113
+ const parents = this.relations.get(rel.entityType) ?? new Set();
114
+ parents.add(rel.parentType);
115
+ this.relations.set(rel.entityType, parents);
116
+ }
117
+ for (const name of manifest.withdraws ?? []) {
118
+ this.withdrawn.set(name, manifest.id);
119
+ this.operations.delete(name);
120
+ }
121
+ for (const [name, handler] of Object.entries(registration.operations ?? {})) {
122
+ this.defineOperation(name, handler);
123
+ }
124
+ }
125
+ defineOperation(name, handler) {
126
+ if (this.withdrawn.has(name))
127
+ return; // withdrawn by another manifest — never binds
128
+ this.operations.set(name, handler);
129
+ }
130
+ // -- RPC surface ----------------------------------------------------------
131
+ /** Trigger lazy migration (the coordinator calls this at provision time). */
132
+ async migrate() {
133
+ await this.ensureMigrations();
134
+ }
135
+ /** Admin scope-tuple write (role assignment / grant scoped to this scope). */
136
+ async writeTuple(subject, relation, object, expiresAt) {
137
+ await this.queue.enqueue(() => {
138
+ this.sql.exec(`INSERT OR REPLACE INTO _substrat_tuples (subject, relation, object, expires_at)
139
+ VALUES (?, ?, ?, ?)`, subject, relation, object, expiresAt);
140
+ });
141
+ }
142
+ async invoke(operation, input, principal, tenantId, scopeId) {
143
+ await this.ensureMigrations();
144
+ const handler = this.operations.get(operation);
145
+ if (!handler)
146
+ throw new Error(`unknown operation: ${operation}`);
147
+ return this.queue.enqueue(async () => {
148
+ let result;
149
+ // The async transaction is the K-4 boundary: guards + handler + emits
150
+ // commit together, or a throw (from either) rolls domain writes AND
151
+ // emitted events back as one — verified across `await` in workerd.
152
+ try {
153
+ await this.ctx.storage.transaction(async () => {
154
+ const ctx = this.operationContext(principal, tenantId, scopeId);
155
+ await this.runGuards(operation, ctx, input);
156
+ result = await handler(ctx, input);
157
+ });
158
+ }
159
+ catch (err) {
160
+ throw toRpcError(err);
161
+ }
162
+ // Post-commit: drain the outbox to consumers, each delivery its own txn.
163
+ await this.dispatch(tenantId, scopeId);
164
+ return result;
165
+ });
166
+ }
167
+ // -- guards (K-17) --------------------------------------------------------
168
+ async runGuards(operation, ctx, input) {
169
+ const declared = this.guards.get(operation);
170
+ if (!declared)
171
+ return;
172
+ for (const guard of declared) {
173
+ const predicate = this.predicates.get(guard.predicate);
174
+ if (!predicate) {
175
+ throw new Error(`unknown guard predicate: '${guard.predicate}' — declared by ${guard.declaredBy} ` +
176
+ `before '${operation}'; no registered module contributes it (operation blocked)`);
177
+ }
178
+ await predicate.handler(ctx, guard.config, input);
179
+ }
180
+ }
181
+ // -- migrations (port of applyPendingMigrations) --------------------------
182
+ ensureMigrations() {
183
+ if (!this.migrationPromise)
184
+ this.migrationPromise = this.applyPendingMigrations();
185
+ return this.migrationPromise;
186
+ }
187
+ async applyPendingMigrations() {
188
+ const pending = [];
189
+ for (const mod of this.modules.values()) {
190
+ for (const migration of mod.migrations) {
191
+ if (!this.applied.has(`${mod.id}@${migration.version}`)) {
192
+ pending.push({ moduleId: mod.id, migration });
193
+ }
194
+ }
195
+ }
196
+ if (pending.length === 0)
197
+ return;
198
+ await this.queue.enqueue(async () => {
199
+ for (const { moduleId, migration } of pending) {
200
+ const key = `${moduleId}@${migration.version}`;
201
+ if (this.applied.has(key))
202
+ continue;
203
+ try {
204
+ await this.ctx.storage.transaction(async () => {
205
+ const already = this.sql
206
+ .exec('SELECT 1 FROM _substrat_migrations WHERE module_id = ? AND version = ?', moduleId, migration.version)
207
+ .toArray()[0];
208
+ if (!already) {
209
+ for (const stmt of migration.sql.split(';')) {
210
+ const s = stmt.trim();
211
+ if (s)
212
+ this.sql.exec(s);
213
+ }
214
+ this.sql.exec('INSERT INTO _substrat_migrations (module_id, version, applied_at) VALUES (?, ?, ?)', moduleId, migration.version, new Date().toISOString());
215
+ }
216
+ });
217
+ }
218
+ catch (err) {
219
+ throw new Error(`migration failed for ${key} — scope fails closed: ${err.message}`);
220
+ }
221
+ this.applied.add(key);
222
+ }
223
+ });
224
+ }
225
+ // -- event dispatch (port of dispatch) ------------------------------------
226
+ async dispatch(tenantId, scopeId) {
227
+ for (let round = 0; round < 50; round++) {
228
+ let deliveredAny = false;
229
+ for (const mod of this.modules.values()) {
230
+ for (const consumer of mod.consumers) {
231
+ const rows = this.sql
232
+ .exec(`SELECT * FROM _substrat_outbox o
233
+ WHERE o.type = ?
234
+ AND NOT EXISTS (
235
+ SELECT 1 FROM _substrat_deliveries d
236
+ WHERE d.event_id = o.id AND d.consumer_module = ?
237
+ )
238
+ ORDER BY o.id`, consumer.eventType, mod.id)
239
+ .toArray();
240
+ for (const row of rows) {
241
+ const event = this.parseOutboxRow(row);
242
+ try {
243
+ await this.ctx.storage.transaction(async () => {
244
+ const ctx = this.operationContext(this.systemPrincipal, tenantId, scopeId, {
245
+ system: mod.id,
246
+ });
247
+ await consumer.handler(ctx, event);
248
+ this.sql.exec(`INSERT INTO _substrat_deliveries (event_id, consumer_module, delivered_at)
249
+ VALUES (?, ?, ?)`, event.id, mod.id, new Date().toISOString());
250
+ });
251
+ deliveredAny = true;
252
+ }
253
+ catch (err) {
254
+ // Dead-letter (v0): journal the failure so one poison event
255
+ // can't wedge the loop. Written outside the rolled-back txn.
256
+ this.sql.exec(`INSERT INTO _substrat_deliveries (event_id, consumer_module, delivered_at, error)
257
+ VALUES (?, ?, ?, ?)`, event.id, mod.id, new Date().toISOString(), String(err));
258
+ }
259
+ }
260
+ }
261
+ }
262
+ if (!deliveredAny)
263
+ return;
264
+ }
265
+ }
266
+ parseOutboxRow(row) {
267
+ return domainEvent.parse({
268
+ id: row.id,
269
+ type: row.type,
270
+ schemaVersion: row.schema_version,
271
+ occurredAt: row.occurred_at,
272
+ tenantId: row.tenant_id,
273
+ scopeId: row.scope_id,
274
+ actor: JSON.parse(row.actor),
275
+ entity: { entityType: row.entity_type, entityId: row.entity_id },
276
+ piiClass: row.pii_class,
277
+ ...(row.subject_id ? { subjectId: row.subject_id } : {}),
278
+ payload: row.payload === null ? undefined : JSON.parse(row.payload),
279
+ });
280
+ }
281
+ // -- operation context (port of operationContext) -------------------------
282
+ operationContext(principal, tenantId, scopeId, systemActor) {
283
+ const checker = this.checker;
284
+ const relations = this.relations;
285
+ const sql = this.sql;
286
+ return {
287
+ tenantId,
288
+ scopeId,
289
+ principal,
290
+ sql: doScopedSql(sql),
291
+ emit: (event) => {
292
+ const parsed = domainEventInput.parse(event);
293
+ const full = domainEvent.parse({
294
+ ...parsed,
295
+ id: eventId.parse(ulid()),
296
+ occurredAt: instant.parse(new Date().toISOString()),
297
+ tenantId,
298
+ scopeId,
299
+ actor: systemActor ?? principal,
300
+ });
301
+ sql.exec(`INSERT INTO _substrat_outbox
302
+ (id, type, schema_version, occurred_at, tenant_id, scope_id, actor,
303
+ entity_type, entity_id, pii_class, subject_id, payload)
304
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, full.id, full.type, full.schemaVersion, full.occurredAt, full.tenantId, full.scopeId, JSON.stringify(full.actor), full.entity.entityType, full.entity.entityId, full.piiClass, full.subjectId ?? null, full.payload === undefined ? null : JSON.stringify(full.payload));
305
+ },
306
+ check: (permission, entity) => systemActor
307
+ ? Promise.resolve({
308
+ allowed: true,
309
+ proof: [
310
+ {
311
+ subject: objectRef.parse(`system:${systemActor.system.replace(/[^a-zA-Z0-9_.-]/g, '-')}`),
312
+ relation: `granted:${permission}`,
313
+ object: objectRef.parse(`scope:${scopeId}`),
314
+ },
315
+ ],
316
+ })
317
+ : checker.check(principal, permission, { tenantId, scopeId }, entity),
318
+ link: (child, parent) => {
319
+ const allowed = relations.get(child.entityType);
320
+ if (!allowed?.has(parent.entityType)) {
321
+ throw new Error(`undeclared entity relation: ${child.entityType} → ${parent.entityType} ` +
322
+ `(declare it in a module manifest's entityRelations)`);
323
+ }
324
+ sql.exec(`INSERT OR IGNORE INTO _substrat_tuples (subject, relation, object)
325
+ VALUES (?, 'parent', ?)`, `${child.entityType}:${child.entityId}`, `${parent.entityType}:${parent.entityId}`);
326
+ },
327
+ };
328
+ }
329
+ controlPlaneReader() {
330
+ const ns = this.env.CONTROL_PLANE;
331
+ const stub = ns.get(ns.idFromName('control-plane'));
332
+ return {
333
+ tenantTuples: (tenantId, subject, relationPrefix) => stub.tenantTuples(tenantId, subject, relationPrefix),
334
+ getRole: (tenantId, key) => stub.getRole(tenantId, key),
335
+ };
336
+ }
337
+ };
338
+ }
339
+ //# sourceMappingURL=scope-do.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-do.js","sourceRoot":"","sources":["../src/scope-do.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Per-scope serialization (K-6). One operation runs to completion before the
3
+ * next starts — the conservative semantics both adapters must honor. A Durable
4
+ * Object's input gate "over-delivers" (it allows subtler interleavings around
5
+ * non-storage awaits), so — exactly as the pure adapter does — the CF adapter
6
+ * enforces strict serialization explicitly with a per-scope task queue rather
7
+ * than trusting the gate. Kernel and module code may never depend on any
8
+ * interleaving subtler than strict.
9
+ *
10
+ * Identical in spirit to `adapter-sqlite/src/actor.ts`; kept here so the DO owns
11
+ * its own queue with no cross-package coupling.
12
+ */
13
+ export declare class OperationQueue {
14
+ private tail;
15
+ enqueue<T>(op: () => Promise<T> | T): Promise<T>;
16
+ }
17
+ //# sourceMappingURL=serialization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAuC;IAEnD,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAMjD"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Per-scope serialization (K-6). One operation runs to completion before the
3
+ * next starts — the conservative semantics both adapters must honor. A Durable
4
+ * Object's input gate "over-delivers" (it allows subtler interleavings around
5
+ * non-storage awaits), so — exactly as the pure adapter does — the CF adapter
6
+ * enforces strict serialization explicitly with a per-scope task queue rather
7
+ * than trusting the gate. Kernel and module code may never depend on any
8
+ * interleaving subtler than strict.
9
+ *
10
+ * Identical in spirit to `adapter-sqlite/src/actor.ts`; kept here so the DO owns
11
+ * its own queue with no cross-package coupling.
12
+ */
13
+ export class OperationQueue {
14
+ tail = Promise.resolve();
15
+ enqueue(op) {
16
+ const result = this.tail.then(op);
17
+ // The chain must survive failures; callers still see the rejection.
18
+ this.tail = result.catch(() => undefined);
19
+ return result;
20
+ }
21
+ }
22
+ //# sourceMappingURL=serialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.js","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,cAAc;IACjB,IAAI,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEnD,OAAO,CAAI,EAAwB;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClC,oEAAoE;QACpE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
package/dist/sql.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import type { ScopedSql } from '@substrat-run/kernel';
2
+ /**
3
+ * Adapts a Durable Object's `SqlStorage` to the kernel's `ScopedSql` contract
4
+ * (`query`/`exec`). DO SQL is synchronous — `exec` returns a cursor eagerly —
5
+ * so this mirrors the better-sqlite3 wrapper in `adapter-sqlite` one-to-one.
6
+ *
7
+ * Note (from the spikes): the DO runtime FORBIDS manual `BEGIN`/`COMMIT` via SQL.
8
+ * Use `ctx.storage.transaction(async () => …)` — the ASYNC transaction API — which
9
+ * commits on success and rolls back on a throw EVEN ACROSS an `await` (verified in
10
+ * workerd). The ScopeDO therefore wraps each operation exactly like the pure
11
+ * adapter's `BEGIN IMMEDIATE … COMMIT/ROLLBACK`: domain writes and outbox emits
12
+ * commit or roll back together, with read-your-own-writes intact and no buffering.
13
+ * (`transactionSync` also exists but is synchronous-only — it commits at the first
14
+ * await, so it is not used for the async operation body.)
15
+ */
16
+ export declare function doScopedSql(sql: SqlStorage): ScopedSql;
17
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,sBAAsB,CAAC;AAEhE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,CAStD"}
package/dist/sql.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Adapts a Durable Object's `SqlStorage` to the kernel's `ScopedSql` contract
3
+ * (`query`/`exec`). DO SQL is synchronous — `exec` returns a cursor eagerly —
4
+ * so this mirrors the better-sqlite3 wrapper in `adapter-sqlite` one-to-one.
5
+ *
6
+ * Note (from the spikes): the DO runtime FORBIDS manual `BEGIN`/`COMMIT` via SQL.
7
+ * Use `ctx.storage.transaction(async () => …)` — the ASYNC transaction API — which
8
+ * commits on success and rolls back on a throw EVEN ACROSS an `await` (verified in
9
+ * workerd). The ScopeDO therefore wraps each operation exactly like the pure
10
+ * adapter's `BEGIN IMMEDIATE … COMMIT/ROLLBACK`: domain writes and outbox emits
11
+ * commit or roll back together, with read-your-own-writes intact and no buffering.
12
+ * (`transactionSync` also exists but is synchronous-only — it commits at the first
13
+ * await, so it is not used for the async operation body.)
14
+ */
15
+ export function doScopedSql(sql) {
16
+ return {
17
+ query: (q, params = []) => sql.exec(q, ...params).toArray(),
18
+ exec: (q, params = []) => {
19
+ const cursor = sql.exec(q, ...params);
20
+ return { changes: cursor.rowsWritten };
21
+ },
22
+ };
23
+ }
24
+ //# sourceMappingURL=sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,GAAe;IACzC,OAAO;QACL,KAAK,EAAE,CAA+B,CAAS,EAAE,SAA8B,EAAE,EAAO,EAAE,CACxF,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAI,MAAqB,CAAC,CAAC,OAAO,EAAS;QACzD,IAAI,EAAE,CAAC,CAAS,EAAE,SAA8B,EAAE,EAAE,EAAE;YACpD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAI,MAAqB,CAAC,CAAC;YACtD,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@substrat-run/adapter-cloudflare",
3
+ "version": "0.2.0",
4
+ "description": "Cloudflare Durable-Object scope host (D-14): DO-per-scope, real kernel semantics on Workers",
5
+ "license": "AGPL-3.0-only",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/substrat-run/substrat.git",
9
+ "directory": "packages/adapter-cloudflare"
10
+ },
11
+ "homepage": "https://github.com/substrat-run/substrat",
12
+ "type": "module",
13
+ "main": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "dependencies": {
25
+ "@substrat-run/kernel": "^0.2.0",
26
+ "@substrat-run/contracts": "^0.2.0"
27
+ },
28
+ "devDependencies": {
29
+ "@cloudflare/vitest-pool-workers": "^0.8.19",
30
+ "@cloudflare/workers-types": "^4.20250109.0",
31
+ "wrangler": "^4.110.0",
32
+ "typescript": "^5.6.0",
33
+ "vitest": "^3.0.0",
34
+ "@substrat-run/contract-tests": "^0.2.0"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "scripts": {
40
+ "build": "tsc -p tsconfig.json",
41
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
42
+ "test": "vitest run"
43
+ }
44
+ }