@run-iq/server 0.1.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 @@
1
+ {"version":3,"sources":["../src/app.ts","../src/config.ts","../src/routes/health.ts","../src/routes/evaluate.ts","../src/schemas/evaluate.ts","../src/server.ts"],"sourcesContent":["import Fastify from 'fastify';\nimport type { FastifyInstance, FastifyError } from 'fastify';\nimport { PPEError, ValidationError, RuleConflictError, SnapshotFailureError } from '@run-iq/core';\nimport { type ServerConfig, resolveConfig } from './config.js';\nimport { healthRoute } from './routes/health.js';\nimport { createEvaluateRoute } from './routes/evaluate.js';\n\nexport function createApp(\n partial: Partial<ServerConfig> & Pick<ServerConfig, 'plugins' | 'dsls'>,\n): FastifyInstance {\n const config = resolveConfig(partial);\n\n const app = Fastify({\n logger: config.logLevel !== 'silent' ? { level: config.logLevel ?? 'info' } : false,\n });\n\n // Register routes\n app.register(healthRoute);\n app.register(createEvaluateRoute(config));\n\n // Global error handler\n app.setErrorHandler((error: FastifyError | Error, _request, reply) => {\n if ('validation' in error && (error as FastifyError).validation) {\n return reply.status(400).send({\n error: 'Validation Error',\n message: error.message,\n statusCode: 400,\n });\n }\n\n if (error instanceof ValidationError) {\n return reply.status(400).send({\n error: 'Validation Error',\n message: error.message,\n code: error.code,\n reasons: error.reasons,\n statusCode: 400,\n });\n }\n\n if (error instanceof RuleConflictError) {\n return reply.status(409).send({\n error: 'Rule Conflict',\n message: error.message,\n code: error.code,\n ruleIds: error.ruleIds,\n statusCode: 409,\n });\n }\n\n if (error instanceof SnapshotFailureError) {\n return reply.status(503).send({\n error: 'Snapshot Failure',\n message: error.message,\n code: error.code,\n statusCode: 503,\n });\n }\n\n if (error instanceof PPEError) {\n return reply.status(422).send({\n error: 'Processing Error',\n message: error.message,\n code: error.code,\n statusCode: 422,\n });\n }\n\n return reply.status(500).send({\n error: 'Internal Server Error',\n message: 'An unexpected error occurred',\n statusCode: 500,\n });\n });\n\n return app;\n}\n","import type { PPEPlugin, DSLEvaluator, ISnapshotAdapter } from '@run-iq/core';\n\nexport interface ServerConfig {\n readonly port: number;\n readonly host: string;\n readonly plugins: PPEPlugin[];\n readonly dsls: DSLEvaluator[];\n readonly snapshot?: ISnapshotAdapter | undefined;\n readonly strict?: boolean | undefined;\n readonly timeout?:\n | {\n readonly dsl?: number | undefined;\n readonly hook?: number | undefined;\n readonly pipeline?: number | undefined;\n }\n | undefined;\n readonly logLevel?: 'info' | 'warn' | 'error' | 'silent' | undefined;\n}\n\nconst DEFAULT_PORT = 3000;\nconst DEFAULT_HOST = '0.0.0.0';\nconst DEFAULT_LOG_LEVEL = 'info';\n\nexport function resolveConfig(\n partial: Partial<ServerConfig> & Pick<ServerConfig, 'plugins' | 'dsls'>,\n): ServerConfig {\n return {\n port: partial.port ?? DEFAULT_PORT,\n host: partial.host ?? DEFAULT_HOST,\n plugins: partial.plugins,\n dsls: partial.dsls,\n snapshot: partial.snapshot,\n strict: partial.strict ?? true,\n timeout: partial.timeout,\n logLevel: partial.logLevel ?? DEFAULT_LOG_LEVEL,\n };\n}\n","import type { FastifyInstance } from 'fastify';\n\nconst ENGINE_VERSION = '0.1.2';\n\nexport async function healthRoute(app: FastifyInstance): Promise<void> {\n app.get('/health', async () => {\n return { status: 'ok', engine: ENGINE_VERSION };\n });\n}\n","import type { FastifyInstance, FastifyPluginAsync } from 'fastify';\nimport { PPEEngine, hydrateRules } from '@run-iq/core';\nimport type { PPEEngineConfig, EvaluationInput } from '@run-iq/core';\nimport type { ServerConfig } from '../config.js';\nimport { evaluateRequestSchema } from '../schemas/evaluate.js';\n\ninterface EvaluateBody {\n rules: Record<string, unknown>[];\n input: {\n requestId: string;\n data: Record<string, unknown>;\n meta: {\n tenantId: string;\n userId?: string;\n tags?: string[];\n context?: Record<string, unknown>;\n effectiveDate?: string;\n };\n };\n}\n\nexport function createEvaluateRoute(config: ServerConfig): FastifyPluginAsync {\n return async function evaluateRoute(app: FastifyInstance): Promise<void> {\n const engineConfig: PPEEngineConfig = {\n plugins: config.plugins,\n dsls: config.dsls,\n snapshot: config.snapshot,\n strict: config.strict,\n timeout: config.timeout,\n dryRun: config.snapshot == null,\n };\n\n const engine = new PPEEngine(engineConfig);\n\n app.post<{ Body: EvaluateBody }>(\n '/evaluate',\n {\n schema: {\n body: evaluateRequestSchema,\n },\n },\n async (request) => {\n const { rules: rawRules, input: rawInput } = request.body;\n\n const rules = hydrateRules(rawRules);\n\n const input: EvaluationInput = {\n requestId: rawInput.requestId,\n data: rawInput.data,\n meta: {\n tenantId: rawInput.meta.tenantId,\n userId: rawInput.meta.userId,\n tags: rawInput.meta.tags,\n context: rawInput.meta.context,\n effectiveDate: rawInput.meta.effectiveDate\n ? new Date(rawInput.meta.effectiveDate)\n : undefined,\n },\n };\n\n const result = await engine.evaluate(rules, input);\n\n return result;\n },\n );\n };\n}\n","export const evaluateRequestSchema = {\n type: 'object',\n required: ['rules', 'input'],\n properties: {\n rules: {\n type: 'array',\n items: {\n type: 'object',\n required: [\n 'id',\n 'version',\n 'model',\n 'params',\n 'priority',\n 'effectiveFrom',\n 'tags',\n 'checksum',\n ],\n properties: {\n id: { type: 'string' },\n version: { type: 'number' },\n model: { type: 'string' },\n params: {},\n condition: {\n type: 'object',\n properties: {\n dsl: { type: 'string' },\n value: {},\n },\n },\n priority: { type: 'number' },\n effectiveFrom: { type: 'string' },\n effectiveUntil: { type: ['string', 'null'] },\n tags: { type: 'array', items: { type: 'string' } },\n checksum: { type: 'string' },\n schemaVersion: { type: 'string' },\n },\n },\n },\n input: {\n type: 'object',\n required: ['requestId', 'data', 'meta'],\n properties: {\n requestId: { type: 'string' },\n data: { type: 'object' },\n meta: {\n type: 'object',\n required: ['tenantId'],\n properties: {\n tenantId: { type: 'string' },\n userId: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n context: { type: 'object' },\n effectiveDate: { type: 'string' },\n },\n },\n },\n },\n },\n} as const;\n\nexport const evaluateResponseSchema = {\n type: 'object',\n properties: {\n requestId: { type: 'string' },\n value: {},\n breakdown: { type: 'array' },\n appliedRules: { type: 'array' },\n skippedRules: { type: 'array' },\n trace: { type: 'object' },\n snapshotId: { type: 'string' },\n engineVersion: { type: 'string' },\n pluginVersions: { type: 'object' },\n dslVersions: { type: 'object' },\n timestamp: { type: 'string' },\n meta: { type: 'object' },\n },\n} as const;\n","import type { ServerConfig } from './config.js';\nimport { createApp } from './app.js';\nimport { resolveConfig } from './config.js';\n\nexport async function start(\n partial: Partial<ServerConfig> & Pick<ServerConfig, 'plugins' | 'dsls'>,\n): Promise<void> {\n const config = resolveConfig(partial);\n const app = createApp(partial);\n\n const shutdown = async (signal: string): Promise<void> => {\n app.log.info(`Received ${signal}, shutting down gracefully…`);\n await app.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => void shutdown('SIGINT'));\n process.on('SIGTERM', () => void shutdown('SIGTERM'));\n\n await app.listen({ port: config.port, host: config.host });\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,330 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/standalone.ts
31
+ var standalone_exports = {};
32
+ __export(standalone_exports, {
33
+ loadDSLs: () => loadDSLs,
34
+ loadPlugins: () => loadPlugins,
35
+ parseList: () => parseList,
36
+ parseLogLevel: () => parseLogLevel
37
+ });
38
+ module.exports = __toCommonJS(standalone_exports);
39
+
40
+ // src/app.ts
41
+ var import_fastify = __toESM(require("fastify"), 1);
42
+ var import_core2 = require("@run-iq/core");
43
+
44
+ // src/config.ts
45
+ var DEFAULT_PORT = 3e3;
46
+ var DEFAULT_HOST = "0.0.0.0";
47
+ var DEFAULT_LOG_LEVEL = "info";
48
+ function resolveConfig(partial) {
49
+ return {
50
+ port: partial.port ?? DEFAULT_PORT,
51
+ host: partial.host ?? DEFAULT_HOST,
52
+ plugins: partial.plugins,
53
+ dsls: partial.dsls,
54
+ snapshot: partial.snapshot,
55
+ strict: partial.strict ?? true,
56
+ timeout: partial.timeout,
57
+ logLevel: partial.logLevel ?? DEFAULT_LOG_LEVEL
58
+ };
59
+ }
60
+
61
+ // src/routes/health.ts
62
+ var ENGINE_VERSION = "0.1.2";
63
+ async function healthRoute(app) {
64
+ app.get("/health", async () => {
65
+ return { status: "ok", engine: ENGINE_VERSION };
66
+ });
67
+ }
68
+
69
+ // src/routes/evaluate.ts
70
+ var import_core = require("@run-iq/core");
71
+
72
+ // src/schemas/evaluate.ts
73
+ var evaluateRequestSchema = {
74
+ type: "object",
75
+ required: ["rules", "input"],
76
+ properties: {
77
+ rules: {
78
+ type: "array",
79
+ items: {
80
+ type: "object",
81
+ required: [
82
+ "id",
83
+ "version",
84
+ "model",
85
+ "params",
86
+ "priority",
87
+ "effectiveFrom",
88
+ "tags",
89
+ "checksum"
90
+ ],
91
+ properties: {
92
+ id: { type: "string" },
93
+ version: { type: "number" },
94
+ model: { type: "string" },
95
+ params: {},
96
+ condition: {
97
+ type: "object",
98
+ properties: {
99
+ dsl: { type: "string" },
100
+ value: {}
101
+ }
102
+ },
103
+ priority: { type: "number" },
104
+ effectiveFrom: { type: "string" },
105
+ effectiveUntil: { type: ["string", "null"] },
106
+ tags: { type: "array", items: { type: "string" } },
107
+ checksum: { type: "string" },
108
+ schemaVersion: { type: "string" }
109
+ }
110
+ }
111
+ },
112
+ input: {
113
+ type: "object",
114
+ required: ["requestId", "data", "meta"],
115
+ properties: {
116
+ requestId: { type: "string" },
117
+ data: { type: "object" },
118
+ meta: {
119
+ type: "object",
120
+ required: ["tenantId"],
121
+ properties: {
122
+ tenantId: { type: "string" },
123
+ userId: { type: "string" },
124
+ tags: { type: "array", items: { type: "string" } },
125
+ context: { type: "object" },
126
+ effectiveDate: { type: "string" }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+ };
133
+
134
+ // src/routes/evaluate.ts
135
+ function createEvaluateRoute(config) {
136
+ return async function evaluateRoute(app) {
137
+ const engineConfig = {
138
+ plugins: config.plugins,
139
+ dsls: config.dsls,
140
+ snapshot: config.snapshot,
141
+ strict: config.strict,
142
+ timeout: config.timeout,
143
+ dryRun: config.snapshot == null
144
+ };
145
+ const engine = new import_core.PPEEngine(engineConfig);
146
+ app.post(
147
+ "/evaluate",
148
+ {
149
+ schema: {
150
+ body: evaluateRequestSchema
151
+ }
152
+ },
153
+ async (request) => {
154
+ const { rules: rawRules, input: rawInput } = request.body;
155
+ const rules = (0, import_core.hydrateRules)(rawRules);
156
+ const input = {
157
+ requestId: rawInput.requestId,
158
+ data: rawInput.data,
159
+ meta: {
160
+ tenantId: rawInput.meta.tenantId,
161
+ userId: rawInput.meta.userId,
162
+ tags: rawInput.meta.tags,
163
+ context: rawInput.meta.context,
164
+ effectiveDate: rawInput.meta.effectiveDate ? new Date(rawInput.meta.effectiveDate) : void 0
165
+ }
166
+ };
167
+ const result = await engine.evaluate(rules, input);
168
+ return result;
169
+ }
170
+ );
171
+ };
172
+ }
173
+
174
+ // src/app.ts
175
+ function createApp(partial) {
176
+ const config = resolveConfig(partial);
177
+ const app = (0, import_fastify.default)({
178
+ logger: config.logLevel !== "silent" ? { level: config.logLevel ?? "info" } : false
179
+ });
180
+ app.register(healthRoute);
181
+ app.register(createEvaluateRoute(config));
182
+ app.setErrorHandler((error, _request, reply) => {
183
+ if ("validation" in error && error.validation) {
184
+ return reply.status(400).send({
185
+ error: "Validation Error",
186
+ message: error.message,
187
+ statusCode: 400
188
+ });
189
+ }
190
+ if (error instanceof import_core2.ValidationError) {
191
+ return reply.status(400).send({
192
+ error: "Validation Error",
193
+ message: error.message,
194
+ code: error.code,
195
+ reasons: error.reasons,
196
+ statusCode: 400
197
+ });
198
+ }
199
+ if (error instanceof import_core2.RuleConflictError) {
200
+ return reply.status(409).send({
201
+ error: "Rule Conflict",
202
+ message: error.message,
203
+ code: error.code,
204
+ ruleIds: error.ruleIds,
205
+ statusCode: 409
206
+ });
207
+ }
208
+ if (error instanceof import_core2.SnapshotFailureError) {
209
+ return reply.status(503).send({
210
+ error: "Snapshot Failure",
211
+ message: error.message,
212
+ code: error.code,
213
+ statusCode: 503
214
+ });
215
+ }
216
+ if (error instanceof import_core2.PPEError) {
217
+ return reply.status(422).send({
218
+ error: "Processing Error",
219
+ message: error.message,
220
+ code: error.code,
221
+ statusCode: 422
222
+ });
223
+ }
224
+ return reply.status(500).send({
225
+ error: "Internal Server Error",
226
+ message: "An unexpected error occurred",
227
+ statusCode: 500
228
+ });
229
+ });
230
+ return app;
231
+ }
232
+
233
+ // src/server.ts
234
+ async function start(partial) {
235
+ const config = resolveConfig(partial);
236
+ const app = createApp(partial);
237
+ const shutdown = async (signal) => {
238
+ app.log.info(`Received ${signal}, shutting down gracefully\u2026`);
239
+ await app.close();
240
+ process.exit(0);
241
+ };
242
+ process.on("SIGINT", () => void shutdown("SIGINT"));
243
+ process.on("SIGTERM", () => void shutdown("SIGTERM"));
244
+ await app.listen({ port: config.port, host: config.host });
245
+ }
246
+
247
+ // src/standalone.ts
248
+ var PLUGIN_MAP = {
249
+ fiscal: "@run-iq/plugin-fiscal"
250
+ };
251
+ var DSL_MAP = {
252
+ jsonlogic: "@run-iq/dsl-jsonlogic"
253
+ };
254
+ function parseList(value) {
255
+ if (!value) return [];
256
+ return value.split(",").map((s) => s.trim()).filter(Boolean);
257
+ }
258
+ function parseLogLevel(value) {
259
+ const valid = ["info", "warn", "error", "silent"];
260
+ if (value && valid.includes(value)) {
261
+ return value;
262
+ }
263
+ return "info";
264
+ }
265
+ async function loadPlugins(names) {
266
+ const plugins = [];
267
+ for (const name of names) {
268
+ const pkg = PLUGIN_MAP[name];
269
+ if (!pkg) {
270
+ console.warn(`Unknown plugin "${name}", skipping.`);
271
+ continue;
272
+ }
273
+ try {
274
+ const mod = await import(pkg);
275
+ const PluginClass = mod["default"] ?? mod[Object.keys(mod)[0]];
276
+ if (typeof PluginClass === "function") {
277
+ plugins.push(new PluginClass());
278
+ }
279
+ } catch {
280
+ console.warn(`Plugin "${name}" (${pkg}) not installed, skipping.`);
281
+ }
282
+ }
283
+ return plugins;
284
+ }
285
+ async function loadDSLs(names) {
286
+ const dsls = [];
287
+ for (const name of names) {
288
+ const pkg = DSL_MAP[name];
289
+ if (!pkg) {
290
+ console.warn(`Unknown DSL "${name}", skipping.`);
291
+ continue;
292
+ }
293
+ try {
294
+ const mod = await import(pkg);
295
+ const EvaluatorClass = mod["default"] ?? mod[Object.keys(mod)[0]];
296
+ if (typeof EvaluatorClass === "function") {
297
+ dsls.push(new EvaluatorClass());
298
+ }
299
+ } catch {
300
+ console.warn(`DSL "${name}" (${pkg}) not installed, skipping.`);
301
+ }
302
+ }
303
+ return dsls;
304
+ }
305
+ async function main() {
306
+ const port = Number(process.env["PORT"]) || 3e3;
307
+ const host = process.env["HOST"] ?? "0.0.0.0";
308
+ const logLevel = parseLogLevel(process.env["LOG_LEVEL"]);
309
+ const strict = process.env["STRICT"] !== "false";
310
+ const pluginNames = parseList(process.env["PLUGINS"]);
311
+ const dslNames = parseList(process.env["DSLS"]);
312
+ const plugins = await loadPlugins(pluginNames);
313
+ const dsls = await loadDSLs(dslNames);
314
+ console.log(
315
+ `Starting @run-iq/server \u2014 port=${String(port)} host=${host} plugins=[${plugins.map((p) => p.name).join(",")}] dsls=[${dsls.map((d) => d.dsl).join(",")}]`
316
+ );
317
+ await start({ port, host, logLevel, strict, plugins, dsls });
318
+ }
319
+ main().catch((err) => {
320
+ console.error("Failed to start @run-iq/server:", err);
321
+ process.exit(1);
322
+ });
323
+ // Annotate the CommonJS export names for ESM import in node:
324
+ 0 && (module.exports = {
325
+ loadDSLs,
326
+ loadPlugins,
327
+ parseList,
328
+ parseLogLevel
329
+ });
330
+ //# sourceMappingURL=standalone.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/standalone.ts","../src/app.ts","../src/config.ts","../src/routes/health.ts","../src/routes/evaluate.ts","../src/schemas/evaluate.ts","../src/server.ts"],"sourcesContent":["/* eslint-disable no-console */\n/**\n * Standalone entry point for Docker / direct `node dist/standalone.js` usage.\n *\n * Reads configuration from environment variables:\n * PORT – HTTP port (default 3000)\n * HOST – Bind address (default 0.0.0.0)\n * LOG_LEVEL – info|warn|error|silent (default info)\n * STRICT – Snapshot strict mode (default true)\n * PLUGINS – Comma-separated list (e.g. \"fiscal\")\n * DSLS – Comma-separated list (e.g. \"jsonlogic\")\n */\n\nimport type { PPEPlugin, DSLEvaluator } from '@run-iq/core';\nimport { start } from './server.js';\n\nconst PLUGIN_MAP: Record<string, string> = {\n fiscal: '@run-iq/plugin-fiscal',\n};\n\nconst DSL_MAP: Record<string, string> = {\n jsonlogic: '@run-iq/dsl-jsonlogic',\n};\n\nexport function parseList(value: string | undefined): string[] {\n if (!value) return [];\n return value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nexport function parseLogLevel(value: string | undefined): 'info' | 'warn' | 'error' | 'silent' {\n const valid = ['info', 'warn', 'error', 'silent'] as const;\n if (value && (valid as readonly string[]).includes(value)) {\n return value as (typeof valid)[number];\n }\n return 'info';\n}\n\nexport async function loadPlugins(names: string[]): Promise<PPEPlugin[]> {\n const plugins: PPEPlugin[] = [];\n for (const name of names) {\n const pkg = PLUGIN_MAP[name];\n if (!pkg) {\n console.warn(`Unknown plugin \"${name}\", skipping.`);\n continue;\n }\n try {\n const mod: Record<string, unknown> = await import(pkg);\n const PluginClass = mod['default'] ?? mod[Object.keys(mod)[0]!];\n if (typeof PluginClass === 'function') {\n plugins.push(new (PluginClass as new () => PPEPlugin)());\n }\n } catch {\n console.warn(`Plugin \"${name}\" (${pkg}) not installed, skipping.`);\n }\n }\n return plugins;\n}\n\nexport async function loadDSLs(names: string[]): Promise<DSLEvaluator[]> {\n const dsls: DSLEvaluator[] = [];\n for (const name of names) {\n const pkg = DSL_MAP[name];\n if (!pkg) {\n console.warn(`Unknown DSL \"${name}\", skipping.`);\n continue;\n }\n try {\n const mod: Record<string, unknown> = await import(pkg);\n const EvaluatorClass = mod['default'] ?? mod[Object.keys(mod)[0]!];\n if (typeof EvaluatorClass === 'function') {\n dsls.push(new (EvaluatorClass as new () => DSLEvaluator)());\n }\n } catch {\n console.warn(`DSL \"${name}\" (${pkg}) not installed, skipping.`);\n }\n }\n return dsls;\n}\n\nasync function main(): Promise<void> {\n const port = Number(process.env['PORT']) || 3000;\n const host = process.env['HOST'] ?? '0.0.0.0';\n const logLevel = parseLogLevel(process.env['LOG_LEVEL']);\n const strict = process.env['STRICT'] !== 'false';\n\n const pluginNames = parseList(process.env['PLUGINS']);\n const dslNames = parseList(process.env['DSLS']);\n\n const plugins = await loadPlugins(pluginNames);\n const dsls = await loadDSLs(dslNames);\n\n console.log(\n `Starting @run-iq/server — port=${String(port)} host=${host} plugins=[${plugins.map((p) => p.name).join(',')}] dsls=[${dsls.map((d) => d.dsl).join(',')}]`,\n );\n\n await start({ port, host, logLevel, strict, plugins, dsls });\n}\n\nmain().catch((err: unknown) => {\n console.error('Failed to start @run-iq/server:', err);\n process.exit(1);\n});\n","import Fastify from 'fastify';\nimport type { FastifyInstance, FastifyError } from 'fastify';\nimport { PPEError, ValidationError, RuleConflictError, SnapshotFailureError } from '@run-iq/core';\nimport { type ServerConfig, resolveConfig } from './config.js';\nimport { healthRoute } from './routes/health.js';\nimport { createEvaluateRoute } from './routes/evaluate.js';\n\nexport function createApp(\n partial: Partial<ServerConfig> & Pick<ServerConfig, 'plugins' | 'dsls'>,\n): FastifyInstance {\n const config = resolveConfig(partial);\n\n const app = Fastify({\n logger: config.logLevel !== 'silent' ? { level: config.logLevel ?? 'info' } : false,\n });\n\n // Register routes\n app.register(healthRoute);\n app.register(createEvaluateRoute(config));\n\n // Global error handler\n app.setErrorHandler((error: FastifyError | Error, _request, reply) => {\n if ('validation' in error && (error as FastifyError).validation) {\n return reply.status(400).send({\n error: 'Validation Error',\n message: error.message,\n statusCode: 400,\n });\n }\n\n if (error instanceof ValidationError) {\n return reply.status(400).send({\n error: 'Validation Error',\n message: error.message,\n code: error.code,\n reasons: error.reasons,\n statusCode: 400,\n });\n }\n\n if (error instanceof RuleConflictError) {\n return reply.status(409).send({\n error: 'Rule Conflict',\n message: error.message,\n code: error.code,\n ruleIds: error.ruleIds,\n statusCode: 409,\n });\n }\n\n if (error instanceof SnapshotFailureError) {\n return reply.status(503).send({\n error: 'Snapshot Failure',\n message: error.message,\n code: error.code,\n statusCode: 503,\n });\n }\n\n if (error instanceof PPEError) {\n return reply.status(422).send({\n error: 'Processing Error',\n message: error.message,\n code: error.code,\n statusCode: 422,\n });\n }\n\n return reply.status(500).send({\n error: 'Internal Server Error',\n message: 'An unexpected error occurred',\n statusCode: 500,\n });\n });\n\n return app;\n}\n","import type { PPEPlugin, DSLEvaluator, ISnapshotAdapter } from '@run-iq/core';\n\nexport interface ServerConfig {\n readonly port: number;\n readonly host: string;\n readonly plugins: PPEPlugin[];\n readonly dsls: DSLEvaluator[];\n readonly snapshot?: ISnapshotAdapter | undefined;\n readonly strict?: boolean | undefined;\n readonly timeout?:\n | {\n readonly dsl?: number | undefined;\n readonly hook?: number | undefined;\n readonly pipeline?: number | undefined;\n }\n | undefined;\n readonly logLevel?: 'info' | 'warn' | 'error' | 'silent' | undefined;\n}\n\nconst DEFAULT_PORT = 3000;\nconst DEFAULT_HOST = '0.0.0.0';\nconst DEFAULT_LOG_LEVEL = 'info';\n\nexport function resolveConfig(\n partial: Partial<ServerConfig> & Pick<ServerConfig, 'plugins' | 'dsls'>,\n): ServerConfig {\n return {\n port: partial.port ?? DEFAULT_PORT,\n host: partial.host ?? DEFAULT_HOST,\n plugins: partial.plugins,\n dsls: partial.dsls,\n snapshot: partial.snapshot,\n strict: partial.strict ?? true,\n timeout: partial.timeout,\n logLevel: partial.logLevel ?? DEFAULT_LOG_LEVEL,\n };\n}\n","import type { FastifyInstance } from 'fastify';\n\nconst ENGINE_VERSION = '0.1.2';\n\nexport async function healthRoute(app: FastifyInstance): Promise<void> {\n app.get('/health', async () => {\n return { status: 'ok', engine: ENGINE_VERSION };\n });\n}\n","import type { FastifyInstance, FastifyPluginAsync } from 'fastify';\nimport { PPEEngine, hydrateRules } from '@run-iq/core';\nimport type { PPEEngineConfig, EvaluationInput } from '@run-iq/core';\nimport type { ServerConfig } from '../config.js';\nimport { evaluateRequestSchema } from '../schemas/evaluate.js';\n\ninterface EvaluateBody {\n rules: Record<string, unknown>[];\n input: {\n requestId: string;\n data: Record<string, unknown>;\n meta: {\n tenantId: string;\n userId?: string;\n tags?: string[];\n context?: Record<string, unknown>;\n effectiveDate?: string;\n };\n };\n}\n\nexport function createEvaluateRoute(config: ServerConfig): FastifyPluginAsync {\n return async function evaluateRoute(app: FastifyInstance): Promise<void> {\n const engineConfig: PPEEngineConfig = {\n plugins: config.plugins,\n dsls: config.dsls,\n snapshot: config.snapshot,\n strict: config.strict,\n timeout: config.timeout,\n dryRun: config.snapshot == null,\n };\n\n const engine = new PPEEngine(engineConfig);\n\n app.post<{ Body: EvaluateBody }>(\n '/evaluate',\n {\n schema: {\n body: evaluateRequestSchema,\n },\n },\n async (request) => {\n const { rules: rawRules, input: rawInput } = request.body;\n\n const rules = hydrateRules(rawRules);\n\n const input: EvaluationInput = {\n requestId: rawInput.requestId,\n data: rawInput.data,\n meta: {\n tenantId: rawInput.meta.tenantId,\n userId: rawInput.meta.userId,\n tags: rawInput.meta.tags,\n context: rawInput.meta.context,\n effectiveDate: rawInput.meta.effectiveDate\n ? new Date(rawInput.meta.effectiveDate)\n : undefined,\n },\n };\n\n const result = await engine.evaluate(rules, input);\n\n return result;\n },\n );\n };\n}\n","export const evaluateRequestSchema = {\n type: 'object',\n required: ['rules', 'input'],\n properties: {\n rules: {\n type: 'array',\n items: {\n type: 'object',\n required: [\n 'id',\n 'version',\n 'model',\n 'params',\n 'priority',\n 'effectiveFrom',\n 'tags',\n 'checksum',\n ],\n properties: {\n id: { type: 'string' },\n version: { type: 'number' },\n model: { type: 'string' },\n params: {},\n condition: {\n type: 'object',\n properties: {\n dsl: { type: 'string' },\n value: {},\n },\n },\n priority: { type: 'number' },\n effectiveFrom: { type: 'string' },\n effectiveUntil: { type: ['string', 'null'] },\n tags: { type: 'array', items: { type: 'string' } },\n checksum: { type: 'string' },\n schemaVersion: { type: 'string' },\n },\n },\n },\n input: {\n type: 'object',\n required: ['requestId', 'data', 'meta'],\n properties: {\n requestId: { type: 'string' },\n data: { type: 'object' },\n meta: {\n type: 'object',\n required: ['tenantId'],\n properties: {\n tenantId: { type: 'string' },\n userId: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n context: { type: 'object' },\n effectiveDate: { type: 'string' },\n },\n },\n },\n },\n },\n} as const;\n\nexport const evaluateResponseSchema = {\n type: 'object',\n properties: {\n requestId: { type: 'string' },\n value: {},\n breakdown: { type: 'array' },\n appliedRules: { type: 'array' },\n skippedRules: { type: 'array' },\n trace: { type: 'object' },\n snapshotId: { type: 'string' },\n engineVersion: { type: 'string' },\n pluginVersions: { type: 'object' },\n dslVersions: { type: 'object' },\n timestamp: { type: 'string' },\n meta: { type: 'object' },\n },\n} as const;\n","import type { ServerConfig } from './config.js';\nimport { createApp } from './app.js';\nimport { resolveConfig } from './config.js';\n\nexport async function start(\n partial: Partial<ServerConfig> & Pick<ServerConfig, 'plugins' | 'dsls'>,\n): Promise<void> {\n const config = resolveConfig(partial);\n const app = createApp(partial);\n\n const shutdown = async (signal: string): Promise<void> => {\n app.log.info(`Received ${signal}, shutting down gracefully…`);\n await app.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => void shutdown('SIGINT'));\n process.on('SIGTERM', () => void shutdown('SIGTERM'));\n\n await app.listen({ port: config.port, host: config.host });\n}\n"],"mappings":"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","names":["import_core","Fastify"]}
@@ -0,0 +1,20 @@
1
+ import { DSLEvaluator, PPEPlugin } from '@run-iq/core';
2
+
3
+ /**
4
+ * Standalone entry point for Docker / direct `node dist/standalone.js` usage.
5
+ *
6
+ * Reads configuration from environment variables:
7
+ * PORT – HTTP port (default 3000)
8
+ * HOST – Bind address (default 0.0.0.0)
9
+ * LOG_LEVEL – info|warn|error|silent (default info)
10
+ * STRICT – Snapshot strict mode (default true)
11
+ * PLUGINS – Comma-separated list (e.g. "fiscal")
12
+ * DSLS – Comma-separated list (e.g. "jsonlogic")
13
+ */
14
+
15
+ declare function parseList(value: string | undefined): string[];
16
+ declare function parseLogLevel(value: string | undefined): 'info' | 'warn' | 'error' | 'silent';
17
+ declare function loadPlugins(names: string[]): Promise<PPEPlugin[]>;
18
+ declare function loadDSLs(names: string[]): Promise<DSLEvaluator[]>;
19
+
20
+ export { loadDSLs, loadPlugins, parseList, parseLogLevel };
@@ -0,0 +1,20 @@
1
+ import { DSLEvaluator, PPEPlugin } from '@run-iq/core';
2
+
3
+ /**
4
+ * Standalone entry point for Docker / direct `node dist/standalone.js` usage.
5
+ *
6
+ * Reads configuration from environment variables:
7
+ * PORT – HTTP port (default 3000)
8
+ * HOST – Bind address (default 0.0.0.0)
9
+ * LOG_LEVEL – info|warn|error|silent (default info)
10
+ * STRICT – Snapshot strict mode (default true)
11
+ * PLUGINS – Comma-separated list (e.g. "fiscal")
12
+ * DSLS – Comma-separated list (e.g. "jsonlogic")
13
+ */
14
+
15
+ declare function parseList(value: string | undefined): string[];
16
+ declare function parseLogLevel(value: string | undefined): 'info' | 'warn' | 'error' | 'silent';
17
+ declare function loadPlugins(names: string[]): Promise<PPEPlugin[]>;
18
+ declare function loadDSLs(names: string[]): Promise<DSLEvaluator[]>;
19
+
20
+ export { loadDSLs, loadPlugins, parseList, parseLogLevel };