@c4a/core 0.6.18 → 0.7.0
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/index.js +444 -7
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -12980,10 +12980,11 @@ var DEFAULT_PATH_FILTER = {
|
|
|
12980
12980
|
]
|
|
12981
12981
|
},
|
|
12982
12982
|
code: {
|
|
12983
|
-
include: ["**/*.{ts,tsx}"],
|
|
12983
|
+
include: ["**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}"],
|
|
12984
12984
|
exclude: [
|
|
12985
12985
|
"**/__{tests,test,e2e,mocks,fixtures,snapshots}__/**",
|
|
12986
|
-
"**/*.{test,spec
|
|
12986
|
+
"**/*.{test,spec}.{ts,tsx,mts,cts,js,jsx,mjs,cjs}",
|
|
12987
|
+
"**/*.d.{ts,mts,cts}"
|
|
12987
12988
|
]
|
|
12988
12989
|
},
|
|
12989
12990
|
doc: {
|
|
@@ -13125,6 +13126,419 @@ var factSchema = exports_external.union([
|
|
|
13125
13126
|
activeFactSchema,
|
|
13126
13127
|
deprecatedFactSchema
|
|
13127
13128
|
]);
|
|
13129
|
+
// src/schemas/indexerEvidenceAdapterSchema.ts
|
|
13130
|
+
import { createHash } from "node:crypto";
|
|
13131
|
+
|
|
13132
|
+
// src/indexerOutputRedaction.ts
|
|
13133
|
+
var INDEXER_OUTPUT_REDACTION_MARKER = "[REDACTED:indexer-output]";
|
|
13134
|
+
var SECRET_TOKEN = /^(?:password|passwd|pwd|secret|token|credential|credentials|cookie)$/u;
|
|
13135
|
+
var SECRET_COMPOUND = /^(?:api-key|access-key|private-key|client-secret|access-token|refresh-token)$/u;
|
|
13136
|
+
var NON_SECRET_SUFFIX = new Set([
|
|
13137
|
+
"budget",
|
|
13138
|
+
"count",
|
|
13139
|
+
"digest",
|
|
13140
|
+
"fingerprint",
|
|
13141
|
+
"hash",
|
|
13142
|
+
"index",
|
|
13143
|
+
"kind",
|
|
13144
|
+
"length",
|
|
13145
|
+
"limit",
|
|
13146
|
+
"name",
|
|
13147
|
+
"ref",
|
|
13148
|
+
"reference",
|
|
13149
|
+
"references",
|
|
13150
|
+
"refs",
|
|
13151
|
+
"status",
|
|
13152
|
+
"type"
|
|
13153
|
+
]);
|
|
13154
|
+
function keyTokens(key) {
|
|
13155
|
+
return key.replace(/([a-z0-9])([A-Z])/gu, "$1-$2").replace(/[^A-Za-z0-9]+/gu, "-").toLowerCase().split("-").filter(Boolean);
|
|
13156
|
+
}
|
|
13157
|
+
function sensitiveKey(key, value) {
|
|
13158
|
+
const tokens = keyTokens(key);
|
|
13159
|
+
if (tokens.length === 0)
|
|
13160
|
+
return false;
|
|
13161
|
+
const normalized = tokens.join("-");
|
|
13162
|
+
if (normalized === "authorization" && value !== null && typeof value === "object") {
|
|
13163
|
+
return false;
|
|
13164
|
+
}
|
|
13165
|
+
if (NON_SECRET_SUFFIX.has(tokens.at(-1)))
|
|
13166
|
+
return false;
|
|
13167
|
+
return SECRET_COMPOUND.test(normalized) || tokens.some((token) => SECRET_TOKEN.test(token)) || normalized === "authorization";
|
|
13168
|
+
}
|
|
13169
|
+
function escapeRegExp(value) {
|
|
13170
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
13171
|
+
}
|
|
13172
|
+
function normalizedBlockedScalars(policy) {
|
|
13173
|
+
const identities = new Set;
|
|
13174
|
+
const values = [];
|
|
13175
|
+
for (const value of policy.blocked_scalars ?? []) {
|
|
13176
|
+
if (typeof value === "number" && !Number.isFinite(value))
|
|
13177
|
+
continue;
|
|
13178
|
+
if (typeof value === "string" && value.length === 0)
|
|
13179
|
+
continue;
|
|
13180
|
+
const identity = `${typeof value}:${String(value)}`;
|
|
13181
|
+
if (identities.has(identity))
|
|
13182
|
+
continue;
|
|
13183
|
+
identities.add(identity);
|
|
13184
|
+
values.push(value);
|
|
13185
|
+
}
|
|
13186
|
+
return values.sort((left, right) => String(right).length - String(left).length);
|
|
13187
|
+
}
|
|
13188
|
+
function replaceWithCount(value, pattern, replacement, count) {
|
|
13189
|
+
return value.replace(pattern, (...args) => {
|
|
13190
|
+
count.replacements += 1;
|
|
13191
|
+
if (typeof replacement === "string")
|
|
13192
|
+
return replacement;
|
|
13193
|
+
return replacement(...args.slice(0, -2));
|
|
13194
|
+
});
|
|
13195
|
+
}
|
|
13196
|
+
function redactKnownText(value, count) {
|
|
13197
|
+
let output = value;
|
|
13198
|
+
output = replaceWithCount(output, /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/gu, INDEXER_OUTPUT_REDACTION_MARKER, count);
|
|
13199
|
+
output = replaceWithCount(output, /(\bauthorization\s*:\s*(?:bearer|basic)\s+)[^\s,;]+/giu, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
|
|
13200
|
+
output = replaceWithCount(output, /([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+:[^\s/@]+@/giu, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}@`, count);
|
|
13201
|
+
output = replaceWithCount(output, /([?&](?:access_token|refresh_token|api_key|password|secret)=)[^&#\s]+/giu, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
|
|
13202
|
+
const key = "(?:[A-Za-z0-9_.-]*(?:password|passwd|pwd|secret|token|credential|cookie)[A-Za-z0-9_.-]*|api[-_]?key|access[-_]?(?:key|token)|private[-_]?key|client[-_]?secret|authorization)";
|
|
13203
|
+
const assignment = `(?:=\\s*|:\\s+(?=\\S)|:\\s*(?=["']))`;
|
|
13204
|
+
output = replaceWithCount(output, new RegExp(`((?:["']?${key}["']?)\\s*${assignment})(?:"(?:\\\\.|[^"])*"|'(?:\\\\.|[^'])*'|[^\\s,;}\\]]+)`, "giu"), (_match, prefix) => `${prefix}"${INDEXER_OUTPUT_REDACTION_MARKER}"`, count);
|
|
13205
|
+
return output;
|
|
13206
|
+
}
|
|
13207
|
+
function redactBlockedText(value, blocked, count) {
|
|
13208
|
+
let output = value;
|
|
13209
|
+
for (const scalar of blocked) {
|
|
13210
|
+
const pattern = typeof scalar === "number" ? new RegExp(`(?<![0-9.])${escapeRegExp(String(scalar))}(?![0-9.])`, "gu") : new RegExp(escapeRegExp(scalar), "gu");
|
|
13211
|
+
output = replaceWithCount(output, pattern, INDEXER_OUTPUT_REDACTION_MARKER, count);
|
|
13212
|
+
}
|
|
13213
|
+
return output;
|
|
13214
|
+
}
|
|
13215
|
+
function redactText(value, blocked, count) {
|
|
13216
|
+
return redactBlockedText(redactKnownText(value, count), blocked, count);
|
|
13217
|
+
}
|
|
13218
|
+
function blockedScalar(value, blocked) {
|
|
13219
|
+
return blocked.some((candidate) => typeof candidate === typeof value && Object.is(candidate, value));
|
|
13220
|
+
}
|
|
13221
|
+
function redactStructured(value, blocked, count, seen) {
|
|
13222
|
+
if (blockedScalar(value, blocked)) {
|
|
13223
|
+
count.replacements += 1;
|
|
13224
|
+
return INDEXER_OUTPUT_REDACTION_MARKER;
|
|
13225
|
+
}
|
|
13226
|
+
if (typeof value === "string")
|
|
13227
|
+
return redactText(value, blocked, count);
|
|
13228
|
+
if (value === null || typeof value !== "object")
|
|
13229
|
+
return value;
|
|
13230
|
+
if (seen.has(value))
|
|
13231
|
+
throw new TypeError("Indexer output redaction requires an acyclic value");
|
|
13232
|
+
seen.add(value);
|
|
13233
|
+
if (value instanceof Date) {
|
|
13234
|
+
const redacted2 = redactText(value.toISOString(), blocked, count);
|
|
13235
|
+
seen.delete(value);
|
|
13236
|
+
return redacted2;
|
|
13237
|
+
}
|
|
13238
|
+
if (value instanceof Error) {
|
|
13239
|
+
const redacted2 = {
|
|
13240
|
+
name: redactText(value.name, blocked, count),
|
|
13241
|
+
message: redactText(value.message, blocked, count)
|
|
13242
|
+
};
|
|
13243
|
+
seen.delete(value);
|
|
13244
|
+
return redacted2;
|
|
13245
|
+
}
|
|
13246
|
+
if (Array.isArray(value)) {
|
|
13247
|
+
const redacted2 = value.map((item) => redactStructured(item, blocked, count, seen));
|
|
13248
|
+
seen.delete(value);
|
|
13249
|
+
return redacted2;
|
|
13250
|
+
}
|
|
13251
|
+
const redacted = {};
|
|
13252
|
+
for (const [key, item] of Object.entries(value)) {
|
|
13253
|
+
const safeKey = redactText(key, blocked, count);
|
|
13254
|
+
if (sensitiveKey(key, item)) {
|
|
13255
|
+
count.replacements += 1;
|
|
13256
|
+
redacted[safeKey] = INDEXER_OUTPUT_REDACTION_MARKER;
|
|
13257
|
+
} else {
|
|
13258
|
+
redacted[safeKey] = redactStructured(item, blocked, count, seen);
|
|
13259
|
+
}
|
|
13260
|
+
}
|
|
13261
|
+
seen.delete(value);
|
|
13262
|
+
return redacted;
|
|
13263
|
+
}
|
|
13264
|
+
function redactIndexerOutput(input) {
|
|
13265
|
+
const count = { replacements: 0 };
|
|
13266
|
+
const blocked = normalizedBlockedScalars(input.policy ?? {});
|
|
13267
|
+
const value = typeof input.value === "string" ? redactText(input.value, blocked, count) : redactStructured(input.value, blocked, count, new WeakSet);
|
|
13268
|
+
return {
|
|
13269
|
+
value,
|
|
13270
|
+
redacted: count.replacements > 0,
|
|
13271
|
+
replacement_count: count.replacements
|
|
13272
|
+
};
|
|
13273
|
+
}
|
|
13274
|
+
function redactIndexerOutputText(input) {
|
|
13275
|
+
return redactIndexerOutput(input).value;
|
|
13276
|
+
}
|
|
13277
|
+
function assertIndexerOutputSafe(input) {
|
|
13278
|
+
const result = redactIndexerOutput(input);
|
|
13279
|
+
if (result.redacted) {
|
|
13280
|
+
throw new TypeError(`Indexer ${input.channel} was blocked by the common output redaction boundary`);
|
|
13281
|
+
}
|
|
13282
|
+
return input.value;
|
|
13283
|
+
}
|
|
13284
|
+
|
|
13285
|
+
// src/schemas/indexerEvidenceAdapterSchema.ts
|
|
13286
|
+
var digestSchema = exports_external.string().regex(/^sha256:[a-f0-9]{64}$/u);
|
|
13287
|
+
var idSchema = exports_external.string().regex(/^[a-z0-9][a-z0-9._/-]*$/u).superRefine((value, context) => {
|
|
13288
|
+
if (value.split("/").some((segment) => segment.length === 0 || segment === "." || segment === "..")) {
|
|
13289
|
+
context.addIssue({
|
|
13290
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13291
|
+
message: "must not contain empty, current-directory, or parent-directory segments"
|
|
13292
|
+
});
|
|
13293
|
+
}
|
|
13294
|
+
});
|
|
13295
|
+
var semverSchema = exports_external.string().regex(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u);
|
|
13296
|
+
var canonicalRefSchema = exports_external.string().regex(/^[a-z][a-z0-9.-]*:[A-Za-z0-9][A-Za-z0-9._~:/#@+-]*$/u);
|
|
13297
|
+
var packageCoordinateSchema = exports_external.string().regex(/^(?:@[a-z0-9._-]+\/)?[a-z0-9][a-z0-9._-]*$/u);
|
|
13298
|
+
var portablePathSchema = exports_external.string().superRefine((value, context) => {
|
|
13299
|
+
const segments = value.split("/");
|
|
13300
|
+
if (value.length === 0 || value.includes("\x00") || value.includes("\\") || value.startsWith("/") || /^[A-Za-z]:\//u.test(value) || segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) {
|
|
13301
|
+
context.addIssue({
|
|
13302
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13303
|
+
message: "must be a portable relative path"
|
|
13304
|
+
});
|
|
13305
|
+
}
|
|
13306
|
+
});
|
|
13307
|
+
function addDuplicateIssues(values, context, field) {
|
|
13308
|
+
const seen = new Set;
|
|
13309
|
+
values.forEach((value, index) => {
|
|
13310
|
+
if (seen.has(value)) {
|
|
13311
|
+
context.addIssue({
|
|
13312
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13313
|
+
message: `${field} must not contain duplicate value ${value}`,
|
|
13314
|
+
path: [index]
|
|
13315
|
+
});
|
|
13316
|
+
}
|
|
13317
|
+
seen.add(value);
|
|
13318
|
+
});
|
|
13319
|
+
}
|
|
13320
|
+
var adapterIdentitySchema = exports_external.object({
|
|
13321
|
+
id: idSchema,
|
|
13322
|
+
package: packageCoordinateSchema,
|
|
13323
|
+
export: exports_external.string().regex(/^[A-Za-z_$][A-Za-z0-9_$.-]*$/u),
|
|
13324
|
+
version: semverSchema,
|
|
13325
|
+
digest: digestSchema
|
|
13326
|
+
}).strict();
|
|
13327
|
+
var adapterLocatorSchema = exports_external.object({
|
|
13328
|
+
source_ref: canonicalRefSchema,
|
|
13329
|
+
module_ref: canonicalRefSchema.nullable(),
|
|
13330
|
+
normalized_path: portablePathSchema,
|
|
13331
|
+
qualified_item_path: exports_external.string().min(1).max(1024),
|
|
13332
|
+
signature_digest: digestSchema
|
|
13333
|
+
}).strict();
|
|
13334
|
+
var indexerEvidenceAdapterFactSchema = exports_external.object({
|
|
13335
|
+
fact_ref: canonicalRefSchema,
|
|
13336
|
+
kind: idSchema,
|
|
13337
|
+
locator: adapterLocatorSchema,
|
|
13338
|
+
payload_digest: digestSchema,
|
|
13339
|
+
denominator: exports_external.enum(["none", "eligible-file", "loc", "symbol", "protocol-item"])
|
|
13340
|
+
}).strict();
|
|
13341
|
+
var indexerEvidenceAdapterFileSchema = exports_external.object({
|
|
13342
|
+
file_ref: canonicalRefSchema,
|
|
13343
|
+
source_ref: canonicalRefSchema,
|
|
13344
|
+
module_ref: canonicalRefSchema.nullable(),
|
|
13345
|
+
normalized_path: portablePathSchema,
|
|
13346
|
+
role: exports_external.enum(["primary-owner", "enricher"]),
|
|
13347
|
+
coverage_tier: exports_external.enum(["ast-catalog", "lightweight-evidence"]),
|
|
13348
|
+
disposition: exports_external.enum(["analyzed", "unsupported", "excluded"]),
|
|
13349
|
+
facts: exports_external.array(indexerEvidenceAdapterFactSchema)
|
|
13350
|
+
}).strict().superRefine((value, context) => {
|
|
13351
|
+
addDuplicateIssues(value.facts.map((fact2) => fact2.fact_ref), context, "facts");
|
|
13352
|
+
if (value.disposition !== "analyzed" && value.facts.length > 0) {
|
|
13353
|
+
context.addIssue({
|
|
13354
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13355
|
+
message: "unsupported or excluded files cannot publish facts",
|
|
13356
|
+
path: ["facts"]
|
|
13357
|
+
});
|
|
13358
|
+
}
|
|
13359
|
+
if ((value.role === "enricher" || value.coverage_tier === "lightweight-evidence") && value.facts.some((fact2) => fact2.denominator !== "none")) {
|
|
13360
|
+
context.addIssue({
|
|
13361
|
+
code: exports_external.ZodIssueCode.custom,
|
|
13362
|
+
message: "enricher and lightweight evidence facts cannot contribute denominators",
|
|
13363
|
+
path: ["facts"]
|
|
13364
|
+
});
|
|
13365
|
+
}
|
|
13366
|
+
});
|
|
13367
|
+
var toolchainStepSchema = exports_external.object({
|
|
13368
|
+
step: idSchema,
|
|
13369
|
+
package: packageCoordinateSchema,
|
|
13370
|
+
export: exports_external.string().regex(/^[A-Za-z_$][A-Za-z0-9_$.-]*$/u),
|
|
13371
|
+
version: semverSchema,
|
|
13372
|
+
digest: digestSchema,
|
|
13373
|
+
capabilities: exports_external.array(idSchema).min(1),
|
|
13374
|
+
input_digest: digestSchema,
|
|
13375
|
+
output_digest: digestSchema
|
|
13376
|
+
}).strict().superRefine((value, context) => {
|
|
13377
|
+
addDuplicateIssues(value.capabilities, context, "capabilities");
|
|
13378
|
+
});
|
|
13379
|
+
var adapterDiagnosticSchema = exports_external.object({
|
|
13380
|
+
code: idSchema,
|
|
13381
|
+
fact_ref: canonicalRefSchema.optional(),
|
|
13382
|
+
severity: exports_external.enum(["info", "warning", "error"]),
|
|
13383
|
+
detail_digest: digestSchema
|
|
13384
|
+
}).strict();
|
|
13385
|
+
var indexerEvidenceAdapterResultSchema = exports_external.object({
|
|
13386
|
+
protocol: exports_external.literal("context.indexer.evidence-adapter-result/v1"),
|
|
13387
|
+
adapter: adapterIdentitySchema,
|
|
13388
|
+
authorized_scope: exports_external.object({
|
|
13389
|
+
source_ref: canonicalRefSchema,
|
|
13390
|
+
module_refs: exports_external.array(canonicalRefSchema),
|
|
13391
|
+
scope_digest: digestSchema
|
|
13392
|
+
}).strict(),
|
|
13393
|
+
input_digest: digestSchema,
|
|
13394
|
+
precedence: exports_external.number().int().nonnegative(),
|
|
13395
|
+
files: exports_external.array(indexerEvidenceAdapterFileSchema).min(1),
|
|
13396
|
+
diagnostics: exports_external.array(adapterDiagnosticSchema),
|
|
13397
|
+
toolchain: exports_external.array(toolchainStepSchema).min(1),
|
|
13398
|
+
output_digest: digestSchema
|
|
13399
|
+
}).strict().superRefine((value, context) => {
|
|
13400
|
+
addDuplicateIssues(value.authorized_scope.module_refs, context, "authorized_scope.module_refs");
|
|
13401
|
+
addDuplicateIssues(value.files.map((file) => file.file_ref), context, "files");
|
|
13402
|
+
addDuplicateIssues(value.toolchain.map((step) => step.step), context, "toolchain");
|
|
13403
|
+
});
|
|
13404
|
+
var FACT_PAYLOADS = new WeakMap;
|
|
13405
|
+
function canonicalFactPayload(value, seen = new WeakSet, path = "$") {
|
|
13406
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") {
|
|
13407
|
+
return value;
|
|
13408
|
+
}
|
|
13409
|
+
if (typeof value === "number") {
|
|
13410
|
+
if (!Number.isFinite(value)) {
|
|
13411
|
+
throw new TypeError("Indexer Evidence Adapter fact payload numbers must be finite");
|
|
13412
|
+
}
|
|
13413
|
+
return value;
|
|
13414
|
+
}
|
|
13415
|
+
if (typeof value !== "object") {
|
|
13416
|
+
throw new TypeError(`Indexer Evidence Adapter fact payload ${path} must contain only JSON values`);
|
|
13417
|
+
}
|
|
13418
|
+
if (seen.has(value)) {
|
|
13419
|
+
throw new TypeError(`Indexer Evidence Adapter fact payload ${path} must be acyclic`);
|
|
13420
|
+
}
|
|
13421
|
+
seen.add(value);
|
|
13422
|
+
if (Array.isArray(value)) {
|
|
13423
|
+
const output2 = value.map((item, index) => canonicalFactPayload(item, seen, `${path}[${index}]`));
|
|
13424
|
+
seen.delete(value);
|
|
13425
|
+
return output2;
|
|
13426
|
+
}
|
|
13427
|
+
if (Object.prototype.toString.call(value) !== "[object Object]") {
|
|
13428
|
+
throw new TypeError(`Indexer Evidence Adapter fact payload ${path} must use plain JSON objects; received ${Object.prototype.toString.call(value)}`);
|
|
13429
|
+
}
|
|
13430
|
+
const output = {};
|
|
13431
|
+
for (const [key, item] of Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)) {
|
|
13432
|
+
output[key] = canonicalFactPayload(item, seen, `${path}.${key}`);
|
|
13433
|
+
}
|
|
13434
|
+
seen.delete(value);
|
|
13435
|
+
return output;
|
|
13436
|
+
}
|
|
13437
|
+
function canonicalize(value) {
|
|
13438
|
+
if (Array.isArray(value))
|
|
13439
|
+
return value.map(canonicalize);
|
|
13440
|
+
if (value !== null && typeof value === "object") {
|
|
13441
|
+
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, item]) => [key, canonicalize(item)]));
|
|
13442
|
+
}
|
|
13443
|
+
return value;
|
|
13444
|
+
}
|
|
13445
|
+
function indexerEvidenceAdapterProtocolDigest(value) {
|
|
13446
|
+
const canonical = JSON.stringify(canonicalize(value));
|
|
13447
|
+
return `sha256:${createHash("sha256").update(canonical).digest("hex")}`;
|
|
13448
|
+
}
|
|
13449
|
+
function indexerEvidenceAdapterFileRef(input) {
|
|
13450
|
+
return `adapter-file:${indexerEvidenceAdapterProtocolDigest(input)}`;
|
|
13451
|
+
}
|
|
13452
|
+
function indexerEvidenceAdapterFactRef(input) {
|
|
13453
|
+
return `adapter-fact:${indexerEvidenceAdapterProtocolDigest(input)}`;
|
|
13454
|
+
}
|
|
13455
|
+
function createIndexerEvidenceAdapterFact(input) {
|
|
13456
|
+
const payload = canonicalFactPayload(input.payload);
|
|
13457
|
+
const qualifiedItemPath = input.qualified_item_path.length <= 1024 ? input.qualified_item_path : `${input.qualified_item_path.slice(0, 950)}#${indexerEvidenceAdapterProtocolDigest(input.qualified_item_path)}`;
|
|
13458
|
+
const locator = {
|
|
13459
|
+
source_ref: input.source_ref,
|
|
13460
|
+
module_ref: input.module_ref,
|
|
13461
|
+
normalized_path: input.normalized_path,
|
|
13462
|
+
qualified_item_path: qualifiedItemPath,
|
|
13463
|
+
signature_digest: indexerEvidenceAdapterProtocolDigest(input.signature)
|
|
13464
|
+
};
|
|
13465
|
+
const fact2 = {
|
|
13466
|
+
fact_ref: indexerEvidenceAdapterFactRef({ ...locator, kind: input.kind }),
|
|
13467
|
+
kind: input.kind,
|
|
13468
|
+
locator,
|
|
13469
|
+
payload_digest: indexerEvidenceAdapterProtocolDigest(payload),
|
|
13470
|
+
denominator: input.denominator
|
|
13471
|
+
};
|
|
13472
|
+
FACT_PAYLOADS.set(fact2, payload);
|
|
13473
|
+
return fact2;
|
|
13474
|
+
}
|
|
13475
|
+
function indexerEvidenceAdapterFactPayloads(result) {
|
|
13476
|
+
const payloads = result.files.flatMap((file) => file.facts.map((fact2) => {
|
|
13477
|
+
const payload = FACT_PAYLOADS.get(fact2);
|
|
13478
|
+
if (payload === undefined) {
|
|
13479
|
+
throw new TypeError(`Evidence Adapter fact payload ${fact2.fact_ref} is no longer materialized in this process`);
|
|
13480
|
+
}
|
|
13481
|
+
if (indexerEvidenceAdapterProtocolDigest(payload) !== fact2.payload_digest) {
|
|
13482
|
+
throw new TypeError(`Evidence Adapter fact payload ${fact2.fact_ref} is stale`);
|
|
13483
|
+
}
|
|
13484
|
+
return { fact_ref: fact2.fact_ref, payload };
|
|
13485
|
+
})).sort((left, right) => compareCanonicalText(left.fact_ref, right.fact_ref));
|
|
13486
|
+
return assertIndexerOutputSafe({ channel: "ipc-envelope", value: payloads });
|
|
13487
|
+
}
|
|
13488
|
+
function materializeIndexerEvidenceAdapterResult(result) {
|
|
13489
|
+
return {
|
|
13490
|
+
result,
|
|
13491
|
+
fact_payloads: indexerEvidenceAdapterFactPayloads(result)
|
|
13492
|
+
};
|
|
13493
|
+
}
|
|
13494
|
+
function indexerEvidenceAdapterOutputDigest(value) {
|
|
13495
|
+
return indexerEvidenceAdapterProtocolDigest(value);
|
|
13496
|
+
}
|
|
13497
|
+
function compareCanonicalText(left, right) {
|
|
13498
|
+
if (left < right)
|
|
13499
|
+
return -1;
|
|
13500
|
+
if (left > right)
|
|
13501
|
+
return 1;
|
|
13502
|
+
return 0;
|
|
13503
|
+
}
|
|
13504
|
+
function buildIndexerEvidenceAdapterResult(input) {
|
|
13505
|
+
const canonical = {
|
|
13506
|
+
...input,
|
|
13507
|
+
authorized_scope: {
|
|
13508
|
+
...input.authorized_scope,
|
|
13509
|
+
module_refs: [...input.authorized_scope.module_refs].sort(compareCanonicalText)
|
|
13510
|
+
},
|
|
13511
|
+
files: input.files.map((file) => ({
|
|
13512
|
+
...file,
|
|
13513
|
+
facts: [...file.facts].sort((left, right) => compareCanonicalText(left.fact_ref, right.fact_ref))
|
|
13514
|
+
})).sort((left, right) => compareCanonicalText(left.file_ref, right.file_ref)),
|
|
13515
|
+
diagnostics: [...input.diagnostics].sort((left, right) => compareCanonicalText(left.fact_ref ?? "", right.fact_ref ?? "") || compareCanonicalText(left.code, right.code) || compareCanonicalText(left.severity, right.severity) || compareCanonicalText(left.detail_digest, right.detail_digest)),
|
|
13516
|
+
toolchain: input.toolchain.map((step) => ({
|
|
13517
|
+
...step,
|
|
13518
|
+
capabilities: [...step.capabilities].sort(compareCanonicalText)
|
|
13519
|
+
}))
|
|
13520
|
+
};
|
|
13521
|
+
const payloads = new Map;
|
|
13522
|
+
for (const file of canonical.files) {
|
|
13523
|
+
for (const fact2 of file.facts) {
|
|
13524
|
+
const payload = FACT_PAYLOADS.get(fact2);
|
|
13525
|
+
if (payload !== undefined)
|
|
13526
|
+
payloads.set(fact2.fact_ref, payload);
|
|
13527
|
+
}
|
|
13528
|
+
}
|
|
13529
|
+
const parsed = indexerEvidenceAdapterResultSchema.parse({
|
|
13530
|
+
...canonical,
|
|
13531
|
+
output_digest: indexerEvidenceAdapterOutputDigest(canonical)
|
|
13532
|
+
});
|
|
13533
|
+
for (const file of parsed.files) {
|
|
13534
|
+
for (const fact2 of file.facts) {
|
|
13535
|
+
const payload = payloads.get(fact2.fact_ref);
|
|
13536
|
+
if (payload !== undefined)
|
|
13537
|
+
FACT_PAYLOADS.set(fact2, payload);
|
|
13538
|
+
}
|
|
13539
|
+
}
|
|
13540
|
+
return assertIndexerOutputSafe({ channel: "success-payload", value: parsed });
|
|
13541
|
+
}
|
|
13128
13542
|
// src/errors/c4aError.ts
|
|
13129
13543
|
class C4AError extends Error {
|
|
13130
13544
|
code;
|
|
@@ -13275,10 +13689,10 @@ function mapErrorCodeToStatus(code) {
|
|
|
13275
13689
|
return ERROR_CODE_HTTP_STATUS[code] ?? 500;
|
|
13276
13690
|
}
|
|
13277
13691
|
// src/utils/id.ts
|
|
13278
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
13692
|
+
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
13279
13693
|
function generateId(type, parentId, name) {
|
|
13280
13694
|
const input = `${type}:${parentId}:${name}`;
|
|
13281
|
-
const hash =
|
|
13695
|
+
const hash = createHash2("sha256").update(input).digest("hex");
|
|
13282
13696
|
const hex32 = hash.slice(0, 32);
|
|
13283
13697
|
return `${type}_${hex32}`;
|
|
13284
13698
|
}
|
|
@@ -13286,9 +13700,9 @@ function generateUUID() {
|
|
|
13286
13700
|
return randomUUID();
|
|
13287
13701
|
}
|
|
13288
13702
|
// src/utils/hash.ts
|
|
13289
|
-
import { createHash as
|
|
13703
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
13290
13704
|
function contentHash(content) {
|
|
13291
|
-
return
|
|
13705
|
+
return createHash3("sha256").update(content).digest("hex");
|
|
13292
13706
|
}
|
|
13293
13707
|
// src/utils/object.ts
|
|
13294
13708
|
function isPlainObject(value) {
|
|
@@ -13494,7 +13908,15 @@ var DEFAULT_CONTENT_TYPES = [
|
|
|
13494
13908
|
{
|
|
13495
13909
|
id: "typescript",
|
|
13496
13910
|
category: "code",
|
|
13497
|
-
match: { extensions: [".ts", ".tsx"] },
|
|
13911
|
+
match: { extensions: [".ts", ".tsx", ".mts", ".cts"] },
|
|
13912
|
+
cas: { encoding: "utf8", hashInput: "content" },
|
|
13913
|
+
pipeline: { digest: ["ast", "summary"], extraction: ["entities", "relations"] },
|
|
13914
|
+
display: { icon: "\uD83D\uDCDC", renderer: "code" }
|
|
13915
|
+
},
|
|
13916
|
+
{
|
|
13917
|
+
id: "javascript",
|
|
13918
|
+
category: "code",
|
|
13919
|
+
match: { extensions: [".js", ".jsx", ".mjs", ".cjs"] },
|
|
13498
13920
|
cas: { encoding: "utf8", hashInput: "content" },
|
|
13499
13921
|
pipeline: { digest: ["ast", "summary"], extraction: ["entities", "relations"] },
|
|
13500
13922
|
display: { icon: "\uD83D\uDCDC", renderer: "code" }
|
|
@@ -13627,6 +14049,8 @@ export {
|
|
|
13627
14049
|
resolvePathFilter,
|
|
13628
14050
|
relationAtomSchema,
|
|
13629
14051
|
relatedFactSchema,
|
|
14052
|
+
redactIndexerOutputText,
|
|
14053
|
+
redactIndexerOutput,
|
|
13630
14054
|
productKindSchema,
|
|
13631
14055
|
parseYaml,
|
|
13632
14056
|
parseRef,
|
|
@@ -13637,6 +14061,7 @@ export {
|
|
|
13637
14061
|
metricMilestoneSchema,
|
|
13638
14062
|
metricAtomSchema,
|
|
13639
14063
|
mergeDefaults,
|
|
14064
|
+
materializeIndexerEvidenceAdapterResult,
|
|
13640
14065
|
matchesPathFilter,
|
|
13641
14066
|
mapErrorCodeToStatus,
|
|
13642
14067
|
isVersionVisible,
|
|
@@ -13644,6 +14069,14 @@ export {
|
|
|
13644
14069
|
isPlainObject,
|
|
13645
14070
|
isPathSafe,
|
|
13646
14071
|
isIndexableFile,
|
|
14072
|
+
indexerEvidenceAdapterResultSchema,
|
|
14073
|
+
indexerEvidenceAdapterProtocolDigest,
|
|
14074
|
+
indexerEvidenceAdapterOutputDigest,
|
|
14075
|
+
indexerEvidenceAdapterFileSchema,
|
|
14076
|
+
indexerEvidenceAdapterFileRef,
|
|
14077
|
+
indexerEvidenceAdapterFactSchema,
|
|
14078
|
+
indexerEvidenceAdapterFactRef,
|
|
14079
|
+
indexerEvidenceAdapterFactPayloads,
|
|
13647
14080
|
hasExcludedSegment,
|
|
13648
14081
|
groundingSchema,
|
|
13649
14082
|
globToRegex,
|
|
@@ -13672,6 +14105,7 @@ export {
|
|
|
13672
14105
|
decisionPhaseSchema,
|
|
13673
14106
|
decisionAtomSchema,
|
|
13674
14107
|
createPathMatcher,
|
|
14108
|
+
createIndexerEvidenceAdapterFact,
|
|
13675
14109
|
contentHash,
|
|
13676
14110
|
constraintAtomSchema,
|
|
13677
14111
|
comparisonDimensionValueSchema,
|
|
@@ -13679,9 +14113,11 @@ export {
|
|
|
13679
14113
|
comparisonAtomSchema,
|
|
13680
14114
|
buildSearchPrefix,
|
|
13681
14115
|
buildRef,
|
|
14116
|
+
buildIndexerEvidenceAdapterResult,
|
|
13682
14117
|
boundaryAtomSchema,
|
|
13683
14118
|
behaviorAtomSchema,
|
|
13684
14119
|
attributeAtomSchema,
|
|
14120
|
+
assertIndexerOutputSafe,
|
|
13685
14121
|
Visibility,
|
|
13686
14122
|
UPLOAD_MAX_FILE_SIZE,
|
|
13687
14123
|
UPLOAD_MAX_FILES,
|
|
@@ -13696,6 +14132,7 @@ export {
|
|
|
13696
14132
|
PathFilterConfigSchema,
|
|
13697
14133
|
PackageKind,
|
|
13698
14134
|
NodeType,
|
|
14135
|
+
INDEXER_OUTPUT_REDACTION_MARKER,
|
|
13699
14136
|
INDEXABLE_EXTENSIONS,
|
|
13700
14137
|
INDEXABLE_DOC_EXTENSIONS,
|
|
13701
14138
|
INDEXABLE_CODE_EXTENSIONS,
|