@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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import addFormats from 'ajv-formats';
|
|
1
2
|
import { spawn } from 'child_process';
|
|
2
3
|
import { readFile, writeFile, access, mkdir } from 'fs/promises';
|
|
3
4
|
import { parse, stringify } from 'yaml';
|
|
@@ -8,7 +9,6 @@ import Ajv from 'ajv';
|
|
|
8
9
|
import Ajv2019 from 'ajv/dist/2019';
|
|
9
10
|
import Ajv2020 from 'ajv/dist/2020';
|
|
10
11
|
import AjvDraft04 from 'ajv-draft-04';
|
|
11
|
-
import addFormats from 'ajv-formats';
|
|
12
12
|
import { Readable } from 'stream';
|
|
13
13
|
import picomatch from 'picomatch';
|
|
14
14
|
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';
|
|
@@ -36,6 +36,27 @@ var init_constants = __esm({
|
|
|
36
36
|
MAX_ANCESTOR_SEARCH_DEPTH = 20;
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
+
function applyFulmenAjvFormats(ajv, options = {}) {
|
|
40
|
+
const mode = options.mode ?? "fast";
|
|
41
|
+
const formats = options.formats ?? DEFAULT_FORMATS;
|
|
42
|
+
addFormats(ajv, { mode, formats });
|
|
43
|
+
return ajv;
|
|
44
|
+
}
|
|
45
|
+
var DEFAULT_FORMATS;
|
|
46
|
+
var init_ajv_formats = __esm({
|
|
47
|
+
"src/schema/ajv-formats.ts"() {
|
|
48
|
+
DEFAULT_FORMATS = [
|
|
49
|
+
"date-time",
|
|
50
|
+
"email",
|
|
51
|
+
"hostname",
|
|
52
|
+
"ipv4",
|
|
53
|
+
"ipv6",
|
|
54
|
+
"uri",
|
|
55
|
+
"uri-reference",
|
|
56
|
+
"uuid"
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
});
|
|
39
60
|
|
|
40
61
|
// src/schema/errors.ts
|
|
41
62
|
var errors_exports = {};
|
|
@@ -1591,10 +1612,7 @@ function createAjv(dialect) {
|
|
|
1591
1612
|
// Enable async schema loading for YAML references
|
|
1592
1613
|
loadSchema: loadReferencedSchema
|
|
1593
1614
|
});
|
|
1594
|
-
|
|
1595
|
-
mode: "fast",
|
|
1596
|
-
formats: ["date-time", "email", "hostname", "ipv4", "ipv6", "uri", "uri-reference"]
|
|
1597
|
-
});
|
|
1615
|
+
applyFulmenAjvFormats(ajv);
|
|
1598
1616
|
return ajv;
|
|
1599
1617
|
}
|
|
1600
1618
|
async function getAjv(dialect) {
|
|
@@ -1840,6 +1858,7 @@ var ajvInstances, metaschemaReady, schemaCache;
|
|
|
1840
1858
|
var init_validator = __esm({
|
|
1841
1859
|
"src/schema/validator.ts"() {
|
|
1842
1860
|
init_telemetry();
|
|
1861
|
+
init_ajv_formats();
|
|
1843
1862
|
init_errors();
|
|
1844
1863
|
init_registry();
|
|
1845
1864
|
init_utils();
|
|
@@ -3799,6 +3818,224 @@ var init_capabilities2 = __esm({
|
|
|
3799
3818
|
}
|
|
3800
3819
|
});
|
|
3801
3820
|
|
|
3821
|
+
// src/foundry/signals/config-reload-endpoint.ts
|
|
3822
|
+
function createConfigReloadEndpoint(options) {
|
|
3823
|
+
const { loader, validator, onReload: onReload2, auth, rateLimit, logger, telemetry } = options;
|
|
3824
|
+
return async (payload, req) => {
|
|
3825
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId();
|
|
3826
|
+
const authResult = await auth(req);
|
|
3827
|
+
if (!authResult.authenticated) {
|
|
3828
|
+
if (logger) {
|
|
3829
|
+
logger.warn("Config reload endpoint: authentication failed", {
|
|
3830
|
+
correlation_id: correlationId,
|
|
3831
|
+
reason: authResult.reason
|
|
3832
|
+
});
|
|
3833
|
+
}
|
|
3834
|
+
if (telemetry) {
|
|
3835
|
+
telemetry.emit("fulmen.config.http_endpoint.auth_failed", {
|
|
3836
|
+
correlation_id: correlationId
|
|
3837
|
+
});
|
|
3838
|
+
}
|
|
3839
|
+
return {
|
|
3840
|
+
status: "error",
|
|
3841
|
+
error: "authentication_failed",
|
|
3842
|
+
message: authResult.reason || "Authentication required",
|
|
3843
|
+
statusCode: 401
|
|
3844
|
+
};
|
|
3845
|
+
}
|
|
3846
|
+
const identity = authResult.identity || "unknown";
|
|
3847
|
+
if (rateLimit) {
|
|
3848
|
+
const rateLimitResult = await rateLimit(identity);
|
|
3849
|
+
if (!rateLimitResult.allowed) {
|
|
3850
|
+
if (logger) {
|
|
3851
|
+
logger.warn("Config reload endpoint: rate limit exceeded", {
|
|
3852
|
+
correlation_id: correlationId,
|
|
3853
|
+
identity
|
|
3854
|
+
});
|
|
3855
|
+
}
|
|
3856
|
+
if (telemetry) {
|
|
3857
|
+
telemetry.emit("fulmen.config.http_endpoint.rate_limited", {
|
|
3858
|
+
correlation_id: correlationId
|
|
3859
|
+
});
|
|
3860
|
+
}
|
|
3861
|
+
return {
|
|
3862
|
+
status: "error",
|
|
3863
|
+
error: "rate_limit_exceeded",
|
|
3864
|
+
message: "Rate limit exceeded. Please try again later.",
|
|
3865
|
+
statusCode: 429
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
if (telemetry) {
|
|
3870
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_requested", {
|
|
3871
|
+
correlation_id: correlationId
|
|
3872
|
+
});
|
|
3873
|
+
}
|
|
3874
|
+
try {
|
|
3875
|
+
const config = await loader();
|
|
3876
|
+
if (validator) {
|
|
3877
|
+
const validation = await validator(config);
|
|
3878
|
+
if (!validation.valid) {
|
|
3879
|
+
if (logger) {
|
|
3880
|
+
logger.warn("Config reload endpoint: validation failed", {
|
|
3881
|
+
correlation_id: correlationId,
|
|
3882
|
+
error_count: validation.errors?.length ?? 0
|
|
3883
|
+
});
|
|
3884
|
+
}
|
|
3885
|
+
if (telemetry) {
|
|
3886
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_rejected", {
|
|
3887
|
+
correlation_id: correlationId,
|
|
3888
|
+
reason: "validation_failed"
|
|
3889
|
+
});
|
|
3890
|
+
}
|
|
3891
|
+
return {
|
|
3892
|
+
status: "error",
|
|
3893
|
+
error: "validation_failed",
|
|
3894
|
+
message: "Configuration validation failed",
|
|
3895
|
+
validation_errors: validation.errors,
|
|
3896
|
+
statusCode: 422
|
|
3897
|
+
};
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3900
|
+
if (onReload2) {
|
|
3901
|
+
await onReload2(config);
|
|
3902
|
+
}
|
|
3903
|
+
if (telemetry) {
|
|
3904
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_accepted", {
|
|
3905
|
+
correlation_id: correlationId
|
|
3906
|
+
});
|
|
3907
|
+
}
|
|
3908
|
+
if (logger) {
|
|
3909
|
+
logger.info("Config reload endpoint: reload accepted", {
|
|
3910
|
+
correlation_id: correlationId,
|
|
3911
|
+
reason: payload.reason
|
|
3912
|
+
});
|
|
3913
|
+
}
|
|
3914
|
+
return {
|
|
3915
|
+
status: "reloaded",
|
|
3916
|
+
correlation_id: correlationId,
|
|
3917
|
+
message: "Configuration reloaded",
|
|
3918
|
+
statusCode: 200
|
|
3919
|
+
};
|
|
3920
|
+
} catch (error) {
|
|
3921
|
+
if (logger) {
|
|
3922
|
+
logger.warn("Config reload endpoint: reload failed", {
|
|
3923
|
+
correlation_id: correlationId,
|
|
3924
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3925
|
+
});
|
|
3926
|
+
}
|
|
3927
|
+
if (telemetry) {
|
|
3928
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_error", {
|
|
3929
|
+
correlation_id: correlationId,
|
|
3930
|
+
error_type: error instanceof Error ? error.constructor.name : "unknown"
|
|
3931
|
+
});
|
|
3932
|
+
}
|
|
3933
|
+
return {
|
|
3934
|
+
status: "error",
|
|
3935
|
+
error: "reload_failed",
|
|
3936
|
+
message: error instanceof Error ? error.message : String(error),
|
|
3937
|
+
statusCode: 500
|
|
3938
|
+
};
|
|
3939
|
+
}
|
|
3940
|
+
};
|
|
3941
|
+
}
|
|
3942
|
+
function generateCorrelationId() {
|
|
3943
|
+
return `cfg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
3944
|
+
}
|
|
3945
|
+
var init_config_reload_endpoint = __esm({
|
|
3946
|
+
"src/foundry/signals/config-reload-endpoint.ts"() {
|
|
3947
|
+
}
|
|
3948
|
+
});
|
|
3949
|
+
|
|
3950
|
+
// src/appidentity/runtime.ts
|
|
3951
|
+
function detectRuntime() {
|
|
3952
|
+
const versions = process.versions;
|
|
3953
|
+
if (typeof versions.bun === "string" && versions.bun.length > 0) {
|
|
3954
|
+
return { name: "bun", version: versions.bun };
|
|
3955
|
+
}
|
|
3956
|
+
if (typeof versions.node === "string" && versions.node.length > 0) {
|
|
3957
|
+
return { name: "node", version: versions.node };
|
|
3958
|
+
}
|
|
3959
|
+
return { name: "unknown" };
|
|
3960
|
+
}
|
|
3961
|
+
function buildRuntimeInfo(options = {}) {
|
|
3962
|
+
const runtime = detectRuntime();
|
|
3963
|
+
const serviceName = options.serviceName ?? options.identity?.app.binary_name ?? "unknown-service";
|
|
3964
|
+
const vendor = options.vendor ?? options.identity?.app.vendor;
|
|
3965
|
+
return {
|
|
3966
|
+
service: {
|
|
3967
|
+
name: serviceName,
|
|
3968
|
+
vendor,
|
|
3969
|
+
version: options.version
|
|
3970
|
+
},
|
|
3971
|
+
runtime,
|
|
3972
|
+
platform: {
|
|
3973
|
+
os: process.platform,
|
|
3974
|
+
arch: process.arch
|
|
3975
|
+
}
|
|
3976
|
+
};
|
|
3977
|
+
}
|
|
3978
|
+
var init_runtime = __esm({
|
|
3979
|
+
"src/appidentity/runtime.ts"() {
|
|
3980
|
+
}
|
|
3981
|
+
});
|
|
3982
|
+
|
|
3983
|
+
// src/foundry/signals/control-discovery-endpoint.ts
|
|
3984
|
+
function createControlDiscoveryEndpoint(options) {
|
|
3985
|
+
const { identity, version, endpoints, auth, authSummary, logger, telemetry } = options;
|
|
3986
|
+
return async (req) => {
|
|
3987
|
+
if (auth) {
|
|
3988
|
+
const authResult = await auth(req);
|
|
3989
|
+
if (!authResult.authenticated) {
|
|
3990
|
+
if (logger) {
|
|
3991
|
+
logger.warn("Control discovery endpoint: authentication failed", {
|
|
3992
|
+
reason: authResult.reason
|
|
3993
|
+
});
|
|
3994
|
+
}
|
|
3995
|
+
if (telemetry) {
|
|
3996
|
+
telemetry.emit("fulmen.control.discovery.auth_failed", {
|
|
3997
|
+
service: identity.app.binary_name
|
|
3998
|
+
});
|
|
3999
|
+
}
|
|
4000
|
+
return {
|
|
4001
|
+
status: "error",
|
|
4002
|
+
error: "authentication_failed",
|
|
4003
|
+
message: authResult.reason || "Authentication required",
|
|
4004
|
+
statusCode: 401
|
|
4005
|
+
};
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
if (telemetry) {
|
|
4009
|
+
telemetry.emit("fulmen.control.discovery.served", {
|
|
4010
|
+
service: identity.app.binary_name
|
|
4011
|
+
});
|
|
4012
|
+
}
|
|
4013
|
+
const runtime = buildRuntimeInfo({ identity, version });
|
|
4014
|
+
return {
|
|
4015
|
+
status: "ok",
|
|
4016
|
+
service: {
|
|
4017
|
+
name: identity.app.binary_name,
|
|
4018
|
+
vendor: identity.app.vendor,
|
|
4019
|
+
version
|
|
4020
|
+
},
|
|
4021
|
+
runtime: {
|
|
4022
|
+
name: runtime.runtime.name,
|
|
4023
|
+
version: runtime.runtime.version,
|
|
4024
|
+
platform: runtime.platform.os,
|
|
4025
|
+
arch: runtime.platform.arch
|
|
4026
|
+
},
|
|
4027
|
+
auth_summary: authSummary,
|
|
4028
|
+
endpoints,
|
|
4029
|
+
statusCode: 200
|
|
4030
|
+
};
|
|
4031
|
+
};
|
|
4032
|
+
}
|
|
4033
|
+
var init_control_discovery_endpoint = __esm({
|
|
4034
|
+
"src/foundry/signals/control-discovery-endpoint.ts"() {
|
|
4035
|
+
init_runtime();
|
|
4036
|
+
}
|
|
4037
|
+
});
|
|
4038
|
+
|
|
3802
4039
|
// src/foundry/signals/convenience.ts
|
|
3803
4040
|
async function onShutdown(manager, handler, options = {}) {
|
|
3804
4041
|
await manager.register("SIGTERM", handler, options);
|
|
@@ -4058,7 +4295,7 @@ var init_guards = __esm({
|
|
|
4058
4295
|
function createSignalEndpoint(options) {
|
|
4059
4296
|
const { manager, auth, rateLimit, logger, telemetry, allowedSignals } = options;
|
|
4060
4297
|
return async (payload, req) => {
|
|
4061
|
-
const correlationId = payload.correlation_id ??
|
|
4298
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId2();
|
|
4062
4299
|
const authResult = await auth(req);
|
|
4063
4300
|
if (!authResult.authenticated) {
|
|
4064
4301
|
if (logger) {
|
|
@@ -4181,7 +4418,7 @@ function normalizeSignalName(signal) {
|
|
|
4181
4418
|
}
|
|
4182
4419
|
return `SIG${upper}`;
|
|
4183
4420
|
}
|
|
4184
|
-
function
|
|
4421
|
+
function generateCorrelationId2() {
|
|
4185
4422
|
return `sig-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4186
4423
|
}
|
|
4187
4424
|
function createBearerTokenAuth(expectedToken) {
|
|
@@ -4648,6 +4885,8 @@ var init_signals = __esm({
|
|
|
4648
4885
|
"src/foundry/signals/index.ts"() {
|
|
4649
4886
|
init_capabilities2();
|
|
4650
4887
|
init_catalog();
|
|
4888
|
+
init_config_reload_endpoint();
|
|
4889
|
+
init_control_discovery_endpoint();
|
|
4651
4890
|
init_convenience();
|
|
4652
4891
|
init_double_tap();
|
|
4653
4892
|
init_guards();
|
|
@@ -4793,7 +5032,9 @@ __export(foundry_exports, {
|
|
|
4793
5032
|
clearMimeTypeCache: () => clearMimeTypeCache,
|
|
4794
5033
|
clearPatternCache: () => clearPatternCache,
|
|
4795
5034
|
createBearerTokenAuth: () => createBearerTokenAuth,
|
|
5035
|
+
createConfigReloadEndpoint: () => createConfigReloadEndpoint,
|
|
4796
5036
|
createConfigReloadHandler: () => createConfigReloadHandler,
|
|
5037
|
+
createControlDiscoveryEndpoint: () => createControlDiscoveryEndpoint,
|
|
4797
5038
|
createDoubleTapTracker: () => createDoubleTapTracker,
|
|
4798
5039
|
createSignalEndpoint: () => createSignalEndpoint,
|
|
4799
5040
|
createSignalManager: () => createSignalManager,
|
|
@@ -5825,6 +6066,7 @@ var init_cli = __esm({
|
|
|
5825
6066
|
// src/schema/index.ts
|
|
5826
6067
|
var init_schema = __esm({
|
|
5827
6068
|
"src/schema/index.ts"() {
|
|
6069
|
+
init_ajv_formats();
|
|
5828
6070
|
init_cli();
|
|
5829
6071
|
init_errors();
|
|
5830
6072
|
init_export();
|
|
@@ -5858,6 +6100,7 @@ init_loader2();
|
|
|
5858
6100
|
|
|
5859
6101
|
// src/appidentity/index.ts
|
|
5860
6102
|
init_loader2();
|
|
6103
|
+
init_runtime();
|
|
5861
6104
|
|
|
5862
6105
|
// src/telemetry/http/index.ts
|
|
5863
6106
|
init_telemetry();
|