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.
- package/dist/cli.js +94 -4
- package/dist/cli.js.map +1 -1
- package/dist/emit_audit.d.ts +7 -0
- package/dist/emit_audit.js +89 -0
- package/dist/emit_audit.js.map +1 -0
- package/dist/emit_full.js +19 -0
- package/dist/emit_full.js.map +1 -1
- package/dist/emit_nakama.d.ts +23 -0
- package/dist/emit_nakama.js +510 -0
- package/dist/emit_nakama.js.map +1 -0
- package/dist/emit_openapi.d.ts +7 -0
- package/dist/emit_openapi.js +333 -0
- package/dist/emit_openapi.js.map +1 -0
- package/dist/emit_postman.d.ts +6 -0
- package/dist/emit_postman.js +126 -0
- package/dist/emit_postman.js.map +1 -0
- package/dist/emit_sdk.d.ts +7 -0
- package/dist/emit_sdk.js +162 -0
- package/dist/emit_sdk.js.map +1 -0
- package/dist/emit_seed.d.ts +6 -0
- package/dist/emit_seed.js +88 -0
- package/dist/emit_seed.js.map +1 -0
- package/dist/emit_zod.d.ts +7 -0
- package/dist/emit_zod.js +115 -0
- package/dist/emit_zod.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/cli.ts +97 -4
- package/src/emit_audit.ts +112 -0
- package/src/emit_full.ts +25 -0
- package/src/emit_nakama.ts +576 -0
- package/src/emit_openapi.ts +344 -0
- package/src/emit_postman.ts +145 -0
- package/src/emit_sdk.ts +195 -0
- package/src/emit_seed.ts +91 -0
- package/src/emit_zod.ts +111 -0
- package/src/index.ts +10 -0
|
@@ -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,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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"}
|
package/dist/emit_zod.js
ADDED
|
@@ -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":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,gBAAgB;AAChB,iCAAuD;AAA9C,8FAAA,KAAK,OAAA;AAAE,mGAAA,UAAU,OAAA;AAAE,kGAAA,SAAS,OAAA;AAErC,mCAA8C;AAArC,gGAAA,MAAM,OAAA;AAAE,oGAAA,UAAU,OAAA;AAC3B,qDAAqD;AAA5C,mHAAA,gBAAgB,OAAA;AAEzB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AAEpB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,mCAA4C;AAAnC,0GAAA,gBAAgB,OAAA;AAEzB,yCAA0C;AAAjC,wGAAA,WAAW,OAAA;
|
|
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.
|
|
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.
|
|
78
|
+
console.log("BoneScript compiler v0.5.6");
|
|
78
79
|
console.log("");
|
|
79
80
|
console.log("Usage:");
|
|
80
|
-
console.log(" bonec compile <file>
|
|
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
|
+
}
|