@fulmenhq/tsfulmen 0.2.10 → 0.3.1
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 +48 -0
- package/README.md +1 -1
- package/dist/appidentity/index.js +156 -4150
- package/dist/appidentity/index.js.map +1 -1
- package/dist/bin/prometheus-cli.d.ts +1 -0
- package/dist/bin/prometheus-cli.js +9331 -0
- package/dist/bin/prometheus-cli.js.map +1 -0
- package/dist/bin/schema-cli.d.ts +1 -0
- package/dist/bin/schema-cli.js +6104 -0
- package/dist/bin/schema-cli.js.map +1 -0
- package/dist/bin/signals-cli.d.ts +1 -0
- package/dist/bin/signals-cli.js +2104 -0
- package/dist/bin/signals-cli.js.map +1 -0
- package/dist/config/index.js +29 -4915
- package/dist/config/index.js.map +1 -1
- package/dist/crucible/index.js +120 -5336
- package/dist/crucible/index.js.map +1 -1
- package/dist/errors/index.js +52 -4434
- package/dist/errors/index.js.map +1 -1
- package/dist/foundry/index.js +197 -1874
- package/dist/foundry/index.js.map +1 -1
- package/dist/fulpack/index.js +43 -31
- package/dist/fulpack/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +204 -4185
- package/dist/index.js.map +1 -1
- package/dist/pathfinder/index.js +47 -4378
- package/dist/pathfinder/index.js.map +1 -1
- package/dist/reports/license-inventory.csv +17 -17
- package/dist/schema/index.js +0 -4
- package/dist/schema/index.js.map +1 -1
- package/dist/signals/index.js +231 -3570
- package/dist/signals/index.js.map +1 -1
- package/dist/telemetry/http/index.js +94 -5280
- package/dist/telemetry/http/index.js.map +1 -1
- package/dist/telemetry/index.js +70 -4786
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/prometheus/index.js +461 -4450
- package/dist/telemetry/prometheus/index.js.map +1 -1
- package/package.json +13 -8
package/dist/foundry/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname,
|
|
3
|
-
import { parse
|
|
1
|
+
import { readFile, access } from 'fs/promises';
|
|
2
|
+
import { dirname, join, relative, extname } from 'path';
|
|
3
|
+
import { parse } from 'yaml';
|
|
4
4
|
import addFormats from 'ajv-formats';
|
|
5
|
-
import
|
|
5
|
+
import 'child_process';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import glob from 'fast-glob';
|
|
8
|
-
import '
|
|
9
|
-
import { Command } from 'commander';
|
|
8
|
+
import 'commander';
|
|
10
9
|
import Ajv from 'ajv';
|
|
11
10
|
import Ajv2019 from 'ajv/dist/2019.js';
|
|
12
11
|
import Ajv2020 from 'ajv/dist/2020.js';
|
|
@@ -15,15 +14,10 @@ import { Readable } from 'stream';
|
|
|
15
14
|
import picomatch from 'picomatch';
|
|
16
15
|
import { substringSimilarity, jaro_winkler, damerau_levenshtein, osa_distance, levenshtein, normalize as normalize$1, score as score$1, suggest as suggest$1 } from '@3leaps/string-metrics-wasm';
|
|
17
16
|
|
|
18
|
-
var __defProp = Object.defineProperty;
|
|
19
17
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
20
18
|
var __esm = (fn, res) => function __init() {
|
|
21
19
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
22
20
|
};
|
|
23
|
-
var __export = (target, all) => {
|
|
24
|
-
for (var name in all)
|
|
25
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
|
-
};
|
|
27
21
|
|
|
28
22
|
// src/telemetry/counter.ts
|
|
29
23
|
var Counter;
|
|
@@ -752,23 +746,9 @@ var init_ajv_formats = __esm({
|
|
|
752
746
|
});
|
|
753
747
|
|
|
754
748
|
// src/schema/errors.ts
|
|
755
|
-
var
|
|
756
|
-
__export(errors_exports, {
|
|
757
|
-
ExportErrorReason: () => ExportErrorReason,
|
|
758
|
-
SchemaExportError: () => SchemaExportError,
|
|
759
|
-
SchemaValidationError: () => SchemaValidationError
|
|
760
|
-
});
|
|
761
|
-
var ExportErrorReason, SchemaValidationError, SchemaExportError;
|
|
749
|
+
var SchemaValidationError;
|
|
762
750
|
var init_errors = __esm({
|
|
763
751
|
"src/schema/errors.ts"() {
|
|
764
|
-
ExportErrorReason = /* @__PURE__ */ ((ExportErrorReason2) => {
|
|
765
|
-
ExportErrorReason2["FILE_EXISTS"] = "FILE_EXISTS";
|
|
766
|
-
ExportErrorReason2["WRITE_FAILED"] = "WRITE_FAILED";
|
|
767
|
-
ExportErrorReason2["INVALID_FORMAT"] = "INVALID_FORMAT";
|
|
768
|
-
ExportErrorReason2["PROVENANCE_FAILED"] = "PROVENANCE_FAILED";
|
|
769
|
-
ExportErrorReason2["UNKNOWN"] = "UNKNOWN";
|
|
770
|
-
return ExportErrorReason2;
|
|
771
|
-
})(ExportErrorReason || {});
|
|
772
752
|
SchemaValidationError = class _SchemaValidationError extends Error {
|
|
773
753
|
constructor(message, schemaId, diagnostics = [], source, cause) {
|
|
774
754
|
super(message);
|
|
@@ -908,100 +888,10 @@ Source: ${this.source.type}`;
|
|
|
908
888
|
};
|
|
909
889
|
}
|
|
910
890
|
};
|
|
911
|
-
SchemaExportError = class _SchemaExportError extends SchemaValidationError {
|
|
912
|
-
constructor(message, reason, schemaId, outPath, cause) {
|
|
913
|
-
super(message, schemaId, [], void 0, cause);
|
|
914
|
-
this.reason = reason;
|
|
915
|
-
this.schemaId = schemaId;
|
|
916
|
-
this.outPath = outPath;
|
|
917
|
-
this.cause = cause;
|
|
918
|
-
this.name = "SchemaExportError";
|
|
919
|
-
if (Error.captureStackTrace) {
|
|
920
|
-
Error.captureStackTrace(this, _SchemaExportError);
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
/**
|
|
924
|
-
* Create error for file already exists
|
|
925
|
-
*/
|
|
926
|
-
static fileExists(outPath) {
|
|
927
|
-
return new _SchemaExportError(
|
|
928
|
-
`Output file already exists: ${outPath}. Use overwrite option to replace.`,
|
|
929
|
-
"FILE_EXISTS" /* FILE_EXISTS */,
|
|
930
|
-
void 0,
|
|
931
|
-
outPath
|
|
932
|
-
);
|
|
933
|
-
}
|
|
934
|
-
/**
|
|
935
|
-
* Create error for invalid export format
|
|
936
|
-
*/
|
|
937
|
-
static invalidFormat(format, outPath) {
|
|
938
|
-
return new _SchemaExportError(
|
|
939
|
-
`Invalid export format: ${format}. Must be 'json' or 'yaml'.`,
|
|
940
|
-
"INVALID_FORMAT" /* INVALID_FORMAT */,
|
|
941
|
-
void 0,
|
|
942
|
-
outPath
|
|
943
|
-
);
|
|
944
|
-
}
|
|
945
|
-
/**
|
|
946
|
-
* Create error for write failure
|
|
947
|
-
*/
|
|
948
|
-
static writeFailed(outPath, error) {
|
|
949
|
-
return new _SchemaExportError(
|
|
950
|
-
`Failed to write schema to ${outPath}: ${error.message}`,
|
|
951
|
-
"WRITE_FAILED" /* WRITE_FAILED */,
|
|
952
|
-
void 0,
|
|
953
|
-
outPath,
|
|
954
|
-
error
|
|
955
|
-
);
|
|
956
|
-
}
|
|
957
|
-
/**
|
|
958
|
-
* Create error for provenance extraction failure
|
|
959
|
-
*/
|
|
960
|
-
static provenanceFailed(details, error) {
|
|
961
|
-
return new _SchemaExportError(
|
|
962
|
-
`Failed to extract provenance metadata: ${details}`,
|
|
963
|
-
"PROVENANCE_FAILED" /* PROVENANCE_FAILED */,
|
|
964
|
-
void 0,
|
|
965
|
-
void 0,
|
|
966
|
-
error
|
|
967
|
-
);
|
|
968
|
-
}
|
|
969
|
-
};
|
|
970
891
|
}
|
|
971
892
|
});
|
|
972
893
|
|
|
973
894
|
// src/schema/utils.ts
|
|
974
|
-
function formatDiagnostics(diagnostics) {
|
|
975
|
-
if (diagnostics.length === 0) {
|
|
976
|
-
return "No validation issues found.";
|
|
977
|
-
}
|
|
978
|
-
const lines = [];
|
|
979
|
-
const errors = diagnostics.filter((d) => d.severity === "ERROR");
|
|
980
|
-
const warnings = diagnostics.filter((d) => d.severity === "WARN");
|
|
981
|
-
if (errors.length > 0) {
|
|
982
|
-
lines.push(`\u274C ${errors.length} error(s) found:`);
|
|
983
|
-
errors.forEach((diag, index) => {
|
|
984
|
-
lines.push(` ${index + 1}. ${diag.message}`);
|
|
985
|
-
if (diag.pointer) {
|
|
986
|
-
lines.push(` at ${diag.pointer}`);
|
|
987
|
-
}
|
|
988
|
-
if (diag.keyword) {
|
|
989
|
-
lines.push(` keyword: ${diag.keyword}`);
|
|
990
|
-
}
|
|
991
|
-
});
|
|
992
|
-
}
|
|
993
|
-
if (warnings.length > 0) {
|
|
994
|
-
lines.push("");
|
|
995
|
-
lines.push(`\u26A0\uFE0F ${warnings.length} warning(s) found:`);
|
|
996
|
-
warnings.forEach((diag, index) => {
|
|
997
|
-
lines.push(` ${index + 1}. ${diag.message}`);
|
|
998
|
-
if (diag.pointer) {
|
|
999
|
-
lines.push(` at ${diag.pointer}`);
|
|
1000
|
-
}
|
|
1001
|
-
});
|
|
1002
|
-
}
|
|
1003
|
-
return lines.join("\n");
|
|
1004
|
-
}
|
|
1005
895
|
function createDiagnostic(pointer, message, keyword, severity = "ERROR", source = "ajv", data) {
|
|
1006
896
|
return {
|
|
1007
897
|
pointer,
|
|
@@ -1017,261 +907,27 @@ var init_utils = __esm({
|
|
|
1017
907
|
init_errors();
|
|
1018
908
|
}
|
|
1019
909
|
});
|
|
1020
|
-
async function detectGoneat(customPath) {
|
|
1021
|
-
if (customPath) {
|
|
1022
|
-
try {
|
|
1023
|
-
await access(customPath);
|
|
1024
|
-
return customPath;
|
|
1025
|
-
} catch {
|
|
1026
|
-
return null;
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
if (process.env.GONEAT_PATH) {
|
|
1030
|
-
try {
|
|
1031
|
-
await access(process.env.GONEAT_PATH);
|
|
1032
|
-
return process.env.GONEAT_PATH;
|
|
1033
|
-
} catch {
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
try {
|
|
1037
|
-
await access("./bin/goneat");
|
|
1038
|
-
return "./bin/goneat";
|
|
1039
|
-
} catch {
|
|
1040
|
-
}
|
|
1041
|
-
return "goneat";
|
|
1042
|
-
}
|
|
1043
|
-
async function isGoneatAvailable(goneatPath) {
|
|
1044
|
-
let pathToTest;
|
|
1045
|
-
if (goneatPath) {
|
|
1046
|
-
pathToTest = goneatPath;
|
|
1047
|
-
} else {
|
|
1048
|
-
pathToTest = await detectGoneat();
|
|
1049
|
-
if (!pathToTest) return false;
|
|
1050
|
-
}
|
|
1051
|
-
return new Promise((resolve) => {
|
|
1052
|
-
const proc = spawn(pathToTest, ["version"], { stdio: "ignore" });
|
|
1053
|
-
const timeout = setTimeout(() => {
|
|
1054
|
-
proc.kill();
|
|
1055
|
-
resolve(false);
|
|
1056
|
-
}, 5e3);
|
|
1057
|
-
proc.on("close", (code) => {
|
|
1058
|
-
clearTimeout(timeout);
|
|
1059
|
-
resolve(code === 0);
|
|
1060
|
-
});
|
|
1061
|
-
proc.on("error", () => {
|
|
1062
|
-
clearTimeout(timeout);
|
|
1063
|
-
resolve(false);
|
|
1064
|
-
});
|
|
1065
|
-
});
|
|
1066
|
-
}
|
|
1067
|
-
async function runGoneatValidation(schemaPath, dataPath, goneatPath) {
|
|
1068
|
-
const detected = await detectGoneat(goneatPath);
|
|
1069
|
-
if (!detected) {
|
|
1070
|
-
return {
|
|
1071
|
-
valid: false,
|
|
1072
|
-
diagnostics: [
|
|
1073
|
-
createDiagnostic(
|
|
1074
|
-
"",
|
|
1075
|
-
"goneat binary not found. Install goneat or specify path with --goneat-path",
|
|
1076
|
-
"goneat-unavailable",
|
|
1077
|
-
"ERROR",
|
|
1078
|
-
"goneat"
|
|
1079
|
-
)
|
|
1080
|
-
],
|
|
1081
|
-
source: "goneat"
|
|
1082
|
-
};
|
|
1083
|
-
}
|
|
1084
|
-
if (!await isGoneatAvailable(detected)) {
|
|
1085
|
-
return {
|
|
1086
|
-
valid: false,
|
|
1087
|
-
diagnostics: [
|
|
1088
|
-
createDiagnostic(
|
|
1089
|
-
"",
|
|
1090
|
-
`goneat binary found at '${detected}' but not executable or version check failed`,
|
|
1091
|
-
"goneat-not-executable",
|
|
1092
|
-
"ERROR",
|
|
1093
|
-
"goneat"
|
|
1094
|
-
)
|
|
1095
|
-
],
|
|
1096
|
-
source: "goneat"
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
|
-
return new Promise((resolve) => {
|
|
1100
|
-
const args = [
|
|
1101
|
-
"schema",
|
|
1102
|
-
"validate",
|
|
1103
|
-
"--schema",
|
|
1104
|
-
schemaPath,
|
|
1105
|
-
"--data",
|
|
1106
|
-
dataPath,
|
|
1107
|
-
"--format",
|
|
1108
|
-
"json"
|
|
1109
|
-
];
|
|
1110
|
-
const proc = spawn(detected, args);
|
|
1111
|
-
let stdout = "";
|
|
1112
|
-
let stderr = "";
|
|
1113
|
-
proc.stdout.on("data", (data) => {
|
|
1114
|
-
stdout += data.toString();
|
|
1115
|
-
});
|
|
1116
|
-
proc.stderr.on("data", (data) => {
|
|
1117
|
-
stderr += data.toString();
|
|
1118
|
-
});
|
|
1119
|
-
proc.on("close", (code) => {
|
|
1120
|
-
let output;
|
|
1121
|
-
try {
|
|
1122
|
-
output = JSON.parse(stdout);
|
|
1123
|
-
} catch {
|
|
1124
|
-
resolve({
|
|
1125
|
-
valid: false,
|
|
1126
|
-
diagnostics: [
|
|
1127
|
-
createDiagnostic(
|
|
1128
|
-
"",
|
|
1129
|
-
`goneat validation failed: ${stderr || "unknown error"}`,
|
|
1130
|
-
"goneat-error",
|
|
1131
|
-
"ERROR",
|
|
1132
|
-
"goneat"
|
|
1133
|
-
)
|
|
1134
|
-
],
|
|
1135
|
-
source: "goneat"
|
|
1136
|
-
});
|
|
1137
|
-
return;
|
|
1138
|
-
}
|
|
1139
|
-
const diagnostics = output.errors?.map(
|
|
1140
|
-
(error) => createDiagnostic(
|
|
1141
|
-
error.path || "",
|
|
1142
|
-
error.message,
|
|
1143
|
-
error.keyword || "validation",
|
|
1144
|
-
"ERROR",
|
|
1145
|
-
"goneat"
|
|
1146
|
-
)
|
|
1147
|
-
) || [];
|
|
1148
|
-
resolve({
|
|
1149
|
-
valid: code === 0 && output.valid,
|
|
1150
|
-
diagnostics,
|
|
1151
|
-
source: "goneat"
|
|
1152
|
-
});
|
|
1153
|
-
});
|
|
1154
|
-
proc.on("error", (error) => {
|
|
1155
|
-
resolve({
|
|
1156
|
-
valid: false,
|
|
1157
|
-
diagnostics: [
|
|
1158
|
-
createDiagnostic(
|
|
1159
|
-
"",
|
|
1160
|
-
`Failed to execute goneat: ${error.message}`,
|
|
1161
|
-
"goneat-spawn-error",
|
|
1162
|
-
"ERROR",
|
|
1163
|
-
"goneat"
|
|
1164
|
-
)
|
|
1165
|
-
],
|
|
1166
|
-
source: "goneat"
|
|
1167
|
-
});
|
|
1168
|
-
});
|
|
1169
|
-
});
|
|
1170
|
-
}
|
|
1171
910
|
var init_goneat_bridge = __esm({
|
|
1172
911
|
"src/schema/goneat-bridge.ts"() {
|
|
1173
912
|
init_utils();
|
|
1174
913
|
}
|
|
1175
914
|
});
|
|
1176
|
-
function parseSchemaInput(input) {
|
|
1177
|
-
if (!input) {
|
|
1178
|
-
throw SchemaValidationError.parseFailed(
|
|
1179
|
-
{ type: "string", content: "" },
|
|
1180
|
-
new Error("schema content is empty")
|
|
1181
|
-
);
|
|
1182
|
-
}
|
|
1183
|
-
try {
|
|
1184
|
-
if (typeof input === "string") {
|
|
1185
|
-
try {
|
|
1186
|
-
return JSON.parse(input);
|
|
1187
|
-
} catch {
|
|
1188
|
-
return parse(input);
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
if (Buffer.isBuffer(input)) {
|
|
1192
|
-
const content = input.toString("utf-8");
|
|
1193
|
-
try {
|
|
1194
|
-
return JSON.parse(content);
|
|
1195
|
-
} catch {
|
|
1196
|
-
return parse(content);
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
return input;
|
|
1200
|
-
} catch (error) {
|
|
1201
|
-
throw SchemaValidationError.parseFailed(
|
|
1202
|
-
{
|
|
1203
|
-
type: typeof input === "string" ? "string" : "object",
|
|
1204
|
-
content: typeof input === "string" ? input : JSON.stringify(input)
|
|
1205
|
-
},
|
|
1206
|
-
error
|
|
1207
|
-
);
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
function sortObjectKeys(obj) {
|
|
1211
|
-
if (obj === null || typeof obj !== "object") {
|
|
1212
|
-
return obj;
|
|
1213
|
-
}
|
|
1214
|
-
if (Array.isArray(obj)) {
|
|
1215
|
-
return obj.map(sortObjectKeys);
|
|
1216
|
-
}
|
|
1217
|
-
const sorted = {};
|
|
1218
|
-
const keys = Object.keys(obj).sort();
|
|
1219
|
-
for (const key of keys) {
|
|
1220
|
-
sorted[key] = sortObjectKeys(obj[key]);
|
|
1221
|
-
}
|
|
1222
|
-
return sorted;
|
|
1223
|
-
}
|
|
1224
|
-
function normalizeSchema(input, options = {}) {
|
|
1225
|
-
try {
|
|
1226
|
-
const parsed = parseSchemaInput(input);
|
|
1227
|
-
const sorted = sortObjectKeys(parsed);
|
|
1228
|
-
if (options.compact) {
|
|
1229
|
-
return JSON.stringify(sorted);
|
|
1230
|
-
}
|
|
1231
|
-
return JSON.stringify(sorted, null, 2);
|
|
1232
|
-
} catch (error) {
|
|
1233
|
-
if (error instanceof SchemaValidationError) {
|
|
1234
|
-
throw error;
|
|
1235
|
-
}
|
|
1236
|
-
throw SchemaValidationError.parseFailed(
|
|
1237
|
-
{
|
|
1238
|
-
type: typeof input === "string" ? "string" : "object",
|
|
1239
|
-
content: typeof input === "string" ? input : JSON.stringify(input)
|
|
1240
|
-
},
|
|
1241
|
-
error
|
|
1242
|
-
);
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
function compareSchemas(schemaA, schemaB, options = {}) {
|
|
1246
|
-
const normalizedA = normalizeSchema(schemaA, options);
|
|
1247
|
-
const normalizedB = normalizeSchema(schemaB, options);
|
|
1248
|
-
return {
|
|
1249
|
-
equal: normalizedA === normalizedB,
|
|
1250
|
-
normalizedA,
|
|
1251
|
-
normalizedB
|
|
1252
|
-
};
|
|
1253
|
-
}
|
|
1254
915
|
var init_normalizer = __esm({
|
|
1255
916
|
"src/schema/normalizer.ts"() {
|
|
1256
917
|
init_errors();
|
|
1257
918
|
}
|
|
1258
919
|
});
|
|
1259
920
|
function optionsChanged(newOptions) {
|
|
1260
|
-
if (!
|
|
1261
|
-
|
|
1262
|
-
return newOptions.baseDir !== globalRegistryOptions.baseDir || JSON.stringify(newOptions.patterns) !== JSON.stringify(globalRegistryOptions.patterns) || newOptions.followSymlinks !== globalRegistryOptions.followSymlinks || newOptions.maxDepth !== globalRegistryOptions.maxDepth;
|
|
921
|
+
if (!globalRegistryOptions) return false;
|
|
922
|
+
return true;
|
|
1263
923
|
}
|
|
1264
924
|
function getSchemaRegistry(options) {
|
|
1265
|
-
if (!globalRegistry || optionsChanged(
|
|
925
|
+
if (!globalRegistry || optionsChanged()) {
|
|
1266
926
|
globalRegistry = new SchemaRegistry(options);
|
|
1267
927
|
globalRegistryOptions = options;
|
|
1268
928
|
}
|
|
1269
929
|
return globalRegistry;
|
|
1270
930
|
}
|
|
1271
|
-
async function listSchemas(prefix, options) {
|
|
1272
|
-
const registry = getSchemaRegistry(options);
|
|
1273
|
-
return registry.listSchemas(prefix);
|
|
1274
|
-
}
|
|
1275
931
|
var DEFAULT_PATTERNS, SchemaRegistry, globalRegistry, globalRegistryOptions;
|
|
1276
932
|
var init_registry2 = __esm({
|
|
1277
933
|
"src/schema/registry.ts"() {
|
|
@@ -1297,1277 +953,163 @@ var init_registry2 = __esm({
|
|
|
1297
953
|
return join(__dirname4, "..", "..", "schemas", "crucible-ts");
|
|
1298
954
|
}
|
|
1299
955
|
/**
|
|
1300
|
-
* Build logical schema ID from file path
|
|
1301
|
-
*/
|
|
1302
|
-
buildSchemaId(filePath, baseDir) {
|
|
1303
|
-
const relativePath = relative(baseDir, filePath);
|
|
1304
|
-
const withoutExt = relativePath.replace(/\.(schema\.(json|yaml|yml))$/, "");
|
|
1305
|
-
return withoutExt.replace(/\\/g, "/");
|
|
1306
|
-
}
|
|
1307
|
-
/**
|
|
1308
|
-
* Extract schema format from file extension
|
|
1309
|
-
*/
|
|
1310
|
-
getSchemaFormat(filePath) {
|
|
1311
|
-
const ext = extname(filePath).toLowerCase();
|
|
1312
|
-
switch (ext) {
|
|
1313
|
-
case ".json":
|
|
1314
|
-
return "json";
|
|
1315
|
-
case ".yaml":
|
|
1316
|
-
case ".yml":
|
|
1317
|
-
return "yaml";
|
|
1318
|
-
default:
|
|
1319
|
-
return "json";
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
/**
|
|
1323
|
-
* Extract metadata from schema file
|
|
1324
|
-
*/
|
|
1325
|
-
async extractMetadata(filePath) {
|
|
1326
|
-
try {
|
|
1327
|
-
const content = await readFile(filePath, "utf-8");
|
|
1328
|
-
const format = this.getSchemaFormat(filePath);
|
|
1329
|
-
let parsed;
|
|
1330
|
-
if (format === "yaml") {
|
|
1331
|
-
parsed = parse(content);
|
|
1332
|
-
} else {
|
|
1333
|
-
parsed = JSON.parse(content);
|
|
1334
|
-
}
|
|
1335
|
-
const baseDir = this.options.baseDir ?? "";
|
|
1336
|
-
const relativePath = relative(baseDir, filePath);
|
|
1337
|
-
return {
|
|
1338
|
-
id: this.buildSchemaId(filePath, baseDir),
|
|
1339
|
-
path: filePath,
|
|
1340
|
-
relativePath,
|
|
1341
|
-
format,
|
|
1342
|
-
version: parsed.$schema || parsed.version,
|
|
1343
|
-
description: parsed.title || parsed.description,
|
|
1344
|
-
schemaDraft: parsed.$schema
|
|
1345
|
-
};
|
|
1346
|
-
} catch (error) {
|
|
1347
|
-
throw SchemaValidationError.registryError(
|
|
1348
|
-
"metadata extraction",
|
|
1349
|
-
`Failed to process ${filePath}: ${error.message}`
|
|
1350
|
-
);
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
/**
|
|
1354
|
-
* Discover and index all available schemas
|
|
1355
|
-
*/
|
|
1356
|
-
async discoverSchemas() {
|
|
1357
|
-
try {
|
|
1358
|
-
const baseDir = this.options.baseDir ?? "";
|
|
1359
|
-
const patterns = this.options.patterns ?? [];
|
|
1360
|
-
if (patterns.length === 0) {
|
|
1361
|
-
this.schemas.clear();
|
|
1362
|
-
return;
|
|
1363
|
-
}
|
|
1364
|
-
const pattern = patterns.map((p) => join(baseDir, p));
|
|
1365
|
-
try {
|
|
1366
|
-
await access(baseDir);
|
|
1367
|
-
} catch {
|
|
1368
|
-
this.schemas.clear();
|
|
1369
|
-
return;
|
|
1370
|
-
}
|
|
1371
|
-
const files = await glob(pattern, {
|
|
1372
|
-
absolute: true,
|
|
1373
|
-
followSymbolicLinks: this.options.followSymlinks,
|
|
1374
|
-
deep: this.options.maxDepth,
|
|
1375
|
-
onlyFiles: true,
|
|
1376
|
-
suppressErrors: true
|
|
1377
|
-
// Don't throw on permission errors
|
|
1378
|
-
});
|
|
1379
|
-
this.schemas.clear();
|
|
1380
|
-
for (const filePath of files) {
|
|
1381
|
-
try {
|
|
1382
|
-
const metadata = await this.extractMetadata(filePath);
|
|
1383
|
-
this.schemas.set(metadata.id, metadata);
|
|
1384
|
-
} catch (error) {
|
|
1385
|
-
console.warn(`Warning: Failed to process schema ${filePath}:`, error);
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
} catch (error) {
|
|
1389
|
-
throw SchemaValidationError.registryError("discovery", error.message);
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
/**
|
|
1393
|
-
* List available schemas with optional prefix filtering
|
|
1394
|
-
*/
|
|
1395
|
-
async listSchemas(prefix) {
|
|
1396
|
-
if (this.schemas.size === 0) {
|
|
1397
|
-
await this.discoverSchemas();
|
|
1398
|
-
}
|
|
1399
|
-
const schemas = Array.from(this.schemas.values());
|
|
1400
|
-
if (prefix) {
|
|
1401
|
-
return schemas.filter((schema) => schema.id.startsWith(prefix));
|
|
1402
|
-
}
|
|
1403
|
-
return schemas;
|
|
1404
|
-
}
|
|
1405
|
-
/**
|
|
1406
|
-
* Get schema by logical ID
|
|
1407
|
-
*/
|
|
1408
|
-
async getSchema(id) {
|
|
1409
|
-
if (this.schemas.size === 0) {
|
|
1410
|
-
await this.discoverSchemas();
|
|
1411
|
-
}
|
|
1412
|
-
const schema = this.schemas.get(id);
|
|
1413
|
-
if (!schema) {
|
|
1414
|
-
throw SchemaValidationError.schemaNotFound(id);
|
|
1415
|
-
}
|
|
1416
|
-
return schema;
|
|
1417
|
-
}
|
|
1418
|
-
/**
|
|
1419
|
-
* Get schema by file path
|
|
1420
|
-
*/
|
|
1421
|
-
async getSchemaByPath(filePath) {
|
|
1422
|
-
if (this.schemas.size === 0) {
|
|
1423
|
-
await this.discoverSchemas();
|
|
1424
|
-
}
|
|
1425
|
-
const absolutePath = filePath.startsWith("/") ? filePath : join(process.cwd(), filePath);
|
|
1426
|
-
for (const schema of this.schemas.values()) {
|
|
1427
|
-
if (schema.path === absolutePath) {
|
|
1428
|
-
return schema;
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
throw SchemaValidationError.schemaNotFound(filePath);
|
|
1432
|
-
}
|
|
1433
|
-
/**
|
|
1434
|
-
* Check if schema exists
|
|
1435
|
-
*/
|
|
1436
|
-
async hasSchema(id) {
|
|
1437
|
-
if (this.schemas.size === 0) {
|
|
1438
|
-
await this.discoverSchemas();
|
|
1439
|
-
}
|
|
1440
|
-
return this.schemas.has(id);
|
|
1441
|
-
}
|
|
1442
|
-
/**
|
|
1443
|
-
* Get registry size
|
|
1444
|
-
*/
|
|
1445
|
-
get size() {
|
|
1446
|
-
return this.schemas.size;
|
|
1447
|
-
}
|
|
1448
|
-
/**
|
|
1449
|
-
* Clear registry cache
|
|
1450
|
-
*/
|
|
1451
|
-
clear() {
|
|
1452
|
-
this.schemas.clear();
|
|
1453
|
-
}
|
|
1454
|
-
};
|
|
1455
|
-
}
|
|
1456
|
-
});
|
|
1457
|
-
|
|
1458
|
-
// src/schema/export.ts
|
|
1459
|
-
var export_exports = {};
|
|
1460
|
-
__export(export_exports, {
|
|
1461
|
-
exportSchema: () => exportSchema,
|
|
1462
|
-
stripProvenance: () => stripProvenance
|
|
1463
|
-
});
|
|
1464
|
-
async function extractProvenanceMetadata(schemaId) {
|
|
1465
|
-
try {
|
|
1466
|
-
const __filename3 = fileURLToPath(import.meta.url);
|
|
1467
|
-
const __dirname4 = dirname(__filename3);
|
|
1468
|
-
const metadataPath = join(__dirname4, "..", "..", ".crucible", "metadata", "metadata.yaml");
|
|
1469
|
-
const metadataContent = await readFile(metadataPath, "utf-8");
|
|
1470
|
-
const metadata = parse(metadataContent);
|
|
1471
|
-
const crucibleSource = metadata.sources?.[0];
|
|
1472
|
-
const crucibleVersion = crucibleSource?.version || "unknown";
|
|
1473
|
-
const revision = crucibleSource?.commit;
|
|
1474
|
-
const pkgPath = join(__dirname4, "..", "..", "package.json");
|
|
1475
|
-
const pkgContent = await readFile(pkgPath, "utf-8");
|
|
1476
|
-
const pkg = JSON.parse(pkgContent);
|
|
1477
|
-
return {
|
|
1478
|
-
schema_id: schemaId,
|
|
1479
|
-
crucible_version: crucibleVersion,
|
|
1480
|
-
library_version: pkg.version,
|
|
1481
|
-
revision,
|
|
1482
|
-
exported_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1483
|
-
export_source: "tsfulmen"
|
|
1484
|
-
};
|
|
1485
|
-
} catch (error) {
|
|
1486
|
-
throw SchemaExportError.provenanceFailed(error.message, error);
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
function embedProvenance(schemaContent, provenance, format) {
|
|
1490
|
-
if (format === "json") {
|
|
1491
|
-
const withProvenance = {
|
|
1492
|
-
...schemaContent,
|
|
1493
|
-
$comment: {
|
|
1494
|
-
...typeof schemaContent.$comment === "object" ? schemaContent.$comment : {},
|
|
1495
|
-
"x-crucible-source": provenance
|
|
1496
|
-
}
|
|
1497
|
-
};
|
|
1498
|
-
return JSON.stringify(withProvenance, null, 2);
|
|
1499
|
-
}
|
|
1500
|
-
const yamlContent = stringify(schemaContent, {
|
|
1501
|
-
indent: 2,
|
|
1502
|
-
lineWidth: 0
|
|
1503
|
-
});
|
|
1504
|
-
const provenanceComment = [
|
|
1505
|
-
"# x-crucible-source:",
|
|
1506
|
-
`# schema_id: ${provenance.schema_id}`,
|
|
1507
|
-
`# crucible_version: ${provenance.crucible_version}`,
|
|
1508
|
-
`# library_version: ${provenance.library_version}`,
|
|
1509
|
-
...provenance.revision ? [`# revision: ${provenance.revision}`] : [],
|
|
1510
|
-
`# exported_at: ${provenance.exported_at}`,
|
|
1511
|
-
`# export_source: ${provenance.export_source}`,
|
|
1512
|
-
""
|
|
1513
|
-
].join("\n");
|
|
1514
|
-
return provenanceComment + yamlContent;
|
|
1515
|
-
}
|
|
1516
|
-
function detectFormat(outPath, formatOption) {
|
|
1517
|
-
if (formatOption && formatOption !== "auto") {
|
|
1518
|
-
return formatOption;
|
|
1519
|
-
}
|
|
1520
|
-
const ext = extname(outPath).toLowerCase();
|
|
1521
|
-
switch (ext) {
|
|
1522
|
-
case ".json":
|
|
1523
|
-
return "json";
|
|
1524
|
-
case ".yaml":
|
|
1525
|
-
case ".yml":
|
|
1526
|
-
return "yaml";
|
|
1527
|
-
default:
|
|
1528
|
-
throw SchemaExportError.invalidFormat(ext, outPath);
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
async function exportSchema(options) {
|
|
1532
|
-
const {
|
|
1533
|
-
schemaId,
|
|
1534
|
-
outPath,
|
|
1535
|
-
includeProvenance = true,
|
|
1536
|
-
validate = true,
|
|
1537
|
-
overwrite = false,
|
|
1538
|
-
format: formatOption,
|
|
1539
|
-
baseDir
|
|
1540
|
-
} = options;
|
|
1541
|
-
const format = detectFormat(outPath, formatOption);
|
|
1542
|
-
if (!overwrite) {
|
|
1543
|
-
try {
|
|
1544
|
-
await access(outPath);
|
|
1545
|
-
throw SchemaExportError.fileExists(outPath);
|
|
1546
|
-
} catch (error) {
|
|
1547
|
-
if (error.code !== "ENOENT") {
|
|
1548
|
-
throw error;
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
const registry = getSchemaRegistry({ baseDir });
|
|
1553
|
-
const schema = await registry.getSchema(schemaId);
|
|
1554
|
-
const schemaContent = await readFile(schema.path, "utf-8");
|
|
1555
|
-
if (validate) {
|
|
1556
|
-
const validationResult = await validateSchema(schemaContent);
|
|
1557
|
-
if (!validationResult.valid) {
|
|
1558
|
-
throw SchemaValidationError.validationFailed(schemaId, validationResult.diagnostics, {
|
|
1559
|
-
type: "file",
|
|
1560
|
-
id: schema.path
|
|
1561
|
-
});
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
let schemaObject;
|
|
1565
|
-
try {
|
|
1566
|
-
schemaObject = JSON.parse(schemaContent);
|
|
1567
|
-
} catch {
|
|
1568
|
-
schemaObject = parse(schemaContent);
|
|
1569
|
-
}
|
|
1570
|
-
Object.freeze(schemaObject);
|
|
1571
|
-
let provenance;
|
|
1572
|
-
let outputContent;
|
|
1573
|
-
if (includeProvenance) {
|
|
1574
|
-
provenance = await extractProvenanceMetadata(schemaId);
|
|
1575
|
-
outputContent = embedProvenance(schemaObject, provenance, format);
|
|
1576
|
-
} else {
|
|
1577
|
-
if (format === "json") {
|
|
1578
|
-
outputContent = JSON.stringify(schemaObject, null, 2);
|
|
1579
|
-
} else {
|
|
1580
|
-
outputContent = stringify(schemaObject, { indent: 2, lineWidth: 0 });
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
await mkdir(dirname(outPath), { recursive: true });
|
|
1584
|
-
try {
|
|
1585
|
-
await writeFile(outPath, outputContent, "utf-8");
|
|
1586
|
-
} catch (error) {
|
|
1587
|
-
throw SchemaExportError.writeFailed(outPath, error);
|
|
1588
|
-
}
|
|
1589
|
-
return {
|
|
1590
|
-
success: true,
|
|
1591
|
-
schemaId,
|
|
1592
|
-
outPath,
|
|
1593
|
-
format,
|
|
1594
|
-
includeProvenance,
|
|
1595
|
-
provenance
|
|
1596
|
-
};
|
|
1597
|
-
}
|
|
1598
|
-
function stripProvenance(content) {
|
|
1599
|
-
try {
|
|
1600
|
-
const parsed = JSON.parse(content);
|
|
1601
|
-
if (parsed.$comment && typeof parsed.$comment === "object") {
|
|
1602
|
-
const comment = { ...parsed.$comment };
|
|
1603
|
-
delete comment["x-crucible-source"];
|
|
1604
|
-
if (Object.keys(comment).length === 0) {
|
|
1605
|
-
delete parsed.$comment;
|
|
1606
|
-
} else {
|
|
1607
|
-
parsed.$comment = comment;
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1610
|
-
return JSON.stringify(parsed, null, 2);
|
|
1611
|
-
} catch {
|
|
1612
|
-
const lines = content.split("\n");
|
|
1613
|
-
const filtered = lines.filter((line) => {
|
|
1614
|
-
const trimmed = line.trim();
|
|
1615
|
-
return !(trimmed.startsWith("# x-crucible-source:") || trimmed.startsWith("# ") && /^#\s+(schema_id|crucible_version|library_version|revision|exported_at|export_source):/.test(
|
|
1616
|
-
trimmed
|
|
1617
|
-
));
|
|
1618
|
-
});
|
|
1619
|
-
while (filtered.length > 0 && filtered[0]?.trim() === "") {
|
|
1620
|
-
filtered.shift();
|
|
1621
|
-
}
|
|
1622
|
-
return filtered.join("\n");
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
var init_export = __esm({
|
|
1626
|
-
"src/schema/export.ts"() {
|
|
1627
|
-
init_errors();
|
|
1628
|
-
init_registry2();
|
|
1629
|
-
init_validator();
|
|
1630
|
-
}
|
|
1631
|
-
});
|
|
1632
|
-
|
|
1633
|
-
// src/appidentity/cache.ts
|
|
1634
|
-
function getCachedIdentity() {
|
|
1635
|
-
return cachedIdentity;
|
|
1636
|
-
}
|
|
1637
|
-
function setCachedIdentity(identity) {
|
|
1638
|
-
cachedIdentity = identity;
|
|
1639
|
-
}
|
|
1640
|
-
function clearIdentityCache() {
|
|
1641
|
-
cachedIdentity = null;
|
|
1642
|
-
}
|
|
1643
|
-
var cachedIdentity;
|
|
1644
|
-
var init_cache = __esm({
|
|
1645
|
-
"src/appidentity/cache.ts"() {
|
|
1646
|
-
cachedIdentity = null;
|
|
1647
|
-
}
|
|
1648
|
-
});
|
|
1649
|
-
|
|
1650
|
-
// src/appidentity/constants.ts
|
|
1651
|
-
var APP_IDENTITY_FILENAME, APP_IDENTITY_DIR, APP_IDENTITY_ENV_VAR, APP_IDENTITY_SCHEMA_ID, MAX_ANCESTOR_SEARCH_DEPTH;
|
|
1652
|
-
var init_constants = __esm({
|
|
1653
|
-
"src/appidentity/constants.ts"() {
|
|
1654
|
-
APP_IDENTITY_FILENAME = "app.yaml";
|
|
1655
|
-
APP_IDENTITY_DIR = ".fulmen";
|
|
1656
|
-
APP_IDENTITY_ENV_VAR = "FULMEN_APP_IDENTITY_PATH";
|
|
1657
|
-
APP_IDENTITY_SCHEMA_ID = "config/repository/app-identity/v1.0.0/app-identity";
|
|
1658
|
-
MAX_ANCESTOR_SEARCH_DEPTH = 20;
|
|
1659
|
-
}
|
|
1660
|
-
});
|
|
1661
|
-
var init_correlation = __esm({
|
|
1662
|
-
"src/errors/correlation.ts"() {
|
|
1663
|
-
}
|
|
1664
|
-
});
|
|
1665
|
-
|
|
1666
|
-
// src/errors/severity.ts
|
|
1667
|
-
function getDefaultSeverity() {
|
|
1668
|
-
return {
|
|
1669
|
-
name: Severity.MEDIUM,
|
|
1670
|
-
level: 2
|
|
1671
|
-
};
|
|
1672
|
-
}
|
|
1673
|
-
var Severity, SEVERITY_LEVELS;
|
|
1674
|
-
var init_severity = __esm({
|
|
1675
|
-
"src/errors/severity.ts"() {
|
|
1676
|
-
Severity = {
|
|
1677
|
-
INFO: "info",
|
|
1678
|
-
LOW: "low",
|
|
1679
|
-
MEDIUM: "medium",
|
|
1680
|
-
HIGH: "high",
|
|
1681
|
-
CRITICAL: "critical"
|
|
1682
|
-
};
|
|
1683
|
-
SEVERITY_LEVELS = {
|
|
1684
|
-
info: 0,
|
|
1685
|
-
low: 1,
|
|
1686
|
-
medium: 2,
|
|
1687
|
-
high: 3,
|
|
1688
|
-
critical: 4
|
|
1689
|
-
};
|
|
1690
|
-
}
|
|
1691
|
-
});
|
|
1692
|
-
|
|
1693
|
-
// src/errors/serialization.ts
|
|
1694
|
-
function extractErrorMessage(error) {
|
|
1695
|
-
if (error instanceof Error) {
|
|
1696
|
-
return error.message;
|
|
1697
|
-
}
|
|
1698
|
-
if (isErrorLike(error)) {
|
|
1699
|
-
return error.message;
|
|
1700
|
-
}
|
|
1701
|
-
if (typeof error === "string") {
|
|
1702
|
-
return error;
|
|
1703
|
-
}
|
|
1704
|
-
return String(error);
|
|
1705
|
-
}
|
|
1706
|
-
function extractStackTrace(error) {
|
|
1707
|
-
if (error instanceof Error) {
|
|
1708
|
-
return error.stack;
|
|
1709
|
-
}
|
|
1710
|
-
if (isErrorLike(error) && typeof error.stack === "string") {
|
|
1711
|
-
return error.stack;
|
|
1712
|
-
}
|
|
1713
|
-
return void 0;
|
|
1714
|
-
}
|
|
1715
|
-
function isErrorLike(value) {
|
|
1716
|
-
return typeof value === "object" && value !== null && "message" in value && typeof value.message === "string";
|
|
1717
|
-
}
|
|
1718
|
-
var init_serialization = __esm({
|
|
1719
|
-
"src/errors/serialization.ts"() {
|
|
1720
|
-
init_severity();
|
|
1721
|
-
}
|
|
1722
|
-
});
|
|
1723
|
-
|
|
1724
|
-
// src/errors/validators.ts
|
|
1725
|
-
async function validateErrorData(data) {
|
|
1726
|
-
return ErrorValidator.getInstance().validate(data);
|
|
1727
|
-
}
|
|
1728
|
-
var ErrorValidator;
|
|
1729
|
-
var init_validators = __esm({
|
|
1730
|
-
"src/errors/validators.ts"() {
|
|
1731
|
-
init_schema();
|
|
1732
|
-
ErrorValidator = class _ErrorValidator {
|
|
1733
|
-
static instance;
|
|
1734
|
-
validateFn = null;
|
|
1735
|
-
initPromise = null;
|
|
1736
|
-
initError = null;
|
|
1737
|
-
constructor() {
|
|
1738
|
-
}
|
|
1739
|
-
/**
|
|
1740
|
-
* Get singleton instance
|
|
1741
|
-
*/
|
|
1742
|
-
static getInstance() {
|
|
1743
|
-
if (!_ErrorValidator.instance) {
|
|
1744
|
-
_ErrorValidator.instance = new _ErrorValidator();
|
|
1745
|
-
}
|
|
1746
|
-
return _ErrorValidator.instance;
|
|
1747
|
-
}
|
|
1748
|
-
/**
|
|
1749
|
-
* Initialize validator (lazy load, async)
|
|
1750
|
-
*/
|
|
1751
|
-
async init() {
|
|
1752
|
-
if (this.validateFn !== null || this.initError !== null) {
|
|
1753
|
-
return;
|
|
1754
|
-
}
|
|
1755
|
-
if (this.initPromise) {
|
|
1756
|
-
return this.initPromise;
|
|
1757
|
-
}
|
|
1758
|
-
this.initPromise = (async () => {
|
|
1759
|
-
try {
|
|
1760
|
-
await compileSchemaById("pathfinder/v1.0.0/error-response");
|
|
1761
|
-
await compileSchemaById("assessment/v1.0.0/severity-definitions");
|
|
1762
|
-
this.validateFn = await compileSchemaById("error-handling/v1.0.0/error-response");
|
|
1763
|
-
} catch (err) {
|
|
1764
|
-
this.initError = err instanceof Error ? err : new Error(String(err));
|
|
1765
|
-
throw new Error(`Failed to initialize error validator: ${this.initError.message}`);
|
|
1766
|
-
}
|
|
1767
|
-
})();
|
|
1768
|
-
return this.initPromise;
|
|
1769
|
-
}
|
|
1770
|
-
/**
|
|
1771
|
-
* Validate error data against schema
|
|
1772
|
-
*
|
|
1773
|
-
* @param data - Data to validate
|
|
1774
|
-
* @returns Promise resolving to true if valid, false otherwise
|
|
1775
|
-
* @throws {Error} If validator failed to initialize
|
|
1776
|
-
*/
|
|
1777
|
-
async validate(data) {
|
|
1778
|
-
if (this.validateFn === null) {
|
|
1779
|
-
await this.init();
|
|
1780
|
-
}
|
|
1781
|
-
if (this.initError) {
|
|
1782
|
-
throw this.initError;
|
|
1783
|
-
}
|
|
1784
|
-
if (!this.validateFn) {
|
|
1785
|
-
throw new Error("Validator not initialized");
|
|
1786
|
-
}
|
|
1787
|
-
return this.validateFn(data);
|
|
1788
|
-
}
|
|
1789
|
-
/**
|
|
1790
|
-
* Get validation errors from last validation
|
|
1791
|
-
*
|
|
1792
|
-
* @returns Validation errors or null
|
|
1793
|
-
*/
|
|
1794
|
-
getErrors() {
|
|
1795
|
-
if (!this.validateFn) {
|
|
1796
|
-
return null;
|
|
1797
|
-
}
|
|
1798
|
-
return this.validateFn.errors;
|
|
1799
|
-
}
|
|
1800
|
-
/**
|
|
1801
|
-
* Reset validator state (for testing)
|
|
1802
|
-
* @internal
|
|
1803
|
-
*/
|
|
1804
|
-
static _reset() {
|
|
1805
|
-
_ErrorValidator.instance = new _ErrorValidator();
|
|
1806
|
-
}
|
|
1807
|
-
};
|
|
1808
|
-
}
|
|
1809
|
-
});
|
|
1810
|
-
|
|
1811
|
-
// src/errors/fulmen-error.ts
|
|
1812
|
-
function isFulmenErrorData(value) {
|
|
1813
|
-
return typeof value === "object" && value !== null && "code" in value && typeof value.code === "string" && "message" in value && typeof value.message === "string";
|
|
1814
|
-
}
|
|
1815
|
-
var FulmenError;
|
|
1816
|
-
var init_fulmen_error = __esm({
|
|
1817
|
-
"src/errors/fulmen-error.ts"() {
|
|
1818
|
-
init_serialization();
|
|
1819
|
-
init_severity();
|
|
1820
|
-
init_validators();
|
|
1821
|
-
FulmenError = class _FulmenError extends Error {
|
|
1822
|
-
data;
|
|
1823
|
-
constructor(data) {
|
|
1824
|
-
super(data.message);
|
|
1825
|
-
this.name = "FulmenError";
|
|
1826
|
-
this.data = Object.freeze({ ...data });
|
|
1827
|
-
Error.captureStackTrace(this, _FulmenError);
|
|
1828
|
-
}
|
|
1829
|
-
/**
|
|
1830
|
-
* Serialize to JSON (schema-compliant)
|
|
1831
|
-
*/
|
|
1832
|
-
toJSON() {
|
|
1833
|
-
return this.data;
|
|
1834
|
-
}
|
|
1835
|
-
/**
|
|
1836
|
-
* Check equality with another FulmenError
|
|
1837
|
-
*/
|
|
1838
|
-
equals(other) {
|
|
1839
|
-
return JSON.stringify(this.data) === JSON.stringify(other.data);
|
|
1840
|
-
}
|
|
1841
|
-
/**
|
|
1842
|
-
* Get severity level for comparison
|
|
1843
|
-
*/
|
|
1844
|
-
getSeverityLevel() {
|
|
1845
|
-
return this.data.severity_level ?? SEVERITY_LEVELS[this.data.severity ?? "medium"];
|
|
1846
|
-
}
|
|
1847
|
-
/**
|
|
1848
|
-
* Wrap an existing error with FulmenError structure
|
|
1849
|
-
*
|
|
1850
|
-
* @param error - Error to wrap (Error instance or FulmenErrorData)
|
|
1851
|
-
* @param options - Additional error options
|
|
1852
|
-
* @returns New FulmenError instance
|
|
1853
|
-
*
|
|
1854
|
-
* @example
|
|
1855
|
-
* ```typescript
|
|
1856
|
-
* try {
|
|
1857
|
-
* throw new Error('Config invalid');
|
|
1858
|
-
* } catch (err) {
|
|
1859
|
-
* const fulmenErr = FulmenError.wrap(err, {
|
|
1860
|
-
* code: 'CONFIG_INVALID',
|
|
1861
|
-
* severity: 'high',
|
|
1862
|
-
* exit_code: 2
|
|
1863
|
-
* });
|
|
1864
|
-
* throw fulmenErr;
|
|
1865
|
-
* }
|
|
1866
|
-
* ```
|
|
1867
|
-
*/
|
|
1868
|
-
static wrap(error, options = {}) {
|
|
1869
|
-
if (error instanceof _FulmenError) {
|
|
1870
|
-
const effectiveSeverity = options.severity ?? error.data.severity ?? Severity.MEDIUM;
|
|
1871
|
-
const effectiveSeverityLevel = SEVERITY_LEVELS[effectiveSeverity];
|
|
1872
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1873
|
-
return new _FulmenError({
|
|
1874
|
-
...error.data,
|
|
1875
|
-
...options,
|
|
1876
|
-
code: options.code ?? error.data.code,
|
|
1877
|
-
message: error.data.message,
|
|
1878
|
-
severity: effectiveSeverity,
|
|
1879
|
-
// Consistent severity
|
|
1880
|
-
severity_level: effectiveSeverityLevel,
|
|
1881
|
-
// Recomputed level
|
|
1882
|
-
timestamp
|
|
1883
|
-
// Updated timestamp
|
|
1884
|
-
});
|
|
1885
|
-
}
|
|
1886
|
-
if (isFulmenErrorData(error)) {
|
|
1887
|
-
const defaultSeverity = getDefaultSeverity();
|
|
1888
|
-
const effectiveSeverity = options.severity ?? error.severity ?? defaultSeverity.name;
|
|
1889
|
-
const effectiveSeverityLevel = SEVERITY_LEVELS[effectiveSeverity];
|
|
1890
|
-
return new _FulmenError({
|
|
1891
|
-
...error,
|
|
1892
|
-
...options,
|
|
1893
|
-
severity: effectiveSeverity,
|
|
1894
|
-
severity_level: effectiveSeverityLevel,
|
|
1895
|
-
// Recomputed, not from error.severity_level
|
|
1896
|
-
timestamp: error.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
1897
|
-
});
|
|
1898
|
-
}
|
|
1899
|
-
return _FulmenError.fromError(error, options);
|
|
1900
|
-
}
|
|
1901
|
-
/**
|
|
1902
|
-
* Create FulmenError from native Error object
|
|
1903
|
-
*
|
|
1904
|
-
* @param err - Native Error instance
|
|
1905
|
-
* @param options - Error options
|
|
1906
|
-
* @returns New FulmenError instance
|
|
1907
|
-
*
|
|
1908
|
-
* @example
|
|
1909
|
-
* ```typescript
|
|
1910
|
-
* const err = new TypeError('Invalid type');
|
|
1911
|
-
* const fulmenErr = FulmenError.fromError(err, {
|
|
1912
|
-
* code: 'TYPE_ERROR',
|
|
1913
|
-
* severity: 'medium'
|
|
1914
|
-
* });
|
|
1915
|
-
* ```
|
|
1916
|
-
*/
|
|
1917
|
-
static fromError(err, options = {}) {
|
|
1918
|
-
const code = options.code ?? "UNKNOWN_ERROR";
|
|
1919
|
-
const severity = options.severity ?? Severity.MEDIUM;
|
|
1920
|
-
const severityLevel = SEVERITY_LEVELS[severity];
|
|
1921
|
-
const message = extractErrorMessage(err);
|
|
1922
|
-
const stack = extractStackTrace(err);
|
|
1923
|
-
const data = {
|
|
1924
|
-
code,
|
|
1925
|
-
message,
|
|
1926
|
-
severity,
|
|
1927
|
-
severity_level: severityLevel,
|
|
1928
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1929
|
-
...options,
|
|
1930
|
-
context: {
|
|
1931
|
-
...options.context,
|
|
1932
|
-
originalName: err instanceof Error ? err.name : typeof err,
|
|
1933
|
-
stack
|
|
1934
|
-
},
|
|
1935
|
-
original: stack || message
|
|
1936
|
-
};
|
|
1937
|
-
return new _FulmenError(data);
|
|
1938
|
-
}
|
|
1939
|
-
/**
|
|
1940
|
-
* Validate error data against schema
|
|
1941
|
-
*
|
|
1942
|
-
* @param data - Error data to validate
|
|
1943
|
-
* @returns Promise resolving to true if valid
|
|
1944
|
-
*
|
|
1945
|
-
* @example
|
|
1946
|
-
* ```typescript
|
|
1947
|
-
* const data = { code: 'TEST', message: 'Test error' };
|
|
1948
|
-
* if (await FulmenError.validate(data)) {
|
|
1949
|
-
* const err = new FulmenError(data);
|
|
1950
|
-
* }
|
|
1951
|
-
* ```
|
|
1952
|
-
*/
|
|
1953
|
-
static async validate(data) {
|
|
1954
|
-
return validateErrorData(data);
|
|
1955
|
-
}
|
|
1956
|
-
/**
|
|
1957
|
-
* Exit process with structured error
|
|
1958
|
-
*
|
|
1959
|
-
* Logs error as JSON and exits with specified exit code.
|
|
1960
|
-
* Mockable for testing (override process.exit).
|
|
1961
|
-
*
|
|
1962
|
-
* @param error - FulmenError instance
|
|
1963
|
-
* @param options - Exit options
|
|
1964
|
-
*
|
|
1965
|
-
* @example
|
|
1966
|
-
* ```typescript
|
|
1967
|
-
* const err = FulmenError.fromError(new Error('Fatal'), {
|
|
1968
|
-
* code: 'FATAL_ERROR',
|
|
1969
|
-
* exit_code: 1
|
|
1970
|
-
* });
|
|
1971
|
-
* FulmenError.exitWithError(err); // Exits with code 1
|
|
1972
|
-
* ```
|
|
1973
|
-
*/
|
|
1974
|
-
static exitWithError(error, options = {}) {
|
|
1975
|
-
const logger = options.logger ?? console.error;
|
|
1976
|
-
const exitCode = error.data.exit_code ?? 1;
|
|
1977
|
-
logger(JSON.stringify(error.toJSON(), null, 2));
|
|
1978
|
-
process.exit(exitCode);
|
|
1979
|
-
}
|
|
1980
|
-
};
|
|
1981
|
-
}
|
|
1982
|
-
});
|
|
1983
|
-
|
|
1984
|
-
// src/errors/index.ts
|
|
1985
|
-
var init_errors2 = __esm({
|
|
1986
|
-
"src/errors/index.ts"() {
|
|
1987
|
-
init_correlation();
|
|
1988
|
-
init_fulmen_error();
|
|
1989
|
-
init_serialization();
|
|
1990
|
-
init_severity();
|
|
1991
|
-
init_validators();
|
|
1992
|
-
}
|
|
1993
|
-
});
|
|
1994
|
-
|
|
1995
|
-
// src/appidentity/errors.ts
|
|
1996
|
-
var errors_exports2 = {};
|
|
1997
|
-
__export(errors_exports2, {
|
|
1998
|
-
AppIdentityError: () => AppIdentityError
|
|
1999
|
-
});
|
|
2000
|
-
var AppIdentityError;
|
|
2001
|
-
var init_errors3 = __esm({
|
|
2002
|
-
"src/appidentity/errors.ts"() {
|
|
2003
|
-
init_errors2();
|
|
2004
|
-
AppIdentityError = class _AppIdentityError extends FulmenError {
|
|
2005
|
-
identityPath;
|
|
2006
|
-
constructor(message, identityPath, cause) {
|
|
2007
|
-
let errorData;
|
|
2008
|
-
if (cause) {
|
|
2009
|
-
errorData = FulmenError.fromError(cause, {
|
|
2010
|
-
code: "APP_IDENTITY_ERROR",
|
|
2011
|
-
severity: "high",
|
|
2012
|
-
context: { identityPath }
|
|
2013
|
-
}).data;
|
|
2014
|
-
} else {
|
|
2015
|
-
errorData = {
|
|
2016
|
-
code: "APP_IDENTITY_ERROR",
|
|
2017
|
-
message,
|
|
2018
|
-
severity: "high",
|
|
2019
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2020
|
-
context: { identityPath }
|
|
2021
|
-
};
|
|
2022
|
-
}
|
|
2023
|
-
super(errorData);
|
|
2024
|
-
this.name = "AppIdentityError";
|
|
2025
|
-
this.identityPath = identityPath;
|
|
2026
|
-
if (Error.captureStackTrace) {
|
|
2027
|
-
Error.captureStackTrace(this, _AppIdentityError);
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
|
-
/**
|
|
2031
|
-
* Create error for identity not found
|
|
2032
|
-
*/
|
|
2033
|
-
static notFound(searchedPaths) {
|
|
2034
|
-
const message = `App identity not found
|
|
2035
|
-
Searched paths:
|
|
2036
|
-
${searchedPaths.map((p) => ` - ${p}`).join("\n")}`;
|
|
2037
|
-
return new _AppIdentityError(message);
|
|
2038
|
-
}
|
|
2039
|
-
/**
|
|
2040
|
-
* Create error for schema validation failure
|
|
2041
|
-
*/
|
|
2042
|
-
static validationFailed(path, diagnostics) {
|
|
2043
|
-
const errorCount = diagnostics.filter((d) => d.severity === "ERROR").length;
|
|
2044
|
-
const warningCount = diagnostics.filter((d) => d.severity === "WARN").length;
|
|
2045
|
-
let message = `Invalid app identity: ${path}
|
|
2046
|
-
`;
|
|
2047
|
-
message += `Validation errors: ${errorCount} error(s), ${warningCount} warning(s)
|
|
2048
|
-
`;
|
|
2049
|
-
const displayDiagnostics = diagnostics.slice(0, 3);
|
|
2050
|
-
for (const diag of displayDiagnostics) {
|
|
2051
|
-
message += ` - ${diag.message}`;
|
|
2052
|
-
if (diag.pointer) {
|
|
2053
|
-
message += ` at ${diag.pointer}`;
|
|
2054
|
-
}
|
|
2055
|
-
message += "\n";
|
|
2056
|
-
}
|
|
2057
|
-
if (diagnostics.length > 3) {
|
|
2058
|
-
message += ` ... and ${diagnostics.length - 3} more
|
|
2059
|
-
`;
|
|
2060
|
-
}
|
|
2061
|
-
return new _AppIdentityError(message, path);
|
|
2062
|
-
}
|
|
2063
|
-
/**
|
|
2064
|
-
* Create error for environment variable override pointing to missing file
|
|
2065
|
-
*/
|
|
2066
|
-
static envOverrideMissing(envPath) {
|
|
2067
|
-
const message = `FULMEN_APP_IDENTITY_PATH points to missing file: ${envPath}
|
|
2068
|
-
`;
|
|
2069
|
-
return new _AppIdentityError(message, envPath);
|
|
2070
|
-
}
|
|
2071
|
-
/**
|
|
2072
|
-
* Create error for YAML parsing failure
|
|
2073
|
-
*/
|
|
2074
|
-
static parseFailed(path, cause) {
|
|
2075
|
-
const message = `Failed to parse identity file: ${path}
|
|
2076
|
-
${cause.message}`;
|
|
2077
|
-
return new _AppIdentityError(message, path, cause);
|
|
2078
|
-
}
|
|
2079
|
-
/**
|
|
2080
|
-
* Create error for file read failure
|
|
2081
|
-
*/
|
|
2082
|
-
static readFailed(path, cause) {
|
|
2083
|
-
const message = `Failed to read identity file: ${path}
|
|
2084
|
-
${cause.message}`;
|
|
2085
|
-
return new _AppIdentityError(message, path, cause);
|
|
2086
|
-
}
|
|
2087
|
-
/**
|
|
2088
|
-
* Create error for embedded identity already registered
|
|
2089
|
-
*
|
|
2090
|
-
* Uses first-wins semantics - once registered, cannot be replaced
|
|
2091
|
-
*/
|
|
2092
|
-
static alreadyRegistered() {
|
|
2093
|
-
const message = "Embedded identity already registered. Registration uses first-wins semantics and cannot be replaced.";
|
|
2094
|
-
return new _AppIdentityError(message);
|
|
2095
|
-
}
|
|
2096
|
-
/**
|
|
2097
|
-
* Create error for embedded identity YAML parsing failure
|
|
2098
|
-
*/
|
|
2099
|
-
static embeddedParseFailed(cause) {
|
|
2100
|
-
const message = `Failed to parse embedded identity YAML: ${cause.message}`;
|
|
2101
|
-
return new _AppIdentityError(message, void 0, cause);
|
|
2102
|
-
}
|
|
2103
|
-
/**
|
|
2104
|
-
* Create error for embedded identity schema validation failure
|
|
2105
|
-
*/
|
|
2106
|
-
static embeddedValidationFailed(diagnostics) {
|
|
2107
|
-
const errorCount = diagnostics.filter((d) => d.severity === "ERROR").length;
|
|
2108
|
-
const warningCount = diagnostics.filter((d) => d.severity === "WARN").length;
|
|
2109
|
-
let message = "Invalid embedded identity\n";
|
|
2110
|
-
message += `Validation errors: ${errorCount} error(s), ${warningCount} warning(s)
|
|
2111
|
-
`;
|
|
2112
|
-
const displayDiagnostics = diagnostics.slice(0, 3);
|
|
2113
|
-
for (const diag of displayDiagnostics) {
|
|
2114
|
-
message += ` - ${diag.message}`;
|
|
2115
|
-
if (diag.pointer) {
|
|
2116
|
-
message += ` at ${diag.pointer}`;
|
|
2117
|
-
}
|
|
2118
|
-
message += "\n";
|
|
2119
|
-
}
|
|
2120
|
-
if (diagnostics.length > 3) {
|
|
2121
|
-
message += ` ... and ${diagnostics.length - 3} more
|
|
2122
|
-
`;
|
|
2123
|
-
}
|
|
2124
|
-
return new _AppIdentityError(message);
|
|
2125
|
-
}
|
|
2126
|
-
};
|
|
2127
|
-
}
|
|
2128
|
-
});
|
|
2129
|
-
async function discoverIdentityPath(options) {
|
|
2130
|
-
if (options?.path) {
|
|
2131
|
-
const exists = await fileExists(options.path);
|
|
2132
|
-
if (!exists) {
|
|
2133
|
-
throw AppIdentityError.notFound([options.path]);
|
|
2134
|
-
}
|
|
2135
|
-
return { path: options.path, source: "explicit" };
|
|
2136
|
-
}
|
|
2137
|
-
const envPath = process.env[APP_IDENTITY_ENV_VAR];
|
|
2138
|
-
if (envPath) {
|
|
2139
|
-
const exists = await fileExists(envPath);
|
|
2140
|
-
if (!exists) {
|
|
2141
|
-
throw AppIdentityError.envOverrideMissing(envPath);
|
|
2142
|
-
}
|
|
2143
|
-
return { path: envPath, source: "env" };
|
|
2144
|
-
}
|
|
2145
|
-
const startDir = options?.startDir || process.cwd();
|
|
2146
|
-
const result = await searchAncestors(startDir);
|
|
2147
|
-
if (result) {
|
|
2148
|
-
return { path: result, source: "ancestor" };
|
|
2149
|
-
}
|
|
2150
|
-
return null;
|
|
2151
|
-
}
|
|
2152
|
-
async function searchAncestors(startDir) {
|
|
2153
|
-
let currentDir = startDir;
|
|
2154
|
-
const searchedPaths = [];
|
|
2155
|
-
for (let i = 0; i < MAX_ANCESTOR_SEARCH_DEPTH; i++) {
|
|
2156
|
-
const candidatePath = join(currentDir, APP_IDENTITY_DIR, APP_IDENTITY_FILENAME);
|
|
2157
|
-
searchedPaths.push(candidatePath);
|
|
2158
|
-
if (await fileExists(candidatePath)) {
|
|
2159
|
-
return candidatePath;
|
|
2160
|
-
}
|
|
2161
|
-
const parentDir = dirname(currentDir);
|
|
2162
|
-
if (parentDir === currentDir) {
|
|
2163
|
-
throw AppIdentityError.notFound(searchedPaths);
|
|
2164
|
-
}
|
|
2165
|
-
currentDir = parentDir;
|
|
2166
|
-
}
|
|
2167
|
-
throw AppIdentityError.notFound(searchedPaths);
|
|
2168
|
-
}
|
|
2169
|
-
async function fileExists(path) {
|
|
2170
|
-
try {
|
|
2171
|
-
await access(path);
|
|
2172
|
-
return true;
|
|
2173
|
-
} catch {
|
|
2174
|
-
return false;
|
|
2175
|
-
}
|
|
2176
|
-
}
|
|
2177
|
-
var init_discovery = __esm({
|
|
2178
|
-
"src/appidentity/discovery.ts"() {
|
|
2179
|
-
init_constants();
|
|
2180
|
-
init_errors3();
|
|
2181
|
-
}
|
|
2182
|
-
});
|
|
2183
|
-
function getEmbeddedIdentity() {
|
|
2184
|
-
return embeddedIdentity;
|
|
2185
|
-
}
|
|
2186
|
-
var embeddedIdentity;
|
|
2187
|
-
var init_embedded = __esm({
|
|
2188
|
-
"src/appidentity/embedded.ts"() {
|
|
2189
|
-
init_schema();
|
|
2190
|
-
init_constants();
|
|
2191
|
-
init_errors3();
|
|
2192
|
-
embeddedIdentity = null;
|
|
2193
|
-
}
|
|
2194
|
-
});
|
|
2195
|
-
|
|
2196
|
-
// src/appidentity/loader.ts
|
|
2197
|
-
var loader_exports = {};
|
|
2198
|
-
__export(loader_exports, {
|
|
2199
|
-
clearIdentityCache: () => clearIdentityCache,
|
|
2200
|
-
getCachedIdentity: () => getCachedIdentity,
|
|
2201
|
-
loadIdentity: () => loadIdentity
|
|
2202
|
-
});
|
|
2203
|
-
function deepFreeze(obj) {
|
|
2204
|
-
Object.freeze(obj);
|
|
2205
|
-
Object.getOwnPropertyNames(obj).forEach((prop) => {
|
|
2206
|
-
const value = obj[prop];
|
|
2207
|
-
if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
|
|
2208
|
-
deepFreeze(value);
|
|
2209
|
-
}
|
|
2210
|
-
});
|
|
2211
|
-
return obj;
|
|
2212
|
-
}
|
|
2213
|
-
async function loadIdentity(options) {
|
|
2214
|
-
if (options?.identity) {
|
|
2215
|
-
return deepFreeze(structuredClone(options.identity));
|
|
2216
|
-
}
|
|
2217
|
-
if (!options?.skipCache) {
|
|
2218
|
-
const cached = getCachedIdentity();
|
|
2219
|
-
if (cached) {
|
|
2220
|
-
return cached;
|
|
2221
|
-
}
|
|
2222
|
-
}
|
|
2223
|
-
let discovery;
|
|
2224
|
-
try {
|
|
2225
|
-
discovery = await discoverIdentityPath({
|
|
2226
|
-
path: options?.path,
|
|
2227
|
-
startDir: options?.startDir
|
|
2228
|
-
});
|
|
2229
|
-
} catch (error) {
|
|
2230
|
-
const hasExplicitPath = Boolean(options?.path);
|
|
2231
|
-
const hasEnvOverride = Boolean(process.env[APP_IDENTITY_ENV_VAR]);
|
|
2232
|
-
if (!hasExplicitPath && !hasEnvOverride && error instanceof AppIdentityError) {
|
|
2233
|
-
const embedded = getEmbeddedIdentity();
|
|
2234
|
-
if (embedded) {
|
|
2235
|
-
setCachedIdentity(embedded);
|
|
2236
|
-
return embedded;
|
|
2237
|
-
}
|
|
2238
|
-
}
|
|
2239
|
-
throw error;
|
|
2240
|
-
}
|
|
2241
|
-
if (!discovery) {
|
|
2242
|
-
const embedded = getEmbeddedIdentity();
|
|
2243
|
-
if (embedded) {
|
|
2244
|
-
setCachedIdentity(embedded);
|
|
2245
|
-
return embedded;
|
|
2246
|
-
}
|
|
2247
|
-
throw AppIdentityError.notFound([]);
|
|
2248
|
-
}
|
|
2249
|
-
let content;
|
|
2250
|
-
try {
|
|
2251
|
-
content = await readFile(discovery.path, "utf-8");
|
|
2252
|
-
} catch (error) {
|
|
2253
|
-
throw AppIdentityError.readFailed(
|
|
2254
|
-
discovery.path,
|
|
2255
|
-
error instanceof Error ? error : new Error(String(error))
|
|
2256
|
-
);
|
|
2257
|
-
}
|
|
2258
|
-
let parsed;
|
|
2259
|
-
try {
|
|
2260
|
-
parsed = parse(content);
|
|
2261
|
-
} catch (error) {
|
|
2262
|
-
throw AppIdentityError.parseFailed(
|
|
2263
|
-
discovery.path,
|
|
2264
|
-
error instanceof Error ? error : new Error(String(error))
|
|
2265
|
-
);
|
|
2266
|
-
}
|
|
2267
|
-
if (!options?.skipValidation) {
|
|
2268
|
-
const result = await validateDataBySchemaId(parsed, APP_IDENTITY_SCHEMA_ID);
|
|
2269
|
-
if (!result.valid) {
|
|
2270
|
-
throw AppIdentityError.validationFailed(discovery.path, result.diagnostics);
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
const identity = deepFreeze(structuredClone(parsed));
|
|
2274
|
-
setCachedIdentity(identity);
|
|
2275
|
-
return identity;
|
|
2276
|
-
}
|
|
2277
|
-
var init_loader = __esm({
|
|
2278
|
-
"src/appidentity/loader.ts"() {
|
|
2279
|
-
init_schema();
|
|
2280
|
-
init_cache();
|
|
2281
|
-
init_constants();
|
|
2282
|
-
init_discovery();
|
|
2283
|
-
init_embedded();
|
|
2284
|
-
init_errors3();
|
|
2285
|
-
}
|
|
2286
|
-
});
|
|
2287
|
-
function createCLI(options = {}) {
|
|
2288
|
-
const program = new Command();
|
|
2289
|
-
program.name("tsfulmen-schema").description("Schema validation and discovery CLI for Fulmen (developer tool)").version("0.1.0");
|
|
2290
|
-
program.command("list").description("List available schemas from registry").argument("[prefix]", "Filter schemas by prefix").option("--base-dir <path>", "Override schema base directory").action(async (prefix, cmdOptions) => {
|
|
2291
|
-
try {
|
|
2292
|
-
const schemas = await listSchemas(prefix, {
|
|
2293
|
-
baseDir: cmdOptions?.baseDir || options.baseDir
|
|
2294
|
-
});
|
|
2295
|
-
if (schemas.length === 0) {
|
|
2296
|
-
console.log("No schemas found");
|
|
2297
|
-
return;
|
|
2298
|
-
}
|
|
2299
|
-
console.log(`Found ${schemas.length} schema(s):
|
|
2300
|
-
`);
|
|
2301
|
-
for (const schema of schemas) {
|
|
2302
|
-
console.log(` ${schema.id}`);
|
|
2303
|
-
console.log(` Format: ${schema.format}`);
|
|
2304
|
-
console.log(` Path: ${schema.relativePath}`);
|
|
2305
|
-
if (schema.description) {
|
|
2306
|
-
console.log(` Description: ${schema.description}`);
|
|
2307
|
-
}
|
|
2308
|
-
console.log();
|
|
2309
|
-
}
|
|
2310
|
-
} catch (error) {
|
|
2311
|
-
console.error("Error listing schemas:", error.message);
|
|
2312
|
-
process.exit(1);
|
|
2313
|
-
}
|
|
2314
|
-
});
|
|
2315
|
-
program.command("show").description("Show schema details").requiredOption("--schema-id <id>", "Schema ID to show").option("--base-dir <path>", "Override schema base directory").action(async (cmdOptions) => {
|
|
2316
|
-
try {
|
|
2317
|
-
const registry = getSchemaRegistry({
|
|
2318
|
-
baseDir: cmdOptions.baseDir || options.baseDir
|
|
2319
|
-
});
|
|
2320
|
-
const schema = await registry.getSchema(cmdOptions.schemaId);
|
|
2321
|
-
console.log("Schema Details:\n");
|
|
2322
|
-
console.log(` ID: ${schema.id}`);
|
|
2323
|
-
console.log(` Format: ${schema.format}`);
|
|
2324
|
-
console.log(` Path: ${schema.path}`);
|
|
2325
|
-
console.log(` Relative Path: ${schema.relativePath}`);
|
|
2326
|
-
if (schema.version) {
|
|
2327
|
-
console.log(` Version: ${schema.version}`);
|
|
2328
|
-
}
|
|
2329
|
-
if (schema.description) {
|
|
2330
|
-
console.log(` Description: ${schema.description}`);
|
|
2331
|
-
}
|
|
2332
|
-
if (schema.schemaDraft) {
|
|
2333
|
-
console.log(` Schema Draft: ${schema.schemaDraft}`);
|
|
2334
|
-
}
|
|
2335
|
-
const content = await readFile(schema.path, "utf-8");
|
|
2336
|
-
console.log("\nSchema Content:");
|
|
2337
|
-
console.log(content);
|
|
2338
|
-
} catch (error) {
|
|
2339
|
-
console.error("Error showing schema:", error.message);
|
|
2340
|
-
process.exit(1);
|
|
2341
|
-
}
|
|
2342
|
-
});
|
|
2343
|
-
program.command("validate").description("Validate data file against schema").requiredOption("--schema-id <id>", "Schema ID to validate against").argument("<file>", "Data file to validate").option("--use-goneat", "Use goneat for validation (requires goneat binary)").option("--goneat-path <path>", "Path to goneat binary").option("--base-dir <path>", "Override schema base directory").action(
|
|
2344
|
-
async (file, cmdOptions) => {
|
|
2345
|
-
try {
|
|
2346
|
-
let result;
|
|
2347
|
-
if (cmdOptions.useGoneat) {
|
|
2348
|
-
const available = await isGoneatAvailable(cmdOptions.goneatPath);
|
|
2349
|
-
if (!available) {
|
|
2350
|
-
console.error("\u274C goneat not available. Install goneat or remove --use-goneat flag.");
|
|
2351
|
-
console.error(" AJV validation (default) works without external dependencies.");
|
|
2352
|
-
process.exit(1);
|
|
2353
|
-
}
|
|
2354
|
-
const registry = getSchemaRegistry({
|
|
2355
|
-
baseDir: cmdOptions.baseDir || options.baseDir
|
|
2356
|
-
});
|
|
2357
|
-
const schema = await registry.getSchema(cmdOptions.schemaId);
|
|
2358
|
-
console.log("Using goneat validation...");
|
|
2359
|
-
result = await runGoneatValidation(schema.path, file, cmdOptions.goneatPath);
|
|
2360
|
-
} else {
|
|
2361
|
-
console.log("Using AJV validation...");
|
|
2362
|
-
result = await validateFileBySchemaId(file, cmdOptions.schemaId, {
|
|
2363
|
-
baseDir: cmdOptions.baseDir || options.baseDir
|
|
2364
|
-
});
|
|
2365
|
-
}
|
|
2366
|
-
if (result.valid) {
|
|
2367
|
-
console.log(`\u2705 Validation passed (${result.source})`);
|
|
2368
|
-
process.exit(0);
|
|
2369
|
-
} else {
|
|
2370
|
-
console.log(`\u274C Validation failed (${result.source})`);
|
|
2371
|
-
console.log("\nDiagnostics:");
|
|
2372
|
-
console.log(formatDiagnostics(result.diagnostics));
|
|
2373
|
-
process.exit(1);
|
|
2374
|
-
}
|
|
2375
|
-
} catch (error) {
|
|
2376
|
-
console.error("Error validating file:", error.message);
|
|
2377
|
-
process.exit(1);
|
|
2378
|
-
}
|
|
2379
|
-
}
|
|
2380
|
-
);
|
|
2381
|
-
program.command("validate-schema").description("Validate a schema file itself").argument("<file>", "Schema file to validate").action(async (file) => {
|
|
2382
|
-
try {
|
|
2383
|
-
const content = await readFile(file, "utf-8");
|
|
2384
|
-
const { validateSchema: validateSchema2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
2385
|
-
const result = await validateSchema2(content);
|
|
2386
|
-
if (result.valid) {
|
|
2387
|
-
console.log("\u2705 Schema is valid");
|
|
2388
|
-
process.exit(0);
|
|
2389
|
-
} else {
|
|
2390
|
-
console.log("\u274C Schema is invalid");
|
|
2391
|
-
console.log("\nDiagnostics:");
|
|
2392
|
-
console.log(formatDiagnostics(result.diagnostics));
|
|
2393
|
-
process.exit(1);
|
|
2394
|
-
}
|
|
2395
|
-
} catch (error) {
|
|
2396
|
-
console.error("Error validating schema:", error.message);
|
|
2397
|
-
process.exit(1);
|
|
2398
|
-
}
|
|
2399
|
-
});
|
|
2400
|
-
program.command("normalize").description("Normalize schema to canonical JSON format").argument("<file>", "Schema file to normalize").option("--compact", "Output compact JSON (no formatting)").option("-o, --output <file>", "Write to output file instead of stdout").action(async (file, cmdOptions) => {
|
|
2401
|
-
try {
|
|
2402
|
-
const content = await readFile(file, "utf-8");
|
|
2403
|
-
const normalized = normalizeSchema(content, {
|
|
2404
|
-
compact: cmdOptions.compact
|
|
2405
|
-
});
|
|
2406
|
-
if (cmdOptions.output) {
|
|
2407
|
-
await writeFile(cmdOptions.output, normalized, "utf-8");
|
|
2408
|
-
console.log(`\u2705 Normalized schema written to ${cmdOptions.output}`);
|
|
2409
|
-
} else {
|
|
2410
|
-
console.log(normalized);
|
|
2411
|
-
}
|
|
2412
|
-
} catch (error) {
|
|
2413
|
-
console.error("Error normalizing schema:", error.message);
|
|
2414
|
-
process.exit(1);
|
|
2415
|
-
}
|
|
2416
|
-
});
|
|
2417
|
-
program.command("compare").description("Compare two schemas for semantic equality").argument("<file1>", "First schema file").argument("<file2>", "Second schema file").option("--show-normalized", "Show normalized outputs").action(async (file1, file2, cmdOptions) => {
|
|
2418
|
-
try {
|
|
2419
|
-
const content1 = await readFile(file1, "utf-8");
|
|
2420
|
-
const content2 = await readFile(file2, "utf-8");
|
|
2421
|
-
const result = compareSchemas(content1, content2);
|
|
2422
|
-
if (result.equal) {
|
|
2423
|
-
console.log("\u2705 Schemas are semantically equal");
|
|
2424
|
-
} else {
|
|
2425
|
-
console.log("\u274C Schemas differ");
|
|
956
|
+
* Build logical schema ID from file path
|
|
957
|
+
*/
|
|
958
|
+
buildSchemaId(filePath, baseDir) {
|
|
959
|
+
const relativePath = relative(baseDir, filePath);
|
|
960
|
+
const withoutExt = relativePath.replace(/\.(schema\.(json|yaml|yml))$/, "");
|
|
961
|
+
return withoutExt.replace(/\\/g, "/");
|
|
2426
962
|
}
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
963
|
+
/**
|
|
964
|
+
* Extract schema format from file extension
|
|
965
|
+
*/
|
|
966
|
+
getSchemaFormat(filePath) {
|
|
967
|
+
const ext = extname(filePath).toLowerCase();
|
|
968
|
+
switch (ext) {
|
|
969
|
+
case ".json":
|
|
970
|
+
return "json";
|
|
971
|
+
case ".yaml":
|
|
972
|
+
case ".yml":
|
|
973
|
+
return "yaml";
|
|
974
|
+
default:
|
|
975
|
+
return "json";
|
|
976
|
+
}
|
|
2432
977
|
}
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
schemaId: cmdOptions.schemaId,
|
|
2446
|
-
outPath: cmdOptions.out,
|
|
2447
|
-
includeProvenance: cmdOptions.provenance ?? true,
|
|
2448
|
-
validate: cmdOptions.validate ?? true,
|
|
2449
|
-
overwrite: cmdOptions.force ?? false,
|
|
2450
|
-
format: cmdOptions.format ?? "auto",
|
|
2451
|
-
baseDir: cmdOptions.baseDir || options.baseDir
|
|
2452
|
-
});
|
|
2453
|
-
console.log("\u2705 Schema exported successfully");
|
|
2454
|
-
console.log(` Schema ID: ${result.schemaId}`);
|
|
2455
|
-
console.log(` Output: ${result.outPath}`);
|
|
2456
|
-
console.log(` Format: ${result.format}`);
|
|
2457
|
-
if (result.provenance) {
|
|
2458
|
-
console.log("\nProvenance:");
|
|
2459
|
-
console.log(` Crucible: ${result.provenance.crucible_version}`);
|
|
2460
|
-
console.log(` Library: ${result.provenance.library_version}`);
|
|
2461
|
-
if (result.provenance.revision) {
|
|
2462
|
-
console.log(` Revision: ${result.provenance.revision}`);
|
|
978
|
+
/**
|
|
979
|
+
* Extract metadata from schema file
|
|
980
|
+
*/
|
|
981
|
+
async extractMetadata(filePath) {
|
|
982
|
+
try {
|
|
983
|
+
const content = await readFile(filePath, "utf-8");
|
|
984
|
+
const format = this.getSchemaFormat(filePath);
|
|
985
|
+
let parsed;
|
|
986
|
+
if (format === "yaml") {
|
|
987
|
+
parsed = parse(content);
|
|
988
|
+
} else {
|
|
989
|
+
parsed = JSON.parse(content);
|
|
2463
990
|
}
|
|
2464
|
-
|
|
991
|
+
const baseDir = this.options.baseDir ?? "";
|
|
992
|
+
const relativePath = relative(baseDir, filePath);
|
|
993
|
+
return {
|
|
994
|
+
id: this.buildSchemaId(filePath, baseDir),
|
|
995
|
+
path: filePath,
|
|
996
|
+
relativePath,
|
|
997
|
+
format,
|
|
998
|
+
version: parsed.$schema || parsed.version,
|
|
999
|
+
description: parsed.title || parsed.description,
|
|
1000
|
+
schemaDraft: parsed.$schema
|
|
1001
|
+
};
|
|
1002
|
+
} catch (error) {
|
|
1003
|
+
throw SchemaValidationError.registryError(
|
|
1004
|
+
"metadata extraction",
|
|
1005
|
+
`Failed to process ${filePath}: ${error.message}`
|
|
1006
|
+
);
|
|
2465
1007
|
}
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* Discover and index all available schemas
|
|
1011
|
+
*/
|
|
1012
|
+
async discoverSchemas() {
|
|
1013
|
+
try {
|
|
1014
|
+
const baseDir = this.options.baseDir ?? "";
|
|
1015
|
+
const patterns = this.options.patterns ?? [];
|
|
1016
|
+
if (patterns.length === 0) {
|
|
1017
|
+
this.schemas.clear();
|
|
1018
|
+
return;
|
|
2474
1019
|
}
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
process.exit(exitCodes2.EXIT_INVALID_ARGUMENT);
|
|
2482
|
-
break;
|
|
2483
|
-
default:
|
|
2484
|
-
process.exit(exitCodes2.EXIT_FAILURE);
|
|
1020
|
+
const pattern = patterns.map((p) => join(baseDir, p));
|
|
1021
|
+
try {
|
|
1022
|
+
await access(baseDir);
|
|
1023
|
+
} catch {
|
|
1024
|
+
this.schemas.clear();
|
|
1025
|
+
return;
|
|
2485
1026
|
}
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
1027
|
+
const files = await glob(pattern, {
|
|
1028
|
+
absolute: true,
|
|
1029
|
+
followSymbolicLinks: this.options.followSymlinks,
|
|
1030
|
+
deep: this.options.maxDepth,
|
|
1031
|
+
onlyFiles: true,
|
|
1032
|
+
suppressErrors: true
|
|
1033
|
+
// Don't throw on permission errors
|
|
1034
|
+
});
|
|
1035
|
+
this.schemas.clear();
|
|
1036
|
+
for (const filePath of files) {
|
|
1037
|
+
try {
|
|
1038
|
+
const metadata = await this.extractMetadata(filePath);
|
|
1039
|
+
this.schemas.set(metadata.id, metadata);
|
|
1040
|
+
} catch (error) {
|
|
1041
|
+
console.warn(`Warning: Failed to process schema ${filePath}:`, error);
|
|
1042
|
+
}
|
|
2491
1043
|
}
|
|
2492
|
-
|
|
1044
|
+
} catch (error) {
|
|
1045
|
+
throw SchemaValidationError.registryError("discovery", error.message);
|
|
2493
1046
|
}
|
|
2494
|
-
process.exit(exitCodes2.EXIT_FAILURE);
|
|
2495
1047
|
}
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
const identity = await loadIdentity2({ path: cmdOptions.path });
|
|
2503
|
-
if (cmdOptions.json) {
|
|
2504
|
-
console.log(JSON.stringify(identity, null, 2));
|
|
2505
|
-
} else {
|
|
2506
|
-
console.log("Application Identity:\n");
|
|
2507
|
-
console.log(` Binary Name: ${identity.app.binary_name}`);
|
|
2508
|
-
console.log(` Vendor: ${identity.app.vendor}`);
|
|
2509
|
-
console.log(` Env Prefix: ${identity.app.env_prefix}`);
|
|
2510
|
-
console.log(` Config Name: ${identity.app.config_name}`);
|
|
2511
|
-
console.log(` Description: ${identity.app.description}`);
|
|
2512
|
-
if (identity.metadata) {
|
|
2513
|
-
console.log("\nMetadata:");
|
|
2514
|
-
if (identity.metadata.license) {
|
|
2515
|
-
console.log(` License: ${identity.metadata.license}`);
|
|
2516
|
-
}
|
|
2517
|
-
if (identity.metadata.repository_category) {
|
|
2518
|
-
console.log(` Category: ${identity.metadata.repository_category}`);
|
|
2519
|
-
}
|
|
2520
|
-
if (identity.metadata.telemetry_namespace) {
|
|
2521
|
-
console.log(` Telemetry: ${identity.metadata.telemetry_namespace}`);
|
|
2522
|
-
}
|
|
2523
|
-
if (identity.metadata.project_url) {
|
|
2524
|
-
console.log(` Project URL: ${identity.metadata.project_url}`);
|
|
2525
|
-
}
|
|
1048
|
+
/**
|
|
1049
|
+
* List available schemas with optional prefix filtering
|
|
1050
|
+
*/
|
|
1051
|
+
async listSchemas(prefix) {
|
|
1052
|
+
if (this.schemas.size === 0) {
|
|
1053
|
+
await this.discoverSchemas();
|
|
2526
1054
|
}
|
|
1055
|
+
const schemas = Array.from(this.schemas.values());
|
|
1056
|
+
if (prefix) {
|
|
1057
|
+
return schemas.filter((schema) => schema.id.startsWith(prefix));
|
|
1058
|
+
}
|
|
1059
|
+
return schemas;
|
|
2527
1060
|
}
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
if (error.message.includes("not found")) {
|
|
2535
|
-
process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
|
|
1061
|
+
/**
|
|
1062
|
+
* Get schema by logical ID
|
|
1063
|
+
*/
|
|
1064
|
+
async getSchema(id) {
|
|
1065
|
+
if (this.schemas.size === 0) {
|
|
1066
|
+
await this.discoverSchemas();
|
|
2536
1067
|
}
|
|
2537
|
-
|
|
2538
|
-
|
|
1068
|
+
const schema = this.schemas.get(id);
|
|
1069
|
+
if (!schema) {
|
|
1070
|
+
throw SchemaValidationError.schemaNotFound(id);
|
|
2539
1071
|
}
|
|
1072
|
+
return schema;
|
|
2540
1073
|
}
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
|
|
2548
|
-
console.log("Validating application identity...");
|
|
2549
|
-
const identity = await loadIdentity2({ path: file });
|
|
2550
|
-
console.log("\u2705 Identity is valid");
|
|
2551
|
-
console.log(` Binary: ${identity.app.binary_name}`);
|
|
2552
|
-
console.log(` Vendor: ${identity.app.vendor}`);
|
|
2553
|
-
process.exit(exitCodes2.EXIT_SUCCESS);
|
|
2554
|
-
} catch (error) {
|
|
2555
|
-
const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
|
|
2556
|
-
const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors3(), errors_exports2));
|
|
2557
|
-
console.error("\u274C Identity validation failed:", error.message);
|
|
2558
|
-
if (error instanceof AppIdentityError2) {
|
|
2559
|
-
if (error.message.includes("not found")) {
|
|
2560
|
-
process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
|
|
1074
|
+
/**
|
|
1075
|
+
* Get schema by file path
|
|
1076
|
+
*/
|
|
1077
|
+
async getSchemaByPath(filePath) {
|
|
1078
|
+
if (this.schemas.size === 0) {
|
|
1079
|
+
await this.discoverSchemas();
|
|
2561
1080
|
}
|
|
2562
|
-
|
|
2563
|
-
|
|
1081
|
+
const absolutePath = filePath.startsWith("/") ? filePath : join(process.cwd(), filePath);
|
|
1082
|
+
for (const schema of this.schemas.values()) {
|
|
1083
|
+
if (schema.path === absolutePath) {
|
|
1084
|
+
return schema;
|
|
1085
|
+
}
|
|
2564
1086
|
}
|
|
1087
|
+
throw SchemaValidationError.schemaNotFound(filePath);
|
|
2565
1088
|
}
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
1089
|
+
/**
|
|
1090
|
+
* Check if schema exists
|
|
1091
|
+
*/
|
|
1092
|
+
async hasSchema(id) {
|
|
1093
|
+
if (this.schemas.size === 0) {
|
|
1094
|
+
await this.discoverSchemas();
|
|
1095
|
+
}
|
|
1096
|
+
return this.schemas.has(id);
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* Get registry size
|
|
1100
|
+
*/
|
|
1101
|
+
get size() {
|
|
1102
|
+
return this.schemas.size;
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Clear registry cache
|
|
1106
|
+
*/
|
|
1107
|
+
clear() {
|
|
1108
|
+
this.schemas.clear();
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
});
|
|
2571
1113
|
var init_cli = __esm({
|
|
2572
1114
|
"src/schema/cli.ts"() {
|
|
2573
1115
|
init_goneat_bridge();
|
|
@@ -2575,10 +1117,13 @@ var init_cli = __esm({
|
|
|
2575
1117
|
init_registry2();
|
|
2576
1118
|
init_utils();
|
|
2577
1119
|
init_validator();
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
1120
|
+
}
|
|
1121
|
+
});
|
|
1122
|
+
var init_export = __esm({
|
|
1123
|
+
"src/schema/export.ts"() {
|
|
1124
|
+
init_errors();
|
|
1125
|
+
init_registry2();
|
|
1126
|
+
init_validator();
|
|
2582
1127
|
}
|
|
2583
1128
|
});
|
|
2584
1129
|
|
|
@@ -2598,7 +1143,7 @@ var init_schema = __esm({
|
|
|
2598
1143
|
});
|
|
2599
1144
|
|
|
2600
1145
|
// src/telemetry/validators.ts
|
|
2601
|
-
var
|
|
1146
|
+
var init_validators = __esm({
|
|
2602
1147
|
"src/telemetry/validators.ts"() {
|
|
2603
1148
|
init_schema();
|
|
2604
1149
|
}
|
|
@@ -2615,24 +1160,10 @@ var init_telemetry = __esm({
|
|
|
2615
1160
|
init_histogram();
|
|
2616
1161
|
init_taxonomy();
|
|
2617
1162
|
init_types();
|
|
2618
|
-
|
|
1163
|
+
init_validators();
|
|
2619
1164
|
metrics = new MetricsRegistry();
|
|
2620
1165
|
}
|
|
2621
1166
|
});
|
|
2622
|
-
|
|
2623
|
-
// src/schema/validator.ts
|
|
2624
|
-
var validator_exports = {};
|
|
2625
|
-
__export(validator_exports, {
|
|
2626
|
-
clearCache: () => clearCache,
|
|
2627
|
-
compileSchema: () => compileSchema,
|
|
2628
|
-
compileSchemaById: () => compileSchemaById,
|
|
2629
|
-
getCacheSize: () => getCacheSize,
|
|
2630
|
-
validateData: () => validateData,
|
|
2631
|
-
validateDataBySchemaId: () => validateDataBySchemaId,
|
|
2632
|
-
validateFile: () => validateFile,
|
|
2633
|
-
validateFileBySchemaId: () => validateFileBySchemaId,
|
|
2634
|
-
validateSchema: () => validateSchema
|
|
2635
|
-
});
|
|
2636
1167
|
async function loadMetaSchema(draft) {
|
|
2637
1168
|
const __filename3 = fileURLToPath(import.meta.url);
|
|
2638
1169
|
const __dirname4 = dirname(__filename3);
|
|
@@ -2860,104 +1391,6 @@ function validateData(data, validator) {
|
|
|
2860
1391
|
}
|
|
2861
1392
|
return result;
|
|
2862
1393
|
}
|
|
2863
|
-
async function validateFile(filePath, validator) {
|
|
2864
|
-
try {
|
|
2865
|
-
const content = await readFile(filePath, "utf-8");
|
|
2866
|
-
let data;
|
|
2867
|
-
try {
|
|
2868
|
-
data = JSON.parse(content);
|
|
2869
|
-
} catch {
|
|
2870
|
-
data = parse(content);
|
|
2871
|
-
}
|
|
2872
|
-
return validateData(data, validator);
|
|
2873
|
-
} catch (error) {
|
|
2874
|
-
if (error instanceof SchemaValidationError) {
|
|
2875
|
-
throw error;
|
|
2876
|
-
}
|
|
2877
|
-
throw SchemaValidationError.validationFailed(
|
|
2878
|
-
filePath,
|
|
2879
|
-
[
|
|
2880
|
-
createDiagnostic(
|
|
2881
|
-
"",
|
|
2882
|
-
`Failed to read or parse file: ${error.message}`,
|
|
2883
|
-
"file-read",
|
|
2884
|
-
"ERROR",
|
|
2885
|
-
"ajv"
|
|
2886
|
-
)
|
|
2887
|
-
],
|
|
2888
|
-
{ type: "file", id: filePath }
|
|
2889
|
-
);
|
|
2890
|
-
}
|
|
2891
|
-
}
|
|
2892
|
-
async function validateSchema(schema) {
|
|
2893
|
-
try {
|
|
2894
|
-
let parsedSchema;
|
|
2895
|
-
if (typeof schema === "string") {
|
|
2896
|
-
try {
|
|
2897
|
-
parsedSchema = JSON.parse(schema);
|
|
2898
|
-
} catch {
|
|
2899
|
-
parsedSchema = parse(schema);
|
|
2900
|
-
}
|
|
2901
|
-
} else if (Buffer.isBuffer(schema)) {
|
|
2902
|
-
const content = schema.toString("utf-8");
|
|
2903
|
-
try {
|
|
2904
|
-
parsedSchema = JSON.parse(content);
|
|
2905
|
-
} catch {
|
|
2906
|
-
parsedSchema = parse(content);
|
|
2907
|
-
}
|
|
2908
|
-
} else {
|
|
2909
|
-
parsedSchema = schema;
|
|
2910
|
-
}
|
|
2911
|
-
const dialect = detectDialect(parsedSchema);
|
|
2912
|
-
const ajv = await getAjv(dialect);
|
|
2913
|
-
const metaValid = ajv.validateSchema(parsedSchema);
|
|
2914
|
-
if (!metaValid && ajv.errors) {
|
|
2915
|
-
const diagnostics = ajv.errors.map(
|
|
2916
|
-
(error) => createDiagnostic(
|
|
2917
|
-
error.instancePath || "",
|
|
2918
|
-
error.message || "Schema meta-validation failed",
|
|
2919
|
-
error.keyword || "unknown",
|
|
2920
|
-
"ERROR",
|
|
2921
|
-
"ajv"
|
|
2922
|
-
)
|
|
2923
|
-
);
|
|
2924
|
-
return { valid: false, diagnostics, source: "ajv" };
|
|
2925
|
-
}
|
|
2926
|
-
await compileSchema(parsedSchema);
|
|
2927
|
-
return {
|
|
2928
|
-
valid: true,
|
|
2929
|
-
diagnostics: [],
|
|
2930
|
-
source: "ajv"
|
|
2931
|
-
};
|
|
2932
|
-
} catch (error) {
|
|
2933
|
-
if (error instanceof SchemaValidationError) {
|
|
2934
|
-
return {
|
|
2935
|
-
valid: false,
|
|
2936
|
-
diagnostics: error.diagnostics,
|
|
2937
|
-
source: "ajv"
|
|
2938
|
-
};
|
|
2939
|
-
}
|
|
2940
|
-
return {
|
|
2941
|
-
valid: false,
|
|
2942
|
-
diagnostics: [
|
|
2943
|
-
createDiagnostic(
|
|
2944
|
-
"",
|
|
2945
|
-
`Schema validation failed: ${error.message}`,
|
|
2946
|
-
"schema-validation",
|
|
2947
|
-
"ERROR",
|
|
2948
|
-
"ajv"
|
|
2949
|
-
)
|
|
2950
|
-
],
|
|
2951
|
-
source: "ajv"
|
|
2952
|
-
};
|
|
2953
|
-
}
|
|
2954
|
-
}
|
|
2955
|
-
function clearCache() {
|
|
2956
|
-
schemaCache.clear();
|
|
2957
|
-
}
|
|
2958
|
-
function getCacheSize() {
|
|
2959
|
-
return schemaCache.size;
|
|
2960
|
-
}
|
|
2961
1394
|
async function compileSchemaById(schemaId, registryOptions) {
|
|
2962
1395
|
try {
|
|
2963
1396
|
const registry = getSchemaRegistry(registryOptions);
|
|
@@ -2985,15 +1418,6 @@ async function validateDataBySchemaId(data, schemaId, registryOptions) {
|
|
|
2985
1418
|
throw error;
|
|
2986
1419
|
}
|
|
2987
1420
|
}
|
|
2988
|
-
async function validateFileBySchemaId(filePath, schemaId, registryOptions) {
|
|
2989
|
-
try {
|
|
2990
|
-
const validator = await compileSchemaById(schemaId, registryOptions);
|
|
2991
|
-
return validateFile(filePath, validator);
|
|
2992
|
-
} catch (error) {
|
|
2993
|
-
metrics.counter("schema_validation_errors").inc();
|
|
2994
|
-
throw error;
|
|
2995
|
-
}
|
|
2996
|
-
}
|
|
2997
1421
|
var ajvInstances, metaschemaReady, schemaCache;
|
|
2998
1422
|
var init_validator = __esm({
|
|
2999
1423
|
"src/schema/validator.ts"() {
|
|
@@ -3010,7 +1434,7 @@ var init_validator = __esm({
|
|
|
3010
1434
|
|
|
3011
1435
|
// src/foundry/errors.ts
|
|
3012
1436
|
var FoundryCatalogError;
|
|
3013
|
-
var
|
|
1437
|
+
var init_errors2 = __esm({
|
|
3014
1438
|
"src/foundry/errors.ts"() {
|
|
3015
1439
|
FoundryCatalogError = class _FoundryCatalogError extends Error {
|
|
3016
1440
|
constructor(message, catalog, cause) {
|
|
@@ -3136,10 +1560,10 @@ async function loadAllCatalogs() {
|
|
|
3136
1560
|
return { patterns, httpStatuses, mimeTypes, countryCodes };
|
|
3137
1561
|
}
|
|
3138
1562
|
var __filename, __dirname2, SSOT_PATHS, SCHEMA_IDS;
|
|
3139
|
-
var
|
|
1563
|
+
var init_loader = __esm({
|
|
3140
1564
|
"src/foundry/loader.ts"() {
|
|
3141
1565
|
init_validator();
|
|
3142
|
-
|
|
1566
|
+
init_errors2();
|
|
3143
1567
|
__filename = fileURLToPath(import.meta.url);
|
|
3144
1568
|
__dirname2 = dirname(__filename);
|
|
3145
1569
|
SSOT_PATHS = {
|
|
@@ -3173,13 +1597,13 @@ function deepClone(obj) {
|
|
|
3173
1597
|
}
|
|
3174
1598
|
return cloned;
|
|
3175
1599
|
}
|
|
3176
|
-
function
|
|
1600
|
+
function deepFreeze(obj) {
|
|
3177
1601
|
Object.freeze(obj);
|
|
3178
1602
|
for (const key in obj) {
|
|
3179
1603
|
if (Object.hasOwn(obj, key)) {
|
|
3180
1604
|
const value = obj[key];
|
|
3181
1605
|
if (value !== null && typeof value === "object") {
|
|
3182
|
-
|
|
1606
|
+
deepFreeze(value);
|
|
3183
1607
|
}
|
|
3184
1608
|
}
|
|
3185
1609
|
}
|
|
@@ -3205,23 +1629,23 @@ async function getCountryByAlpha2(code) {
|
|
|
3205
1629
|
await ensureCatalogLoaded();
|
|
3206
1630
|
const normalized = code.toUpperCase();
|
|
3207
1631
|
const country = alpha2Index.get(normalized);
|
|
3208
|
-
return country ?
|
|
1632
|
+
return country ? deepFreeze(deepClone(country)) : null;
|
|
3209
1633
|
}
|
|
3210
1634
|
async function getCountryByAlpha3(code) {
|
|
3211
1635
|
await ensureCatalogLoaded();
|
|
3212
1636
|
const normalized = code.toUpperCase();
|
|
3213
1637
|
const country = alpha3Index.get(normalized);
|
|
3214
|
-
return country ?
|
|
1638
|
+
return country ? deepFreeze(deepClone(country)) : null;
|
|
3215
1639
|
}
|
|
3216
1640
|
async function getCountryByNumeric(code) {
|
|
3217
1641
|
await ensureCatalogLoaded();
|
|
3218
1642
|
const normalized = normalizeNumeric(code);
|
|
3219
1643
|
const country = numericIndex.get(normalized);
|
|
3220
|
-
return country ?
|
|
1644
|
+
return country ? deepFreeze(deepClone(country)) : null;
|
|
3221
1645
|
}
|
|
3222
1646
|
async function listCountries() {
|
|
3223
1647
|
await ensureCatalogLoaded();
|
|
3224
|
-
return Array.from(alpha2Index.values()).map((c) =>
|
|
1648
|
+
return Array.from(alpha2Index.values()).map((c) => deepFreeze(deepClone(c)));
|
|
3225
1649
|
}
|
|
3226
1650
|
function clearCountryCodeCache() {
|
|
3227
1651
|
catalogCache = null;
|
|
@@ -3232,7 +1656,7 @@ function clearCountryCodeCache() {
|
|
|
3232
1656
|
var catalogCache, alpha2Index, alpha3Index, numericIndex;
|
|
3233
1657
|
var init_country_codes = __esm({
|
|
3234
1658
|
"src/foundry/country-codes.ts"() {
|
|
3235
|
-
|
|
1659
|
+
init_loader();
|
|
3236
1660
|
catalogCache = null;
|
|
3237
1661
|
alpha2Index = /* @__PURE__ */ new Map();
|
|
3238
1662
|
alpha3Index = /* @__PURE__ */ new Map();
|
|
@@ -3908,13 +2332,13 @@ function deepClone2(obj) {
|
|
|
3908
2332
|
}
|
|
3909
2333
|
return cloned;
|
|
3910
2334
|
}
|
|
3911
|
-
function
|
|
2335
|
+
function deepFreeze2(obj) {
|
|
3912
2336
|
Object.freeze(obj);
|
|
3913
2337
|
for (const key in obj) {
|
|
3914
2338
|
if (Object.hasOwn(obj, key)) {
|
|
3915
2339
|
const value = obj[key];
|
|
3916
2340
|
if (value !== null && typeof value === "object") {
|
|
3917
|
-
|
|
2341
|
+
deepFreeze2(value);
|
|
3918
2342
|
}
|
|
3919
2343
|
}
|
|
3920
2344
|
}
|
|
@@ -3939,7 +2363,7 @@ async function ensureCatalogLoaded2() {
|
|
|
3939
2363
|
async function getHttpStatus(code) {
|
|
3940
2364
|
await ensureCatalogLoaded2();
|
|
3941
2365
|
const status = statusCodeIndex.get(code);
|
|
3942
|
-
return status ?
|
|
2366
|
+
return status ? deepFreeze2(deepClone2(status)) : null;
|
|
3943
2367
|
}
|
|
3944
2368
|
function isInformational(code) {
|
|
3945
2369
|
return code >= 100 && code < 200;
|
|
@@ -3958,7 +2382,7 @@ function isServerError(code) {
|
|
|
3958
2382
|
}
|
|
3959
2383
|
async function listHttpStatuses() {
|
|
3960
2384
|
await ensureCatalogLoaded2();
|
|
3961
|
-
return Array.from(statusCodeIndex.values()).map((s) =>
|
|
2385
|
+
return Array.from(statusCodeIndex.values()).map((s) => deepFreeze2(deepClone2(s)));
|
|
3962
2386
|
}
|
|
3963
2387
|
async function getStatusReason(code) {
|
|
3964
2388
|
const status = await getHttpStatus(code);
|
|
@@ -3971,7 +2395,7 @@ function clearHttpStatusCache() {
|
|
|
3971
2395
|
var catalogCache2, statusCodeIndex;
|
|
3972
2396
|
var init_http_statuses = __esm({
|
|
3973
2397
|
"src/foundry/http-statuses.ts"() {
|
|
3974
|
-
|
|
2398
|
+
init_loader();
|
|
3975
2399
|
catalogCache2 = null;
|
|
3976
2400
|
statusCodeIndex = /* @__PURE__ */ new Map();
|
|
3977
2401
|
}
|
|
@@ -4307,13 +2731,13 @@ function deepClone3(obj) {
|
|
|
4307
2731
|
}
|
|
4308
2732
|
return cloned;
|
|
4309
2733
|
}
|
|
4310
|
-
function
|
|
2734
|
+
function deepFreeze3(obj) {
|
|
4311
2735
|
Object.freeze(obj);
|
|
4312
2736
|
for (const key in obj) {
|
|
4313
2737
|
if (Object.hasOwn(obj, key)) {
|
|
4314
2738
|
const value = obj[key];
|
|
4315
2739
|
if (value !== null && typeof value === "object") {
|
|
4316
|
-
|
|
2740
|
+
deepFreeze3(value);
|
|
4317
2741
|
}
|
|
4318
2742
|
}
|
|
4319
2743
|
}
|
|
@@ -4337,13 +2761,13 @@ async function getMimeType(mimeString) {
|
|
|
4337
2761
|
await ensureCatalogLoaded3();
|
|
4338
2762
|
const normalized = mimeString.toLowerCase();
|
|
4339
2763
|
const mimeType = mimeStringIndex.get(normalized);
|
|
4340
|
-
return mimeType ?
|
|
2764
|
+
return mimeType ? deepFreeze3(deepClone3(mimeType)) : null;
|
|
4341
2765
|
}
|
|
4342
2766
|
async function getMimeTypeByExtension(extension) {
|
|
4343
2767
|
await ensureCatalogLoaded3();
|
|
4344
2768
|
const normalized = extension.toLowerCase().replace(/^\./, "");
|
|
4345
2769
|
const mimeType = extensionIndex.get(normalized);
|
|
4346
|
-
return mimeType ?
|
|
2770
|
+
return mimeType ? deepFreeze3(deepClone3(mimeType)) : null;
|
|
4347
2771
|
}
|
|
4348
2772
|
async function isSupportedMimeType(mime) {
|
|
4349
2773
|
await ensureCatalogLoaded3();
|
|
@@ -4394,7 +2818,7 @@ function detectMimeTypeFromBuffer(buffer, options = {}) {
|
|
|
4394
2818
|
throw new Error("Detector not initialized");
|
|
4395
2819
|
}
|
|
4396
2820
|
const result = detectorInstance.detect(buffer, options);
|
|
4397
|
-
return result ?
|
|
2821
|
+
return result ? deepFreeze3(deepClone3(result)) : null;
|
|
4398
2822
|
}
|
|
4399
2823
|
async function detectMimeTypeFromStream(stream, options = {}) {
|
|
4400
2824
|
await ensureCatalogLoaded3();
|
|
@@ -4426,7 +2850,7 @@ function matchMagicNumber(buffer, mimeType) {
|
|
|
4426
2850
|
}
|
|
4427
2851
|
async function listMimeTypes() {
|
|
4428
2852
|
await ensureCatalogLoaded3();
|
|
4429
|
-
return Array.from(mimeStringIndex.values()).map((m) =>
|
|
2853
|
+
return Array.from(mimeStringIndex.values()).map((m) => deepFreeze3(deepClone3(m)));
|
|
4430
2854
|
}
|
|
4431
2855
|
function clearMimeTypeCache() {
|
|
4432
2856
|
catalogCache3 = null;
|
|
@@ -4438,7 +2862,7 @@ var catalogCache3, mimeStringIndex, extensionIndex, detectorInstance;
|
|
|
4438
2862
|
var init_mime_types = __esm({
|
|
4439
2863
|
"src/foundry/mime-types.ts"() {
|
|
4440
2864
|
init_detector();
|
|
4441
|
-
|
|
2865
|
+
init_loader();
|
|
4442
2866
|
catalogCache3 = null;
|
|
4443
2867
|
mimeStringIndex = /* @__PURE__ */ new Map();
|
|
4444
2868
|
extensionIndex = /* @__PURE__ */ new Map();
|
|
@@ -4460,13 +2884,13 @@ function deepClone4(obj) {
|
|
|
4460
2884
|
}
|
|
4461
2885
|
return cloned;
|
|
4462
2886
|
}
|
|
4463
|
-
function
|
|
2887
|
+
function deepFreeze4(obj) {
|
|
4464
2888
|
Object.freeze(obj);
|
|
4465
2889
|
for (const key in obj) {
|
|
4466
2890
|
if (Object.hasOwn(obj, key)) {
|
|
4467
2891
|
const value = obj[key];
|
|
4468
2892
|
if (value !== null && typeof value === "object") {
|
|
4469
|
-
|
|
2893
|
+
deepFreeze4(value);
|
|
4470
2894
|
}
|
|
4471
2895
|
}
|
|
4472
2896
|
}
|
|
@@ -4484,7 +2908,7 @@ async function ensureCatalogLoaded4() {
|
|
|
4484
2908
|
async function getPattern(id) {
|
|
4485
2909
|
await ensureCatalogLoaded4();
|
|
4486
2910
|
const pattern = patternIndex.get(id);
|
|
4487
|
-
return pattern ?
|
|
2911
|
+
return pattern ? deepFreeze4(deepClone4(pattern)) : null;
|
|
4488
2912
|
}
|
|
4489
2913
|
async function getPatternRegex(id) {
|
|
4490
2914
|
await ensureCatalogLoaded4();
|
|
@@ -4544,7 +2968,7 @@ async function matchPattern(id, value) {
|
|
|
4544
2968
|
}
|
|
4545
2969
|
async function listPatterns() {
|
|
4546
2970
|
await ensureCatalogLoaded4();
|
|
4547
|
-
return Array.from(patternIndex.values()).map((p) =>
|
|
2971
|
+
return Array.from(patternIndex.values()).map((p) => deepFreeze4(deepClone4(p)));
|
|
4548
2972
|
}
|
|
4549
2973
|
async function describePattern(id) {
|
|
4550
2974
|
const pattern = await getPattern(id);
|
|
@@ -4559,8 +2983,8 @@ function clearPatternCache() {
|
|
|
4559
2983
|
var catalogCache4, patternIndex, compiledRegexCache, compiledGlobCache;
|
|
4560
2984
|
var init_patterns = __esm({
|
|
4561
2985
|
"src/foundry/patterns.ts"() {
|
|
4562
|
-
|
|
4563
|
-
|
|
2986
|
+
init_errors2();
|
|
2987
|
+
init_loader();
|
|
4564
2988
|
catalogCache4 = null;
|
|
4565
2989
|
patternIndex = /* @__PURE__ */ new Map();
|
|
4566
2990
|
compiledRegexCache = /* @__PURE__ */ new Map();
|
|
@@ -4671,7 +3095,7 @@ var __filename2, __dirname3, SSOT_PATHS2, SCHEMA_ID, cachedCatalog;
|
|
|
4671
3095
|
var init_catalog = __esm({
|
|
4672
3096
|
"src/foundry/signals/catalog.ts"() {
|
|
4673
3097
|
init_validator();
|
|
4674
|
-
|
|
3098
|
+
init_errors2();
|
|
4675
3099
|
__filename2 = fileURLToPath(import.meta.url);
|
|
4676
3100
|
__dirname3 = dirname(__filename2);
|
|
4677
3101
|
SSOT_PATHS2 = {
|
|
@@ -4787,7 +3211,7 @@ var init_capabilities2 = __esm({
|
|
|
4787
3211
|
function createConfigReloadEndpoint(options) {
|
|
4788
3212
|
const { loader, validator, onReload: onReload2, auth, rateLimit, logger, telemetry } = options;
|
|
4789
3213
|
return async (payload, req) => {
|
|
4790
|
-
const correlationId = payload.correlation_id ??
|
|
3214
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId();
|
|
4791
3215
|
const authResult = await auth(req);
|
|
4792
3216
|
if (!authResult.authenticated) {
|
|
4793
3217
|
if (logger) {
|
|
@@ -4904,7 +3328,7 @@ function createConfigReloadEndpoint(options) {
|
|
|
4904
3328
|
}
|
|
4905
3329
|
};
|
|
4906
3330
|
}
|
|
4907
|
-
function
|
|
3331
|
+
function generateCorrelationId() {
|
|
4908
3332
|
return `cfg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4909
3333
|
}
|
|
4910
3334
|
var init_config_reload_endpoint = __esm({
|
|
@@ -5249,7 +3673,7 @@ function ensureWindows() {
|
|
|
5249
3673
|
}
|
|
5250
3674
|
var init_guards = __esm({
|
|
5251
3675
|
"src/foundry/signals/guards.ts"() {
|
|
5252
|
-
|
|
3676
|
+
init_errors2();
|
|
5253
3677
|
init_capabilities2();
|
|
5254
3678
|
init_catalog();
|
|
5255
3679
|
init_windows();
|
|
@@ -5260,7 +3684,7 @@ var init_guards = __esm({
|
|
|
5260
3684
|
function createSignalEndpoint(options) {
|
|
5261
3685
|
const { manager, auth, rateLimit, logger, telemetry, allowedSignals } = options;
|
|
5262
3686
|
return async (payload, req) => {
|
|
5263
|
-
const correlationId = payload.correlation_id ??
|
|
3687
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId2();
|
|
5264
3688
|
const authResult = await auth(req);
|
|
5265
3689
|
if (!authResult.authenticated) {
|
|
5266
3690
|
if (logger) {
|
|
@@ -5383,7 +3807,7 @@ function normalizeSignalName(signal) {
|
|
|
5383
3807
|
}
|
|
5384
3808
|
return `SIG${upper}`;
|
|
5385
3809
|
}
|
|
5386
|
-
function
|
|
3810
|
+
function generateCorrelationId2() {
|
|
5387
3811
|
return `sig-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
5388
3812
|
}
|
|
5389
3813
|
function createBearerTokenAuth(expectedToken) {
|
|
@@ -5885,9 +4309,9 @@ var init_distance = __esm({
|
|
|
5885
4309
|
});
|
|
5886
4310
|
|
|
5887
4311
|
// src/foundry/similarity/errors.ts
|
|
5888
|
-
var
|
|
4312
|
+
var init_errors3 = __esm({
|
|
5889
4313
|
"src/foundry/similarity/errors.ts"() {
|
|
5890
|
-
|
|
4314
|
+
init_errors2();
|
|
5891
4315
|
}
|
|
5892
4316
|
});
|
|
5893
4317
|
function toNormalizationLocale(locale) {
|
|
@@ -5975,7 +4399,7 @@ var init_suggest = __esm({
|
|
|
5975
4399
|
var init_similarity = __esm({
|
|
5976
4400
|
"src/foundry/similarity/index.ts"() {
|
|
5977
4401
|
init_distance();
|
|
5978
|
-
|
|
4402
|
+
init_errors3();
|
|
5979
4403
|
init_normalization();
|
|
5980
4404
|
init_score();
|
|
5981
4405
|
init_suggest();
|
|
@@ -5983,115 +4407,14 @@ var init_similarity = __esm({
|
|
|
5983
4407
|
});
|
|
5984
4408
|
|
|
5985
4409
|
// src/foundry/index.ts
|
|
5986
|
-
var foundry_exports = {};
|
|
5987
|
-
__export(foundry_exports, {
|
|
5988
|
-
ConfigReloadTracker: () => ConfigReloadTracker,
|
|
5989
|
-
EXIT_CODES_VERSION: () => EXIT_CODES_VERSION,
|
|
5990
|
-
FoundryCatalogError: () => FoundryCatalogError,
|
|
5991
|
-
SignalManager: () => SignalManager,
|
|
5992
|
-
SimplifiedMode: () => SimplifiedMode,
|
|
5993
|
-
VERSION: () => VERSION,
|
|
5994
|
-
casefold: () => casefold,
|
|
5995
|
-
clearCountryCodeCache: () => clearCountryCodeCache,
|
|
5996
|
-
clearHttpStatusCache: () => clearHttpStatusCache,
|
|
5997
|
-
clearMimeTypeCache: () => clearMimeTypeCache,
|
|
5998
|
-
clearPatternCache: () => clearPatternCache,
|
|
5999
|
-
createBearerTokenAuth: () => createBearerTokenAuth,
|
|
6000
|
-
createConfigReloadEndpoint: () => createConfigReloadEndpoint,
|
|
6001
|
-
createConfigReloadHandler: () => createConfigReloadHandler,
|
|
6002
|
-
createControlDiscoveryEndpoint: () => createControlDiscoveryEndpoint,
|
|
6003
|
-
createDoubleTapTracker: () => createDoubleTapTracker,
|
|
6004
|
-
createSignalEndpoint: () => createSignalEndpoint,
|
|
6005
|
-
createSignalManager: () => createSignalManager,
|
|
6006
|
-
createSimpleRateLimiter: () => createSimpleRateLimiter,
|
|
6007
|
-
describePattern: () => describePattern,
|
|
6008
|
-
detectMimeType: () => detectMimeType,
|
|
6009
|
-
detectMimeTypeFromBuffer: () => detectMimeTypeFromBuffer,
|
|
6010
|
-
detectMimeTypeFromFile: () => detectMimeTypeFromFile,
|
|
6011
|
-
detectMimeTypeFromStream: () => detectMimeTypeFromStream,
|
|
6012
|
-
distance: () => distance,
|
|
6013
|
-
ensurePOSIX: () => ensurePOSIX,
|
|
6014
|
-
ensureSignalExitCodesSupported: () => ensureSignalExitCodesSupported,
|
|
6015
|
-
ensureSupported: () => ensureSupported,
|
|
6016
|
-
ensureWindows: () => ensureWindows,
|
|
6017
|
-
equalsIgnoreCase: () => equalsIgnoreCase,
|
|
6018
|
-
exitCodeMetadata: () => exitCodeMetadata,
|
|
6019
|
-
exitCodes: () => exitCodes,
|
|
6020
|
-
getBehavior: () => getBehavior,
|
|
6021
|
-
getCountryByAlpha2: () => getCountryByAlpha2,
|
|
6022
|
-
getCountryByAlpha3: () => getCountryByAlpha3,
|
|
6023
|
-
getCountryByNumeric: () => getCountryByNumeric,
|
|
6024
|
-
getExitCodeInfo: () => getExitCodeInfo,
|
|
6025
|
-
getFallbackMetadata: () => getFallbackMetadata,
|
|
6026
|
-
getHttpFallbackGuidance: () => getHttpFallbackGuidance,
|
|
6027
|
-
getHttpStatus: () => getHttpStatus,
|
|
6028
|
-
getMimeType: () => getMimeType,
|
|
6029
|
-
getMimeTypeByExtension: () => getMimeTypeByExtension,
|
|
6030
|
-
getPattern: () => getPattern,
|
|
6031
|
-
getPatternRegex: () => getPatternRegex,
|
|
6032
|
-
getPlatform: () => getPlatform,
|
|
6033
|
-
getPlatformCapabilities: () => getPlatformCapabilities,
|
|
6034
|
-
getSignal: () => getSignal,
|
|
6035
|
-
getSignalCatalog: () => getSignalCatalog,
|
|
6036
|
-
getSignalNumber: () => getSignalNumber,
|
|
6037
|
-
getSignalPlatformCapabilities: () => getPlatformCapabilities2,
|
|
6038
|
-
getSignalsVersion: () => getSignalsVersion,
|
|
6039
|
-
getSimplifiedCodeDescription: () => getSimplifiedCodeDescription,
|
|
6040
|
-
getSimplifiedCodes: () => getSimplifiedCodes,
|
|
6041
|
-
getStatusReason: () => getStatusReason,
|
|
6042
|
-
getWindowTimeRemaining: () => getWindowTimeRemaining,
|
|
6043
|
-
getWindowsEvent: () => getWindowsEvent,
|
|
6044
|
-
handleDoubleTap: () => handleDoubleTap,
|
|
6045
|
-
handleWindowsFallback: () => handleWindowsFallback,
|
|
6046
|
-
isClientError: () => isClientError,
|
|
6047
|
-
isInformational: () => isInformational,
|
|
6048
|
-
isPOSIX: () => isPOSIX,
|
|
6049
|
-
isRedirection: () => isRedirection,
|
|
6050
|
-
isServerError: () => isServerError,
|
|
6051
|
-
isSignalPOSIX: () => isPOSIX2,
|
|
6052
|
-
isSignalWindows: () => isWindows2,
|
|
6053
|
-
isSuccess: () => isSuccess,
|
|
6054
|
-
isSupportedMimeType: () => isSupportedMimeType,
|
|
6055
|
-
isWindows: () => isWindows,
|
|
6056
|
-
isWithinWindow: () => isWithinWindow,
|
|
6057
|
-
listBehaviors: () => listBehaviors,
|
|
6058
|
-
listCountries: () => listCountries,
|
|
6059
|
-
listHttpStatuses: () => listHttpStatuses,
|
|
6060
|
-
listMimeTypes: () => listMimeTypes,
|
|
6061
|
-
listPatterns: () => listPatterns,
|
|
6062
|
-
listSignals: () => listSignals,
|
|
6063
|
-
loadAllCatalogs: () => loadAllCatalogs,
|
|
6064
|
-
loadCountryCodeCatalog: () => loadCountryCodeCatalog,
|
|
6065
|
-
loadHttpStatusCatalog: () => loadHttpStatusCatalog,
|
|
6066
|
-
loadMimeTypeCatalog: () => loadMimeTypeCatalog,
|
|
6067
|
-
loadPatternCatalog: () => loadPatternCatalog,
|
|
6068
|
-
mapExitCodeToSimplified: () => mapExitCodeToSimplified,
|
|
6069
|
-
matchMagicNumber: () => matchMagicNumber,
|
|
6070
|
-
matchPattern: () => matchPattern,
|
|
6071
|
-
normalize: () => normalize,
|
|
6072
|
-
onAnyShutdown: () => onAnyShutdown,
|
|
6073
|
-
onEmergencyQuit: () => onEmergencyQuit,
|
|
6074
|
-
onReload: () => onReload,
|
|
6075
|
-
onShutdown: () => onShutdown,
|
|
6076
|
-
onUSR1: () => onUSR1,
|
|
6077
|
-
onUSR2: () => onUSR2,
|
|
6078
|
-
requiresFallback: () => requiresFallback,
|
|
6079
|
-
resetDoubleTap: () => resetDoubleTap,
|
|
6080
|
-
score: () => score,
|
|
6081
|
-
stripAccents: () => stripAccents,
|
|
6082
|
-
suggest: () => suggest,
|
|
6083
|
-
supportsSignal: () => supportsSignal,
|
|
6084
|
-
supportsSignalBasedExitCodes: () => supportsSignalExitCodes2,
|
|
6085
|
-
supportsSignalExitCodes: () => supportsSignalExitCodes
|
|
6086
|
-
});
|
|
6087
4410
|
var VERSION;
|
|
6088
4411
|
var init_foundry = __esm({
|
|
6089
4412
|
"src/foundry/index.ts"() {
|
|
6090
4413
|
init_country_codes();
|
|
6091
|
-
|
|
4414
|
+
init_errors2();
|
|
6092
4415
|
init_exit_codes();
|
|
6093
4416
|
init_http_statuses();
|
|
6094
|
-
|
|
4417
|
+
init_loader();
|
|
6095
4418
|
init_mime_types();
|
|
6096
4419
|
init_patterns();
|
|
6097
4420
|
init_signals();
|