@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/crucible/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile, access, mkdir, writeFile, readdir, stat } from 'fs/promises';
|
|
2
2
|
import { dirname, join, extname, relative } from 'path';
|
|
3
3
|
import { parse, stringify, parseDocument } from 'yaml';
|
|
4
|
+
import addFormats from 'ajv-formats';
|
|
4
5
|
import { spawn } from 'child_process';
|
|
5
6
|
import { fileURLToPath } from 'url';
|
|
6
7
|
import glob from 'fast-glob';
|
|
@@ -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';
|
|
@@ -730,6 +730,27 @@ var init_types = __esm({
|
|
|
730
730
|
"src/telemetry/types.ts"() {
|
|
731
731
|
}
|
|
732
732
|
});
|
|
733
|
+
function applyFulmenAjvFormats(ajv, options = {}) {
|
|
734
|
+
const mode = options.mode ?? "fast";
|
|
735
|
+
const formats = options.formats ?? DEFAULT_FORMATS;
|
|
736
|
+
addFormats(ajv, { mode, formats });
|
|
737
|
+
return ajv;
|
|
738
|
+
}
|
|
739
|
+
var DEFAULT_FORMATS;
|
|
740
|
+
var init_ajv_formats = __esm({
|
|
741
|
+
"src/schema/ajv-formats.ts"() {
|
|
742
|
+
DEFAULT_FORMATS = [
|
|
743
|
+
"date-time",
|
|
744
|
+
"email",
|
|
745
|
+
"hostname",
|
|
746
|
+
"ipv4",
|
|
747
|
+
"ipv6",
|
|
748
|
+
"uri",
|
|
749
|
+
"uri-reference",
|
|
750
|
+
"uuid"
|
|
751
|
+
];
|
|
752
|
+
}
|
|
753
|
+
});
|
|
733
754
|
|
|
734
755
|
// src/schema/errors.ts
|
|
735
756
|
var errors_exports = {};
|
|
@@ -1557,10 +1578,7 @@ function createAjv(dialect) {
|
|
|
1557
1578
|
// Enable async schema loading for YAML references
|
|
1558
1579
|
loadSchema: loadReferencedSchema
|
|
1559
1580
|
});
|
|
1560
|
-
|
|
1561
|
-
mode: "fast",
|
|
1562
|
-
formats: ["date-time", "email", "hostname", "ipv4", "ipv6", "uri", "uri-reference"]
|
|
1563
|
-
});
|
|
1581
|
+
applyFulmenAjvFormats(ajv);
|
|
1564
1582
|
return ajv;
|
|
1565
1583
|
}
|
|
1566
1584
|
async function getAjv(dialect) {
|
|
@@ -1806,6 +1824,7 @@ var ajvInstances, metaschemaReady, schemaCache;
|
|
|
1806
1824
|
var init_validator = __esm({
|
|
1807
1825
|
"src/schema/validator.ts"() {
|
|
1808
1826
|
init_telemetry();
|
|
1827
|
+
init_ajv_formats();
|
|
1809
1828
|
init_errors();
|
|
1810
1829
|
init_registry2();
|
|
1811
1830
|
init_utils();
|
|
@@ -3765,6 +3784,224 @@ var init_capabilities2 = __esm({
|
|
|
3765
3784
|
}
|
|
3766
3785
|
});
|
|
3767
3786
|
|
|
3787
|
+
// src/foundry/signals/config-reload-endpoint.ts
|
|
3788
|
+
function createConfigReloadEndpoint(options) {
|
|
3789
|
+
const { loader, validator, onReload: onReload2, auth, rateLimit, logger, telemetry } = options;
|
|
3790
|
+
return async (payload, req) => {
|
|
3791
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId();
|
|
3792
|
+
const authResult = await auth(req);
|
|
3793
|
+
if (!authResult.authenticated) {
|
|
3794
|
+
if (logger) {
|
|
3795
|
+
logger.warn("Config reload endpoint: authentication failed", {
|
|
3796
|
+
correlation_id: correlationId,
|
|
3797
|
+
reason: authResult.reason
|
|
3798
|
+
});
|
|
3799
|
+
}
|
|
3800
|
+
if (telemetry) {
|
|
3801
|
+
telemetry.emit("fulmen.config.http_endpoint.auth_failed", {
|
|
3802
|
+
correlation_id: correlationId
|
|
3803
|
+
});
|
|
3804
|
+
}
|
|
3805
|
+
return {
|
|
3806
|
+
status: "error",
|
|
3807
|
+
error: "authentication_failed",
|
|
3808
|
+
message: authResult.reason || "Authentication required",
|
|
3809
|
+
statusCode: 401
|
|
3810
|
+
};
|
|
3811
|
+
}
|
|
3812
|
+
const identity = authResult.identity || "unknown";
|
|
3813
|
+
if (rateLimit) {
|
|
3814
|
+
const rateLimitResult = await rateLimit(identity);
|
|
3815
|
+
if (!rateLimitResult.allowed) {
|
|
3816
|
+
if (logger) {
|
|
3817
|
+
logger.warn("Config reload endpoint: rate limit exceeded", {
|
|
3818
|
+
correlation_id: correlationId,
|
|
3819
|
+
identity
|
|
3820
|
+
});
|
|
3821
|
+
}
|
|
3822
|
+
if (telemetry) {
|
|
3823
|
+
telemetry.emit("fulmen.config.http_endpoint.rate_limited", {
|
|
3824
|
+
correlation_id: correlationId
|
|
3825
|
+
});
|
|
3826
|
+
}
|
|
3827
|
+
return {
|
|
3828
|
+
status: "error",
|
|
3829
|
+
error: "rate_limit_exceeded",
|
|
3830
|
+
message: "Rate limit exceeded. Please try again later.",
|
|
3831
|
+
statusCode: 429
|
|
3832
|
+
};
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
if (telemetry) {
|
|
3836
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_requested", {
|
|
3837
|
+
correlation_id: correlationId
|
|
3838
|
+
});
|
|
3839
|
+
}
|
|
3840
|
+
try {
|
|
3841
|
+
const config = await loader();
|
|
3842
|
+
if (validator) {
|
|
3843
|
+
const validation = await validator(config);
|
|
3844
|
+
if (!validation.valid) {
|
|
3845
|
+
if (logger) {
|
|
3846
|
+
logger.warn("Config reload endpoint: validation failed", {
|
|
3847
|
+
correlation_id: correlationId,
|
|
3848
|
+
error_count: validation.errors?.length ?? 0
|
|
3849
|
+
});
|
|
3850
|
+
}
|
|
3851
|
+
if (telemetry) {
|
|
3852
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_rejected", {
|
|
3853
|
+
correlation_id: correlationId,
|
|
3854
|
+
reason: "validation_failed"
|
|
3855
|
+
});
|
|
3856
|
+
}
|
|
3857
|
+
return {
|
|
3858
|
+
status: "error",
|
|
3859
|
+
error: "validation_failed",
|
|
3860
|
+
message: "Configuration validation failed",
|
|
3861
|
+
validation_errors: validation.errors,
|
|
3862
|
+
statusCode: 422
|
|
3863
|
+
};
|
|
3864
|
+
}
|
|
3865
|
+
}
|
|
3866
|
+
if (onReload2) {
|
|
3867
|
+
await onReload2(config);
|
|
3868
|
+
}
|
|
3869
|
+
if (telemetry) {
|
|
3870
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_accepted", {
|
|
3871
|
+
correlation_id: correlationId
|
|
3872
|
+
});
|
|
3873
|
+
}
|
|
3874
|
+
if (logger) {
|
|
3875
|
+
logger.info("Config reload endpoint: reload accepted", {
|
|
3876
|
+
correlation_id: correlationId,
|
|
3877
|
+
reason: payload.reason
|
|
3878
|
+
});
|
|
3879
|
+
}
|
|
3880
|
+
return {
|
|
3881
|
+
status: "reloaded",
|
|
3882
|
+
correlation_id: correlationId,
|
|
3883
|
+
message: "Configuration reloaded",
|
|
3884
|
+
statusCode: 200
|
|
3885
|
+
};
|
|
3886
|
+
} catch (error) {
|
|
3887
|
+
if (logger) {
|
|
3888
|
+
logger.warn("Config reload endpoint: reload failed", {
|
|
3889
|
+
correlation_id: correlationId,
|
|
3890
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3891
|
+
});
|
|
3892
|
+
}
|
|
3893
|
+
if (telemetry) {
|
|
3894
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_error", {
|
|
3895
|
+
correlation_id: correlationId,
|
|
3896
|
+
error_type: error instanceof Error ? error.constructor.name : "unknown"
|
|
3897
|
+
});
|
|
3898
|
+
}
|
|
3899
|
+
return {
|
|
3900
|
+
status: "error",
|
|
3901
|
+
error: "reload_failed",
|
|
3902
|
+
message: error instanceof Error ? error.message : String(error),
|
|
3903
|
+
statusCode: 500
|
|
3904
|
+
};
|
|
3905
|
+
}
|
|
3906
|
+
};
|
|
3907
|
+
}
|
|
3908
|
+
function generateCorrelationId() {
|
|
3909
|
+
return `cfg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
3910
|
+
}
|
|
3911
|
+
var init_config_reload_endpoint = __esm({
|
|
3912
|
+
"src/foundry/signals/config-reload-endpoint.ts"() {
|
|
3913
|
+
}
|
|
3914
|
+
});
|
|
3915
|
+
|
|
3916
|
+
// src/appidentity/runtime.ts
|
|
3917
|
+
function detectRuntime() {
|
|
3918
|
+
const versions = process.versions;
|
|
3919
|
+
if (typeof versions.bun === "string" && versions.bun.length > 0) {
|
|
3920
|
+
return { name: "bun", version: versions.bun };
|
|
3921
|
+
}
|
|
3922
|
+
if (typeof versions.node === "string" && versions.node.length > 0) {
|
|
3923
|
+
return { name: "node", version: versions.node };
|
|
3924
|
+
}
|
|
3925
|
+
return { name: "unknown" };
|
|
3926
|
+
}
|
|
3927
|
+
function buildRuntimeInfo(options = {}) {
|
|
3928
|
+
const runtime = detectRuntime();
|
|
3929
|
+
const serviceName = options.serviceName ?? options.identity?.app.binary_name ?? "unknown-service";
|
|
3930
|
+
const vendor = options.vendor ?? options.identity?.app.vendor;
|
|
3931
|
+
return {
|
|
3932
|
+
service: {
|
|
3933
|
+
name: serviceName,
|
|
3934
|
+
vendor,
|
|
3935
|
+
version: options.version
|
|
3936
|
+
},
|
|
3937
|
+
runtime,
|
|
3938
|
+
platform: {
|
|
3939
|
+
os: process.platform,
|
|
3940
|
+
arch: process.arch
|
|
3941
|
+
}
|
|
3942
|
+
};
|
|
3943
|
+
}
|
|
3944
|
+
var init_runtime = __esm({
|
|
3945
|
+
"src/appidentity/runtime.ts"() {
|
|
3946
|
+
}
|
|
3947
|
+
});
|
|
3948
|
+
|
|
3949
|
+
// src/foundry/signals/control-discovery-endpoint.ts
|
|
3950
|
+
function createControlDiscoveryEndpoint(options) {
|
|
3951
|
+
const { identity, version, endpoints, auth, authSummary, logger, telemetry } = options;
|
|
3952
|
+
return async (req) => {
|
|
3953
|
+
if (auth) {
|
|
3954
|
+
const authResult = await auth(req);
|
|
3955
|
+
if (!authResult.authenticated) {
|
|
3956
|
+
if (logger) {
|
|
3957
|
+
logger.warn("Control discovery endpoint: authentication failed", {
|
|
3958
|
+
reason: authResult.reason
|
|
3959
|
+
});
|
|
3960
|
+
}
|
|
3961
|
+
if (telemetry) {
|
|
3962
|
+
telemetry.emit("fulmen.control.discovery.auth_failed", {
|
|
3963
|
+
service: identity.app.binary_name
|
|
3964
|
+
});
|
|
3965
|
+
}
|
|
3966
|
+
return {
|
|
3967
|
+
status: "error",
|
|
3968
|
+
error: "authentication_failed",
|
|
3969
|
+
message: authResult.reason || "Authentication required",
|
|
3970
|
+
statusCode: 401
|
|
3971
|
+
};
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
if (telemetry) {
|
|
3975
|
+
telemetry.emit("fulmen.control.discovery.served", {
|
|
3976
|
+
service: identity.app.binary_name
|
|
3977
|
+
});
|
|
3978
|
+
}
|
|
3979
|
+
const runtime = buildRuntimeInfo({ identity, version });
|
|
3980
|
+
return {
|
|
3981
|
+
status: "ok",
|
|
3982
|
+
service: {
|
|
3983
|
+
name: identity.app.binary_name,
|
|
3984
|
+
vendor: identity.app.vendor,
|
|
3985
|
+
version
|
|
3986
|
+
},
|
|
3987
|
+
runtime: {
|
|
3988
|
+
name: runtime.runtime.name,
|
|
3989
|
+
version: runtime.runtime.version,
|
|
3990
|
+
platform: runtime.platform.os,
|
|
3991
|
+
arch: runtime.platform.arch
|
|
3992
|
+
},
|
|
3993
|
+
auth_summary: authSummary,
|
|
3994
|
+
endpoints,
|
|
3995
|
+
statusCode: 200
|
|
3996
|
+
};
|
|
3997
|
+
};
|
|
3998
|
+
}
|
|
3999
|
+
var init_control_discovery_endpoint = __esm({
|
|
4000
|
+
"src/foundry/signals/control-discovery-endpoint.ts"() {
|
|
4001
|
+
init_runtime();
|
|
4002
|
+
}
|
|
4003
|
+
});
|
|
4004
|
+
|
|
3768
4005
|
// src/foundry/signals/convenience.ts
|
|
3769
4006
|
async function onShutdown(manager, handler, options = {}) {
|
|
3770
4007
|
await manager.register("SIGTERM", handler, options);
|
|
@@ -4024,7 +4261,7 @@ var init_guards = __esm({
|
|
|
4024
4261
|
function createSignalEndpoint(options) {
|
|
4025
4262
|
const { manager, auth, rateLimit, logger, telemetry, allowedSignals } = options;
|
|
4026
4263
|
return async (payload, req) => {
|
|
4027
|
-
const correlationId = payload.correlation_id ??
|
|
4264
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId2();
|
|
4028
4265
|
const authResult = await auth(req);
|
|
4029
4266
|
if (!authResult.authenticated) {
|
|
4030
4267
|
if (logger) {
|
|
@@ -4147,7 +4384,7 @@ function normalizeSignalName(signal) {
|
|
|
4147
4384
|
}
|
|
4148
4385
|
return `SIG${upper}`;
|
|
4149
4386
|
}
|
|
4150
|
-
function
|
|
4387
|
+
function generateCorrelationId2() {
|
|
4151
4388
|
return `sig-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4152
4389
|
}
|
|
4153
4390
|
function createBearerTokenAuth(expectedToken) {
|
|
@@ -4614,6 +4851,8 @@ var init_signals = __esm({
|
|
|
4614
4851
|
"src/foundry/signals/index.ts"() {
|
|
4615
4852
|
init_capabilities2();
|
|
4616
4853
|
init_catalog();
|
|
4854
|
+
init_config_reload_endpoint();
|
|
4855
|
+
init_control_discovery_endpoint();
|
|
4617
4856
|
init_convenience();
|
|
4618
4857
|
init_double_tap();
|
|
4619
4858
|
init_guards();
|
|
@@ -4759,7 +4998,9 @@ __export(foundry_exports, {
|
|
|
4759
4998
|
clearMimeTypeCache: () => clearMimeTypeCache,
|
|
4760
4999
|
clearPatternCache: () => clearPatternCache,
|
|
4761
5000
|
createBearerTokenAuth: () => createBearerTokenAuth,
|
|
5001
|
+
createConfigReloadEndpoint: () => createConfigReloadEndpoint,
|
|
4762
5002
|
createConfigReloadHandler: () => createConfigReloadHandler,
|
|
5003
|
+
createControlDiscoveryEndpoint: () => createControlDiscoveryEndpoint,
|
|
4763
5004
|
createDoubleTapTracker: () => createDoubleTapTracker,
|
|
4764
5005
|
createSignalEndpoint: () => createSignalEndpoint,
|
|
4765
5006
|
createSignalManager: () => createSignalManager,
|
|
@@ -5815,6 +6056,7 @@ var init_cli = __esm({
|
|
|
5815
6056
|
// src/schema/index.ts
|
|
5816
6057
|
var init_schema = __esm({
|
|
5817
6058
|
"src/schema/index.ts"() {
|
|
6059
|
+
init_ajv_formats();
|
|
5818
6060
|
init_cli();
|
|
5819
6061
|
init_errors();
|
|
5820
6062
|
init_export();
|