@fulmenhq/tsfulmen 0.2.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/README.md +61 -7
- package/config/crucible-ts/agentic/roles/README.md +3 -3
- package/config/crucible-ts/library/fulencode/fixtures/README.md +18 -0
- package/config/crucible-ts/library/fulencode/fixtures/bom/bom.yaml +14 -0
- package/config/crucible-ts/library/fulencode/fixtures/detection/detection.yaml +12 -0
- package/config/crucible-ts/library/fulencode/fixtures/invalid-encodings/base64.yaml +10 -0
- package/config/crucible-ts/library/fulencode/fixtures/normalization/text-safe.yaml +10 -0
- package/config/crucible-ts/library/fulencode/fixtures/telemetry/telemetry-test-cases.yaml +24 -0
- package/config/crucible-ts/library/fulencode/fixtures/valid-encodings/base64.yaml +11 -0
- package/config/crucible-ts/taxonomy/library/platform-modules/v1.0.0/modules.yaml +2 -2
- package/config/crucible-ts/taxonomy/metrics.yaml +79 -1
- package/dist/appidentity/index.d.ts +31 -109
- package/dist/appidentity/index.js +369 -60
- package/dist/appidentity/index.js.map +1 -1
- package/dist/config/index.d.ts +46 -1
- package/dist/config/index.js +427 -62
- package/dist/config/index.js.map +1 -1
- package/dist/crucible/index.js +367 -59
- package/dist/crucible/index.js.map +1 -1
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +367 -59
- package/dist/errors/index.js.map +1 -1
- package/dist/foundry/index.d.ts +2 -1
- package/dist/foundry/index.js +368 -60
- package/dist/foundry/index.js.map +1 -1
- package/dist/fulencode/index.d.ts +102 -0
- package/dist/fulencode/index.js +806 -0
- package/dist/fulencode/index.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +370 -61
- package/dist/index.js.map +1 -1
- package/dist/pathfinder/index.d.ts +1 -1
- package/dist/pathfinder/index.js +367 -59
- package/dist/pathfinder/index.js.map +1 -1
- package/dist/reports/license-inventory.csv +31 -24
- package/dist/schema/index.d.ts +16 -3
- package/dist/schema/index.js +368 -60
- package/dist/schema/index.js.map +1 -1
- package/dist/signals/index.d.ts +483 -395
- package/dist/signals/index.js +368 -60
- package/dist/signals/index.js.map +1 -1
- package/dist/telemetry/http/index.js +368 -59
- package/dist/telemetry/http/index.js.map +1 -1
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.js +367 -59
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/prometheus/index.d.ts +1 -1
- package/dist/telemetry/prometheus/index.js +369 -59
- package/dist/telemetry/prometheus/index.js.map +1 -1
- package/dist/{types-BJswWpQC.d.ts → types-DdoeE7F5.d.ts} +1 -1
- package/dist/types-Dv5TERCM.d.ts +108 -0
- package/package.json +13 -8
- package/schemas/crucible-ts/library/fulencode/v1.0.0/README.md +37 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/bom-result.schema.json +48 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/decode-options.schema.json +60 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/decoding-result.schema.json +70 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/detect-options.schema.json +25 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/detection-result.schema.json +57 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/encode-options.schema.json +71 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/encoding-result.schema.json +57 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-config.schema.json +8 -4
- package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-error.schema.json +66 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/normalization-result.schema.json +73 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/normalize-options.schema.json +44 -0
- package/schemas/crucible-ts/meta/README.md +38 -2
- package/schemas/crucible-ts/meta/draft-04/schema.json +222 -0
- package/schemas/crucible-ts/meta/draft-06/schema.json +218 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/applicator.json +93 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/content.json +21 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/core.json +58 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/format.json +15 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/meta-data.json +35 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/validation.json +119 -0
- package/schemas/crucible-ts/meta/draft-2019-09/offline.schema.json +148 -0
- package/schemas/crucible-ts/meta/draft-2019-09/schema.json +62 -0
- package/schemas/crucible-ts/meta/fixtures/draft-04-sample.json +16 -0
- package/schemas/crucible-ts/meta/fixtures/draft-06-sample.json +16 -0
- package/schemas/crucible-ts/meta/fixtures/draft-07-sample.json +34 -0
- package/schemas/crucible-ts/meta/fixtures/draft-2019-09-sample.json +21 -0
- package/schemas/crucible-ts/meta/fixtures/draft-2020-12-sample.json +21 -0
- package/schemas/crucible-ts/taxonomy/library/fulencode/normalization-profiles/v1.0.0/profiles.yaml +16 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/PROVENANCE.md +64 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/access-tier.dimension.json +103 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/retention-lifecycle.dimension.json +103 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/schema-stability.dimension.json +100 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/sensitivity.dimension.json +130 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/velocity-mode.dimension.json +79 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/volatility.dimension.json +72 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/volume-tier.dimension.json +66 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/catalog/classifiers/README.md +29 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/access-tier-classification.md +163 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/classifiers-framework.md +157 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/data-sensitivity-classification.md +259 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/retention-lifecycle-classification.md +200 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/schema-stability-classification.md +205 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/velocity-mode-classification.md +222 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/volatility-classification.md +209 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/volume-tier-classification.md +200 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/ailink/v0/README.md +48 -0
- package/schemas/crucible-ts/upstream/3leaps/{ailink → crucible/schemas/ailink}/v0/prompt.schema.json +4 -18
- package/schemas/crucible-ts/upstream/3leaps/{ailink → crucible/schemas/ailink}/v0/search-response.schema.json +7 -37
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/classifiers/v0/dimension-definition.schema.json +247 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/classifiers/v0/sensitivity-level.schema.json +67 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/error-response.schema.json +59 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/lifecycle-phases.data.json +102 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/lifecycle-phases.schema.json +101 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/release-phase.schema.json +18 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/types.schema.json +177 -0
- package/schemas/crucible-ts/upstream/3leaps/PROVENANCE.md +0 -43
- /package/schemas/crucible-ts/upstream/3leaps/{agentic → crucible/schemas/agentic}/v0/role-prompt.schema.json +0 -0
|
@@ -3,7 +3,7 @@ import { metrics } from '../index.js';
|
|
|
3
3
|
import { b as MetricsRegistry } from '../../registry-_yEKhTTl.js';
|
|
4
4
|
import { S as SignalManager } from '../../manager-CH3fX7zO.js';
|
|
5
5
|
import { IncomingMessage, ServerResponse, Server } from 'node:http';
|
|
6
|
-
import '../../types-
|
|
6
|
+
import '../../types-DdoeE7F5.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Prometheus exporter constants
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import 'crypto';
|
|
2
|
+
import addFormats from 'ajv-formats';
|
|
2
3
|
import { spawn } from 'child_process';
|
|
3
4
|
import { readFile, writeFile, access, mkdir } from 'fs/promises';
|
|
4
5
|
import { parse, stringify } from 'yaml';
|
|
@@ -6,7 +7,9 @@ import { dirname, join, relative, extname } from 'path';
|
|
|
6
7
|
import { fileURLToPath } from 'url';
|
|
7
8
|
import glob from 'fast-glob';
|
|
8
9
|
import Ajv from 'ajv';
|
|
9
|
-
import
|
|
10
|
+
import Ajv2019 from 'ajv/dist/2019';
|
|
11
|
+
import Ajv2020 from 'ajv/dist/2020';
|
|
12
|
+
import AjvDraft04 from 'ajv-draft-04';
|
|
10
13
|
import { Readable } from 'stream';
|
|
11
14
|
import picomatch from 'picomatch';
|
|
12
15
|
import { suggest as suggest$1, substringSimilarity, score as score$1, normalize as normalize$1, jaro_winkler, damerau_levenshtein, osa_distance, levenshtein } from '@3leaps/string-metrics-wasm';
|
|
@@ -117,6 +120,27 @@ var init_serialization = __esm({
|
|
|
117
120
|
init_severity();
|
|
118
121
|
}
|
|
119
122
|
});
|
|
123
|
+
function applyFulmenAjvFormats(ajv, options = {}) {
|
|
124
|
+
const mode = options.mode ?? "fast";
|
|
125
|
+
const formats = options.formats ?? DEFAULT_FORMATS;
|
|
126
|
+
addFormats(ajv, { mode, formats });
|
|
127
|
+
return ajv;
|
|
128
|
+
}
|
|
129
|
+
var DEFAULT_FORMATS;
|
|
130
|
+
var init_ajv_formats = __esm({
|
|
131
|
+
"src/schema/ajv-formats.ts"() {
|
|
132
|
+
DEFAULT_FORMATS = [
|
|
133
|
+
"date-time",
|
|
134
|
+
"email",
|
|
135
|
+
"hostname",
|
|
136
|
+
"ipv4",
|
|
137
|
+
"ipv6",
|
|
138
|
+
"uri",
|
|
139
|
+
"uri-reference",
|
|
140
|
+
"uuid"
|
|
141
|
+
];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
120
144
|
|
|
121
145
|
// src/schema/errors.ts
|
|
122
146
|
var errors_exports = {};
|
|
@@ -1572,20 +1596,14 @@ async function loadMetaSchema(draft) {
|
|
|
1572
1596
|
const content = await readFile(metaSchemaPath, "utf-8");
|
|
1573
1597
|
return JSON.parse(content);
|
|
1574
1598
|
}
|
|
1575
|
-
async function loadVocabularySchemas() {
|
|
1599
|
+
async function loadVocabularySchemas(draft) {
|
|
1600
|
+
if (draft !== "draft-2019-09" && draft !== "draft-2020-12") {
|
|
1601
|
+
return [];
|
|
1602
|
+
}
|
|
1576
1603
|
const __filename3 = fileURLToPath(import.meta.url);
|
|
1577
1604
|
const __dirname4 = dirname(__filename3);
|
|
1578
|
-
const vocabDir = join(
|
|
1579
|
-
|
|
1580
|
-
"..",
|
|
1581
|
-
"..",
|
|
1582
|
-
"schemas",
|
|
1583
|
-
"crucible-ts",
|
|
1584
|
-
"meta",
|
|
1585
|
-
"draft-2020-12",
|
|
1586
|
-
"meta"
|
|
1587
|
-
);
|
|
1588
|
-
const vocabFiles = [
|
|
1605
|
+
const vocabDir = join(__dirname4, "..", "..", "schemas", "crucible-ts", "meta", draft, "meta");
|
|
1606
|
+
const vocabFiles = draft === "draft-2020-12" ? [
|
|
1589
1607
|
"core.json",
|
|
1590
1608
|
"applicator.json",
|
|
1591
1609
|
"unevaluated.json",
|
|
@@ -1593,6 +1611,13 @@ async function loadVocabularySchemas() {
|
|
|
1593
1611
|
"meta-data.json",
|
|
1594
1612
|
"format-annotation.json",
|
|
1595
1613
|
"content.json"
|
|
1614
|
+
] : [
|
|
1615
|
+
"core.json",
|
|
1616
|
+
"applicator.json",
|
|
1617
|
+
"validation.json",
|
|
1618
|
+
"meta-data.json",
|
|
1619
|
+
"format.json",
|
|
1620
|
+
"content.json"
|
|
1596
1621
|
];
|
|
1597
1622
|
const schemas = [];
|
|
1598
1623
|
for (const file of vocabFiles) {
|
|
@@ -1647,47 +1672,65 @@ async function loadReferencedSchema(uri) {
|
|
|
1647
1672
|
}
|
|
1648
1673
|
return JSON.parse(content);
|
|
1649
1674
|
}
|
|
1650
|
-
function
|
|
1651
|
-
if (!
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1675
|
+
function detectDialect(schema) {
|
|
1676
|
+
if (schema && typeof schema === "object" && !Array.isArray(schema)) {
|
|
1677
|
+
const maybeSchema = schema;
|
|
1678
|
+
const declared = maybeSchema.$schema;
|
|
1679
|
+
if (typeof declared === "string") {
|
|
1680
|
+
if (declared.includes("draft-04")) return "draft-04";
|
|
1681
|
+
if (declared.includes("draft-06")) return "draft-06";
|
|
1682
|
+
if (declared.includes("draft-07")) return "draft-07";
|
|
1683
|
+
if (declared.includes("draft/2019-09")) return "draft-2019-09";
|
|
1684
|
+
if (declared.includes("draft/2020-12")) return "draft-2020-12";
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
return "draft-2020-12";
|
|
1688
|
+
}
|
|
1689
|
+
function createAjv(dialect) {
|
|
1690
|
+
const AjvCtor = dialect === "draft-2020-12" ? Ajv2020 : dialect === "draft-2019-09" ? Ajv2019 : dialect === "draft-04" ? AjvDraft04 : Ajv;
|
|
1691
|
+
const ajv = new AjvCtor({
|
|
1692
|
+
strict: false,
|
|
1693
|
+
allErrors: true,
|
|
1694
|
+
verbose: true,
|
|
1695
|
+
// Allow schemas with $id to be added without replacing existing ones
|
|
1696
|
+
addUsedSchema: false,
|
|
1697
|
+
// draft-04 uses "id"; later drafts use "$id"
|
|
1698
|
+
schemaId: dialect === "draft-04" ? "id" : "$id",
|
|
1699
|
+
// Enable async schema loading for YAML references
|
|
1700
|
+
loadSchema: loadReferencedSchema
|
|
1701
|
+
});
|
|
1702
|
+
applyFulmenAjvFormats(ajv);
|
|
1703
|
+
return ajv;
|
|
1704
|
+
}
|
|
1705
|
+
async function getAjv(dialect) {
|
|
1706
|
+
const existing = ajvInstances.get(dialect);
|
|
1707
|
+
if (existing) {
|
|
1708
|
+
const ready = metaschemaReady.get(dialect);
|
|
1709
|
+
if (ready) await ready;
|
|
1710
|
+
return existing;
|
|
1711
|
+
}
|
|
1712
|
+
const ajv = createAjv(dialect);
|
|
1713
|
+
ajvInstances.set(dialect, ajv);
|
|
1714
|
+
const readyPromise = Promise.all([loadVocabularySchemas(dialect), loadMetaSchema(dialect)]).then(([vocabSchemas, metaSchema]) => {
|
|
1715
|
+
for (const vocabSchema of vocabSchemas) {
|
|
1716
|
+
try {
|
|
1717
|
+
ajv.addMetaSchema(vocabSchema);
|
|
1718
|
+
} catch {
|
|
1674
1719
|
}
|
|
1675
|
-
}
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1720
|
+
}
|
|
1721
|
+
try {
|
|
1722
|
+
ajv.addMetaSchema(metaSchema);
|
|
1723
|
+
} catch {
|
|
1724
|
+
}
|
|
1725
|
+
}).catch((error) => {
|
|
1726
|
+
throw new Error(`Failed to load metaschemas (${dialect}): ${error}`);
|
|
1727
|
+
});
|
|
1728
|
+
metaschemaReady.set(dialect, readyPromise);
|
|
1729
|
+
await readyPromise;
|
|
1730
|
+
return ajv;
|
|
1680
1731
|
}
|
|
1681
1732
|
async function compileSchema(schema, options = {}) {
|
|
1682
|
-
const
|
|
1683
|
-
if (metaschemaReady) {
|
|
1684
|
-
await metaschemaReady;
|
|
1685
|
-
}
|
|
1686
|
-
const cacheKey = typeof schema === "string" ? schema : JSON.stringify(schema);
|
|
1687
|
-
const cached = schemaCache.get(cacheKey);
|
|
1688
|
-
if (cached !== void 0) {
|
|
1689
|
-
return cached;
|
|
1690
|
-
}
|
|
1733
|
+
const baseKey = typeof schema === "string" ? schema : JSON.stringify(schema);
|
|
1691
1734
|
let parsedSchema;
|
|
1692
1735
|
if (typeof schema === "string") {
|
|
1693
1736
|
try {
|
|
@@ -1705,18 +1748,27 @@ async function compileSchema(schema, options = {}) {
|
|
|
1705
1748
|
} else {
|
|
1706
1749
|
parsedSchema = schema;
|
|
1707
1750
|
}
|
|
1751
|
+
const dialect = detectDialect(parsedSchema);
|
|
1752
|
+
const ajv = await getAjv(dialect);
|
|
1753
|
+
const cacheKey = `${dialect}:${baseKey}`;
|
|
1754
|
+
const cached = schemaCache.get(cacheKey);
|
|
1755
|
+
if (cached !== void 0) {
|
|
1756
|
+
return cached;
|
|
1757
|
+
}
|
|
1708
1758
|
try {
|
|
1709
1759
|
if (options.aliases && options.aliases.length > 0) {
|
|
1710
1760
|
for (const alias of options.aliases) {
|
|
1711
1761
|
if (alias && ajv.getSchema(alias) === void 0) {
|
|
1712
1762
|
try {
|
|
1713
|
-
|
|
1763
|
+
if (typeof parsedSchema === "object" && parsedSchema !== null) {
|
|
1764
|
+
ajv.addSchema(parsedSchema, alias);
|
|
1765
|
+
}
|
|
1714
1766
|
} catch {
|
|
1715
1767
|
}
|
|
1716
1768
|
}
|
|
1717
1769
|
}
|
|
1718
1770
|
}
|
|
1719
|
-
const validator = await ajv.compileAsync(parsedSchema);
|
|
1771
|
+
const validator = typeof parsedSchema === "boolean" ? ajv.compile(parsedSchema) : await ajv.compileAsync(parsedSchema);
|
|
1720
1772
|
schemaCache.set(cacheKey, validator);
|
|
1721
1773
|
return validator;
|
|
1722
1774
|
} catch (error) {
|
|
@@ -1786,8 +1838,39 @@ async function validateFile(filePath, validator) {
|
|
|
1786
1838
|
}
|
|
1787
1839
|
async function validateSchema(schema) {
|
|
1788
1840
|
try {
|
|
1789
|
-
|
|
1790
|
-
|
|
1841
|
+
let parsedSchema;
|
|
1842
|
+
if (typeof schema === "string") {
|
|
1843
|
+
try {
|
|
1844
|
+
parsedSchema = JSON.parse(schema);
|
|
1845
|
+
} catch {
|
|
1846
|
+
parsedSchema = parse(schema);
|
|
1847
|
+
}
|
|
1848
|
+
} else if (Buffer.isBuffer(schema)) {
|
|
1849
|
+
const content = schema.toString("utf-8");
|
|
1850
|
+
try {
|
|
1851
|
+
parsedSchema = JSON.parse(content);
|
|
1852
|
+
} catch {
|
|
1853
|
+
parsedSchema = parse(content);
|
|
1854
|
+
}
|
|
1855
|
+
} else {
|
|
1856
|
+
parsedSchema = schema;
|
|
1857
|
+
}
|
|
1858
|
+
const dialect = detectDialect(parsedSchema);
|
|
1859
|
+
const ajv = await getAjv(dialect);
|
|
1860
|
+
const metaValid = ajv.validateSchema(parsedSchema);
|
|
1861
|
+
if (!metaValid && ajv.errors) {
|
|
1862
|
+
const diagnostics = ajv.errors.map(
|
|
1863
|
+
(error) => createDiagnostic(
|
|
1864
|
+
error.instancePath || "",
|
|
1865
|
+
error.message || "Schema meta-validation failed",
|
|
1866
|
+
error.keyword || "unknown",
|
|
1867
|
+
"ERROR",
|
|
1868
|
+
"ajv"
|
|
1869
|
+
)
|
|
1870
|
+
);
|
|
1871
|
+
return { valid: false, diagnostics, source: "ajv" };
|
|
1872
|
+
}
|
|
1873
|
+
await compileSchema(parsedSchema);
|
|
1791
1874
|
return {
|
|
1792
1875
|
valid: true,
|
|
1793
1876
|
diagnostics: [],
|
|
@@ -1858,14 +1941,16 @@ async function validateFileBySchemaId(filePath, schemaId, registryOptions) {
|
|
|
1858
1941
|
throw error;
|
|
1859
1942
|
}
|
|
1860
1943
|
}
|
|
1861
|
-
var
|
|
1944
|
+
var ajvInstances, metaschemaReady, schemaCache;
|
|
1862
1945
|
var init_validator = __esm({
|
|
1863
1946
|
"src/schema/validator.ts"() {
|
|
1864
1947
|
init_telemetry();
|
|
1948
|
+
init_ajv_formats();
|
|
1865
1949
|
init_errors();
|
|
1866
1950
|
init_registry();
|
|
1867
1951
|
init_utils();
|
|
1868
|
-
|
|
1952
|
+
ajvInstances = /* @__PURE__ */ new Map();
|
|
1953
|
+
metaschemaReady = /* @__PURE__ */ new Map();
|
|
1869
1954
|
schemaCache = /* @__PURE__ */ new Map();
|
|
1870
1955
|
}
|
|
1871
1956
|
});
|
|
@@ -3820,6 +3905,224 @@ var init_capabilities2 = __esm({
|
|
|
3820
3905
|
}
|
|
3821
3906
|
});
|
|
3822
3907
|
|
|
3908
|
+
// src/foundry/signals/config-reload-endpoint.ts
|
|
3909
|
+
function createConfigReloadEndpoint(options) {
|
|
3910
|
+
const { loader, validator, onReload: onReload2, auth, rateLimit, logger, telemetry } = options;
|
|
3911
|
+
return async (payload, req) => {
|
|
3912
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId();
|
|
3913
|
+
const authResult = await auth(req);
|
|
3914
|
+
if (!authResult.authenticated) {
|
|
3915
|
+
if (logger) {
|
|
3916
|
+
logger.warn("Config reload endpoint: authentication failed", {
|
|
3917
|
+
correlation_id: correlationId,
|
|
3918
|
+
reason: authResult.reason
|
|
3919
|
+
});
|
|
3920
|
+
}
|
|
3921
|
+
if (telemetry) {
|
|
3922
|
+
telemetry.emit("fulmen.config.http_endpoint.auth_failed", {
|
|
3923
|
+
correlation_id: correlationId
|
|
3924
|
+
});
|
|
3925
|
+
}
|
|
3926
|
+
return {
|
|
3927
|
+
status: "error",
|
|
3928
|
+
error: "authentication_failed",
|
|
3929
|
+
message: authResult.reason || "Authentication required",
|
|
3930
|
+
statusCode: 401
|
|
3931
|
+
};
|
|
3932
|
+
}
|
|
3933
|
+
const identity = authResult.identity || "unknown";
|
|
3934
|
+
if (rateLimit) {
|
|
3935
|
+
const rateLimitResult = await rateLimit(identity);
|
|
3936
|
+
if (!rateLimitResult.allowed) {
|
|
3937
|
+
if (logger) {
|
|
3938
|
+
logger.warn("Config reload endpoint: rate limit exceeded", {
|
|
3939
|
+
correlation_id: correlationId,
|
|
3940
|
+
identity
|
|
3941
|
+
});
|
|
3942
|
+
}
|
|
3943
|
+
if (telemetry) {
|
|
3944
|
+
telemetry.emit("fulmen.config.http_endpoint.rate_limited", {
|
|
3945
|
+
correlation_id: correlationId
|
|
3946
|
+
});
|
|
3947
|
+
}
|
|
3948
|
+
return {
|
|
3949
|
+
status: "error",
|
|
3950
|
+
error: "rate_limit_exceeded",
|
|
3951
|
+
message: "Rate limit exceeded. Please try again later.",
|
|
3952
|
+
statusCode: 429
|
|
3953
|
+
};
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
if (telemetry) {
|
|
3957
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_requested", {
|
|
3958
|
+
correlation_id: correlationId
|
|
3959
|
+
});
|
|
3960
|
+
}
|
|
3961
|
+
try {
|
|
3962
|
+
const config = await loader();
|
|
3963
|
+
if (validator) {
|
|
3964
|
+
const validation = await validator(config);
|
|
3965
|
+
if (!validation.valid) {
|
|
3966
|
+
if (logger) {
|
|
3967
|
+
logger.warn("Config reload endpoint: validation failed", {
|
|
3968
|
+
correlation_id: correlationId,
|
|
3969
|
+
error_count: validation.errors?.length ?? 0
|
|
3970
|
+
});
|
|
3971
|
+
}
|
|
3972
|
+
if (telemetry) {
|
|
3973
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_rejected", {
|
|
3974
|
+
correlation_id: correlationId,
|
|
3975
|
+
reason: "validation_failed"
|
|
3976
|
+
});
|
|
3977
|
+
}
|
|
3978
|
+
return {
|
|
3979
|
+
status: "error",
|
|
3980
|
+
error: "validation_failed",
|
|
3981
|
+
message: "Configuration validation failed",
|
|
3982
|
+
validation_errors: validation.errors,
|
|
3983
|
+
statusCode: 422
|
|
3984
|
+
};
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
if (onReload2) {
|
|
3988
|
+
await onReload2(config);
|
|
3989
|
+
}
|
|
3990
|
+
if (telemetry) {
|
|
3991
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_accepted", {
|
|
3992
|
+
correlation_id: correlationId
|
|
3993
|
+
});
|
|
3994
|
+
}
|
|
3995
|
+
if (logger) {
|
|
3996
|
+
logger.info("Config reload endpoint: reload accepted", {
|
|
3997
|
+
correlation_id: correlationId,
|
|
3998
|
+
reason: payload.reason
|
|
3999
|
+
});
|
|
4000
|
+
}
|
|
4001
|
+
return {
|
|
4002
|
+
status: "reloaded",
|
|
4003
|
+
correlation_id: correlationId,
|
|
4004
|
+
message: "Configuration reloaded",
|
|
4005
|
+
statusCode: 200
|
|
4006
|
+
};
|
|
4007
|
+
} catch (error) {
|
|
4008
|
+
if (logger) {
|
|
4009
|
+
logger.warn("Config reload endpoint: reload failed", {
|
|
4010
|
+
correlation_id: correlationId,
|
|
4011
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4012
|
+
});
|
|
4013
|
+
}
|
|
4014
|
+
if (telemetry) {
|
|
4015
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_error", {
|
|
4016
|
+
correlation_id: correlationId,
|
|
4017
|
+
error_type: error instanceof Error ? error.constructor.name : "unknown"
|
|
4018
|
+
});
|
|
4019
|
+
}
|
|
4020
|
+
return {
|
|
4021
|
+
status: "error",
|
|
4022
|
+
error: "reload_failed",
|
|
4023
|
+
message: error instanceof Error ? error.message : String(error),
|
|
4024
|
+
statusCode: 500
|
|
4025
|
+
};
|
|
4026
|
+
}
|
|
4027
|
+
};
|
|
4028
|
+
}
|
|
4029
|
+
function generateCorrelationId() {
|
|
4030
|
+
return `cfg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4031
|
+
}
|
|
4032
|
+
var init_config_reload_endpoint = __esm({
|
|
4033
|
+
"src/foundry/signals/config-reload-endpoint.ts"() {
|
|
4034
|
+
}
|
|
4035
|
+
});
|
|
4036
|
+
|
|
4037
|
+
// src/appidentity/runtime.ts
|
|
4038
|
+
function detectRuntime() {
|
|
4039
|
+
const versions = process.versions;
|
|
4040
|
+
if (typeof versions.bun === "string" && versions.bun.length > 0) {
|
|
4041
|
+
return { name: "bun", version: versions.bun };
|
|
4042
|
+
}
|
|
4043
|
+
if (typeof versions.node === "string" && versions.node.length > 0) {
|
|
4044
|
+
return { name: "node", version: versions.node };
|
|
4045
|
+
}
|
|
4046
|
+
return { name: "unknown" };
|
|
4047
|
+
}
|
|
4048
|
+
function buildRuntimeInfo(options = {}) {
|
|
4049
|
+
const runtime = detectRuntime();
|
|
4050
|
+
const serviceName = options.serviceName ?? options.identity?.app.binary_name ?? "unknown-service";
|
|
4051
|
+
const vendor = options.vendor ?? options.identity?.app.vendor;
|
|
4052
|
+
return {
|
|
4053
|
+
service: {
|
|
4054
|
+
name: serviceName,
|
|
4055
|
+
vendor,
|
|
4056
|
+
version: options.version
|
|
4057
|
+
},
|
|
4058
|
+
runtime,
|
|
4059
|
+
platform: {
|
|
4060
|
+
os: process.platform,
|
|
4061
|
+
arch: process.arch
|
|
4062
|
+
}
|
|
4063
|
+
};
|
|
4064
|
+
}
|
|
4065
|
+
var init_runtime = __esm({
|
|
4066
|
+
"src/appidentity/runtime.ts"() {
|
|
4067
|
+
}
|
|
4068
|
+
});
|
|
4069
|
+
|
|
4070
|
+
// src/foundry/signals/control-discovery-endpoint.ts
|
|
4071
|
+
function createControlDiscoveryEndpoint(options) {
|
|
4072
|
+
const { identity, version, endpoints, auth, authSummary, logger, telemetry } = options;
|
|
4073
|
+
return async (req) => {
|
|
4074
|
+
if (auth) {
|
|
4075
|
+
const authResult = await auth(req);
|
|
4076
|
+
if (!authResult.authenticated) {
|
|
4077
|
+
if (logger) {
|
|
4078
|
+
logger.warn("Control discovery endpoint: authentication failed", {
|
|
4079
|
+
reason: authResult.reason
|
|
4080
|
+
});
|
|
4081
|
+
}
|
|
4082
|
+
if (telemetry) {
|
|
4083
|
+
telemetry.emit("fulmen.control.discovery.auth_failed", {
|
|
4084
|
+
service: identity.app.binary_name
|
|
4085
|
+
});
|
|
4086
|
+
}
|
|
4087
|
+
return {
|
|
4088
|
+
status: "error",
|
|
4089
|
+
error: "authentication_failed",
|
|
4090
|
+
message: authResult.reason || "Authentication required",
|
|
4091
|
+
statusCode: 401
|
|
4092
|
+
};
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
if (telemetry) {
|
|
4096
|
+
telemetry.emit("fulmen.control.discovery.served", {
|
|
4097
|
+
service: identity.app.binary_name
|
|
4098
|
+
});
|
|
4099
|
+
}
|
|
4100
|
+
const runtime = buildRuntimeInfo({ identity, version });
|
|
4101
|
+
return {
|
|
4102
|
+
status: "ok",
|
|
4103
|
+
service: {
|
|
4104
|
+
name: identity.app.binary_name,
|
|
4105
|
+
vendor: identity.app.vendor,
|
|
4106
|
+
version
|
|
4107
|
+
},
|
|
4108
|
+
runtime: {
|
|
4109
|
+
name: runtime.runtime.name,
|
|
4110
|
+
version: runtime.runtime.version,
|
|
4111
|
+
platform: runtime.platform.os,
|
|
4112
|
+
arch: runtime.platform.arch
|
|
4113
|
+
},
|
|
4114
|
+
auth_summary: authSummary,
|
|
4115
|
+
endpoints,
|
|
4116
|
+
statusCode: 200
|
|
4117
|
+
};
|
|
4118
|
+
};
|
|
4119
|
+
}
|
|
4120
|
+
var init_control_discovery_endpoint = __esm({
|
|
4121
|
+
"src/foundry/signals/control-discovery-endpoint.ts"() {
|
|
4122
|
+
init_runtime();
|
|
4123
|
+
}
|
|
4124
|
+
});
|
|
4125
|
+
|
|
3823
4126
|
// src/foundry/signals/convenience.ts
|
|
3824
4127
|
async function onShutdown(manager, handler, options = {}) {
|
|
3825
4128
|
await manager.register("SIGTERM", handler, options);
|
|
@@ -4079,7 +4382,7 @@ var init_guards = __esm({
|
|
|
4079
4382
|
function createSignalEndpoint(options) {
|
|
4080
4383
|
const { manager, auth, rateLimit, logger, telemetry, allowedSignals } = options;
|
|
4081
4384
|
return async (payload, req) => {
|
|
4082
|
-
const correlationId = payload.correlation_id ??
|
|
4385
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId2();
|
|
4083
4386
|
const authResult = await auth(req);
|
|
4084
4387
|
if (!authResult.authenticated) {
|
|
4085
4388
|
if (logger) {
|
|
@@ -4202,7 +4505,7 @@ function normalizeSignalName(signal) {
|
|
|
4202
4505
|
}
|
|
4203
4506
|
return `SIG${upper}`;
|
|
4204
4507
|
}
|
|
4205
|
-
function
|
|
4508
|
+
function generateCorrelationId2() {
|
|
4206
4509
|
return `sig-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4207
4510
|
}
|
|
4208
4511
|
function createBearerTokenAuth(expectedToken) {
|
|
@@ -4669,6 +4972,8 @@ var init_signals = __esm({
|
|
|
4669
4972
|
"src/foundry/signals/index.ts"() {
|
|
4670
4973
|
init_capabilities2();
|
|
4671
4974
|
init_catalog();
|
|
4975
|
+
init_config_reload_endpoint();
|
|
4976
|
+
init_control_discovery_endpoint();
|
|
4672
4977
|
init_convenience();
|
|
4673
4978
|
init_double_tap();
|
|
4674
4979
|
init_guards();
|
|
@@ -4814,7 +5119,9 @@ __export(foundry_exports, {
|
|
|
4814
5119
|
clearMimeTypeCache: () => clearMimeTypeCache,
|
|
4815
5120
|
clearPatternCache: () => clearPatternCache,
|
|
4816
5121
|
createBearerTokenAuth: () => createBearerTokenAuth,
|
|
5122
|
+
createConfigReloadEndpoint: () => createConfigReloadEndpoint,
|
|
4817
5123
|
createConfigReloadHandler: () => createConfigReloadHandler,
|
|
5124
|
+
createControlDiscoveryEndpoint: () => createControlDiscoveryEndpoint,
|
|
4818
5125
|
createDoubleTapTracker: () => createDoubleTapTracker,
|
|
4819
5126
|
createSignalEndpoint: () => createSignalEndpoint,
|
|
4820
5127
|
createSignalManager: () => createSignalManager,
|
|
@@ -5584,6 +5891,7 @@ var init_cli = __esm({
|
|
|
5584
5891
|
// src/schema/index.ts
|
|
5585
5892
|
var init_schema = __esm({
|
|
5586
5893
|
"src/schema/index.ts"() {
|
|
5894
|
+
init_ajv_formats();
|
|
5587
5895
|
init_cli();
|
|
5588
5896
|
init_errors();
|
|
5589
5897
|
init_export();
|
|
@@ -10714,6 +11022,7 @@ __export(appidentity_exports, {
|
|
|
10714
11022
|
AppIdentityError: () => AppIdentityError,
|
|
10715
11023
|
MAX_ANCESTOR_SEARCH_DEPTH: () => MAX_ANCESTOR_SEARCH_DEPTH,
|
|
10716
11024
|
buildEnvVar: () => buildEnvVar,
|
|
11025
|
+
buildRuntimeInfo: () => buildRuntimeInfo,
|
|
10717
11026
|
clearEmbeddedIdentity: () => clearEmbeddedIdentity,
|
|
10718
11027
|
clearIdentityCache: () => clearIdentityCache,
|
|
10719
11028
|
getBinaryName: () => getBinaryName,
|
|
@@ -10736,6 +11045,7 @@ var init_appidentity = __esm({
|
|
|
10736
11045
|
init_errors4();
|
|
10737
11046
|
init_helpers();
|
|
10738
11047
|
init_loader2();
|
|
11048
|
+
init_runtime();
|
|
10739
11049
|
}
|
|
10740
11050
|
});
|
|
10741
11051
|
|