@fulmenhq/tsfulmen 0.2.2 → 0.2.4
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 +42 -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 +185 -40
- 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 +5 -5
package/dist/errors/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
+
import addFormats from 'ajv-formats';
|
|
2
3
|
import { spawn } from 'child_process';
|
|
3
4
|
import { readFile, access, mkdir, writeFile } from 'fs/promises';
|
|
4
5
|
import { parse, stringify } from 'yaml';
|
|
@@ -9,7 +10,6 @@ import Ajv from 'ajv';
|
|
|
9
10
|
import Ajv2019 from 'ajv/dist/2019';
|
|
10
11
|
import Ajv2020 from 'ajv/dist/2020';
|
|
11
12
|
import AjvDraft04 from 'ajv-draft-04';
|
|
12
|
-
import addFormats from 'ajv-formats';
|
|
13
13
|
import { Readable } from 'stream';
|
|
14
14
|
import picomatch from 'picomatch';
|
|
15
15
|
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';
|
|
@@ -173,6 +173,27 @@ var init_serialization = __esm({
|
|
|
173
173
|
init_severity();
|
|
174
174
|
}
|
|
175
175
|
});
|
|
176
|
+
function applyFulmenAjvFormats(ajv, options = {}) {
|
|
177
|
+
const mode = options.mode ?? "fast";
|
|
178
|
+
const formats = options.formats ?? DEFAULT_FORMATS;
|
|
179
|
+
addFormats(ajv, { mode, formats });
|
|
180
|
+
return ajv;
|
|
181
|
+
}
|
|
182
|
+
var DEFAULT_FORMATS;
|
|
183
|
+
var init_ajv_formats = __esm({
|
|
184
|
+
"src/schema/ajv-formats.ts"() {
|
|
185
|
+
DEFAULT_FORMATS = [
|
|
186
|
+
"date-time",
|
|
187
|
+
"email",
|
|
188
|
+
"hostname",
|
|
189
|
+
"ipv4",
|
|
190
|
+
"ipv6",
|
|
191
|
+
"uri",
|
|
192
|
+
"uri-reference",
|
|
193
|
+
"uuid"
|
|
194
|
+
];
|
|
195
|
+
}
|
|
196
|
+
});
|
|
176
197
|
|
|
177
198
|
// src/schema/errors.ts
|
|
178
199
|
var errors_exports = {};
|
|
@@ -1728,10 +1749,7 @@ function createAjv(dialect) {
|
|
|
1728
1749
|
// Enable async schema loading for YAML references
|
|
1729
1750
|
loadSchema: loadReferencedSchema
|
|
1730
1751
|
});
|
|
1731
|
-
|
|
1732
|
-
mode: "fast",
|
|
1733
|
-
formats: ["date-time", "email", "hostname", "ipv4", "ipv6", "uri", "uri-reference"]
|
|
1734
|
-
});
|
|
1752
|
+
applyFulmenAjvFormats(ajv);
|
|
1735
1753
|
return ajv;
|
|
1736
1754
|
}
|
|
1737
1755
|
async function getAjv(dialect) {
|
|
@@ -1977,6 +1995,7 @@ var ajvInstances, metaschemaReady, schemaCache;
|
|
|
1977
1995
|
var init_validator = __esm({
|
|
1978
1996
|
"src/schema/validator.ts"() {
|
|
1979
1997
|
init_telemetry();
|
|
1998
|
+
init_ajv_formats();
|
|
1980
1999
|
init_errors();
|
|
1981
2000
|
init_registry();
|
|
1982
2001
|
init_utils();
|
|
@@ -3936,6 +3955,224 @@ var init_capabilities2 = __esm({
|
|
|
3936
3955
|
}
|
|
3937
3956
|
});
|
|
3938
3957
|
|
|
3958
|
+
// src/foundry/signals/config-reload-endpoint.ts
|
|
3959
|
+
function createConfigReloadEndpoint(options) {
|
|
3960
|
+
const { loader, validator, onReload: onReload2, auth, rateLimit, logger, telemetry } = options;
|
|
3961
|
+
return async (payload, req) => {
|
|
3962
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId2();
|
|
3963
|
+
const authResult = await auth(req);
|
|
3964
|
+
if (!authResult.authenticated) {
|
|
3965
|
+
if (logger) {
|
|
3966
|
+
logger.warn("Config reload endpoint: authentication failed", {
|
|
3967
|
+
correlation_id: correlationId,
|
|
3968
|
+
reason: authResult.reason
|
|
3969
|
+
});
|
|
3970
|
+
}
|
|
3971
|
+
if (telemetry) {
|
|
3972
|
+
telemetry.emit("fulmen.config.http_endpoint.auth_failed", {
|
|
3973
|
+
correlation_id: correlationId
|
|
3974
|
+
});
|
|
3975
|
+
}
|
|
3976
|
+
return {
|
|
3977
|
+
status: "error",
|
|
3978
|
+
error: "authentication_failed",
|
|
3979
|
+
message: authResult.reason || "Authentication required",
|
|
3980
|
+
statusCode: 401
|
|
3981
|
+
};
|
|
3982
|
+
}
|
|
3983
|
+
const identity = authResult.identity || "unknown";
|
|
3984
|
+
if (rateLimit) {
|
|
3985
|
+
const rateLimitResult = await rateLimit(identity);
|
|
3986
|
+
if (!rateLimitResult.allowed) {
|
|
3987
|
+
if (logger) {
|
|
3988
|
+
logger.warn("Config reload endpoint: rate limit exceeded", {
|
|
3989
|
+
correlation_id: correlationId,
|
|
3990
|
+
identity
|
|
3991
|
+
});
|
|
3992
|
+
}
|
|
3993
|
+
if (telemetry) {
|
|
3994
|
+
telemetry.emit("fulmen.config.http_endpoint.rate_limited", {
|
|
3995
|
+
correlation_id: correlationId
|
|
3996
|
+
});
|
|
3997
|
+
}
|
|
3998
|
+
return {
|
|
3999
|
+
status: "error",
|
|
4000
|
+
error: "rate_limit_exceeded",
|
|
4001
|
+
message: "Rate limit exceeded. Please try again later.",
|
|
4002
|
+
statusCode: 429
|
|
4003
|
+
};
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
if (telemetry) {
|
|
4007
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_requested", {
|
|
4008
|
+
correlation_id: correlationId
|
|
4009
|
+
});
|
|
4010
|
+
}
|
|
4011
|
+
try {
|
|
4012
|
+
const config = await loader();
|
|
4013
|
+
if (validator) {
|
|
4014
|
+
const validation = await validator(config);
|
|
4015
|
+
if (!validation.valid) {
|
|
4016
|
+
if (logger) {
|
|
4017
|
+
logger.warn("Config reload endpoint: validation failed", {
|
|
4018
|
+
correlation_id: correlationId,
|
|
4019
|
+
error_count: validation.errors?.length ?? 0
|
|
4020
|
+
});
|
|
4021
|
+
}
|
|
4022
|
+
if (telemetry) {
|
|
4023
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_rejected", {
|
|
4024
|
+
correlation_id: correlationId,
|
|
4025
|
+
reason: "validation_failed"
|
|
4026
|
+
});
|
|
4027
|
+
}
|
|
4028
|
+
return {
|
|
4029
|
+
status: "error",
|
|
4030
|
+
error: "validation_failed",
|
|
4031
|
+
message: "Configuration validation failed",
|
|
4032
|
+
validation_errors: validation.errors,
|
|
4033
|
+
statusCode: 422
|
|
4034
|
+
};
|
|
4035
|
+
}
|
|
4036
|
+
}
|
|
4037
|
+
if (onReload2) {
|
|
4038
|
+
await onReload2(config);
|
|
4039
|
+
}
|
|
4040
|
+
if (telemetry) {
|
|
4041
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_accepted", {
|
|
4042
|
+
correlation_id: correlationId
|
|
4043
|
+
});
|
|
4044
|
+
}
|
|
4045
|
+
if (logger) {
|
|
4046
|
+
logger.info("Config reload endpoint: reload accepted", {
|
|
4047
|
+
correlation_id: correlationId,
|
|
4048
|
+
reason: payload.reason
|
|
4049
|
+
});
|
|
4050
|
+
}
|
|
4051
|
+
return {
|
|
4052
|
+
status: "reloaded",
|
|
4053
|
+
correlation_id: correlationId,
|
|
4054
|
+
message: "Configuration reloaded",
|
|
4055
|
+
statusCode: 200
|
|
4056
|
+
};
|
|
4057
|
+
} catch (error) {
|
|
4058
|
+
if (logger) {
|
|
4059
|
+
logger.warn("Config reload endpoint: reload failed", {
|
|
4060
|
+
correlation_id: correlationId,
|
|
4061
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4062
|
+
});
|
|
4063
|
+
}
|
|
4064
|
+
if (telemetry) {
|
|
4065
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_error", {
|
|
4066
|
+
correlation_id: correlationId,
|
|
4067
|
+
error_type: error instanceof Error ? error.constructor.name : "unknown"
|
|
4068
|
+
});
|
|
4069
|
+
}
|
|
4070
|
+
return {
|
|
4071
|
+
status: "error",
|
|
4072
|
+
error: "reload_failed",
|
|
4073
|
+
message: error instanceof Error ? error.message : String(error),
|
|
4074
|
+
statusCode: 500
|
|
4075
|
+
};
|
|
4076
|
+
}
|
|
4077
|
+
};
|
|
4078
|
+
}
|
|
4079
|
+
function generateCorrelationId2() {
|
|
4080
|
+
return `cfg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4081
|
+
}
|
|
4082
|
+
var init_config_reload_endpoint = __esm({
|
|
4083
|
+
"src/foundry/signals/config-reload-endpoint.ts"() {
|
|
4084
|
+
}
|
|
4085
|
+
});
|
|
4086
|
+
|
|
4087
|
+
// src/appidentity/runtime.ts
|
|
4088
|
+
function detectRuntime() {
|
|
4089
|
+
const versions = process.versions;
|
|
4090
|
+
if (typeof versions.bun === "string" && versions.bun.length > 0) {
|
|
4091
|
+
return { name: "bun", version: versions.bun };
|
|
4092
|
+
}
|
|
4093
|
+
if (typeof versions.node === "string" && versions.node.length > 0) {
|
|
4094
|
+
return { name: "node", version: versions.node };
|
|
4095
|
+
}
|
|
4096
|
+
return { name: "unknown" };
|
|
4097
|
+
}
|
|
4098
|
+
function buildRuntimeInfo(options = {}) {
|
|
4099
|
+
const runtime = detectRuntime();
|
|
4100
|
+
const serviceName = options.serviceName ?? options.identity?.app.binary_name ?? "unknown-service";
|
|
4101
|
+
const vendor = options.vendor ?? options.identity?.app.vendor;
|
|
4102
|
+
return {
|
|
4103
|
+
service: {
|
|
4104
|
+
name: serviceName,
|
|
4105
|
+
vendor,
|
|
4106
|
+
version: options.version
|
|
4107
|
+
},
|
|
4108
|
+
runtime,
|
|
4109
|
+
platform: {
|
|
4110
|
+
os: process.platform,
|
|
4111
|
+
arch: process.arch
|
|
4112
|
+
}
|
|
4113
|
+
};
|
|
4114
|
+
}
|
|
4115
|
+
var init_runtime = __esm({
|
|
4116
|
+
"src/appidentity/runtime.ts"() {
|
|
4117
|
+
}
|
|
4118
|
+
});
|
|
4119
|
+
|
|
4120
|
+
// src/foundry/signals/control-discovery-endpoint.ts
|
|
4121
|
+
function createControlDiscoveryEndpoint(options) {
|
|
4122
|
+
const { identity, version, endpoints, auth, authSummary, logger, telemetry } = options;
|
|
4123
|
+
return async (req) => {
|
|
4124
|
+
if (auth) {
|
|
4125
|
+
const authResult = await auth(req);
|
|
4126
|
+
if (!authResult.authenticated) {
|
|
4127
|
+
if (logger) {
|
|
4128
|
+
logger.warn("Control discovery endpoint: authentication failed", {
|
|
4129
|
+
reason: authResult.reason
|
|
4130
|
+
});
|
|
4131
|
+
}
|
|
4132
|
+
if (telemetry) {
|
|
4133
|
+
telemetry.emit("fulmen.control.discovery.auth_failed", {
|
|
4134
|
+
service: identity.app.binary_name
|
|
4135
|
+
});
|
|
4136
|
+
}
|
|
4137
|
+
return {
|
|
4138
|
+
status: "error",
|
|
4139
|
+
error: "authentication_failed",
|
|
4140
|
+
message: authResult.reason || "Authentication required",
|
|
4141
|
+
statusCode: 401
|
|
4142
|
+
};
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4145
|
+
if (telemetry) {
|
|
4146
|
+
telemetry.emit("fulmen.control.discovery.served", {
|
|
4147
|
+
service: identity.app.binary_name
|
|
4148
|
+
});
|
|
4149
|
+
}
|
|
4150
|
+
const runtime = buildRuntimeInfo({ identity, version });
|
|
4151
|
+
return {
|
|
4152
|
+
status: "ok",
|
|
4153
|
+
service: {
|
|
4154
|
+
name: identity.app.binary_name,
|
|
4155
|
+
vendor: identity.app.vendor,
|
|
4156
|
+
version
|
|
4157
|
+
},
|
|
4158
|
+
runtime: {
|
|
4159
|
+
name: runtime.runtime.name,
|
|
4160
|
+
version: runtime.runtime.version,
|
|
4161
|
+
platform: runtime.platform.os,
|
|
4162
|
+
arch: runtime.platform.arch
|
|
4163
|
+
},
|
|
4164
|
+
auth_summary: authSummary,
|
|
4165
|
+
endpoints,
|
|
4166
|
+
statusCode: 200
|
|
4167
|
+
};
|
|
4168
|
+
};
|
|
4169
|
+
}
|
|
4170
|
+
var init_control_discovery_endpoint = __esm({
|
|
4171
|
+
"src/foundry/signals/control-discovery-endpoint.ts"() {
|
|
4172
|
+
init_runtime();
|
|
4173
|
+
}
|
|
4174
|
+
});
|
|
4175
|
+
|
|
3939
4176
|
// src/foundry/signals/convenience.ts
|
|
3940
4177
|
async function onShutdown(manager, handler, options = {}) {
|
|
3941
4178
|
await manager.register("SIGTERM", handler, options);
|
|
@@ -4195,7 +4432,7 @@ var init_guards = __esm({
|
|
|
4195
4432
|
function createSignalEndpoint(options) {
|
|
4196
4433
|
const { manager, auth, rateLimit, logger, telemetry, allowedSignals } = options;
|
|
4197
4434
|
return async (payload, req) => {
|
|
4198
|
-
const correlationId = payload.correlation_id ??
|
|
4435
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId3();
|
|
4199
4436
|
const authResult = await auth(req);
|
|
4200
4437
|
if (!authResult.authenticated) {
|
|
4201
4438
|
if (logger) {
|
|
@@ -4318,7 +4555,7 @@ function normalizeSignalName(signal) {
|
|
|
4318
4555
|
}
|
|
4319
4556
|
return `SIG${upper}`;
|
|
4320
4557
|
}
|
|
4321
|
-
function
|
|
4558
|
+
function generateCorrelationId3() {
|
|
4322
4559
|
return `sig-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4323
4560
|
}
|
|
4324
4561
|
function createBearerTokenAuth(expectedToken) {
|
|
@@ -4785,6 +5022,8 @@ var init_signals = __esm({
|
|
|
4785
5022
|
"src/foundry/signals/index.ts"() {
|
|
4786
5023
|
init_capabilities2();
|
|
4787
5024
|
init_catalog();
|
|
5025
|
+
init_config_reload_endpoint();
|
|
5026
|
+
init_control_discovery_endpoint();
|
|
4788
5027
|
init_convenience();
|
|
4789
5028
|
init_double_tap();
|
|
4790
5029
|
init_guards();
|
|
@@ -4930,7 +5169,9 @@ __export(foundry_exports, {
|
|
|
4930
5169
|
clearMimeTypeCache: () => clearMimeTypeCache,
|
|
4931
5170
|
clearPatternCache: () => clearPatternCache,
|
|
4932
5171
|
createBearerTokenAuth: () => createBearerTokenAuth,
|
|
5172
|
+
createConfigReloadEndpoint: () => createConfigReloadEndpoint,
|
|
4933
5173
|
createConfigReloadHandler: () => createConfigReloadHandler,
|
|
5174
|
+
createControlDiscoveryEndpoint: () => createControlDiscoveryEndpoint,
|
|
4934
5175
|
createDoubleTapTracker: () => createDoubleTapTracker,
|
|
4935
5176
|
createSignalEndpoint: () => createSignalEndpoint,
|
|
4936
5177
|
createSignalManager: () => createSignalManager,
|
|
@@ -5653,6 +5894,7 @@ var init_cli = __esm({
|
|
|
5653
5894
|
// src/schema/index.ts
|
|
5654
5895
|
var init_schema = __esm({
|
|
5655
5896
|
"src/schema/index.ts"() {
|
|
5897
|
+
init_ajv_formats();
|
|
5656
5898
|
init_cli();
|
|
5657
5899
|
init_errors();
|
|
5658
5900
|
init_export();
|