bonescript-compiler 0.2.1 → 0.4.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/LICENSE +21 -21
- package/dist/algorithm_catalog.js +166 -166
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +75 -543
- package/dist/cli.js.map +1 -1
- package/dist/commands/check.d.ts +5 -0
- package/dist/commands/check.js +34 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/compile.d.ts +5 -0
- package/dist/commands/compile.js +215 -0
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/debug.d.ts +5 -0
- package/dist/commands/debug.js +59 -0
- package/dist/commands/debug.js.map +1 -0
- package/dist/commands/diff.d.ts +5 -0
- package/dist/commands/diff.js +125 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/fmt.d.ts +5 -0
- package/dist/commands/fmt.js +49 -0
- package/dist/commands/fmt.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.js +96 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/ir.d.ts +5 -0
- package/dist/commands/ir.js +27 -0
- package/dist/commands/ir.js.map +1 -0
- package/dist/commands/lex.d.ts +5 -0
- package/dist/commands/lex.js +21 -0
- package/dist/commands/lex.js.map +1 -0
- package/dist/commands/parse.d.ts +5 -0
- package/dist/commands/parse.js +30 -0
- package/dist/commands/parse.js.map +1 -0
- package/dist/commands/test.d.ts +5 -0
- package/dist/commands/test.js +61 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/verify_determinism.d.ts +5 -0
- package/dist/commands/verify_determinism.js +64 -0
- package/dist/commands/verify_determinism.js.map +1 -0
- package/dist/commands/watch.d.ts +5 -0
- package/dist/commands/watch.js +50 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/emit_auth.d.ts +6 -0
- package/dist/emit_auth.js +69 -0
- package/dist/emit_auth.js.map +1 -0
- package/dist/emit_capability.d.ts +13 -0
- package/dist/emit_capability.js +292 -128
- package/dist/emit_capability.js.map +1 -1
- package/dist/emit_composition.js +37 -3
- package/dist/emit_composition.js.map +1 -1
- package/dist/emit_database.d.ts +7 -0
- package/dist/emit_database.js +74 -0
- package/dist/emit_database.js.map +1 -0
- package/dist/emit_deploy.js +162 -162
- package/dist/emit_events.d.ts +1 -0
- package/dist/emit_events.js +342 -275
- package/dist/emit_events.js.map +1 -1
- package/dist/emit_full.js +135 -95
- package/dist/emit_full.js.map +1 -1
- package/dist/emit_index.d.ts +6 -0
- package/dist/emit_index.js +157 -0
- package/dist/emit_index.js.map +1 -0
- package/dist/emit_maintenance.js +249 -249
- package/dist/emit_models.d.ts +12 -0
- package/dist/emit_models.js +171 -0
- package/dist/emit_models.js.map +1 -0
- package/dist/emit_openapi.d.ts +9 -0
- package/dist/emit_openapi.js +308 -0
- package/dist/emit_openapi.js.map +1 -0
- package/dist/emit_package.d.ts +7 -0
- package/dist/emit_package.js +70 -0
- package/dist/emit_package.js.map +1 -0
- package/dist/emit_router.d.ts +12 -0
- package/dist/emit_router.js +390 -0
- package/dist/emit_router.js.map +1 -0
- package/dist/emit_runtime.d.ts +17 -11
- package/dist/emit_runtime.js +29 -686
- package/dist/emit_runtime.js.map +1 -1
- package/dist/emit_sourcemap.js +66 -66
- package/dist/emit_tests.js +37 -0
- package/dist/emit_tests.js.map +1 -1
- package/dist/emitter.js +34 -5
- package/dist/emitter.js.map +1 -1
- package/dist/extension_manager.d.ts +2 -2
- package/dist/extension_manager.js +6 -3
- package/dist/extension_manager.js.map +1 -1
- package/dist/lowering.d.ts +5 -14
- package/dist/lowering.js +47 -417
- package/dist/lowering.js.map +1 -1
- package/dist/lowering_channels.d.ts +11 -0
- package/dist/lowering_channels.js +102 -0
- package/dist/lowering_channels.js.map +1 -0
- package/dist/lowering_entities.d.ts +11 -0
- package/dist/lowering_entities.js +222 -0
- package/dist/lowering_entities.js.map +1 -0
- package/dist/lowering_helpers.d.ts +13 -0
- package/dist/lowering_helpers.js +76 -0
- package/dist/lowering_helpers.js.map +1 -0
- package/dist/module_loader.d.ts +2 -2
- package/dist/module_loader.js +20 -23
- package/dist/module_loader.js.map +1 -1
- package/dist/scaffold.d.ts +2 -2
- package/dist/scaffold.js +316 -319
- package/dist/scaffold.js.map +1 -1
- package/dist/typechecker.js +32 -13
- package/dist/typechecker.js.map +1 -1
- package/dist/verifier.d.ts +5 -0
- package/dist/verifier.js +140 -2
- package/dist/verifier.js.map +1 -1
- package/package.json +62 -52
- package/src/algorithm_catalog.ts +345 -345
- package/src/ast.ts +334 -334
- package/src/cli.ts +98 -624
- package/src/commands/check.ts +33 -0
- package/src/commands/compile.ts +191 -0
- package/src/commands/debug.ts +33 -0
- package/src/commands/diff.ts +108 -0
- package/src/commands/fmt.ts +22 -0
- package/src/commands/init.ts +72 -0
- package/src/commands/ir.ts +23 -0
- package/src/commands/lex.ts +17 -0
- package/src/commands/parse.ts +24 -0
- package/src/commands/test.ts +36 -0
- package/src/commands/verify_determinism.ts +66 -0
- package/src/commands/watch.ts +25 -0
- package/src/emit_auth.ts +67 -0
- package/src/emit_batch.ts +140 -140
- package/src/emit_capability.ts +617 -436
- package/src/emit_composition.ts +229 -196
- package/src/emit_database.ts +75 -0
- package/src/emit_deploy.ts +190 -190
- package/src/emit_events.ts +377 -307
- package/src/emit_extras.ts +240 -240
- package/src/emit_full.ts +351 -309
- package/src/emit_index.ts +161 -0
- package/src/emit_maintenance.ts +459 -459
- package/src/emit_models.ts +176 -0
- package/src/emit_openapi.ts +318 -0
- package/src/emit_package.ts +69 -0
- package/src/emit_router.ts +409 -0
- package/src/emit_runtime.ts +17 -728
- package/src/emit_sourcemap.ts +140 -140
- package/src/emit_tests.ts +246 -205
- package/src/emit_websocket.ts +229 -229
- package/src/emitter.ts +31 -5
- package/src/extension_manager.ts +189 -187
- package/src/formatter.ts +297 -297
- package/src/index.ts +88 -88
- package/src/ir.ts +215 -215
- package/src/lexer.ts +630 -630
- package/src/lowering.ts +142 -556
- package/src/lowering_channels.ts +107 -0
- package/src/lowering_entities.ts +248 -0
- package/src/lowering_helpers.ts +75 -0
- package/src/module_loader.ts +112 -114
- package/src/optimizer.ts +196 -196
- package/src/parse_decls.ts +409 -409
- package/src/parse_decls2.ts +244 -244
- package/src/parse_expr.ts +197 -197
- package/src/parse_types.ts +54 -54
- package/src/parser.ts +1 -1
- package/src/parser_base.ts +57 -57
- package/src/parser_recovery.ts +153 -153
- package/src/scaffold.ts +372 -375
- package/src/solver.ts +330 -330
- package/src/typechecker.ts +30 -15
- package/src/types.ts +122 -122
- package/src/verifier.ts +151 -4
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BoneScript Server Entry Point Emitter
|
|
3
|
+
* Generates src/index.ts — the Express server with all middleware and routes wired.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as IR from "./ir";
|
|
7
|
+
import { toSnakeCase, toCamelCase } from "./emit_router";
|
|
8
|
+
|
|
9
|
+
export function emitIndex(system: IR.IRSystem): string {
|
|
10
|
+
const apiModules = system.modules.filter(m => m.kind === "api_service");
|
|
11
|
+
const hasWebSocket = system.modules.some(m => m.kind === "realtime_service");
|
|
12
|
+
const hasBatch = system.modules.some(m =>
|
|
13
|
+
m.interfaces.some(i => i.methods.some(mth => mth.sync === "batch"))
|
|
14
|
+
);
|
|
15
|
+
const lines: string[] = [];
|
|
16
|
+
|
|
17
|
+
lines.push(`// Generated by BoneScript compiler. DO NOT EDIT.`);
|
|
18
|
+
lines.push(`// System: ${system.name}`);
|
|
19
|
+
lines.push(`require("dotenv").config();`);
|
|
20
|
+
lines.push(`import express from "express";`);
|
|
21
|
+
lines.push(`import { createServer } from "http";`);
|
|
22
|
+
lines.push(`import cors from "cors";`);
|
|
23
|
+
lines.push(`import helmet from "helmet";`);
|
|
24
|
+
lines.push(`import rateLimit from "express-rate-limit";`);
|
|
25
|
+
lines.push(`import { authMiddleware } from "./auth";`);
|
|
26
|
+
lines.push(`import { healthRouter } from "./health";`);
|
|
27
|
+
lines.push(`import { logger } from "./logger";`);
|
|
28
|
+
lines.push(`import { eventBus } from "./events";`);
|
|
29
|
+
lines.push(`import { pool } from "./db";`);
|
|
30
|
+
if (hasBatch) lines.push(`import { startBatchWorker } from "./batch";`);
|
|
31
|
+
if (hasWebSocket) lines.push(`import { setupWebSocketServer } from "./websocket";`);
|
|
32
|
+
lines.push(``);
|
|
33
|
+
|
|
34
|
+
for (const mod of apiModules) {
|
|
35
|
+
const model = mod.models[0];
|
|
36
|
+
if (!model) continue;
|
|
37
|
+
const routerName = toCamelCase(toSnakeCase(model.name) + "s") + "Router";
|
|
38
|
+
lines.push(`import { ${routerName} } from "./routes/${toSnakeCase(model.name)}";`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
lines.push(``);
|
|
42
|
+
lines.push(`const app = express();`);
|
|
43
|
+
lines.push(`const httpServer = createServer(app);`);
|
|
44
|
+
lines.push(`const PORT = parseInt(process.env.PORT || "3000");`);
|
|
45
|
+
lines.push(``);
|
|
46
|
+
|
|
47
|
+
// Middleware
|
|
48
|
+
lines.push(`// Middleware`);
|
|
49
|
+
lines.push(`app.use(helmet());`);
|
|
50
|
+
lines.push(`// CORS: restrict to ALLOWED_ORIGINS env var (comma-separated). Defaults to same-origin only.`);
|
|
51
|
+
lines.push(`const __allowedOrigins = (process.env.ALLOWED_ORIGINS || "").split(",").map(s => s.trim()).filter(Boolean);`);
|
|
52
|
+
lines.push(`app.use(cors({`);
|
|
53
|
+
lines.push(` origin: __allowedOrigins.length > 0`);
|
|
54
|
+
lines.push(` ? (origin, cb) => { if (!origin || __allowedOrigins.includes(origin)) cb(null, true); else cb(new Error("Not allowed by CORS")); }`);
|
|
55
|
+
lines.push(` : false,`);
|
|
56
|
+
lines.push(` credentials: true,`);
|
|
57
|
+
lines.push(`}));`);
|
|
58
|
+
lines.push(`app.use(express.json({ limit: "1mb" }));`);
|
|
59
|
+
lines.push(`app.use(express.urlencoded({ extended: false, limit: "1mb" }));`);
|
|
60
|
+
lines.push(`app.use(authMiddleware);`);
|
|
61
|
+
lines.push(``);
|
|
62
|
+
|
|
63
|
+
// Rate limiting
|
|
64
|
+
const gw = system.modules.find(m => m.kind === "gateway");
|
|
65
|
+
const rateVal = gw?.config["rate_limit"] || 300;
|
|
66
|
+
lines.push(`// Global rate limit (default ${rateVal} req/min, override with RATE_LIMIT_MAX env var)`);
|
|
67
|
+
lines.push(`const __globalRateLimit = rateLimit({`);
|
|
68
|
+
lines.push(` windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS || "60000"),`);
|
|
69
|
+
lines.push(` max: parseInt(process.env.RATE_LIMIT_MAX || "${rateVal}"),`);
|
|
70
|
+
lines.push(` standardHeaders: true,`);
|
|
71
|
+
lines.push(` legacyHeaders: false,`);
|
|
72
|
+
lines.push(` message: { error: { code: "RATE_LIMITED", message: "Too many requests, please slow down." } },`);
|
|
73
|
+
lines.push(`});`);
|
|
74
|
+
lines.push(`app.use(__globalRateLimit);`);
|
|
75
|
+
lines.push(``);
|
|
76
|
+
lines.push(`// Strict rate limit on auth endpoints (20 req/min per IP)`);
|
|
77
|
+
lines.push(`const __authRateLimit = rateLimit({`);
|
|
78
|
+
lines.push(` windowMs: 60000,`);
|
|
79
|
+
lines.push(` max: parseInt(process.env.AUTH_RATE_LIMIT_MAX || "20"),`);
|
|
80
|
+
lines.push(` standardHeaders: true,`);
|
|
81
|
+
lines.push(` legacyHeaders: false,`);
|
|
82
|
+
lines.push(` message: { error: { code: "RATE_LIMITED", message: "Too many auth attempts." } },`);
|
|
83
|
+
lines.push(`});`);
|
|
84
|
+
lines.push(``);
|
|
85
|
+
|
|
86
|
+
// Request timeout
|
|
87
|
+
lines.push(`// Request timeout (default 30s, override per-route)`);
|
|
88
|
+
lines.push(`app.use((req: any, res: any, next: any) => {`);
|
|
89
|
+
lines.push(` const timeout = parseInt(process.env.REQUEST_TIMEOUT_MS || "30000");`);
|
|
90
|
+
lines.push(` const timer = setTimeout(() => {`);
|
|
91
|
+
lines.push(` if (!res.headersSent) {`);
|
|
92
|
+
lines.push(` res.status(503).json({ error: { code: "REQUEST_TIMEOUT", message: "Request timed out" } });`);
|
|
93
|
+
lines.push(` }`);
|
|
94
|
+
lines.push(` }, timeout);`);
|
|
95
|
+
lines.push(` res.on("finish", () => clearTimeout(timer));`);
|
|
96
|
+
lines.push(` next();`);
|
|
97
|
+
lines.push(`});`);
|
|
98
|
+
lines.push(``);
|
|
99
|
+
|
|
100
|
+
// Routes
|
|
101
|
+
lines.push(`// Health & metrics`);
|
|
102
|
+
lines.push(`app.use("/health", healthRouter);`);
|
|
103
|
+
lines.push(``);
|
|
104
|
+
lines.push(`// Routes`);
|
|
105
|
+
for (const mod of apiModules) {
|
|
106
|
+
const model = mod.models[0];
|
|
107
|
+
if (!model) continue;
|
|
108
|
+
const routerName = toCamelCase(toSnakeCase(model.name) + "s") + "Router";
|
|
109
|
+
const routePath = `/${toSnakeCase(model.name)}s`;
|
|
110
|
+
lines.push(`app.use("${routePath}", ${routerName});`);
|
|
111
|
+
lines.push(`app.use("${routePath}/login", __authRateLimit);`);
|
|
112
|
+
lines.push(`app.use("${routePath}/register", __authRateLimit);`);
|
|
113
|
+
}
|
|
114
|
+
lines.push(``);
|
|
115
|
+
|
|
116
|
+
if (hasWebSocket) {
|
|
117
|
+
lines.push(`// WebSocket`);
|
|
118
|
+
lines.push(`setupWebSocketServer(httpServer);`);
|
|
119
|
+
lines.push(``);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Startup
|
|
123
|
+
lines.push(`// Start`);
|
|
124
|
+
lines.push(`httpServer.listen(PORT, () => {`);
|
|
125
|
+
lines.push(` logger.info("server_started", { event: "startup", metadata: { port: PORT } });`);
|
|
126
|
+
lines.push(` eventBus.startWorker(parseInt(process.env.EVENT_WORKER_INTERVAL_MS || "1000"));`);
|
|
127
|
+
if (hasBatch) lines.push(` startBatchWorker();`);
|
|
128
|
+
lines.push(` console.log(\`[${system.name}] Running on port \${PORT}\`);`);
|
|
129
|
+
lines.push(` console.log(\` HTTP routes:\`);`);
|
|
130
|
+
for (const mod of apiModules) {
|
|
131
|
+
const model = mod.models[0];
|
|
132
|
+
if (!model) continue;
|
|
133
|
+
lines.push(` console.log(\` /${toSnakeCase(model.name)}s\`);`);
|
|
134
|
+
}
|
|
135
|
+
if (hasWebSocket) lines.push(` console.log(\` WebSocket: /ws?channel=<name>&token=<jwt>\`);`);
|
|
136
|
+
lines.push(` console.log(\` Health: /health/live, /health/ready, /health/metrics\`);`);
|
|
137
|
+
lines.push(`});`);
|
|
138
|
+
lines.push(``);
|
|
139
|
+
|
|
140
|
+
// Graceful shutdown
|
|
141
|
+
lines.push(`// Graceful shutdown`);
|
|
142
|
+
lines.push(`const shutdown = async (signal: string) => {`);
|
|
143
|
+
lines.push(` logger.info("server_stopping", { event: "shutdown", metadata: { signal } });`);
|
|
144
|
+
lines.push(` httpServer.close(async () => {`);
|
|
145
|
+
lines.push(` try {`);
|
|
146
|
+
lines.push(` await pool.end();`);
|
|
147
|
+
lines.push(` logger.info("server_stopped", { event: "shutdown", status: "success" });`);
|
|
148
|
+
lines.push(` } catch (e: any) {`);
|
|
149
|
+
lines.push(` logger.error("shutdown_error", { event: "shutdown", metadata: { error: e.message } });`);
|
|
150
|
+
lines.push(` }`);
|
|
151
|
+
lines.push(` process.exit(0);`);
|
|
152
|
+
lines.push(` });`);
|
|
153
|
+
lines.push(` setTimeout(() => { logger.error("shutdown_timeout", { event: "shutdown" }); process.exit(1); }, 10000);`);
|
|
154
|
+
lines.push(`};`);
|
|
155
|
+
lines.push(`process.on("SIGTERM", () => shutdown("SIGTERM"));`);
|
|
156
|
+
lines.push(`process.on("SIGINT", () => shutdown("SIGINT"));`);
|
|
157
|
+
lines.push(``);
|
|
158
|
+
lines.push(`export { app, httpServer };`);
|
|
159
|
+
|
|
160
|
+
return lines.join("\n");
|
|
161
|
+
}
|