bonescript-compiler 0.8.0 → 0.11.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/src/lowering.ts CHANGED
@@ -17,6 +17,27 @@ function toSnakeCase(s: string): string {
17
17
  return s.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase();
18
18
  }
19
19
 
20
+ /**
21
+ * Extract the entity name from a `participants:` type expression.
22
+ *
23
+ * - `Player` → "Player"
24
+ * - `set<Player>` → "Player"
25
+ * - `list<Player>` → "Player"
26
+ * - `optional<Player>` → "Player"
27
+ * - anything else → null
28
+ */
29
+ function extractParticipantEntity(t: AST.TypeExprNode | null): string | null {
30
+ if (!t) return null;
31
+ if (t.kind === "EntityRefType") return t.name;
32
+ if (t.kind === "GenericType") {
33
+ for (const arg of t.typeArgs) {
34
+ const inner = extractParticipantEntity(arg);
35
+ if (inner) return inner;
36
+ }
37
+ }
38
+ return null;
39
+ }
40
+
20
41
  // ─── Deterministic ID Generation ─────────────────────────────────────────────
21
42
 
22
43
  function makeId(systemName: string, kind: string, name: string): string {
@@ -122,11 +143,30 @@ export class Lowering {
122
143
  }
123
144
 
124
145
  // Lower channels → realtime_service modules
146
+ // Lower channels — realtime_service modules.
147
+ //
148
+ // Capabilities tagged `sync: realtime` are routed into the channel that
149
+ // matches their participant entity, so each room can expose them as typed
150
+ // onMessage handlers. The matching rule: if any of the capability's
151
+ // parameters is the participant entity type (e.g. channel has
152
+ // `participants: set<Player>` and capability has `move(player: Player, ...)`),
153
+ // it gets dispatched on that room.
154
+ const realtimeCaps = capabilities.filter(c => c.sync === "realtime");
125
155
  for (const channel of channels) {
126
- modules.push(this.lowerChannel(channel));
156
+ const channelCaps = realtimeCaps.filter(c => {
157
+ const partEntityName = extractParticipantEntity(channel.participants);
158
+ if (!partEntityName) return false;
159
+ return c.params.some(p => {
160
+ if (p.type.kind === "EntityRefType") return p.type.name === partEntityName;
161
+ // Also match generic types like `set<Player>` if they happen to appear as a param
162
+ if (p.type.kind === "GenericType") {
163
+ return p.type.typeArgs.some(a => a.kind === "EntityRefType" && a.name === partEntityName);
164
+ }
165
+ return false;
166
+ });
167
+ });
168
+ modules.push(this.lowerChannel(channel, channelCaps, entities));
127
169
  }
128
-
129
- // Lower events
130
170
  for (const ev of eventDecls) {
131
171
  events.push(this.lowerEvent(ev));
132
172
  }
@@ -246,6 +286,32 @@ export class Lowering {
246
286
  fields.push(this.lowerField(f));
247
287
  }
248
288
 
289
+ // Auto-add foreign key columns for `belongs_to` relations.
290
+ //
291
+ // Without this, generated migrations reference a column that doesn't exist
292
+ // (e.g. `FOREIGN KEY (seller_id) REFERENCES sellers(id)` when no seller_id
293
+ // is declared in `owns:`). Users were having to duplicate the FK in
294
+ // `owns:` to make it work; we now synthesize it.
295
+ //
296
+ // If the user already declared a column with the same name (the legacy
297
+ // pattern), we don't add a duplicate — their declaration wins so they
298
+ // can override nullability or add @sensitive.
299
+ const existingFieldNames = new Set(fields.map(f => f.name));
300
+ for (const rel of entity.relations) {
301
+ if (rel.relationType !== "belongs_to") continue;
302
+ const fkName = toSnakeCase(rel.target) + "_id";
303
+ if (existingFieldNames.has(fkName)) continue;
304
+ fields.push({
305
+ name: fkName,
306
+ type: "uuid",
307
+ nullable: false,
308
+ unique: false,
309
+ indexed: true,
310
+ default_value: null,
311
+ });
312
+ existingFieldNames.add(fkName);
313
+ }
314
+
249
315
  // Add derived fields as generated columns (stored: false = virtual)
250
316
  const derivedFields: IR.IRField[] = entity.derived.map(d => ({
251
317
  name: d.name,
@@ -490,18 +556,48 @@ export class Lowering {
490
556
 
491
557
  // ─── Channel Lowering ──────────────────────────────────────────────────────
492
558
 
493
- private lowerChannel(channel: AST.ChannelDeclNode): IR.IRModule {
559
+ private lowerChannel(
560
+ channel: AST.ChannelDeclNode,
561
+ realtimeCapabilities: AST.CapabilityDeclNode[] = [],
562
+ entities: AST.EntityDeclNode[] = [],
563
+ ): IR.IRModule {
564
+ // Default lifecycle methods that every Colyseus/WebSocket channel exposes.
565
+ const baseMethods: IR.IRMethod[] = [
566
+ { name: "connect", input: [], output: "connection", preconditions: [], effects: [], emissions: [], idempotent: false, authenticated: true, timeout_ms: 5000, retry: null, pipeline: null, algorithm: null, sync: null },
567
+ { name: "subscribe", input: [{ name: "topic", type: "string", nullable: false, unique: false, indexed: false, default_value: null }], output: "subscription", preconditions: [], effects: [], emissions: [], idempotent: true, authenticated: true, timeout_ms: 5000, retry: null, pipeline: null, algorithm: null, sync: null },
568
+ { name: "publish", input: [{ name: "message", type: "json", nullable: false, unique: false, indexed: false, default_value: null }], output: "void", preconditions: [], effects: [], emissions: [], idempotent: false, authenticated: true, timeout_ms: 5000, retry: null, pipeline: null, algorithm: null, sync: null },
569
+ ];
570
+
571
+ // Realtime capabilities lower as additional interface methods. The
572
+ // Colyseus emitter will turn these into typed onMessage handlers.
573
+ const capMethods = realtimeCapabilities.map(c => this.lowerCapability(c));
574
+
575
+ const participantEntity = extractParticipantEntity(channel.participants);
576
+
577
+ // If we have an entity reference, copy its field definitions into the
578
+ // channel's config so the Colyseus emitter can build a Player schema
579
+ // without re-resolving the AST. We only forward primitive-typed `owns:`
580
+ // fields — entity refs and complex types are skipped because Colyseus
581
+ // schemas need scalar @type decorators.
582
+ const participantFields: { name: string; type: string }[] = [];
583
+ if (participantEntity) {
584
+ const entity = entities.find(e => e.name === participantEntity);
585
+ if (entity) {
586
+ for (const f of entity.owns) {
587
+ if (f.type.kind === "PrimitiveType") {
588
+ participantFields.push({ name: f.name, type: f.type.name });
589
+ }
590
+ }
591
+ }
592
+ }
593
+
494
594
  return {
495
595
  id: makeId(this.systemName, "realtime_service", channel.name),
496
596
  kind: "realtime_service",
497
597
  name: channel.name,
498
598
  interfaces: [{
499
599
  name: `I${channel.name}Channel`,
500
- methods: [
501
- { name: "connect", input: [], output: "connection", preconditions: [], effects: [], emissions: [], idempotent: false, authenticated: true, timeout_ms: 5000, retry: null, pipeline: null, algorithm: null, sync: null },
502
- { name: "subscribe", input: [{ name: "topic", type: "string", nullable: false, unique: false, indexed: false, default_value: null }], output: "subscription", preconditions: [], effects: [], emissions: [], idempotent: true, authenticated: true, timeout_ms: 5000, retry: null, pipeline: null, algorithm: null, sync: null },
503
- { name: "publish", input: [{ name: "message", type: "json", nullable: false, unique: false, indexed: false, default_value: null }], output: "void", preconditions: [], effects: [], emissions: [], idempotent: false, authenticated: true, timeout_ms: 5000, retry: null, pipeline: null, algorithm: null, sync: null },
504
- ],
600
+ methods: [...baseMethods, ...capMethods],
505
601
  }],
506
602
  models: [],
507
603
  events: [],
@@ -513,6 +609,8 @@ export class Lowering {
513
609
  ordering: channel.ordering || "fifo",
514
610
  persistence: channel.persistence || "none",
515
611
  max_size: channel.maxSize || 10000,
612
+ ...(participantEntity ? { participant_entity: participantEntity } : {}),
613
+ ...(participantFields.length > 0 ? { participant_fields: JSON.stringify(participantFields) } : {}),
516
614
  },
517
615
  };
518
616
  }
@@ -1,11 +0,0 @@
1
- /**
2
- * Notification service tests.
3
- *
4
- * Generates the notify.ts file from a sample IR and verifies:
5
- * - webhook is in the provider union
6
- * - HMAC signing helper is emitted
7
- * - URL validation rejects non-http(s) protocols
8
- * - sendWebhook signs requests when NOTIFY_WEBHOOK_SECRET is set
9
- * - sendWebhook posts to NOTIFY_WEBHOOK_URL with the right shape
10
- */
11
- export {};
@@ -1,220 +0,0 @@
1
- "use strict";
2
- /**
3
- * Notification service tests.
4
- *
5
- * Generates the notify.ts file from a sample IR and verifies:
6
- * - webhook is in the provider union
7
- * - HMAC signing helper is emitted
8
- * - URL validation rejects non-http(s) protocols
9
- * - sendWebhook signs requests when NOTIFY_WEBHOOK_SECRET is set
10
- * - sendWebhook posts to NOTIFY_WEBHOOK_URL with the right shape
11
- */
12
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- var desc = Object.getOwnPropertyDescriptor(m, k);
15
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
- desc = { enumerable: true, get: function() { return m[k]; } };
17
- }
18
- Object.defineProperty(o, k2, desc);
19
- }) : (function(o, m, k, k2) {
20
- if (k2 === undefined) k2 = k;
21
- o[k2] = m[k];
22
- }));
23
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
- Object.defineProperty(o, "default", { enumerable: true, value: v });
25
- }) : function(o, v) {
26
- o["default"] = v;
27
- });
28
- var __importStar = (this && this.__importStar) || function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- const emit_notify_1 = require("./emit_notify");
37
- const http = __importStar(require("http"));
38
- const fs = __importStar(require("fs"));
39
- const path = __importStar(require("path"));
40
- const os = __importStar(require("os"));
41
- const crypto_1 = require("crypto");
42
- let passed = 0;
43
- let failed = 0;
44
- function ok(name) { console.log(" v " + name); passed++; }
45
- function fail(name, err) {
46
- const msg = err instanceof Error ? err.message : String(err);
47
- console.log(" x " + name + ": " + msg);
48
- failed++;
49
- }
50
- function buildSystem() {
51
- return {
52
- name: "Test", version: "1.0.0", source_hash: "deadbeef", domain: "saas_platform",
53
- modules: [], events: [
54
- {
55
- id: "evt.OrderPlaced", name: "OrderPlaced",
56
- payload: [{ name: "order_id", type: "uuid", nullable: false, unique: false, indexed: false, default_value: null }],
57
- source: "test", delivery: "at_least_once", ordering: "fifo", ttl_ms: null,
58
- },
59
- ],
60
- flows: [], invariants: [], resolution: {}, extension_points: [],
61
- };
62
- }
63
- async function run() {
64
- console.log("BoneScript Notification Tests\n");
65
- const system = buildSystem();
66
- const code = (0, emit_notify_1.emitNotifyService)(system);
67
- // ─── Static checks on emitted code ──────────────────────────────────────────
68
- if (code.includes('"resend" | "sendgrid" | "webhook" | "log"'))
69
- ok("webhook is in provider union");
70
- else
71
- fail("webhook in provider union", "not found");
72
- if (code.includes("NOTIFY_WEBHOOK_URL"))
73
- ok("webhook URL env var referenced");
74
- else
75
- fail("webhook URL", "NOTIFY_WEBHOOK_URL missing");
76
- if (code.includes("NOTIFY_WEBHOOK_SECRET") && code.includes("createHmac"))
77
- ok("HMAC signing emitted");
78
- else
79
- fail("HMAC signing", "missing createHmac or NOTIFY_WEBHOOK_SECRET");
80
- if (code.includes("X-BoneScript-Signature"))
81
- ok("signature header emitted");
82
- else
83
- fail("signature header", "missing X-BoneScript-Signature");
84
- if (code.includes("X-BoneScript-Event"))
85
- ok("event header emitted");
86
- else
87
- fail("event header", "missing X-BoneScript-Event");
88
- if (code.includes('protocol !== "https:"') && code.includes('protocol !== "http:"'))
89
- ok("URL protocol validation");
90
- else
91
- fail("URL validation", "protocol check missing");
92
- if (code.includes("export async function sendWebhook("))
93
- ok("sendWebhook is exported");
94
- else
95
- fail("sendWebhook export", "function not exported");
96
- // ─── HMAC determinism / uniqueness ─────────────────────────────────────────
97
- const body = JSON.stringify({ ok: true });
98
- const sig = (0, crypto_1.createHmac)("sha256", "test-secret").update(body).digest("hex");
99
- if (sig.length === 64 && /^[a-f0-9]+$/i.test(sig))
100
- ok("HMAC signing produces a 64-char hex digest");
101
- else
102
- fail("HMAC digest shape", "got: " + sig);
103
- const sig2 = (0, crypto_1.createHmac)("sha256", "different").update(body).digest("hex");
104
- if (sig !== sig2)
105
- ok("Different secrets produce different signatures");
106
- else
107
- fail("Signature uniqueness", "collision");
108
- const sig3 = (0, crypto_1.createHmac)("sha256", "test-secret").update(body).digest("hex");
109
- if (sig === sig3)
110
- ok("HMAC signing is deterministic");
111
- else
112
- fail("HMAC determinism", "non-deterministic");
113
- // ─── Mock-server integration test ──────────────────────────────────────────
114
- let receivedBody = null;
115
- let receivedHeaders = {};
116
- const server = http.createServer((req, res) => {
117
- let chunks = "";
118
- req.on("data", (c) => { chunks += c.toString(); });
119
- req.on("end", () => {
120
- receivedBody = chunks;
121
- receivedHeaders = req.headers;
122
- res.writeHead(200, { "Content-Type": "application/json" });
123
- res.end('{"ok":true}');
124
- });
125
- });
126
- // Bind to 127.0.0.1 explicitly so the URL matches the listening socket.
127
- const port = await new Promise((resolve) => {
128
- server.listen(0, "127.0.0.1", () => resolve(server.address().port));
129
- });
130
- // Self-contained harness that mirrors the emitted sendWebhook logic.
131
- const harness = `
132
- const { createHmac } = require("crypto");
133
- function buildSendWebhook() {
134
- const WEBHOOK_URL = process.env.NOTIFY_WEBHOOK_URL || "";
135
- const WEBHOOK_SECRET = process.env.NOTIFY_WEBHOOK_SECRET || "";
136
- const PROVIDER = process.env.NOTIFY_PROVIDER || "log";
137
-
138
- function signPayload(body) {
139
- if (!WEBHOOK_SECRET) return "";
140
- return createHmac("sha256", WEBHOOK_SECRET).update(body).digest("hex");
141
- }
142
-
143
- return async function sendWebhook(payload, eventType) {
144
- if (PROVIDER === "log") { return; }
145
- if (!WEBHOOK_URL) throw new Error("NOTIFY_WEBHOOK_URL is not configured");
146
- let url;
147
- try { url = new URL(WEBHOOK_URL); } catch { throw new Error("Invalid NOTIFY_WEBHOOK_URL"); }
148
- if (url.protocol !== "https:" && url.protocol !== "http:") throw new Error("bad protocol");
149
- const body = JSON.stringify(payload);
150
- const headers = { "Content-Type": "application/json" };
151
- const sig = signPayload(body);
152
- if (sig) headers["X-BoneScript-Signature"] = sig;
153
- if (eventType) headers["X-BoneScript-Event"] = eventType;
154
- const res = await fetch(WEBHOOK_URL, { method: "POST", headers, body });
155
- if (!res.ok) throw new Error("Webhook delivery failed: " + res.status);
156
- };
157
- }
158
- module.exports = { buildSendWebhook };
159
- `;
160
- const tmp = path.join(os.tmpdir(), "bonescript-notify-harness-" + process.pid + ".js");
161
- fs.writeFileSync(tmp, harness, "utf-8");
162
- delete require.cache[tmp];
163
- const { buildSendWebhook } = require(tmp);
164
- try {
165
- process.env.NOTIFY_PROVIDER = "webhook";
166
- process.env.NOTIFY_WEBHOOK_URL = "http://127.0.0.1:" + port + "/hook";
167
- process.env.NOTIFY_WEBHOOK_SECRET = "shhh";
168
- const sendWebhook = buildSendWebhook();
169
- await sendWebhook({ kind: "event", id: "abc" }, "OrderPlaced");
170
- if (!receivedBody)
171
- throw new Error("server did not receive body");
172
- const parsed = JSON.parse(receivedBody);
173
- if (parsed.kind !== "event" || parsed.id !== "abc")
174
- throw new Error("body shape wrong: " + receivedBody);
175
- ok("sendWebhook posts the JSON payload");
176
- if (receivedHeaders["x-bonescript-event"] !== "OrderPlaced")
177
- throw new Error("event header missing or wrong");
178
- ok("sendWebhook sets X-BoneScript-Event header");
179
- const sigHeader = receivedHeaders["x-bonescript-signature"];
180
- const expected = (0, crypto_1.createHmac)("sha256", "shhh").update(receivedBody).digest("hex");
181
- if (sigHeader !== expected)
182
- throw new Error("signature mismatch: got " + sigHeader + " expected " + expected);
183
- ok("sendWebhook signs body with HMAC-SHA256");
184
- // ── Reject non-http(s) protocols ─────────────────────────────────────────
185
- process.env.NOTIFY_WEBHOOK_URL = "ftp://nope/x";
186
- const sw2 = buildSendWebhook();
187
- let threw = false;
188
- try {
189
- await sw2({});
190
- }
191
- catch (err) {
192
- if (err.message === "bad protocol")
193
- threw = true;
194
- }
195
- if (threw)
196
- ok("rejects ftp:// URL");
197
- else
198
- fail("URL protocol rejection", "did not throw");
199
- }
200
- catch (e) {
201
- fail("Webhook integration", e);
202
- }
203
- finally {
204
- server.close();
205
- try {
206
- fs.unlinkSync(tmp);
207
- }
208
- catch { }
209
- }
210
- summary();
211
- }
212
- function summary() {
213
- console.log("\n" + "═".repeat(40));
214
- console.log("Results: " + passed + " passed, " + failed + " failed");
215
- console.log("═".repeat(40));
216
- if (failed > 0)
217
- process.exit(1);
218
- }
219
- run().catch(e => { console.error(e); process.exit(1); });
220
- //# sourceMappingURL=test_notify.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test_notify.js","sourceRoot":"","sources":["../src/test_notify.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- /**
2
- * React hooks emitter tests.
3
- *
4
- * Verifies:
5
- * - hooks file is emitted with the right shape
6
- * - per-entity hooks are present (useList, use<E>, useCreate, useUpdate, useDelete)
7
- * - capability hooks are present (useCapability<Name>)
8
- * - emitted code passes tsc type-checking against installed react types
9
- */
10
- export {};
@@ -1,177 +0,0 @@
1
- "use strict";
2
- /**
3
- * React hooks emitter tests.
4
- *
5
- * Verifies:
6
- * - hooks file is emitted with the right shape
7
- * - per-entity hooks are present (useList, use<E>, useCreate, useUpdate, useDelete)
8
- * - capability hooks are present (useCapability<Name>)
9
- * - emitted code passes tsc type-checking against installed react types
10
- */
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- Object.defineProperty(exports, "__esModule", { value: true });
35
- const fs = __importStar(require("fs"));
36
- const path = __importStar(require("path"));
37
- const os = __importStar(require("os"));
38
- const child_process_1 = require("child_process");
39
- const emit_react_1 = require("./emit_react");
40
- let passed = 0;
41
- let failed = 0;
42
- function ok(name) { console.log(" v " + name); passed++; }
43
- function fail(name, err) {
44
- const msg = err instanceof Error ? err.message : String(err);
45
- console.log(" x " + name + ": " + msg);
46
- failed++;
47
- }
48
- function buildSystem() {
49
- const productModel = {
50
- name: "Product",
51
- fields: [
52
- { name: "id", type: "uuid", nullable: false, unique: true, indexed: true, default_value: null },
53
- { name: "name", type: "string", nullable: false, unique: false, indexed: false, default_value: null },
54
- { name: "price", type: "uint", nullable: false, unique: false, indexed: false, default_value: null },
55
- { name: "stock", type: "uint", nullable: false, unique: false, indexed: false, default_value: null },
56
- ],
57
- primary_key: "id", indexes: [], constraints: [],
58
- };
59
- const purchaseMethod = {
60
- name: "purchase",
61
- input: [
62
- { name: "buyer_id", type: "uuid", nullable: false, unique: false, indexed: false, default_value: null },
63
- { name: "qty", type: "uint", nullable: false, unique: false, indexed: false, default_value: null },
64
- ],
65
- output: "json",
66
- preconditions: [], effects: [], emissions: [],
67
- idempotent: false, authenticated: true, timeout_ms: 5000,
68
- retry: null, pipeline: null, algorithm: null, sync: "transactional",
69
- };
70
- return {
71
- name: "Shop", version: "1.0.0", source_hash: "abc123", domain: "marketplace",
72
- modules: [
73
- {
74
- id: "Shop.api_service.ProductService",
75
- kind: "api_service",
76
- name: "ProductService",
77
- interfaces: [{ name: "ProductService", methods: [purchaseMethod] }],
78
- models: [productModel],
79
- events: [], state_machines: [], relations: [], dependencies: [],
80
- config: {},
81
- },
82
- ],
83
- events: [], flows: [], invariants: [], resolution: {}, extension_points: [],
84
- };
85
- }
86
- function run() {
87
- console.log("BoneScript React Hooks Tests\n");
88
- const system = buildSystem();
89
- const file = (0, emit_react_1.emitReactHooks)(system);
90
- if (file.path === "sdk/react.ts")
91
- ok("Emitted at sdk/react.ts");
92
- else
93
- fail("Emit path", "got: " + file.path);
94
- const code = file.content;
95
- // ─── Surface checks ─────────────────────────────────────────────────────────
96
- for (const [feature, marker] of [
97
- ["ApiProvider", "export function ApiProvider"],
98
- ["ApiClient interface", "export interface ApiClient"],
99
- ["useApi hook", "function useApi"],
100
- ["QueryState", "export interface QueryState<T>"],
101
- ["MutationState", "export interface MutationState<TInput, TOutput>"],
102
- ["PaginatedResponse", "export interface PaginatedResponse<T>"],
103
- ["Product type", "export interface Product {"],
104
- ["useListProduct", "export function useListProduct()"],
105
- ["useProduct", "export function useProduct(id: string | null)"],
106
- ["useCreateProduct", "export function useCreateProduct()"],
107
- ["useUpdateProduct", "export function useUpdateProduct()"],
108
- ["useDeleteProduct", "export function useDeleteProduct()"],
109
- ["useCapabilityPurchase", "export function useCapabilityPurchase()"],
110
- ["fetch wrapper", "async function apiFetch"],
111
- ["Bearer token header", '"Bearer " + token'],
112
- ]) {
113
- if (code.includes(marker))
114
- ok(feature + " is emitted");
115
- else
116
- fail(feature, "marker not found: " + marker);
117
- }
118
- // ─── Type-check the emitted code with tsc ──────────────────────────────────
119
- const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "bonescript-react-test-"));
120
- try {
121
- fs.mkdirSync(path.join(tmp, "sdk"));
122
- fs.writeFileSync(path.join(tmp, "sdk", "react.ts"), code, "utf-8");
123
- fs.writeFileSync(path.join(tmp, "package.json"), JSON.stringify({
124
- name: "react-hooks-test",
125
- version: "1.0.0",
126
- private: true,
127
- dependencies: {
128
- react: "18.3.1",
129
- typescript: "5.6.3",
130
- "@types/react": "18.3.12",
131
- },
132
- }, null, 2), "utf-8");
133
- fs.writeFileSync(path.join(tmp, "tsconfig.json"), JSON.stringify({
134
- compilerOptions: {
135
- target: "ES2020",
136
- module: "commonjs",
137
- lib: ["ES2020", "DOM"],
138
- jsx: "react",
139
- strict: true,
140
- esModuleInterop: true,
141
- skipLibCheck: true,
142
- noEmit: true,
143
- },
144
- include: ["sdk/**/*.ts"],
145
- }, null, 2), "utf-8");
146
- console.log("\n (installing react + types — first run only)");
147
- (0, child_process_1.execSync)("npm install --silent --no-audit --no-fund", { cwd: tmp, stdio: "pipe" });
148
- ok("React + TypeScript installed");
149
- try {
150
- (0, child_process_1.execSync)("npx tsc --noEmit", { cwd: tmp, stdio: "pipe", encoding: "utf-8" });
151
- ok("Generated react.ts type-checks cleanly");
152
- }
153
- catch (e) {
154
- const out = (e.stdout || "") + (e.stderr || "");
155
- throw new Error("tsc errors:\n" + out.split("\n").slice(0, 30).join("\n"));
156
- }
157
- }
158
- catch (e) {
159
- fail("Type-check generated react.ts", e);
160
- }
161
- finally {
162
- try {
163
- fs.rmSync(tmp, { recursive: true, force: true });
164
- }
165
- catch { }
166
- }
167
- summary();
168
- }
169
- function summary() {
170
- console.log("\n" + "═".repeat(40));
171
- console.log("Results: " + passed + " passed, " + failed + " failed");
172
- console.log("═".repeat(40));
173
- if (failed > 0)
174
- process.exit(1);
175
- }
176
- run();
177
- //# sourceMappingURL=test_react.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test_react.js","sourceRoot":"","sources":["../src/test_react.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- /**
2
- * SQLite target end-to-end test.
3
- *
4
- * Compiles a small .bone program to the SQLite target, installs better-sqlite3,
5
- * runs the generated migrations, then performs CRUD against the generated
6
- * db.ts API surface to confirm:
7
- * - schema applies cleanly
8
- * - generated query() handles SELECT / INSERT / UPDATE / DELETE
9
- * - $1, $2 placeholder translation works
10
- * - RETURNING * emulation returns the inserted/updated row
11
- * - ledger prevents re-running the same migration
12
- */
13
- export {};