bonescript-compiler 0.6.2 → 0.8.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,314 @@
1
+ "use strict";
2
+ /**
3
+ * BoneScript Prisma Schema Emitter
4
+ * Generates a Prisma schema file from the IR.
5
+ *
6
+ * Maps BoneScript entities, relations, and constraints to Prisma's
7
+ * schema language. Produces a single `schema.prisma` file that can
8
+ * be used with `npx prisma migrate dev` and `npx prisma generate`.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.PrismaEmitter = void 0;
12
+ function toSnakeCase(s) {
13
+ return s.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase();
14
+ }
15
+ function toPascalCase(s) {
16
+ return s.replace(/(^|[-_\s])(\w)/g, (_, __, c) => c.toUpperCase());
17
+ }
18
+ // ─── Type Mapping ─────────────────────────────────────────────────────────────
19
+ const PRISMA_TYPE_MAP = {
20
+ string: "String",
21
+ uint: "Int",
22
+ int: "Int",
23
+ float: "Float",
24
+ bool: "Boolean",
25
+ timestamp: "DateTime",
26
+ uuid: "String",
27
+ bytes: "Bytes",
28
+ json: "Json",
29
+ };
30
+ function toPrismaType(irType) {
31
+ if (PRISMA_TYPE_MAP[irType])
32
+ return PRISMA_TYPE_MAP[irType];
33
+ const listMatch = irType.match(/^(list|set)<(.+)>$/);
34
+ if (listMatch)
35
+ return `${toPrismaType(listMatch[2])}[]`;
36
+ const optMatch = irType.match(/^optional<(.+)>$/);
37
+ if (optMatch)
38
+ return `${toPrismaType(optMatch[1])}?`;
39
+ // Entity reference — will be handled as a relation
40
+ return "String";
41
+ }
42
+ function toPrismaNativeType(irType) {
43
+ switch (irType) {
44
+ case "uuid": return "@db.Uuid";
45
+ case "string": return null; // default is fine
46
+ case "json": return null; // Json maps directly
47
+ case "bytes": return null;
48
+ case "timestamp": return "@db.Timestamptz";
49
+ case "float": return "@db.DoublePrecision";
50
+ case "uint": return "@db.BigInt";
51
+ case "int": return "@db.BigInt";
52
+ default: return null;
53
+ }
54
+ }
55
+ // ─── Prisma Emitter ───────────────────────────────────────────────────────────
56
+ class PrismaEmitter {
57
+ emit(system) {
58
+ const files = [];
59
+ files.push({
60
+ path: "prisma/schema.prisma",
61
+ content: this.emitSchema(system),
62
+ language: "typescript", // closest match for syntax highlighting
63
+ source_module: "prisma",
64
+ });
65
+ return files;
66
+ }
67
+ emitSchema(system) {
68
+ const lines = [];
69
+ // Header
70
+ lines.push(`// Generated by BoneScript compiler. DO NOT EDIT.`);
71
+ lines.push(`// Source: ${system.name} (${system.source_hash})`);
72
+ lines.push(`// Run: npx prisma migrate dev --name init`);
73
+ lines.push(`// npx prisma generate`);
74
+ lines.push(``);
75
+ // Datasource
76
+ lines.push(`datasource db {`);
77
+ lines.push(` provider = "postgresql"`);
78
+ lines.push(` url = env("DATABASE_URL")`);
79
+ lines.push(`}`);
80
+ lines.push(``);
81
+ // Generator
82
+ lines.push(`generator client {`);
83
+ lines.push(` provider = "prisma-client-js"`);
84
+ lines.push(`}`);
85
+ lines.push(``);
86
+ // Collect all models across modules, deduplicating by name
87
+ const modelMap = new Map();
88
+ const allRelations = [];
89
+ for (const mod of system.modules) {
90
+ if (mod.kind === "data_store" || mod.kind === "api_service") {
91
+ for (const model of mod.models) {
92
+ if (!modelMap.has(model.name)) {
93
+ modelMap.set(model.name, { model, mod });
94
+ }
95
+ }
96
+ allRelations.push(...mod.relations);
97
+ }
98
+ }
99
+ // Deduplicate relations by a stable key
100
+ const seenRelations = new Set();
101
+ const uniqueRelations = [];
102
+ for (const rel of allRelations) {
103
+ const key = `${rel.from_entity}:${rel.to_entity}:${rel.kind}:${rel.foreign_key}`;
104
+ if (!seenRelations.has(key)) {
105
+ seenRelations.add(key);
106
+ uniqueRelations.push(rel);
107
+ }
108
+ }
109
+ // Build a lookup: entity name → relations where it's the "from" side
110
+ const relationsFrom = new Map();
111
+ const relationsTo = new Map();
112
+ for (const rel of uniqueRelations) {
113
+ if (!relationsFrom.has(rel.from_entity))
114
+ relationsFrom.set(rel.from_entity, []);
115
+ relationsFrom.get(rel.from_entity).push(rel);
116
+ if (!relationsTo.has(rel.to_entity))
117
+ relationsTo.set(rel.to_entity, []);
118
+ relationsTo.get(rel.to_entity).push(rel);
119
+ }
120
+ // Emit each model
121
+ for (const [name, { model, mod }] of modelMap) {
122
+ lines.push(this.emitModel(name, model, mod, relationsFrom.get(name) || [], relationsTo.get(name) || [], modelMap));
123
+ lines.push(``);
124
+ }
125
+ // Emit junction tables for many_to_many
126
+ for (const rel of uniqueRelations) {
127
+ if (rel.kind === "many_to_many" && rel.junction_table) {
128
+ lines.push(this.emitJunctionModel(rel));
129
+ lines.push(``);
130
+ }
131
+ }
132
+ // Emit audit_log and event_outbox models (infrastructure)
133
+ lines.push(this.emitAuditLogModel());
134
+ lines.push(``);
135
+ lines.push(this.emitEventOutboxModel());
136
+ lines.push(``);
137
+ return lines.join("\n");
138
+ }
139
+ emitModel(name, model, mod, relationsFrom, relationsTo, allModels) {
140
+ const lines = [];
141
+ const tableName = toSnakeCase(name) + "s";
142
+ lines.push(`model ${toPascalCase(name)} {`);
143
+ // Fields
144
+ for (const field of model.fields) {
145
+ lines.push(` ${this.emitField(field, model, name)}`);
146
+ }
147
+ // State field (if entity has a state machine)
148
+ const hasSM = mod.state_machines.some(sm => sm.entity === name);
149
+ const hasStateField = model.fields.some(f => f.name === "state");
150
+ if (hasSM && !hasStateField) {
151
+ lines.push(` state String`);
152
+ }
153
+ // Relation fields
154
+ for (const rel of relationsFrom) {
155
+ if (rel.kind === "belongs_to") {
156
+ // The FK field is already in the model fields. Add the relation object.
157
+ const targetModel = toPascalCase(rel.to_entity);
158
+ const fieldName = toSnakeCase(rel.to_entity);
159
+ lines.push(` ${fieldName} ${targetModel} @relation(fields: [${rel.foreign_key}], references: [id], onDelete: Cascade)`);
160
+ }
161
+ else if (rel.kind === "has_many") {
162
+ const targetModel = toPascalCase(rel.to_entity);
163
+ const fieldName = toSnakeCase(rel.to_entity) + "s";
164
+ lines.push(` ${fieldName} ${targetModel}[]`);
165
+ }
166
+ else if (rel.kind === "has_one") {
167
+ const targetModel = toPascalCase(rel.to_entity);
168
+ const fieldName = toSnakeCase(rel.to_entity);
169
+ lines.push(` ${fieldName} ${targetModel}?`);
170
+ }
171
+ }
172
+ // Inverse relations (where this model is the "to" side)
173
+ for (const rel of relationsTo) {
174
+ if (rel.kind === "belongs_to") {
175
+ // This model is the target of a belongs_to — add the inverse has_many
176
+ const sourceModel = toPascalCase(rel.from_entity);
177
+ const fieldName = toSnakeCase(rel.from_entity) + "s";
178
+ // Only add if not already covered by relationsFrom
179
+ const alreadyCovered = relationsFrom.some(r => r.to_entity === rel.from_entity && r.kind === "has_many");
180
+ if (!alreadyCovered) {
181
+ lines.push(` ${fieldName} ${sourceModel}[]`);
182
+ }
183
+ }
184
+ }
185
+ // Table mapping
186
+ lines.push(``);
187
+ lines.push(` @@map("${tableName}")`);
188
+ // Indexes
189
+ for (const idx of model.indexes) {
190
+ if (idx.unique) {
191
+ lines.push(` @@unique([${idx.fields.join(", ")}])`);
192
+ }
193
+ else {
194
+ lines.push(` @@index([${idx.fields.join(", ")}])`);
195
+ }
196
+ }
197
+ lines.push(`}`);
198
+ return lines.join("\n");
199
+ }
200
+ emitField(field, model, entityName) {
201
+ const parts = [];
202
+ // Field name (padded for alignment)
203
+ parts.push(field.name.padEnd(14));
204
+ // Type
205
+ let prismaType = toPrismaType(field.type);
206
+ if (field.nullable)
207
+ prismaType += "?";
208
+ parts.push(prismaType.padEnd(12));
209
+ // Attributes
210
+ const attrs = [];
211
+ // Primary key
212
+ if (field.name === model.primary_key) {
213
+ attrs.push("@id");
214
+ }
215
+ // Default values
216
+ if (field.name === "id" && field.type === "uuid") {
217
+ attrs.push("@default(uuid())");
218
+ }
219
+ else if (field.name === "created_at" || (field.type === "timestamp" && field.name.includes("created"))) {
220
+ attrs.push("@default(now())");
221
+ }
222
+ else if (field.name === "updated_at") {
223
+ attrs.push("@updatedAt");
224
+ }
225
+ else if (field.default_value) {
226
+ const dv = this.mapDefaultValue(field.default_value, field.type);
227
+ if (dv)
228
+ attrs.push(dv);
229
+ }
230
+ // Unique constraint (skip if already primary key — @id implies uniqueness)
231
+ if (field.unique && field.name !== model.primary_key) {
232
+ attrs.push("@unique");
233
+ }
234
+ // Native type annotation
235
+ const nativeType = toPrismaNativeType(field.type);
236
+ if (nativeType) {
237
+ attrs.push(nativeType);
238
+ }
239
+ if (attrs.length > 0) {
240
+ parts.push(attrs.join(" "));
241
+ }
242
+ return parts.join(" ").trimEnd();
243
+ }
244
+ mapDefaultValue(value, type) {
245
+ if (value === "gen_random_uuid()" || value === "uuid()")
246
+ return "@default(uuid())";
247
+ if (value === "now()")
248
+ return "@default(now())";
249
+ if (value === "true" || value === "false")
250
+ return `@default(${value})`;
251
+ if (/^\d+$/.test(value))
252
+ return `@default(${value})`;
253
+ if (/^\d+\.\d+$/.test(value))
254
+ return `@default(${value})`;
255
+ if (value.startsWith('"') && value.endsWith('"'))
256
+ return `@default(${value})`;
257
+ return null;
258
+ }
259
+ emitJunctionModel(rel) {
260
+ const lines = [];
261
+ const fromCol = toSnakeCase(rel.from_entity) + "_id";
262
+ const toCol = toSnakeCase(rel.to_entity) + "_id";
263
+ lines.push(`model ${toPascalCase(rel.junction_table)} {`);
264
+ lines.push(` ${fromCol.padEnd(14)} String @db.Uuid`);
265
+ lines.push(` ${toCol.padEnd(14)} String @db.Uuid`);
266
+ lines.push(` created_at DateTime @default(now()) @db.Timestamptz`);
267
+ lines.push(``);
268
+ lines.push(` ${toSnakeCase(rel.from_entity).padEnd(14)} ${toPascalCase(rel.from_entity)} @relation(fields: [${fromCol}], references: [id], onDelete: Cascade)`);
269
+ lines.push(` ${toSnakeCase(rel.to_entity).padEnd(14)} ${toPascalCase(rel.to_entity)} @relation(fields: [${toCol}], references: [id], onDelete: Cascade)`);
270
+ lines.push(``);
271
+ lines.push(` @@id([${fromCol}, ${toCol}])`);
272
+ lines.push(` @@index([${fromCol}])`);
273
+ lines.push(` @@index([${toCol}])`);
274
+ lines.push(` @@map("${rel.junction_table}")`);
275
+ lines.push(`}`);
276
+ return lines.join("\n");
277
+ }
278
+ emitAuditLogModel() {
279
+ return `model AuditLog {
280
+ id String @id @default(uuid()) @db.Uuid
281
+ actor_id String? @db.Uuid
282
+ action String
283
+ entity_type String
284
+ entity_id String? @db.Uuid
285
+ payload Json?
286
+ ip String?
287
+ user_agent String?
288
+ trace_id String? @db.Uuid
289
+ created_at DateTime @default(now()) @db.Timestamptz
290
+
291
+ @@index([actor_id])
292
+ @@index([entity_type, entity_id])
293
+ @@index([created_at])
294
+ @@map("audit_log")
295
+ }`;
296
+ }
297
+ emitEventOutboxModel() {
298
+ return `model EventOutbox {
299
+ id String @id @default(uuid()) @db.Uuid
300
+ event_type String
301
+ payload Json
302
+ status String @default("pending")
303
+ attempts Int @default(0)
304
+ created_at DateTime @default(now()) @db.Timestamptz
305
+ processed_at DateTime? @db.Timestamptz
306
+ error String?
307
+
308
+ @@index([status, created_at])
309
+ @@map("event_outbox")
310
+ }`;
311
+ }
312
+ }
313
+ exports.PrismaEmitter = PrismaEmitter;
314
+ //# sourceMappingURL=emit_prisma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit_prisma.js","sourceRoot":"","sources":["../src/emit_prisma.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * BoneScript React Hooks Emitter
3
+ *
4
+ * Generates a typed React hooks file (sdk/react.ts) on top of the existing
5
+ * fetch SDK. Hooks are zero-dep — they use React's built-in useState +
6
+ * useEffect rather than pulling in @tanstack/react-query so consumers can
7
+ * decide their own data layer.
8
+ *
9
+ * For each entity:
10
+ * useList<Entity>() → { data, loading, error, refetch }
11
+ * use<Entity>(id) → { data, loading, error, refetch }
12
+ * useCreate<Entity>() → mutate(input) → Promise<Entity>
13
+ * useUpdate<Entity>() → mutate(id, patch) → Promise<Entity>
14
+ * useDelete<Entity>() → mutate(id) → Promise<void>
15
+ *
16
+ * For each capability:
17
+ * useCapability<Name>() → mutate(input) → Promise<unknown>
18
+ *
19
+ * Hooks are framework-agnostic in shape (no react-query, no SWR) so they work
20
+ * with Next.js, Vite, CRA, or any plain React app.
21
+ */
22
+ import * as IR from "./ir";
23
+ import { EmittedFile } from "./emitter";
24
+ export declare function emitReactHooks(system: IR.IRSystem): EmittedFile;
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ /**
3
+ * BoneScript React Hooks Emitter
4
+ *
5
+ * Generates a typed React hooks file (sdk/react.ts) on top of the existing
6
+ * fetch SDK. Hooks are zero-dep — they use React's built-in useState +
7
+ * useEffect rather than pulling in @tanstack/react-query so consumers can
8
+ * decide their own data layer.
9
+ *
10
+ * For each entity:
11
+ * useList<Entity>() → { data, loading, error, refetch }
12
+ * use<Entity>(id) → { data, loading, error, refetch }
13
+ * useCreate<Entity>() → mutate(input) → Promise<Entity>
14
+ * useUpdate<Entity>() → mutate(id, patch) → Promise<Entity>
15
+ * useDelete<Entity>() → mutate(id) → Promise<void>
16
+ *
17
+ * For each capability:
18
+ * useCapability<Name>() → mutate(input) → Promise<unknown>
19
+ *
20
+ * Hooks are framework-agnostic in shape (no react-query, no SWR) so they work
21
+ * with Next.js, Vite, CRA, or any plain React app.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.emitReactHooks = void 0;
25
+ function toSnakeCase(s) {
26
+ return s.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase();
27
+ }
28
+ function toPascalCase(s) {
29
+ return s.replace(/(^|[-_\s])(\w)/g, (_, __, c) => c.toUpperCase());
30
+ }
31
+ const TS_TYPE_MAP = {
32
+ string: "string", uint: "number", int: "number", float: "number",
33
+ bool: "boolean", timestamp: "string", uuid: "string", bytes: "string", json: "unknown",
34
+ };
35
+ function toTsType(irType) {
36
+ if (TS_TYPE_MAP[irType])
37
+ return TS_TYPE_MAP[irType];
38
+ const m = irType.match(/^(list|set)<(.+)>$/);
39
+ if (m)
40
+ return `${toTsType(m[2])}[]`;
41
+ const om = irType.match(/^optional<(.+)>$/);
42
+ if (om)
43
+ return `${toTsType(om[1])} | null`;
44
+ return irType;
45
+ }
46
+ function emitReactHooks(system) {
47
+ const lines = [];
48
+ lines.push(`// Generated by BoneScript compiler. DO NOT EDIT.`);
49
+ lines.push(`// React hooks for the ${system.name} API.`);
50
+ lines.push(`//`);
51
+ lines.push(`// Pair with sdk/client.ts. Pass an instance of <System>Client to <ApiProvider>.`);
52
+ lines.push(``);
53
+ lines.push(`import { useCallback, useEffect, useState, createContext, useContext, ReactNode, createElement } from "react";`);
54
+ lines.push(``);
55
+ // Entity types (forward-declared so the hooks compile without importing the SDK)
56
+ // We re-declare them here to keep this file independent — the consumer can
57
+ // also import these types from sdk/client.ts if they prefer.
58
+ const apiModules = system.modules.filter(m => m.kind === "api_service" && m.models.length > 0);
59
+ for (const mod of apiModules) {
60
+ const model = mod.models[0];
61
+ lines.push(`export interface ${toPascalCase(model.name)} {`);
62
+ for (const field of model.fields) {
63
+ const optional = field.nullable ? "?" : "";
64
+ lines.push(` ${field.name}${optional}: ${toTsType(field.type)};`);
65
+ }
66
+ lines.push(`}`);
67
+ lines.push(``);
68
+ }
69
+ lines.push(`export interface ApiClient {`);
70
+ lines.push(` baseUrl: string;`);
71
+ lines.push(` getToken: () => string | null;`);
72
+ lines.push(`}`);
73
+ lines.push(``);
74
+ lines.push(`async function apiFetch<T>(client: ApiClient, method: string, path: string, body?: unknown): Promise<T> {`);
75
+ lines.push(` const headers: Record<string, string> = { "Content-Type": "application/json" };`);
76
+ lines.push(` const token = client.getToken();`);
77
+ lines.push(` if (token) headers["Authorization"] = "Bearer " + token;`);
78
+ lines.push(` const res = await fetch(client.baseUrl + path, {`);
79
+ lines.push(` method,`);
80
+ lines.push(` headers,`);
81
+ lines.push(` body: body !== undefined ? JSON.stringify(body) : undefined,`);
82
+ lines.push(` });`);
83
+ lines.push(` if (!res.ok) {`);
84
+ lines.push(` let errMsg = "Request failed: " + res.status;`);
85
+ lines.push(` try { const j = await res.json() as { error?: { message?: string } }; if (j.error?.message) errMsg = j.error.message; } catch {}`);
86
+ lines.push(` throw new Error(errMsg);`);
87
+ lines.push(` }`);
88
+ lines.push(` if (res.status === 204) return undefined as unknown as T;`);
89
+ lines.push(` return await res.json() as T;`);
90
+ lines.push(`}`);
91
+ lines.push(``);
92
+ // Provider + context. createElement avoids needing JSX in this generated file.
93
+ lines.push(`const ApiContext = createContext<ApiClient | null>(null);`);
94
+ lines.push(``);
95
+ lines.push(`export interface ApiProviderProps {`);
96
+ lines.push(` client: ApiClient;`);
97
+ lines.push(` children: ReactNode;`);
98
+ lines.push(`}`);
99
+ lines.push(``);
100
+ lines.push(`export function ApiProvider(props: ApiProviderProps) {`);
101
+ lines.push(` return createElement(ApiContext.Provider, { value: props.client }, props.children);`);
102
+ lines.push(`}`);
103
+ lines.push(``);
104
+ lines.push(`function useApi(): ApiClient {`);
105
+ lines.push(` const ctx = useContext(ApiContext);`);
106
+ lines.push(` if (!ctx) throw new Error("useApi must be used inside <ApiProvider>");`);
107
+ lines.push(` return ctx;`);
108
+ lines.push(`}`);
109
+ lines.push(``);
110
+ // Generic shape helpers
111
+ lines.push(`export interface QueryState<T> {`);
112
+ lines.push(` data: T | null;`);
113
+ lines.push(` loading: boolean;`);
114
+ lines.push(` error: Error | null;`);
115
+ lines.push(` refetch: () => Promise<void>;`);
116
+ lines.push(`}`);
117
+ lines.push(``);
118
+ lines.push(`export interface MutationState<TInput, TOutput> {`);
119
+ lines.push(` mutate: (input: TInput) => Promise<TOutput>;`);
120
+ lines.push(` loading: boolean;`);
121
+ lines.push(` error: Error | null;`);
122
+ lines.push(` reset: () => void;`);
123
+ lines.push(`}`);
124
+ lines.push(``);
125
+ lines.push(`export interface PaginatedResponse<T> {`);
126
+ lines.push(` items: T[];`);
127
+ lines.push(` total: number;`);
128
+ lines.push(` page: number;`);
129
+ lines.push(` page_size: number;`);
130
+ lines.push(`}`);
131
+ lines.push(``);
132
+ // Generic primitive hooks. Specific entity / capability hooks below wrap these.
133
+ lines.push(`function useQueryGeneric<T>(method: string, path: string, deps: unknown[]): QueryState<T> {`);
134
+ lines.push(` const client = useApi();`);
135
+ lines.push(` const [data, setData] = useState<T | null>(null);`);
136
+ lines.push(` const [loading, setLoading] = useState(true);`);
137
+ lines.push(` const [error, setError] = useState<Error | null>(null);`);
138
+ lines.push(` const fetchOnce = useCallback(async () => {`);
139
+ lines.push(` setLoading(true); setError(null);`);
140
+ lines.push(` try { const result = await apiFetch<T>(client, method, path); setData(result); }`);
141
+ lines.push(` catch (e: unknown) { setError(e instanceof Error ? e : new Error(String(e))); }`);
142
+ lines.push(` finally { setLoading(false); }`);
143
+ // eslint-disable-next-line react-hooks/exhaustive-deps
144
+ lines.push(` }, [client, method, path]);`);
145
+ lines.push(` useEffect(() => { void fetchOnce(); /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, deps);`);
146
+ lines.push(` return { data, loading, error, refetch: fetchOnce };`);
147
+ lines.push(`}`);
148
+ lines.push(``);
149
+ lines.push(`function useMutationGeneric<TInput, TOutput>(builder: (input: TInput) => { method: string; path: string; body?: unknown }): MutationState<TInput, TOutput> {`);
150
+ lines.push(` const client = useApi();`);
151
+ lines.push(` const [loading, setLoading] = useState(false);`);
152
+ lines.push(` const [error, setError] = useState<Error | null>(null);`);
153
+ lines.push(` const mutate = useCallback(async (input: TInput): Promise<TOutput> => {`);
154
+ lines.push(` setLoading(true); setError(null);`);
155
+ lines.push(` try { const req = builder(input); return await apiFetch<TOutput>(client, req.method, req.path, req.body); }`);
156
+ lines.push(` catch (e: unknown) { const err = e instanceof Error ? e : new Error(String(e)); setError(err); throw err; }`);
157
+ lines.push(` finally { setLoading(false); }`);
158
+ lines.push(` }, [client, builder]);`);
159
+ lines.push(` const reset = useCallback(() => setError(null), []);`);
160
+ lines.push(` return { mutate, loading, error, reset };`);
161
+ lines.push(`}`);
162
+ lines.push(``);
163
+ // Per-entity hooks
164
+ for (const mod of apiModules) {
165
+ const model = mod.models[0];
166
+ const entity = toPascalCase(model.name);
167
+ const tableName = toSnakeCase(model.name) + "s";
168
+ const route = `/${tableName}`;
169
+ lines.push(`// ─── ${entity} ───────────────────────────────────────────────────────────`);
170
+ lines.push(``);
171
+ // List
172
+ lines.push(`export function useList${entity}(): QueryState<PaginatedResponse<${entity}>> {`);
173
+ lines.push(` return useQueryGeneric<PaginatedResponse<${entity}>>("GET", "${route}", []);`);
174
+ lines.push(`}`);
175
+ lines.push(``);
176
+ // Read
177
+ lines.push(`export function use${entity}(id: string | null): QueryState<${entity}> {`);
178
+ lines.push(` return useQueryGeneric<${entity}>("GET", id ? \`${route}/\${id}\` : "${route}", [id]);`);
179
+ lines.push(`}`);
180
+ lines.push(``);
181
+ // Create
182
+ const createInputType = `Partial<${entity}>`;
183
+ lines.push(`export function useCreate${entity}(): MutationState<${createInputType}, ${entity}> {`);
184
+ lines.push(` return useMutationGeneric<${createInputType}, ${entity}>((input) => ({ method: "POST", path: "${route}", body: input }));`);
185
+ lines.push(`}`);
186
+ lines.push(``);
187
+ // Update
188
+ lines.push(`export function useUpdate${entity}(): MutationState<{ id: string; patch: Partial<${entity}> }, ${entity}> {`);
189
+ lines.push(` return useMutationGeneric<{ id: string; patch: Partial<${entity}> }, ${entity}>(({ id, patch }) => ({ method: "PUT", path: \`${route}/\${id}\`, body: patch }));`);
190
+ lines.push(`}`);
191
+ lines.push(``);
192
+ // Delete
193
+ lines.push(`export function useDelete${entity}(): MutationState<string, void> {`);
194
+ lines.push(` return useMutationGeneric<string, void>((id) => ({ method: "DELETE", path: \`${route}/\${id}\` }));`);
195
+ lines.push(`}`);
196
+ lines.push(``);
197
+ // Capability hooks
198
+ for (const iface of mod.interfaces) {
199
+ for (const method of iface.methods) {
200
+ if (["create", "read", "update", "delete", "list"].includes(method.name))
201
+ continue;
202
+ const capName = toPascalCase(method.name);
203
+ const inputType = method.input.length > 0
204
+ ? `{ ${method.input.map(p => `${p.name}${p.nullable ? "?" : ""}: ${toTsType(p.type)}`).join("; ")} }`
205
+ : "Record<string, never>";
206
+ const endpoint = `${route}/${method.name.replace(/_/g, "-")}`;
207
+ lines.push(`export function useCapability${capName}(): MutationState<${inputType}, unknown> {`);
208
+ lines.push(` return useMutationGeneric<${inputType}, unknown>((input) => ({ method: "POST", path: "${endpoint}", body: input }));`);
209
+ lines.push(`}`);
210
+ lines.push(``);
211
+ }
212
+ }
213
+ }
214
+ return {
215
+ path: "sdk/react.ts",
216
+ content: lines.join("\n"),
217
+ language: "typescript",
218
+ source_module: "sdk",
219
+ };
220
+ }
221
+ exports.emitReactHooks = emitReactHooks;
222
+ //# sourceMappingURL=emit_react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit_react.js","sourceRoot":"","sources":["../src/emit_react.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * BoneScript SQLite Target Emitter
3
+ *
4
+ * Generates a SQLite-flavored project: same shape as the Express target but
5
+ * with a SQLite type map, no triggers, and the better-sqlite3 driver in place
6
+ * of pg.
7
+ *
8
+ * SQLite differences from PostgreSQL that this emitter handles:
9
+ * - No JSONB / no native UUID — TEXT for both
10
+ * - No CREATE OR REPLACE FUNCTION / no triggers needed (we do updated_at in app code)
11
+ * - Parameter style is ? not $1, $2 — but better-sqlite3 also supports named (:name)
12
+ * - No SKIP LOCKED, no transactional outbox locking semantics — outbox uses simpler ordering
13
+ * - No CHECK constraints with subqueries — basic CHECK only
14
+ *
15
+ * Strategy: keep the SQL flat and portable. Use better-sqlite3's prepared
16
+ * statements. Keep the public interface identical to the Postgres target so
17
+ * route handlers and capability bodies don't need to change.
18
+ */
19
+ import * as IR from "./ir";
20
+ import { EmittedFile } from "./emitter";
21
+ export declare function toSqliteType(irType: string): string;
22
+ export declare function emitSqliteSchema(model: IR.IRModel, mod: IR.IRModule, system: IR.IRSystem): EmittedFile;
23
+ export declare function emitSqliteOutboxSchema(): string;
24
+ export declare function emitSqliteAuditSchema(): string;
25
+ export declare function emitSqliteDbClient(system: IR.IRSystem): string;
26
+ export declare function emitSqliteMigration(_system: IR.IRSystem, schemas: string[]): string;
27
+ export declare function emitSqlitePackageJson(system: IR.IRSystem): string;
28
+ export declare class SqliteEmitter {
29
+ emit(system: IR.IRSystem): EmittedFile[];
30
+ private emitTsConfig;
31
+ private emitEnvExample;
32
+ private emitReadme;
33
+ }