bonescript-compiler 0.5.4 → 0.5.6

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 @@
1
+ {"version":3,"file":"emit_sdk.js","sourceRoot":"","sources":["../src/emit_sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * BoneScript Seed File Emitter
3
+ * Generates a TypeScript seed script from an IRSystem.
4
+ */
5
+ import * as IR from "./ir";
6
+ export declare function emitSeedFile(system: IR.IRSystem): string;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * BoneScript Seed File Emitter
4
+ * Generates a TypeScript seed script from an IRSystem.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.emitSeedFile = void 0;
8
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
9
+ function toSnakeCase(s) {
10
+ return s.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase();
11
+ }
12
+ function seedValue(irType, fieldName, i) {
13
+ if (irType === "string")
14
+ return `"sample_${fieldName}_${i + 1}"`;
15
+ if (irType === "uint" || irType === "int")
16
+ return String(i + 1);
17
+ if (irType === "float")
18
+ return String((i + 1) * 1.5);
19
+ if (irType === "bool")
20
+ return i % 2 === 0 ? "true" : "false";
21
+ if (irType === "uuid")
22
+ return "uuid()";
23
+ if (irType === "timestamp")
24
+ return "new Date().toISOString()";
25
+ if (irType === "bytes")
26
+ return `"sample_${fieldName}_${i + 1}"`;
27
+ if (irType === "json")
28
+ return "JSON.stringify({})";
29
+ const listMatch = irType.match(/^list<(.+)>$/);
30
+ if (listMatch)
31
+ return "JSON.stringify([])";
32
+ const setMatch = irType.match(/^set<(.+)>$/);
33
+ if (setMatch)
34
+ return "JSON.stringify([])";
35
+ const optMatch = irType.match(/^optional<(.+)>$/);
36
+ if (optMatch)
37
+ return "null";
38
+ return `"sample_${fieldName}_${i + 1}"`;
39
+ }
40
+ // ─── Public API ───────────────────────────────────────────────────────────────
41
+ function emitSeedFile(system) {
42
+ const lines = [];
43
+ lines.push(`// Generated by BoneScript compiler.`);
44
+ lines.push(`// Seed script for: ${system.name} v${system.version}`);
45
+ lines.push(`// Run: npx ts-node src/seed.ts`);
46
+ lines.push("");
47
+ lines.push(`import { query, pool } from "./db";`);
48
+ lines.push(`import { v4 as uuid } from "uuid";`);
49
+ lines.push("");
50
+ const seedModels = [];
51
+ for (const mod of system.modules) {
52
+ if (mod.kind === "api_service" || mod.kind === "data_store") {
53
+ for (const model of mod.models) {
54
+ seedModels.push({ mod, model });
55
+ }
56
+ }
57
+ }
58
+ lines.push(`async function main(): Promise<void> {`);
59
+ lines.push(` console.log("Seeding ${system.name}...");`);
60
+ lines.push("");
61
+ for (const { model } of seedModels) {
62
+ const tableName = toSnakeCase(model.name) + "s";
63
+ lines.push(` // Seed ${model.name}`);
64
+ lines.push(` console.log(" Seeding ${tableName}...");`);
65
+ for (let i = 0; i < 3; i++) {
66
+ const fieldNames = model.fields.map((f) => f.name);
67
+ const fieldValues = model.fields.map((f) => seedValue(f.type, f.name, i));
68
+ lines.push(` await query(`);
69
+ lines.push(` \`INSERT INTO ${tableName} (${fieldNames.join(", ")}) VALUES (${fieldNames.map((_, idx) => `$${idx + 1}`).join(", ")}) ON CONFLICT DO NOTHING\`,`);
70
+ lines.push(` [${fieldValues.join(", ")}]`);
71
+ lines.push(` );`);
72
+ }
73
+ lines.push("");
74
+ }
75
+ lines.push(` console.log("Seed complete.");`);
76
+ lines.push(`}`);
77
+ lines.push("");
78
+ lines.push(`main()`);
79
+ lines.push(` .catch((err) => {`);
80
+ lines.push(` console.error("Seed failed:", err);`);
81
+ lines.push(` process.exit(1);`);
82
+ lines.push(` })`);
83
+ lines.push(` .finally(() => pool.end());`);
84
+ lines.push("");
85
+ return lines.join("\n");
86
+ }
87
+ exports.emitSeedFile = emitSeedFile;
88
+ //# sourceMappingURL=emit_seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit_seed.js","sourceRoot":"","sources":["../src/emit_seed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * BoneScript Zod Schema Emitter
3
+ * Generates Zod v3 validation schemas from an IRSystem.
4
+ */
5
+ import * as IR from "./ir";
6
+ export declare function emitZodSchemas(system: IR.IRSystem): string;
7
+ export declare function emitZodPackageAdditions(): string;
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * BoneScript Zod Schema Emitter
4
+ * Generates Zod v3 validation schemas from an IRSystem.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.emitZodPackageAdditions = exports.emitZodSchemas = void 0;
8
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
9
+ function toPascalCase(s) {
10
+ return s
11
+ .replace(/_([a-z])/g, (_, c) => c.toUpperCase())
12
+ .replace(/^([a-z])/, (_, c) => c.toUpperCase());
13
+ }
14
+ function irTypeToZod(irType) {
15
+ if (irType === "string")
16
+ return "z.string()";
17
+ if (irType === "uint")
18
+ return "z.number().int().nonnegative()";
19
+ if (irType === "int")
20
+ return "z.number().int()";
21
+ if (irType === "float")
22
+ return "z.number()";
23
+ if (irType === "bool")
24
+ return "z.boolean()";
25
+ if (irType === "timestamp")
26
+ return "z.string().datetime()";
27
+ if (irType === "uuid")
28
+ return "z.string().uuid()";
29
+ if (irType === "bytes")
30
+ return "z.string()";
31
+ if (irType === "json")
32
+ return "z.unknown()";
33
+ const listMatch = irType.match(/^list<(.+)>$/);
34
+ if (listMatch)
35
+ return `z.array(${irTypeToZod(listMatch[1])})`;
36
+ const setMatch = irType.match(/^set<(.+)>$/);
37
+ if (setMatch)
38
+ return `z.array(${irTypeToZod(setMatch[1])})`;
39
+ const optMatch = irType.match(/^optional<(.+)>$/);
40
+ if (optMatch)
41
+ return `${irTypeToZod(optMatch[1])}.nullable()`;
42
+ return "z.unknown()";
43
+ }
44
+ function applyConstraints(baseZod, fieldName, constraints) {
45
+ let result = baseZod;
46
+ for (const c of constraints) {
47
+ if (c.target !== fieldName)
48
+ continue;
49
+ if (c.kind === "range") {
50
+ if (c.params.min !== undefined)
51
+ result += `.min(${c.params.min})`;
52
+ if (c.params.max !== undefined)
53
+ result += `.max(${c.params.max})`;
54
+ }
55
+ else if (c.kind === "enum") {
56
+ const vals = c.params.values;
57
+ if (vals && vals.length > 0) {
58
+ result = `z.enum([${vals.map((v) => JSON.stringify(v)).join(", ")}])`;
59
+ }
60
+ }
61
+ }
62
+ return result;
63
+ }
64
+ // ─── Public API ───────────────────────────────────────────────────────────────
65
+ function emitZodSchemas(system) {
66
+ const lines = [];
67
+ lines.push(`// Generated by BoneScript compiler.`);
68
+ lines.push(`import { z } from "zod";`);
69
+ lines.push("");
70
+ // Model schemas
71
+ for (const mod of system.modules) {
72
+ for (const model of mod.models) {
73
+ const schemaName = toPascalCase(model.name) + "Schema";
74
+ const typeName = toPascalCase(model.name);
75
+ lines.push(`export const ${schemaName} = z.object({`);
76
+ for (const field of model.fields) {
77
+ let zodType = irTypeToZod(field.type);
78
+ zodType = applyConstraints(zodType, field.name, model.constraints);
79
+ if (field.nullable) {
80
+ zodType = zodType + ".nullable()";
81
+ }
82
+ lines.push(` ${field.name}: ${zodType},`);
83
+ }
84
+ lines.push(`});`);
85
+ lines.push(`export type ${typeName} = z.infer<typeof ${schemaName}>;`);
86
+ lines.push("");
87
+ }
88
+ }
89
+ // Capability input schemas
90
+ for (const mod of system.modules) {
91
+ for (const iface of mod.interfaces) {
92
+ for (const method of iface.methods) {
93
+ if (method.input.length === 0)
94
+ continue;
95
+ const modPascal = toPascalCase(mod.name);
96
+ const methodPascal = toPascalCase(method.name);
97
+ const schemaName = `${modPascal}${methodPascal}InputSchema`;
98
+ lines.push(`export const ${schemaName} = z.object({`);
99
+ for (const field of method.input) {
100
+ const zodType = irTypeToZod(field.type);
101
+ lines.push(` ${field.name}: ${zodType},`);
102
+ }
103
+ lines.push(`});`);
104
+ lines.push("");
105
+ }
106
+ }
107
+ }
108
+ return lines.join("\n");
109
+ }
110
+ exports.emitZodSchemas = emitZodSchemas;
111
+ function emitZodPackageAdditions() {
112
+ return JSON.stringify({ zod: "3.22.4" }, null, 2);
113
+ }
114
+ exports.emitZodPackageAdditions = emitZodPackageAdditions;
115
+ //# sourceMappingURL=emit_zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit_zod.js","sourceRoot":"","sources":["../src/emit_zod.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ export { Lowering } from "./lowering";
13
13
  export { ConstraintSolver } from "./solver";
14
14
  export type { SolverResult } from "./solver";
15
15
  export { FullEmitter } from "./emit_full";
16
+ export { NakamaEmitter } from "./emit_nakama";
17
+ export type { NakamaEmittedFile } from "./emit_nakama";
16
18
  export type { EmittedFile } from "./emitter";
17
19
  export { Verifier } from "./verifier";
18
20
  export type { VerifyResult, VerifyIssue } from "./verifier";
@@ -27,6 +29,12 @@ export * as AST from "./ast";
27
29
  export * as IR from "./ir";
28
30
  export { lookupAlgorithm, listAlgorithms, listByCategory } from "./algorithm_catalog";
29
31
  export { mergeWithExisting, extractImplementations, validateExtensions } from "./extension_manager";
32
+ export { emitOpenApiSpec, emitOpenApiJson } from "./emit_openapi";
33
+ export { emitTypescriptSdk, emitSdkPackageJson } from "./emit_sdk";
34
+ export { emitZodSchemas } from "./emit_zod";
35
+ export { emitPostmanCollection } from "./emit_postman";
36
+ export { emitSeedFile } from "./emit_seed";
37
+ export { emitAuditSchema, emitAuditMiddleware } from "./emit_audit";
30
38
  /**
31
39
  * Convenience function: compile a .bone source string to files.
32
40
  */
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
27
27
  return result;
28
28
  };
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.compile = exports.validateExtensions = exports.extractImplementations = exports.mergeWithExisting = exports.listByCategory = exports.listAlgorithms = exports.lookupAlgorithm = exports.IR = exports.AST = exports.scaffold = exports.Formatter = exports.ModuleLoader = exports.optimize = exports.Verifier = exports.FullEmitter = exports.ConstraintSolver = exports.Lowering = exports.TypeChecker = exports.RecoveringParser = exports.ParseError = exports.Parser = exports.TokenKind = exports.LexerError = exports.Lexer = void 0;
30
+ exports.compile = exports.emitAuditMiddleware = exports.emitAuditSchema = exports.emitSeedFile = exports.emitPostmanCollection = exports.emitZodSchemas = exports.emitSdkPackageJson = exports.emitTypescriptSdk = exports.emitOpenApiJson = exports.emitOpenApiSpec = exports.validateExtensions = exports.extractImplementations = exports.mergeWithExisting = exports.listByCategory = exports.listAlgorithms = exports.lookupAlgorithm = exports.IR = exports.AST = exports.scaffold = exports.Formatter = exports.ModuleLoader = exports.optimize = exports.Verifier = exports.NakamaEmitter = exports.FullEmitter = exports.ConstraintSolver = exports.Lowering = exports.TypeChecker = exports.RecoveringParser = exports.ParseError = exports.Parser = exports.TokenKind = exports.LexerError = exports.Lexer = void 0;
31
31
  // Core pipeline
32
32
  var lexer_1 = require("./lexer");
33
33
  Object.defineProperty(exports, "Lexer", { enumerable: true, get: function () { return lexer_1.Lexer; } });
@@ -46,6 +46,8 @@ var solver_1 = require("./solver");
46
46
  Object.defineProperty(exports, "ConstraintSolver", { enumerable: true, get: function () { return solver_1.ConstraintSolver; } });
47
47
  var emit_full_1 = require("./emit_full");
48
48
  Object.defineProperty(exports, "FullEmitter", { enumerable: true, get: function () { return emit_full_1.FullEmitter; } });
49
+ var emit_nakama_1 = require("./emit_nakama");
50
+ Object.defineProperty(exports, "NakamaEmitter", { enumerable: true, get: function () { return emit_nakama_1.NakamaEmitter; } });
49
51
  var verifier_1 = require("./verifier");
50
52
  Object.defineProperty(exports, "Verifier", { enumerable: true, get: function () { return verifier_1.Verifier; } });
51
53
  var optimizer_1 = require("./optimizer");
@@ -70,6 +72,22 @@ var extension_manager_1 = require("./extension_manager");
70
72
  Object.defineProperty(exports, "mergeWithExisting", { enumerable: true, get: function () { return extension_manager_1.mergeWithExisting; } });
71
73
  Object.defineProperty(exports, "extractImplementations", { enumerable: true, get: function () { return extension_manager_1.extractImplementations; } });
72
74
  Object.defineProperty(exports, "validateExtensions", { enumerable: true, get: function () { return extension_manager_1.validateExtensions; } });
75
+ // New emitters
76
+ var emit_openapi_1 = require("./emit_openapi");
77
+ Object.defineProperty(exports, "emitOpenApiSpec", { enumerable: true, get: function () { return emit_openapi_1.emitOpenApiSpec; } });
78
+ Object.defineProperty(exports, "emitOpenApiJson", { enumerable: true, get: function () { return emit_openapi_1.emitOpenApiJson; } });
79
+ var emit_sdk_1 = require("./emit_sdk");
80
+ Object.defineProperty(exports, "emitTypescriptSdk", { enumerable: true, get: function () { return emit_sdk_1.emitTypescriptSdk; } });
81
+ Object.defineProperty(exports, "emitSdkPackageJson", { enumerable: true, get: function () { return emit_sdk_1.emitSdkPackageJson; } });
82
+ var emit_zod_1 = require("./emit_zod");
83
+ Object.defineProperty(exports, "emitZodSchemas", { enumerable: true, get: function () { return emit_zod_1.emitZodSchemas; } });
84
+ var emit_postman_1 = require("./emit_postman");
85
+ Object.defineProperty(exports, "emitPostmanCollection", { enumerable: true, get: function () { return emit_postman_1.emitPostmanCollection; } });
86
+ var emit_seed_1 = require("./emit_seed");
87
+ Object.defineProperty(exports, "emitSeedFile", { enumerable: true, get: function () { return emit_seed_1.emitSeedFile; } });
88
+ var emit_audit_1 = require("./emit_audit");
89
+ Object.defineProperty(exports, "emitAuditSchema", { enumerable: true, get: function () { return emit_audit_1.emitAuditSchema; } });
90
+ Object.defineProperty(exports, "emitAuditMiddleware", { enumerable: true, get: function () { return emit_audit_1.emitAuditMiddleware; } });
73
91
  /**
74
92
  * Convenience function: compile a .bone source string to files.
75
93
  */
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bonescript-compiler",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "description": "BoneScript compiler — compile .bone system descriptions into complete, runnable Node.js backends",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,6 +12,7 @@
12
12
  "src/**/*.ts",
13
13
  "!src/test.ts",
14
14
  "!src/test_typechecker.ts",
15
+ "!src/test_nakama.ts",
15
16
  "LICENSE",
16
17
  "README.md"
17
18
  ],
@@ -19,7 +20,7 @@
19
20
  "build": "tsc",
20
21
  "prepublishOnly": "npm run build",
21
22
  "start": "ts-node src/cli.ts",
22
- "test": "ts-node src/test.ts && ts-node src/test_typechecker.ts"
23
+ "test": "ts-node src/test.ts && ts-node src/test_typechecker.ts && ts-node src/test_nakama.ts"
23
24
  },
24
25
  "keywords": [
25
26
  "bonescript",
package/src/cli.ts CHANGED
@@ -12,6 +12,7 @@ import { TypeChecker } from "./typechecker";
12
12
  import { Lowering } from "./lowering";
13
13
  import { ConstraintSolver } from "./solver";
14
14
  import { FullEmitter } from "./emit_full";
15
+ import { NakamaEmitter } from "./emit_nakama";
15
16
  import { Verifier } from "./verifier";
16
17
  import { ModuleLoader } from "./module_loader";
17
18
  import { Formatter } from "./formatter";
@@ -31,7 +32,7 @@ function main() {
31
32
 
32
33
  switch (command) {
33
34
  case "compile":
34
- requireFile(args[1], runCompile);
35
+ requireFile(args[1], (src, res) => runCompile(src, res, args.slice(2)));
35
36
  break;
36
37
  case "lex":
37
38
  requireFile(args[1], runLex);
@@ -74,10 +75,10 @@ function main() {
74
75
  }
75
76
 
76
77
  function showHelp() {
77
- console.log("BoneScript compiler v0.2.0");
78
+ console.log("BoneScript compiler v0.5.6");
78
79
  console.log("");
79
80
  console.log("Usage:");
80
- console.log(" bonec compile <file> Compile to runnable project");
81
+ console.log(" bonec compile <file> [--target <target>] Compile to runnable project");
81
82
  console.log(" bonec check <file> Lex + parse + type check (no codegen)");
82
83
  console.log(" bonec lex <file> Show token stream");
83
84
  console.log(" bonec parse <file> Show AST");
@@ -86,6 +87,13 @@ function showHelp() {
86
87
  console.log(" bonec watch <file> Recompile on change");
87
88
  console.log(" bonec diff <old.bone> <new.bone> Show schema migration diff");
88
89
  console.log("");
90
+ console.log("compile options:");
91
+ console.log(" --target <name> Output target (default: express)");
92
+ console.log(" Options: express, nakama");
93
+ console.log(" --no-sdk Skip SDK generation");
94
+ console.log(" --no-openapi Skip OpenAPI spec generation");
95
+ console.log(" --no-seed Skip seed file generation");
96
+ console.log("");
89
97
  console.log("init options:");
90
98
  console.log(" bonec init <name> --domain <name> Scaffold from a domain template");
91
99
  console.log(" --domain <name> Domain template (default: saas_platform)");
@@ -267,7 +275,36 @@ function runInit(args: string[]) {
267
275
 
268
276
  // ─── Compile (full pipeline) ─────────────────────────────────────────────────
269
277
 
270
- function runCompile(source: string, resolved: string) {
278
+ function runCompile(source: string, resolved: string, extraArgs: string[] = []) {
279
+ // Parse --target flag (default: express)
280
+ let target: "express" | "nakama" = "express";
281
+ // Parse optional feature flags (future enhancement — documented for now)
282
+ let _noSdk = false;
283
+ let _noOpenApi = false;
284
+ let _noSeed = false;
285
+ for (let i = 0; i < extraArgs.length; i++) {
286
+ if (extraArgs[i] === "--target" && extraArgs[i + 1]) {
287
+ const t = extraArgs[i + 1];
288
+ if (t !== "express" && t !== "nakama") {
289
+ console.error(`Unknown target '${t}'. Valid targets: express, nakama`);
290
+ process.exit(1);
291
+ }
292
+ target = t;
293
+ i++;
294
+ } else if (extraArgs[i] === "--no-sdk") {
295
+ _noSdk = true;
296
+ } else if (extraArgs[i] === "--no-openapi") {
297
+ _noOpenApi = true;
298
+ } else if (extraArgs[i] === "--no-seed") {
299
+ _noSeed = true;
300
+ }
301
+ }
302
+
303
+ if (target === "nakama") {
304
+ runCompileNakama(source, resolved);
305
+ return;
306
+ }
307
+
271
308
  try {
272
309
  const tokens = new Lexer(source).tokenize();
273
310
  console.log(` [1/7] Lexed: ${tokens.length} tokens`);
@@ -418,6 +455,62 @@ function runCompile(source: string, resolved: string) {
418
455
 
419
456
  main();
420
457
 
458
+ // ─── Compile (Nakama target) ──────────────────────────────────────────────────
459
+
460
+ function runCompileNakama(source: string, resolved: string) {
461
+ try {
462
+ const tokens = new Lexer(source).tokenize();
463
+ console.log(` [1/5] Lexed: ${tokens.length} tokens`);
464
+
465
+ const loader = new ModuleLoader();
466
+ const loadResult = loader.load(resolved);
467
+ if (loadResult.errors.length > 0) {
468
+ for (const e of loadResult.errors.slice(0, 10)) {
469
+ console.log(` ${path.basename(e.file)}: ${e.error.message}`);
470
+ }
471
+ if (!loadResult.ast) process.exit(1);
472
+ }
473
+ const ast = loadResult.ast!;
474
+ console.log(` [2/5] Parsed: ${ast.systems.length} system(s)`);
475
+
476
+ const typeErrors = new TypeChecker().check(ast);
477
+ if (typeErrors.length > 0) {
478
+ for (const err of typeErrors) {
479
+ console.log(` ${err.code} at ${err.loc.line}:${err.loc.column}: ${err.message}`);
480
+ }
481
+ } else {
482
+ console.log(` [3/5] Type check: v (0 errors)`);
483
+ }
484
+
485
+ const sourceHash = createHash("sha256").update(source).digest("hex").slice(0, 16);
486
+ const irSystems = new Lowering().lower(ast, sourceHash);
487
+ console.log(` [4/5] Lowered to IR: ${irSystems.reduce((s, sys) => s + sys.modules.length, 0)} modules`);
488
+
489
+ const emitter = new NakamaEmitter();
490
+ const allFiles: ReturnType<typeof emitter.emit> = [];
491
+ for (const sys of irSystems) {
492
+ allFiles.push(...emitter.emit(sys));
493
+ }
494
+ console.log(` [5/5] Nakama emit: ${allFiles.length} files`);
495
+
496
+ const outputDir = path.resolve(path.dirname(resolved), "output-nakama");
497
+ for (const f of allFiles) {
498
+ const outPath = path.join(outputDir, f.path);
499
+ const dir = path.dirname(outPath);
500
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
501
+ fs.writeFileSync(outPath, f.content, "utf-8");
502
+ }
503
+
504
+ console.log(`\nv Nakama compilation complete. ${allFiles.length} files written to output-nakama/`);
505
+ console.log(`\nNext steps:`);
506
+ console.log(` cd output-nakama && npm install && npm run build`);
507
+ console.log(` # Copy build/ to your Nakama runtime path`);
508
+ } catch (e: any) {
509
+ console.error(`x ${e.message}`);
510
+ process.exit(1);
511
+ }
512
+ }
513
+
421
514
  // ─── Diff ─────────────────────────────────────────────────────────────────────
422
515
 
423
516
  function runDiff(args: string[]) {
@@ -0,0 +1,112 @@
1
+ /**
2
+ * BoneScript Audit Log Emitter
3
+ * Generates audit_log SQL schema and Express audit middleware.
4
+ */
5
+
6
+ import * as IR from "./ir";
7
+
8
+ // ─── emitAuditSchema ─────────────────────────────────────────────────────────
9
+
10
+ export function emitAuditSchema(): string {
11
+ return `-- Generated by BoneScript compiler.
12
+ -- Audit log table for tracking all mutations.
13
+
14
+ CREATE TABLE IF NOT EXISTS audit_log (
15
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
16
+ actor_id VARCHAR,
17
+ action VARCHAR NOT NULL,
18
+ entity_type VARCHAR,
19
+ entity_id VARCHAR,
20
+ payload JSONB,
21
+ ip_address VARCHAR,
22
+ user_agent VARCHAR,
23
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
24
+ );
25
+
26
+ CREATE INDEX IF NOT EXISTS idx_audit_log_actor ON audit_log (actor_id, created_at);
27
+ CREATE INDEX IF NOT EXISTS idx_audit_log_entity ON audit_log (entity_type, entity_id);
28
+ CREATE INDEX IF NOT EXISTS idx_audit_log_action ON audit_log (action, created_at);
29
+ `;
30
+ }
31
+
32
+ // ─── emitAuditMiddleware ──────────────────────────────────────────────────────
33
+
34
+ export function emitAuditMiddleware(system: IR.IRSystem): string {
35
+ const lines: string[] = [];
36
+
37
+ // Collect modules that have audit: true in their policy/config
38
+ const auditModules: string[] = [];
39
+ for (const mod of system.modules) {
40
+ if (mod.config && mod.config["audit"] === true) {
41
+ auditModules.push(mod.name);
42
+ }
43
+ }
44
+
45
+ lines.push(`// Generated by BoneScript compiler.`);
46
+ lines.push(`// Audit middleware for: ${system.name} v${system.version}`);
47
+ if (auditModules.length > 0) {
48
+ lines.push(`//`);
49
+ lines.push(`// Modules requiring audit logging:`);
50
+ for (const name of auditModules) {
51
+ lines.push(`// - ${name}`);
52
+ }
53
+ }
54
+ lines.push("");
55
+ lines.push(`import { Request, Response, NextFunction } from "express";`);
56
+ lines.push(`import { query } from "./db";`);
57
+ lines.push("");
58
+
59
+ lines.push(
60
+ `export function auditLog(action: string, entityType?: string) {`
61
+ );
62
+ lines.push(
63
+ ` return async (req: Request, _res: Response, next: NextFunction): Promise<void> => {`
64
+ );
65
+ lines.push(` try {`);
66
+ lines.push(` const auth = (req as any).auth as { id?: string } | undefined;`);
67
+ lines.push(` const actorId = auth?.id ?? null;`);
68
+ lines.push(
69
+ ` const entityId = req.params.id ?? (req.body as Record<string, unknown>)?.id ?? null;`
70
+ );
71
+ lines.push(` const payload = req.body ?? null;`);
72
+ lines.push(` const ipAddress = req.ip ?? null;`);
73
+ lines.push(` const userAgent = req.headers["user-agent"] ?? null;`);
74
+ lines.push("");
75
+ lines.push(` await query(`);
76
+ lines.push(` \`INSERT INTO audit_log`);
77
+ lines.push(
78
+ ` (actor_id, action, entity_type, entity_id, payload, ip_address, user_agent)`
79
+ );
80
+ lines.push(
81
+ ` VALUES ($1, $2, $3, $4, $5, $6, $7)\`,`
82
+ );
83
+ lines.push(
84
+ ` [actorId, action, entityType ?? null, entityId, JSON.stringify(payload), ipAddress, userAgent]`
85
+ );
86
+ lines.push(` );`);
87
+ lines.push(` } catch (err) {`);
88
+ lines.push(
89
+ ` // Audit failures must not block the request — log and continue`
90
+ );
91
+ lines.push(` console.error("[audit] Failed to write audit log:", err);`);
92
+ lines.push(` }`);
93
+ lines.push(` next();`);
94
+ lines.push(` };`);
95
+ lines.push(`}`);
96
+ lines.push("");
97
+
98
+ lines.push(
99
+ `export async function getAuditLog(entityType: string, entityId: string): Promise<any[]> {`
100
+ );
101
+ lines.push(` const result = await query(`);
102
+ lines.push(
103
+ ` "SELECT * FROM audit_log WHERE entity_type = $1 AND entity_id = $2 ORDER BY created_at DESC LIMIT 100",`
104
+ );
105
+ lines.push(` [entityType, entityId]`);
106
+ lines.push(` );`);
107
+ lines.push(` return result.rows;`);
108
+ lines.push(`}`);
109
+ lines.push("");
110
+
111
+ return lines.join("\n");
112
+ }