@fulmenhq/tsfulmen 0.2.2 → 0.2.3
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/CHANGELOG.md +28 -0
- package/README.md +9 -8
- package/dist/appidentity/index.d.ts +30 -108
- package/dist/appidentity/index.js +251 -8
- package/dist/appidentity/index.js.map +1 -1
- package/dist/config/index.d.ts +46 -1
- package/dist/config/index.js +309 -10
- package/dist/config/index.js.map +1 -1
- package/dist/crucible/index.js +249 -7
- package/dist/crucible/index.js.map +1 -1
- package/dist/errors/index.js +249 -7
- package/dist/errors/index.js.map +1 -1
- package/dist/foundry/index.d.ts +2 -1
- package/dist/foundry/index.js +250 -8
- package/dist/foundry/index.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +252 -9
- package/dist/index.js.map +1 -1
- package/dist/pathfinder/index.js +249 -7
- package/dist/pathfinder/index.js.map +1 -1
- package/dist/reports/license-inventory.csv +29 -23
- package/dist/schema/index.d.ts +14 -1
- package/dist/schema/index.js +250 -8
- package/dist/schema/index.js.map +1 -1
- package/dist/signals/index.d.ts +483 -395
- package/dist/signals/index.js +250 -8
- package/dist/signals/index.js.map +1 -1
- package/dist/telemetry/http/index.js +250 -7
- package/dist/telemetry/http/index.js.map +1 -1
- package/dist/telemetry/index.js +249 -7
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/prometheus/index.js +251 -7
- package/dist/telemetry/prometheus/index.js.map +1 -1
- package/dist/types-Dv5TERCM.d.ts +108 -0
- package/package.json +8 -8
package/dist/pathfinder/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { crc32, xxhash128, createXXHash128, createCRC32 } from 'hash-wasm';
|
|
2
2
|
import { createHash, randomUUID } from 'crypto';
|
|
3
|
+
import addFormats from 'ajv-formats';
|
|
3
4
|
import { spawn } from 'child_process';
|
|
4
5
|
import fs2, { readFile, writeFile, access, mkdir, lstat, realpath } from 'fs/promises';
|
|
5
6
|
import { parse, stringify } from 'yaml';
|
|
@@ -10,7 +11,6 @@ import Ajv from 'ajv';
|
|
|
10
11
|
import Ajv2019 from 'ajv/dist/2019';
|
|
11
12
|
import Ajv2020 from 'ajv/dist/2020';
|
|
12
13
|
import AjvDraft04 from 'ajv-draft-04';
|
|
13
|
-
import addFormats from 'ajv-formats';
|
|
14
14
|
import { Readable } from 'stream';
|
|
15
15
|
import picomatch from 'picomatch';
|
|
16
16
|
import { suggest as suggest$1, substringSimilarity, score as score$1, normalize as normalize$1, jaro_winkler, damerau_levenshtein, osa_distance, levenshtein } from '@3leaps/string-metrics-wasm';
|
|
@@ -409,6 +409,27 @@ var init_serialization = __esm({
|
|
|
409
409
|
init_severity();
|
|
410
410
|
}
|
|
411
411
|
});
|
|
412
|
+
function applyFulmenAjvFormats(ajv, options = {}) {
|
|
413
|
+
const mode = options.mode ?? "fast";
|
|
414
|
+
const formats = options.formats ?? DEFAULT_FORMATS;
|
|
415
|
+
addFormats(ajv, { mode, formats });
|
|
416
|
+
return ajv;
|
|
417
|
+
}
|
|
418
|
+
var DEFAULT_FORMATS;
|
|
419
|
+
var init_ajv_formats = __esm({
|
|
420
|
+
"src/schema/ajv-formats.ts"() {
|
|
421
|
+
DEFAULT_FORMATS = [
|
|
422
|
+
"date-time",
|
|
423
|
+
"email",
|
|
424
|
+
"hostname",
|
|
425
|
+
"ipv4",
|
|
426
|
+
"ipv6",
|
|
427
|
+
"uri",
|
|
428
|
+
"uri-reference",
|
|
429
|
+
"uuid"
|
|
430
|
+
];
|
|
431
|
+
}
|
|
432
|
+
});
|
|
412
433
|
|
|
413
434
|
// src/schema/errors.ts
|
|
414
435
|
var errors_exports = {};
|
|
@@ -1964,10 +1985,7 @@ function createAjv(dialect) {
|
|
|
1964
1985
|
// Enable async schema loading for YAML references
|
|
1965
1986
|
loadSchema: loadReferencedSchema
|
|
1966
1987
|
});
|
|
1967
|
-
|
|
1968
|
-
mode: "fast",
|
|
1969
|
-
formats: ["date-time", "email", "hostname", "ipv4", "ipv6", "uri", "uri-reference"]
|
|
1970
|
-
});
|
|
1988
|
+
applyFulmenAjvFormats(ajv);
|
|
1971
1989
|
return ajv;
|
|
1972
1990
|
}
|
|
1973
1991
|
async function getAjv(dialect) {
|
|
@@ -2213,6 +2231,7 @@ var ajvInstances, metaschemaReady, schemaCache;
|
|
|
2213
2231
|
var init_validator = __esm({
|
|
2214
2232
|
"src/schema/validator.ts"() {
|
|
2215
2233
|
init_telemetry();
|
|
2234
|
+
init_ajv_formats();
|
|
2216
2235
|
init_errors2();
|
|
2217
2236
|
init_registry();
|
|
2218
2237
|
init_utils();
|
|
@@ -4172,6 +4191,224 @@ var init_capabilities2 = __esm({
|
|
|
4172
4191
|
}
|
|
4173
4192
|
});
|
|
4174
4193
|
|
|
4194
|
+
// src/foundry/signals/config-reload-endpoint.ts
|
|
4195
|
+
function createConfigReloadEndpoint(options) {
|
|
4196
|
+
const { loader, validator, onReload: onReload2, auth, rateLimit, logger, telemetry } = options;
|
|
4197
|
+
return async (payload, req) => {
|
|
4198
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId2();
|
|
4199
|
+
const authResult = await auth(req);
|
|
4200
|
+
if (!authResult.authenticated) {
|
|
4201
|
+
if (logger) {
|
|
4202
|
+
logger.warn("Config reload endpoint: authentication failed", {
|
|
4203
|
+
correlation_id: correlationId,
|
|
4204
|
+
reason: authResult.reason
|
|
4205
|
+
});
|
|
4206
|
+
}
|
|
4207
|
+
if (telemetry) {
|
|
4208
|
+
telemetry.emit("fulmen.config.http_endpoint.auth_failed", {
|
|
4209
|
+
correlation_id: correlationId
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
return {
|
|
4213
|
+
status: "error",
|
|
4214
|
+
error: "authentication_failed",
|
|
4215
|
+
message: authResult.reason || "Authentication required",
|
|
4216
|
+
statusCode: 401
|
|
4217
|
+
};
|
|
4218
|
+
}
|
|
4219
|
+
const identity = authResult.identity || "unknown";
|
|
4220
|
+
if (rateLimit) {
|
|
4221
|
+
const rateLimitResult = await rateLimit(identity);
|
|
4222
|
+
if (!rateLimitResult.allowed) {
|
|
4223
|
+
if (logger) {
|
|
4224
|
+
logger.warn("Config reload endpoint: rate limit exceeded", {
|
|
4225
|
+
correlation_id: correlationId,
|
|
4226
|
+
identity
|
|
4227
|
+
});
|
|
4228
|
+
}
|
|
4229
|
+
if (telemetry) {
|
|
4230
|
+
telemetry.emit("fulmen.config.http_endpoint.rate_limited", {
|
|
4231
|
+
correlation_id: correlationId
|
|
4232
|
+
});
|
|
4233
|
+
}
|
|
4234
|
+
return {
|
|
4235
|
+
status: "error",
|
|
4236
|
+
error: "rate_limit_exceeded",
|
|
4237
|
+
message: "Rate limit exceeded. Please try again later.",
|
|
4238
|
+
statusCode: 429
|
|
4239
|
+
};
|
|
4240
|
+
}
|
|
4241
|
+
}
|
|
4242
|
+
if (telemetry) {
|
|
4243
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_requested", {
|
|
4244
|
+
correlation_id: correlationId
|
|
4245
|
+
});
|
|
4246
|
+
}
|
|
4247
|
+
try {
|
|
4248
|
+
const config = await loader();
|
|
4249
|
+
if (validator) {
|
|
4250
|
+
const validation = await validator(config);
|
|
4251
|
+
if (!validation.valid) {
|
|
4252
|
+
if (logger) {
|
|
4253
|
+
logger.warn("Config reload endpoint: validation failed", {
|
|
4254
|
+
correlation_id: correlationId,
|
|
4255
|
+
error_count: validation.errors?.length ?? 0
|
|
4256
|
+
});
|
|
4257
|
+
}
|
|
4258
|
+
if (telemetry) {
|
|
4259
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_rejected", {
|
|
4260
|
+
correlation_id: correlationId,
|
|
4261
|
+
reason: "validation_failed"
|
|
4262
|
+
});
|
|
4263
|
+
}
|
|
4264
|
+
return {
|
|
4265
|
+
status: "error",
|
|
4266
|
+
error: "validation_failed",
|
|
4267
|
+
message: "Configuration validation failed",
|
|
4268
|
+
validation_errors: validation.errors,
|
|
4269
|
+
statusCode: 422
|
|
4270
|
+
};
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
if (onReload2) {
|
|
4274
|
+
await onReload2(config);
|
|
4275
|
+
}
|
|
4276
|
+
if (telemetry) {
|
|
4277
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_accepted", {
|
|
4278
|
+
correlation_id: correlationId
|
|
4279
|
+
});
|
|
4280
|
+
}
|
|
4281
|
+
if (logger) {
|
|
4282
|
+
logger.info("Config reload endpoint: reload accepted", {
|
|
4283
|
+
correlation_id: correlationId,
|
|
4284
|
+
reason: payload.reason
|
|
4285
|
+
});
|
|
4286
|
+
}
|
|
4287
|
+
return {
|
|
4288
|
+
status: "reloaded",
|
|
4289
|
+
correlation_id: correlationId,
|
|
4290
|
+
message: "Configuration reloaded",
|
|
4291
|
+
statusCode: 200
|
|
4292
|
+
};
|
|
4293
|
+
} catch (error) {
|
|
4294
|
+
if (logger) {
|
|
4295
|
+
logger.warn("Config reload endpoint: reload failed", {
|
|
4296
|
+
correlation_id: correlationId,
|
|
4297
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4298
|
+
});
|
|
4299
|
+
}
|
|
4300
|
+
if (telemetry) {
|
|
4301
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_error", {
|
|
4302
|
+
correlation_id: correlationId,
|
|
4303
|
+
error_type: error instanceof Error ? error.constructor.name : "unknown"
|
|
4304
|
+
});
|
|
4305
|
+
}
|
|
4306
|
+
return {
|
|
4307
|
+
status: "error",
|
|
4308
|
+
error: "reload_failed",
|
|
4309
|
+
message: error instanceof Error ? error.message : String(error),
|
|
4310
|
+
statusCode: 500
|
|
4311
|
+
};
|
|
4312
|
+
}
|
|
4313
|
+
};
|
|
4314
|
+
}
|
|
4315
|
+
function generateCorrelationId2() {
|
|
4316
|
+
return `cfg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4317
|
+
}
|
|
4318
|
+
var init_config_reload_endpoint = __esm({
|
|
4319
|
+
"src/foundry/signals/config-reload-endpoint.ts"() {
|
|
4320
|
+
}
|
|
4321
|
+
});
|
|
4322
|
+
|
|
4323
|
+
// src/appidentity/runtime.ts
|
|
4324
|
+
function detectRuntime() {
|
|
4325
|
+
const versions = process.versions;
|
|
4326
|
+
if (typeof versions.bun === "string" && versions.bun.length > 0) {
|
|
4327
|
+
return { name: "bun", version: versions.bun };
|
|
4328
|
+
}
|
|
4329
|
+
if (typeof versions.node === "string" && versions.node.length > 0) {
|
|
4330
|
+
return { name: "node", version: versions.node };
|
|
4331
|
+
}
|
|
4332
|
+
return { name: "unknown" };
|
|
4333
|
+
}
|
|
4334
|
+
function buildRuntimeInfo(options = {}) {
|
|
4335
|
+
const runtime = detectRuntime();
|
|
4336
|
+
const serviceName = options.serviceName ?? options.identity?.app.binary_name ?? "unknown-service";
|
|
4337
|
+
const vendor = options.vendor ?? options.identity?.app.vendor;
|
|
4338
|
+
return {
|
|
4339
|
+
service: {
|
|
4340
|
+
name: serviceName,
|
|
4341
|
+
vendor,
|
|
4342
|
+
version: options.version
|
|
4343
|
+
},
|
|
4344
|
+
runtime,
|
|
4345
|
+
platform: {
|
|
4346
|
+
os: process.platform,
|
|
4347
|
+
arch: process.arch
|
|
4348
|
+
}
|
|
4349
|
+
};
|
|
4350
|
+
}
|
|
4351
|
+
var init_runtime = __esm({
|
|
4352
|
+
"src/appidentity/runtime.ts"() {
|
|
4353
|
+
}
|
|
4354
|
+
});
|
|
4355
|
+
|
|
4356
|
+
// src/foundry/signals/control-discovery-endpoint.ts
|
|
4357
|
+
function createControlDiscoveryEndpoint(options) {
|
|
4358
|
+
const { identity, version, endpoints, auth, authSummary, logger, telemetry } = options;
|
|
4359
|
+
return async (req) => {
|
|
4360
|
+
if (auth) {
|
|
4361
|
+
const authResult = await auth(req);
|
|
4362
|
+
if (!authResult.authenticated) {
|
|
4363
|
+
if (logger) {
|
|
4364
|
+
logger.warn("Control discovery endpoint: authentication failed", {
|
|
4365
|
+
reason: authResult.reason
|
|
4366
|
+
});
|
|
4367
|
+
}
|
|
4368
|
+
if (telemetry) {
|
|
4369
|
+
telemetry.emit("fulmen.control.discovery.auth_failed", {
|
|
4370
|
+
service: identity.app.binary_name
|
|
4371
|
+
});
|
|
4372
|
+
}
|
|
4373
|
+
return {
|
|
4374
|
+
status: "error",
|
|
4375
|
+
error: "authentication_failed",
|
|
4376
|
+
message: authResult.reason || "Authentication required",
|
|
4377
|
+
statusCode: 401
|
|
4378
|
+
};
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
if (telemetry) {
|
|
4382
|
+
telemetry.emit("fulmen.control.discovery.served", {
|
|
4383
|
+
service: identity.app.binary_name
|
|
4384
|
+
});
|
|
4385
|
+
}
|
|
4386
|
+
const runtime = buildRuntimeInfo({ identity, version });
|
|
4387
|
+
return {
|
|
4388
|
+
status: "ok",
|
|
4389
|
+
service: {
|
|
4390
|
+
name: identity.app.binary_name,
|
|
4391
|
+
vendor: identity.app.vendor,
|
|
4392
|
+
version
|
|
4393
|
+
},
|
|
4394
|
+
runtime: {
|
|
4395
|
+
name: runtime.runtime.name,
|
|
4396
|
+
version: runtime.runtime.version,
|
|
4397
|
+
platform: runtime.platform.os,
|
|
4398
|
+
arch: runtime.platform.arch
|
|
4399
|
+
},
|
|
4400
|
+
auth_summary: authSummary,
|
|
4401
|
+
endpoints,
|
|
4402
|
+
statusCode: 200
|
|
4403
|
+
};
|
|
4404
|
+
};
|
|
4405
|
+
}
|
|
4406
|
+
var init_control_discovery_endpoint = __esm({
|
|
4407
|
+
"src/foundry/signals/control-discovery-endpoint.ts"() {
|
|
4408
|
+
init_runtime();
|
|
4409
|
+
}
|
|
4410
|
+
});
|
|
4411
|
+
|
|
4175
4412
|
// src/foundry/signals/convenience.ts
|
|
4176
4413
|
async function onShutdown(manager, handler, options = {}) {
|
|
4177
4414
|
await manager.register("SIGTERM", handler, options);
|
|
@@ -4431,7 +4668,7 @@ var init_guards = __esm({
|
|
|
4431
4668
|
function createSignalEndpoint(options) {
|
|
4432
4669
|
const { manager, auth, rateLimit, logger, telemetry, allowedSignals } = options;
|
|
4433
4670
|
return async (payload, req) => {
|
|
4434
|
-
const correlationId = payload.correlation_id ??
|
|
4671
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId3();
|
|
4435
4672
|
const authResult = await auth(req);
|
|
4436
4673
|
if (!authResult.authenticated) {
|
|
4437
4674
|
if (logger) {
|
|
@@ -4554,7 +4791,7 @@ function normalizeSignalName(signal) {
|
|
|
4554
4791
|
}
|
|
4555
4792
|
return `SIG${upper}`;
|
|
4556
4793
|
}
|
|
4557
|
-
function
|
|
4794
|
+
function generateCorrelationId3() {
|
|
4558
4795
|
return `sig-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4559
4796
|
}
|
|
4560
4797
|
function createBearerTokenAuth(expectedToken) {
|
|
@@ -5021,6 +5258,8 @@ var init_signals = __esm({
|
|
|
5021
5258
|
"src/foundry/signals/index.ts"() {
|
|
5022
5259
|
init_capabilities2();
|
|
5023
5260
|
init_catalog();
|
|
5261
|
+
init_config_reload_endpoint();
|
|
5262
|
+
init_control_discovery_endpoint();
|
|
5024
5263
|
init_convenience();
|
|
5025
5264
|
init_double_tap();
|
|
5026
5265
|
init_guards();
|
|
@@ -5166,7 +5405,9 @@ __export(foundry_exports, {
|
|
|
5166
5405
|
clearMimeTypeCache: () => clearMimeTypeCache,
|
|
5167
5406
|
clearPatternCache: () => clearPatternCache,
|
|
5168
5407
|
createBearerTokenAuth: () => createBearerTokenAuth,
|
|
5408
|
+
createConfigReloadEndpoint: () => createConfigReloadEndpoint,
|
|
5169
5409
|
createConfigReloadHandler: () => createConfigReloadHandler,
|
|
5410
|
+
createControlDiscoveryEndpoint: () => createControlDiscoveryEndpoint,
|
|
5170
5411
|
createDoubleTapTracker: () => createDoubleTapTracker,
|
|
5171
5412
|
createSignalEndpoint: () => createSignalEndpoint,
|
|
5172
5413
|
createSignalManager: () => createSignalManager,
|
|
@@ -5889,6 +6130,7 @@ var init_cli = __esm({
|
|
|
5889
6130
|
// src/schema/index.ts
|
|
5890
6131
|
var init_schema = __esm({
|
|
5891
6132
|
"src/schema/index.ts"() {
|
|
6133
|
+
init_ajv_formats();
|
|
5892
6134
|
init_cli();
|
|
5893
6135
|
init_errors2();
|
|
5894
6136
|
init_export();
|