@ankurhalder/codebase-snapshot 4.0.5 → 4.0.7
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/dist/bin.js +53 -18
- package/dist/{chunk-PCNDUNKT.js → chunk-VRJTXNJV.js} +46 -19
- package/dist/cli.cjs +53 -18
- package/dist/cli.js +17 -2
- package/dist/index.cjs +44 -17
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -874,7 +874,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
874
874
|
},
|
|
875
875
|
{
|
|
876
876
|
rule: "aws-access-key-id",
|
|
877
|
-
pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}/
|
|
877
|
+
pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA|ABIA)[0-9A-Z]{16}/
|
|
878
878
|
},
|
|
879
879
|
{
|
|
880
880
|
// The name is no longer limited to the three snake_case spellings: an
|
|
@@ -913,7 +913,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
913
913
|
// and batch tokens), `whsec_` (Stripe webhook secret), `dckr_pat_` (Docker
|
|
914
914
|
// Hub), `hf_` (HuggingFace), `ya29.` (Google OAuth access token).
|
|
915
915
|
rule: "known-vendor-token-prefix",
|
|
916
|
-
pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128})/
|
|
916
|
+
pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|glrt-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|hvb\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128}|sk_test_[A-Za-z0-9]{16,64}|1\/\/0[A-Za-z0-9_-]{20,64})/
|
|
917
917
|
},
|
|
918
918
|
{
|
|
919
919
|
rule: "slack-webhook-url",
|
|
@@ -1945,6 +1945,7 @@ import * as fs4 from "fs";
|
|
|
1945
1945
|
import { createHash } from "crypto";
|
|
1946
1946
|
import * as path4 from "path";
|
|
1947
1947
|
import { pathToFileURL } from "url";
|
|
1948
|
+
var CONFIG_DIR_SYMBOL = /* @__PURE__ */ Symbol.for("codebase-snapshot.configDir");
|
|
1948
1949
|
var CONFIG_FILENAMES = [
|
|
1949
1950
|
"snapshot.config.ts",
|
|
1950
1951
|
"snapshot.config.js",
|
|
@@ -2483,7 +2484,8 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
|
|
|
2483
2484
|
return resolved;
|
|
2484
2485
|
}
|
|
2485
2486
|
function resolveConfig(userConfig, cliOptions, baseDir) {
|
|
2486
|
-
const
|
|
2487
|
+
const configDir = userConfig?.[CONFIG_DIR_SYMBOL];
|
|
2488
|
+
const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir ?? configDir);
|
|
2487
2489
|
const forcedPreset = resolvePresetName(userConfig?.preset);
|
|
2488
2490
|
if (forcedPreset !== void 0 && !getPreset(forcedPreset)) {
|
|
2489
2491
|
throw new Error(unknownPresetMessage(forcedPreset));
|
|
@@ -2583,7 +2585,11 @@ function resolveConfig(userConfig, cliOptions, baseDir) {
|
|
|
2583
2585
|
hooks: resolveHooks(userConfig?.hooks),
|
|
2584
2586
|
layers,
|
|
2585
2587
|
kinds,
|
|
2586
|
-
|
|
2588
|
+
// `exclude` is the flag spelling of the same setting; writing it in a config used to
|
|
2589
|
+
// be ignored without a word.
|
|
2590
|
+
excludePatterns: resolveExcludePatterns(
|
|
2591
|
+
userConfig?.excludePatterns ?? userConfig?.exclude
|
|
2592
|
+
),
|
|
2587
2593
|
secretRules
|
|
2588
2594
|
});
|
|
2589
2595
|
}
|
|
@@ -2730,21 +2736,28 @@ function isBinaryExtension(filePath) {
|
|
|
2730
2736
|
return BINARY_EXTENSIONS.has(ext);
|
|
2731
2737
|
}
|
|
2732
2738
|
function isBinaryBuffer(buffer) {
|
|
2733
|
-
|
|
2734
|
-
for (let index = 0; index < checkLength; index++) {
|
|
2739
|
+
for (let index = 0; index < buffer.length; index++) {
|
|
2735
2740
|
if (buffer[index] === 0) return true;
|
|
2736
2741
|
}
|
|
2737
2742
|
return false;
|
|
2738
2743
|
}
|
|
2744
|
+
var BINARY_SCAN_BYTES = 8 * 1024 * 1024;
|
|
2745
|
+
var CHUNK = 64 * 1024;
|
|
2739
2746
|
function isBinaryFile(absolutePath) {
|
|
2740
2747
|
if (isBinaryExtension(absolutePath)) return true;
|
|
2741
2748
|
let fd;
|
|
2742
2749
|
try {
|
|
2743
2750
|
fd = fs5.openSync(absolutePath, "r");
|
|
2744
|
-
const buffer = Buffer.alloc(
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2751
|
+
const buffer = Buffer.alloc(CHUNK);
|
|
2752
|
+
let position = 0;
|
|
2753
|
+
while (position < BINARY_SCAN_BYTES) {
|
|
2754
|
+
const wanted = Math.min(CHUNK, BINARY_SCAN_BYTES - position);
|
|
2755
|
+
const bytesRead = fs5.readSync(fd, buffer, 0, wanted, position);
|
|
2756
|
+
if (bytesRead === 0) return false;
|
|
2757
|
+
if (isBinaryBuffer(buffer.subarray(0, bytesRead))) return true;
|
|
2758
|
+
position += bytesRead;
|
|
2759
|
+
}
|
|
2760
|
+
return false;
|
|
2748
2761
|
} catch {
|
|
2749
2762
|
return false;
|
|
2750
2763
|
} finally {
|
|
@@ -3421,11 +3434,11 @@ function addScripts(cwd, notes) {
|
|
|
3421
3434
|
const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
|
|
3422
3435
|
const added = [];
|
|
3423
3436
|
if (!scripts.snapshot) {
|
|
3424
|
-
scripts.snapshot = "codebase-snapshot generate";
|
|
3437
|
+
scripts.snapshot = "npx @ankurhalder/codebase-snapshot generate";
|
|
3425
3438
|
added.push("snapshot");
|
|
3426
3439
|
}
|
|
3427
3440
|
if (!scripts["snapshot:validate"]) {
|
|
3428
|
-
scripts["snapshot:validate"] = "codebase-snapshot validate";
|
|
3441
|
+
scripts["snapshot:validate"] = "npx @ankurhalder/codebase-snapshot validate";
|
|
3429
3442
|
added.push("snapshot:validate");
|
|
3430
3443
|
}
|
|
3431
3444
|
if (added.length === 0) return [];
|
|
@@ -5498,7 +5511,7 @@ function validateSnapshot(configInput) {
|
|
|
5498
5511
|
|
|
5499
5512
|
// src/index.ts
|
|
5500
5513
|
var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
5501
|
-
var GENERATOR_VERSION = "4.0.
|
|
5514
|
+
var GENERATOR_VERSION = "4.0.7";
|
|
5502
5515
|
var SCHEMA_VERSION = "3.0.0";
|
|
5503
5516
|
function sha256Hex2(input) {
|
|
5504
5517
|
return crypto3.createHash("sha256").update(input).digest("hex");
|
|
@@ -6265,8 +6278,8 @@ function generateSnapshot(configInput, options) {
|
|
|
6265
6278
|
const lineCount = countLines(rawContent);
|
|
6266
6279
|
totalLines += lineCount;
|
|
6267
6280
|
totalSizeBytes += stats.size;
|
|
6268
|
-
const layer2 = classifyLayer(relativePath, config.layers);
|
|
6269
|
-
const kind = classifyKind(relativePath, config.kinds);
|
|
6281
|
+
const layer2 = maskPathText(classifyLayer(relativePath, config.layers), config.secretRules);
|
|
6282
|
+
const kind = maskPathText(classifyKind(relativePath, config.kinds), config.secretRules);
|
|
6270
6283
|
const language = detectLanguage(relativePath);
|
|
6271
6284
|
bump(layerCounts, layer2);
|
|
6272
6285
|
bump(kindCounts, kind);
|
|
@@ -6359,7 +6372,9 @@ function generateSnapshot(configInput, options) {
|
|
|
6359
6372
|
name: GENERATOR_NAME,
|
|
6360
6373
|
version: GENERATOR_VERSION
|
|
6361
6374
|
},
|
|
6362
|
-
|
|
6375
|
+
// A branch name is user input and can carry a token: it reaches the manifest,
|
|
6376
|
+
// the README and the audit report.
|
|
6377
|
+
git: { ...gitInfo, branch: maskPathText(gitInfo.branch, config.secretRules) },
|
|
6363
6378
|
budgets: {
|
|
6364
6379
|
maxPartBytes: config.maxPartBytes,
|
|
6365
6380
|
largeFileBytes: config.largeFileBytes
|
|
@@ -6376,7 +6391,12 @@ function generateSnapshot(configInput, options) {
|
|
|
6376
6391
|
include: [...config.include].map(maskName),
|
|
6377
6392
|
preset: config.preset,
|
|
6378
6393
|
layersMode: config.layersMode,
|
|
6379
|
-
budgets: {
|
|
6394
|
+
budgets: {
|
|
6395
|
+
default: config.budgets.default,
|
|
6396
|
+
byLayer: Object.fromEntries(
|
|
6397
|
+
Object.entries(config.budgets.byLayer).map(([name, bytes]) => [maskName(name), bytes])
|
|
6398
|
+
)
|
|
6399
|
+
},
|
|
6380
6400
|
excludePatterns: [...config.excludePatterns].map(maskName),
|
|
6381
6401
|
layers: config.layers.map((layer2) => maskName(layer2.name)),
|
|
6382
6402
|
kinds: config.kinds.map((kind) => maskName(kind.kind))
|
|
@@ -7514,6 +7534,19 @@ function parseCliArgs(argv) {
|
|
|
7514
7534
|
}
|
|
7515
7535
|
command = resolved;
|
|
7516
7536
|
}
|
|
7537
|
+
if (explicitMode !== void 0) {
|
|
7538
|
+
const resolvedMode = COMMAND_ALIASES.get(explicitMode);
|
|
7539
|
+
if (!resolvedMode) {
|
|
7540
|
+
throw new UsageError(
|
|
7541
|
+
`Unknown --mode "${explicitMode}". Expected one of: ${Array.from(COMMAND_ALIASES.keys()).join(", ")}.`
|
|
7542
|
+
);
|
|
7543
|
+
}
|
|
7544
|
+
if (firstPositional !== void 0 && resolvedMode !== command) {
|
|
7545
|
+
throw new UsageError(
|
|
7546
|
+
`--mode ${explicitMode} contradicts the command "${firstPositional}". Pass one or the other.`
|
|
7547
|
+
);
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7517
7550
|
const expectedArgs = COMMAND_ARITY[command];
|
|
7518
7551
|
if (args.length !== expectedArgs) {
|
|
7519
7552
|
if (command === "explain") {
|
|
@@ -7532,6 +7565,7 @@ function parseCliArgs(argv) {
|
|
|
7532
7565
|
if (rawFormat !== "text" && rawFormat !== "json") {
|
|
7533
7566
|
throw new UsageError(`--format must be "text" or "json", received "${rawFormat}".`);
|
|
7534
7567
|
}
|
|
7568
|
+
let onlyNamesMonolith = false;
|
|
7535
7569
|
const rawSkip = values["skip-artifacts"];
|
|
7536
7570
|
const rawOnly = values["only-artifacts"];
|
|
7537
7571
|
if (rawSkip !== void 0 && rawOnly !== void 0) {
|
|
@@ -7540,6 +7574,7 @@ function parseCliArgs(argv) {
|
|
|
7540
7574
|
let skipArtifacts;
|
|
7541
7575
|
if (rawOnly !== void 0) {
|
|
7542
7576
|
const keep = parseArtifactList(String(rawOnly), "--only-artifacts");
|
|
7577
|
+
onlyNamesMonolith = keep.includes("monolith");
|
|
7543
7578
|
skipArtifacts = ARTIFACT_NAMES.filter(
|
|
7544
7579
|
(name) => !keep.includes(name)
|
|
7545
7580
|
);
|
|
@@ -7594,7 +7629,7 @@ function parseCliArgs(argv) {
|
|
|
7594
7629
|
target: values.target === void 0 ? void 0 : String(values.target),
|
|
7595
7630
|
cwd: values.cwd === void 0 ? process.cwd() : path12.resolve(String(values.cwd)),
|
|
7596
7631
|
outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
|
|
7597
|
-
includeMonolith: values["include-monolith"] === true ? true : void 0,
|
|
7632
|
+
includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
|
|
7598
7633
|
includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
|
|
7599
7634
|
maxPartBytes: parseByteOption(
|
|
7600
7635
|
values["max-part-bytes"],
|
|
@@ -1729,7 +1729,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
1729
1729
|
},
|
|
1730
1730
|
{
|
|
1731
1731
|
rule: "aws-access-key-id",
|
|
1732
|
-
pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}/
|
|
1732
|
+
pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA|ABIA)[0-9A-Z]{16}/
|
|
1733
1733
|
},
|
|
1734
1734
|
{
|
|
1735
1735
|
// The name is no longer limited to the three snake_case spellings: an
|
|
@@ -1768,7 +1768,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
1768
1768
|
// and batch tokens), `whsec_` (Stripe webhook secret), `dckr_pat_` (Docker
|
|
1769
1769
|
// Hub), `hf_` (HuggingFace), `ya29.` (Google OAuth access token).
|
|
1770
1770
|
rule: "known-vendor-token-prefix",
|
|
1771
|
-
pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128})/
|
|
1771
|
+
pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|glrt-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|hvb\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128}|sk_test_[A-Za-z0-9]{16,64}|1\/\/0[A-Za-z0-9_-]{20,64})/
|
|
1772
1772
|
},
|
|
1773
1773
|
{
|
|
1774
1774
|
rule: "slack-webhook-url",
|
|
@@ -2665,6 +2665,7 @@ function walkDirectory(dir, baseDir, rootReal, visited, isRoot = false) {
|
|
|
2665
2665
|
}
|
|
2666
2666
|
|
|
2667
2667
|
// src/config.ts
|
|
2668
|
+
var CONFIG_DIR_SYMBOL = /* @__PURE__ */ Symbol.for("codebase-snapshot.configDir");
|
|
2668
2669
|
var CONFIG_FILENAMES = [
|
|
2669
2670
|
"snapshot.config.ts",
|
|
2670
2671
|
"snapshot.config.js",
|
|
@@ -2925,6 +2926,13 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
2925
2926
|
}
|
|
2926
2927
|
async function loadConfigFile(cwd) {
|
|
2927
2928
|
const loaded = await loadConfigFileDetailed(cwd);
|
|
2929
|
+
if (loaded.config && loaded.file && typeof loaded.config === "object") {
|
|
2930
|
+
Object.defineProperty(loaded.config, CONFIG_DIR_SYMBOL, {
|
|
2931
|
+
value: path10.dirname(loaded.file),
|
|
2932
|
+
enumerable: false,
|
|
2933
|
+
configurable: true
|
|
2934
|
+
});
|
|
2935
|
+
}
|
|
2928
2936
|
if (loaded.errors.length > 0) {
|
|
2929
2937
|
throw new Error(`The config file could not be read: ${loaded.errors.join("; ")}`);
|
|
2930
2938
|
}
|
|
@@ -3210,7 +3218,8 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
|
|
|
3210
3218
|
return resolved;
|
|
3211
3219
|
}
|
|
3212
3220
|
function resolveConfig(userConfig, cliOptions, baseDir) {
|
|
3213
|
-
const
|
|
3221
|
+
const configDir = userConfig?.[CONFIG_DIR_SYMBOL];
|
|
3222
|
+
const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir ?? configDir);
|
|
3214
3223
|
const forcedPreset = resolvePresetName(userConfig?.preset);
|
|
3215
3224
|
if (forcedPreset !== void 0 && !getPreset(forcedPreset)) {
|
|
3216
3225
|
throw new Error(unknownPresetMessage(forcedPreset));
|
|
@@ -3310,7 +3319,11 @@ function resolveConfig(userConfig, cliOptions, baseDir) {
|
|
|
3310
3319
|
hooks: resolveHooks(userConfig?.hooks),
|
|
3311
3320
|
layers,
|
|
3312
3321
|
kinds,
|
|
3313
|
-
|
|
3322
|
+
// `exclude` is the flag spelling of the same setting; writing it in a config used to
|
|
3323
|
+
// be ignored without a word.
|
|
3324
|
+
excludePatterns: resolveExcludePatterns(
|
|
3325
|
+
userConfig?.excludePatterns ?? userConfig?.exclude
|
|
3326
|
+
),
|
|
3314
3327
|
secretRules
|
|
3315
3328
|
});
|
|
3316
3329
|
}
|
|
@@ -4077,21 +4090,28 @@ function isBinaryExtension(filePath) {
|
|
|
4077
4090
|
return BINARY_EXTENSIONS.has(ext);
|
|
4078
4091
|
}
|
|
4079
4092
|
function isBinaryBuffer(buffer) {
|
|
4080
|
-
|
|
4081
|
-
for (let index = 0; index < checkLength; index++) {
|
|
4093
|
+
for (let index = 0; index < buffer.length; index++) {
|
|
4082
4094
|
if (buffer[index] === 0) return true;
|
|
4083
4095
|
}
|
|
4084
4096
|
return false;
|
|
4085
4097
|
}
|
|
4098
|
+
var BINARY_SCAN_BYTES = 8 * 1024 * 1024;
|
|
4099
|
+
var CHUNK = 64 * 1024;
|
|
4086
4100
|
function isBinaryFile(absolutePath) {
|
|
4087
4101
|
if (isBinaryExtension(absolutePath)) return true;
|
|
4088
4102
|
let fd;
|
|
4089
4103
|
try {
|
|
4090
4104
|
fd = fs9.openSync(absolutePath, "r");
|
|
4091
|
-
const buffer = Buffer.alloc(
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4105
|
+
const buffer = Buffer.alloc(CHUNK);
|
|
4106
|
+
let position = 0;
|
|
4107
|
+
while (position < BINARY_SCAN_BYTES) {
|
|
4108
|
+
const wanted = Math.min(CHUNK, BINARY_SCAN_BYTES - position);
|
|
4109
|
+
const bytesRead = fs9.readSync(fd, buffer, 0, wanted, position);
|
|
4110
|
+
if (bytesRead === 0) return false;
|
|
4111
|
+
if (isBinaryBuffer(buffer.subarray(0, bytesRead))) return true;
|
|
4112
|
+
position += bytesRead;
|
|
4113
|
+
}
|
|
4114
|
+
return false;
|
|
4095
4115
|
} catch {
|
|
4096
4116
|
return false;
|
|
4097
4117
|
} finally {
|
|
@@ -5261,11 +5281,11 @@ function addScripts(cwd, notes) {
|
|
|
5261
5281
|
const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
|
|
5262
5282
|
const added = [];
|
|
5263
5283
|
if (!scripts.snapshot) {
|
|
5264
|
-
scripts.snapshot = "codebase-snapshot generate";
|
|
5284
|
+
scripts.snapshot = "npx @ankurhalder/codebase-snapshot generate";
|
|
5265
5285
|
added.push("snapshot");
|
|
5266
5286
|
}
|
|
5267
5287
|
if (!scripts["snapshot:validate"]) {
|
|
5268
|
-
scripts["snapshot:validate"] = "codebase-snapshot validate";
|
|
5288
|
+
scripts["snapshot:validate"] = "npx @ankurhalder/codebase-snapshot validate";
|
|
5269
5289
|
added.push("snapshot:validate");
|
|
5270
5290
|
}
|
|
5271
5291
|
if (added.length === 0) return [];
|
|
@@ -5461,7 +5481,7 @@ async function runInit(options) {
|
|
|
5461
5481
|
|
|
5462
5482
|
// src/index.ts
|
|
5463
5483
|
var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
5464
|
-
var GENERATOR_VERSION = "4.0.
|
|
5484
|
+
var GENERATOR_VERSION = "4.0.7";
|
|
5465
5485
|
var SCHEMA_VERSION = "3.0.0";
|
|
5466
5486
|
function sha256Hex2(input) {
|
|
5467
5487
|
return crypto.createHash("sha256").update(input).digest("hex");
|
|
@@ -6228,8 +6248,8 @@ function generateSnapshot(configInput, options) {
|
|
|
6228
6248
|
const lineCount = countLines(rawContent);
|
|
6229
6249
|
totalLines += lineCount;
|
|
6230
6250
|
totalSizeBytes += stats.size;
|
|
6231
|
-
const layer2 = classifyLayer(relativePath, config.layers);
|
|
6232
|
-
const kind = classifyKind(relativePath, config.kinds);
|
|
6251
|
+
const layer2 = maskPathText(classifyLayer(relativePath, config.layers), config.secretRules);
|
|
6252
|
+
const kind = maskPathText(classifyKind(relativePath, config.kinds), config.secretRules);
|
|
6233
6253
|
const language = detectLanguage(relativePath);
|
|
6234
6254
|
bump(layerCounts, layer2);
|
|
6235
6255
|
bump(kindCounts, kind);
|
|
@@ -6322,7 +6342,9 @@ function generateSnapshot(configInput, options) {
|
|
|
6322
6342
|
name: GENERATOR_NAME,
|
|
6323
6343
|
version: GENERATOR_VERSION
|
|
6324
6344
|
},
|
|
6325
|
-
|
|
6345
|
+
// A branch name is user input and can carry a token: it reaches the manifest,
|
|
6346
|
+
// the README and the audit report.
|
|
6347
|
+
git: { ...gitInfo, branch: maskPathText(gitInfo.branch, config.secretRules) },
|
|
6326
6348
|
budgets: {
|
|
6327
6349
|
maxPartBytes: config.maxPartBytes,
|
|
6328
6350
|
largeFileBytes: config.largeFileBytes
|
|
@@ -6339,7 +6361,12 @@ function generateSnapshot(configInput, options) {
|
|
|
6339
6361
|
include: [...config.include].map(maskName),
|
|
6340
6362
|
preset: config.preset,
|
|
6341
6363
|
layersMode: config.layersMode,
|
|
6342
|
-
budgets: {
|
|
6364
|
+
budgets: {
|
|
6365
|
+
default: config.budgets.default,
|
|
6366
|
+
byLayer: Object.fromEntries(
|
|
6367
|
+
Object.entries(config.budgets.byLayer).map(([name, bytes]) => [maskName(name), bytes])
|
|
6368
|
+
)
|
|
6369
|
+
},
|
|
6343
6370
|
excludePatterns: [...config.excludePatterns].map(maskName),
|
|
6344
6371
|
layers: config.layers.map((layer2) => maskName(layer2.name)),
|
|
6345
6372
|
kinds: config.kinds.map((kind) => maskName(kind.kind))
|
|
@@ -6522,5 +6549,5 @@ async function generateSnapshotAsync(configInput, options) {
|
|
|
6522
6549
|
}
|
|
6523
6550
|
|
|
6524
6551
|
export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countLines, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, isBinaryBuffer, isBinaryExtension, isBinaryFile, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, profileForPath, renderConfig, renderDiffText, renderExplainText, renderMinimalConfig, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, unknownPresetMessage, validateSnapshot };
|
|
6525
|
-
//# sourceMappingURL=chunk-
|
|
6526
|
-
//# sourceMappingURL=chunk-
|
|
6552
|
+
//# sourceMappingURL=chunk-VRJTXNJV.js.map
|
|
6553
|
+
//# sourceMappingURL=chunk-VRJTXNJV.js.map
|
package/dist/cli.cjs
CHANGED
|
@@ -896,7 +896,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
896
896
|
},
|
|
897
897
|
{
|
|
898
898
|
rule: "aws-access-key-id",
|
|
899
|
-
pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}/
|
|
899
|
+
pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA|ABIA)[0-9A-Z]{16}/
|
|
900
900
|
},
|
|
901
901
|
{
|
|
902
902
|
// The name is no longer limited to the three snake_case spellings: an
|
|
@@ -935,7 +935,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
935
935
|
// and batch tokens), `whsec_` (Stripe webhook secret), `dckr_pat_` (Docker
|
|
936
936
|
// Hub), `hf_` (HuggingFace), `ya29.` (Google OAuth access token).
|
|
937
937
|
rule: "known-vendor-token-prefix",
|
|
938
|
-
pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128})/
|
|
938
|
+
pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|glrt-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|hvb\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128}|sk_test_[A-Za-z0-9]{16,64}|1\/\/0[A-Za-z0-9_-]{20,64})/
|
|
939
939
|
},
|
|
940
940
|
{
|
|
941
941
|
rule: "slack-webhook-url",
|
|
@@ -1957,6 +1957,7 @@ function renderDiffText(diff) {
|
|
|
1957
1957
|
section("changed:", diff.changed);
|
|
1958
1958
|
return lines.join("\n");
|
|
1959
1959
|
}
|
|
1960
|
+
var CONFIG_DIR_SYMBOL = /* @__PURE__ */ Symbol.for("codebase-snapshot.configDir");
|
|
1960
1961
|
var CONFIG_FILENAMES = [
|
|
1961
1962
|
"snapshot.config.ts",
|
|
1962
1963
|
"snapshot.config.js",
|
|
@@ -2495,7 +2496,8 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
|
|
|
2495
2496
|
return resolved;
|
|
2496
2497
|
}
|
|
2497
2498
|
function resolveConfig(userConfig, cliOptions, baseDir) {
|
|
2498
|
-
const
|
|
2499
|
+
const configDir = userConfig?.[CONFIG_DIR_SYMBOL];
|
|
2500
|
+
const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir ?? configDir);
|
|
2499
2501
|
const forcedPreset = resolvePresetName(userConfig?.preset);
|
|
2500
2502
|
if (forcedPreset !== void 0 && !getPreset(forcedPreset)) {
|
|
2501
2503
|
throw new Error(unknownPresetMessage(forcedPreset));
|
|
@@ -2595,7 +2597,11 @@ function resolveConfig(userConfig, cliOptions, baseDir) {
|
|
|
2595
2597
|
hooks: resolveHooks(userConfig?.hooks),
|
|
2596
2598
|
layers,
|
|
2597
2599
|
kinds,
|
|
2598
|
-
|
|
2600
|
+
// `exclude` is the flag spelling of the same setting; writing it in a config used to
|
|
2601
|
+
// be ignored without a word.
|
|
2602
|
+
excludePatterns: resolveExcludePatterns(
|
|
2603
|
+
userConfig?.excludePatterns ?? userConfig?.exclude
|
|
2604
|
+
),
|
|
2599
2605
|
secretRules
|
|
2600
2606
|
});
|
|
2601
2607
|
}
|
|
@@ -2738,21 +2744,28 @@ function isBinaryExtension(filePath) {
|
|
|
2738
2744
|
return BINARY_EXTENSIONS.has(ext);
|
|
2739
2745
|
}
|
|
2740
2746
|
function isBinaryBuffer(buffer) {
|
|
2741
|
-
|
|
2742
|
-
for (let index = 0; index < checkLength; index++) {
|
|
2747
|
+
for (let index = 0; index < buffer.length; index++) {
|
|
2743
2748
|
if (buffer[index] === 0) return true;
|
|
2744
2749
|
}
|
|
2745
2750
|
return false;
|
|
2746
2751
|
}
|
|
2752
|
+
var BINARY_SCAN_BYTES = 8 * 1024 * 1024;
|
|
2753
|
+
var CHUNK = 64 * 1024;
|
|
2747
2754
|
function isBinaryFile(absolutePath) {
|
|
2748
2755
|
if (isBinaryExtension(absolutePath)) return true;
|
|
2749
2756
|
let fd;
|
|
2750
2757
|
try {
|
|
2751
2758
|
fd = fs9__namespace.openSync(absolutePath, "r");
|
|
2752
|
-
const buffer = Buffer.alloc(
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2759
|
+
const buffer = Buffer.alloc(CHUNK);
|
|
2760
|
+
let position = 0;
|
|
2761
|
+
while (position < BINARY_SCAN_BYTES) {
|
|
2762
|
+
const wanted = Math.min(CHUNK, BINARY_SCAN_BYTES - position);
|
|
2763
|
+
const bytesRead = fs9__namespace.readSync(fd, buffer, 0, wanted, position);
|
|
2764
|
+
if (bytesRead === 0) return false;
|
|
2765
|
+
if (isBinaryBuffer(buffer.subarray(0, bytesRead))) return true;
|
|
2766
|
+
position += bytesRead;
|
|
2767
|
+
}
|
|
2768
|
+
return false;
|
|
2756
2769
|
} catch {
|
|
2757
2770
|
return false;
|
|
2758
2771
|
} finally {
|
|
@@ -3417,11 +3430,11 @@ function addScripts(cwd, notes) {
|
|
|
3417
3430
|
const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
|
|
3418
3431
|
const added = [];
|
|
3419
3432
|
if (!scripts.snapshot) {
|
|
3420
|
-
scripts.snapshot = "codebase-snapshot generate";
|
|
3433
|
+
scripts.snapshot = "npx @ankurhalder/codebase-snapshot generate";
|
|
3421
3434
|
added.push("snapshot");
|
|
3422
3435
|
}
|
|
3423
3436
|
if (!scripts["snapshot:validate"]) {
|
|
3424
|
-
scripts["snapshot:validate"] = "codebase-snapshot validate";
|
|
3437
|
+
scripts["snapshot:validate"] = "npx @ankurhalder/codebase-snapshot validate";
|
|
3425
3438
|
added.push("snapshot:validate");
|
|
3426
3439
|
}
|
|
3427
3440
|
if (added.length === 0) return [];
|
|
@@ -5477,7 +5490,7 @@ function validateSnapshot(configInput) {
|
|
|
5477
5490
|
|
|
5478
5491
|
// src/index.ts
|
|
5479
5492
|
var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
5480
|
-
var GENERATOR_VERSION = "4.0.
|
|
5493
|
+
var GENERATOR_VERSION = "4.0.7";
|
|
5481
5494
|
var SCHEMA_VERSION = "3.0.0";
|
|
5482
5495
|
function sha256Hex2(input) {
|
|
5483
5496
|
return crypto__namespace.createHash("sha256").update(input).digest("hex");
|
|
@@ -6244,8 +6257,8 @@ function generateSnapshot(configInput, options) {
|
|
|
6244
6257
|
const lineCount = countLines(rawContent);
|
|
6245
6258
|
totalLines += lineCount;
|
|
6246
6259
|
totalSizeBytes += stats.size;
|
|
6247
|
-
const layer2 = classifyLayer(relativePath, config.layers);
|
|
6248
|
-
const kind = classifyKind(relativePath, config.kinds);
|
|
6260
|
+
const layer2 = maskPathText(classifyLayer(relativePath, config.layers), config.secretRules);
|
|
6261
|
+
const kind = maskPathText(classifyKind(relativePath, config.kinds), config.secretRules);
|
|
6249
6262
|
const language = detectLanguage(relativePath);
|
|
6250
6263
|
bump(layerCounts, layer2);
|
|
6251
6264
|
bump(kindCounts, kind);
|
|
@@ -6338,7 +6351,9 @@ function generateSnapshot(configInput, options) {
|
|
|
6338
6351
|
name: GENERATOR_NAME,
|
|
6339
6352
|
version: GENERATOR_VERSION
|
|
6340
6353
|
},
|
|
6341
|
-
|
|
6354
|
+
// A branch name is user input and can carry a token: it reaches the manifest,
|
|
6355
|
+
// the README and the audit report.
|
|
6356
|
+
git: { ...gitInfo, branch: maskPathText(gitInfo.branch, config.secretRules) },
|
|
6342
6357
|
budgets: {
|
|
6343
6358
|
maxPartBytes: config.maxPartBytes,
|
|
6344
6359
|
largeFileBytes: config.largeFileBytes
|
|
@@ -6355,7 +6370,12 @@ function generateSnapshot(configInput, options) {
|
|
|
6355
6370
|
include: [...config.include].map(maskName),
|
|
6356
6371
|
preset: config.preset,
|
|
6357
6372
|
layersMode: config.layersMode,
|
|
6358
|
-
budgets: {
|
|
6373
|
+
budgets: {
|
|
6374
|
+
default: config.budgets.default,
|
|
6375
|
+
byLayer: Object.fromEntries(
|
|
6376
|
+
Object.entries(config.budgets.byLayer).map(([name, bytes]) => [maskName(name), bytes])
|
|
6377
|
+
)
|
|
6378
|
+
},
|
|
6359
6379
|
excludePatterns: [...config.excludePatterns].map(maskName),
|
|
6360
6380
|
layers: config.layers.map((layer2) => maskName(layer2.name)),
|
|
6361
6381
|
kinds: config.kinds.map((kind) => maskName(kind.kind))
|
|
@@ -7501,6 +7521,19 @@ function parseCliArgs(argv) {
|
|
|
7501
7521
|
}
|
|
7502
7522
|
command = resolved;
|
|
7503
7523
|
}
|
|
7524
|
+
if (explicitMode !== void 0) {
|
|
7525
|
+
const resolvedMode = COMMAND_ALIASES.get(explicitMode);
|
|
7526
|
+
if (!resolvedMode) {
|
|
7527
|
+
throw new UsageError(
|
|
7528
|
+
`Unknown --mode "${explicitMode}". Expected one of: ${Array.from(COMMAND_ALIASES.keys()).join(", ")}.`
|
|
7529
|
+
);
|
|
7530
|
+
}
|
|
7531
|
+
if (firstPositional !== void 0 && resolvedMode !== command) {
|
|
7532
|
+
throw new UsageError(
|
|
7533
|
+
`--mode ${explicitMode} contradicts the command "${firstPositional}". Pass one or the other.`
|
|
7534
|
+
);
|
|
7535
|
+
}
|
|
7536
|
+
}
|
|
7504
7537
|
const expectedArgs = COMMAND_ARITY[command];
|
|
7505
7538
|
if (args.length !== expectedArgs) {
|
|
7506
7539
|
if (command === "explain") {
|
|
@@ -7519,6 +7552,7 @@ function parseCliArgs(argv) {
|
|
|
7519
7552
|
if (rawFormat !== "text" && rawFormat !== "json") {
|
|
7520
7553
|
throw new UsageError(`--format must be "text" or "json", received "${rawFormat}".`);
|
|
7521
7554
|
}
|
|
7555
|
+
let onlyNamesMonolith = false;
|
|
7522
7556
|
const rawSkip = values["skip-artifacts"];
|
|
7523
7557
|
const rawOnly = values["only-artifacts"];
|
|
7524
7558
|
if (rawSkip !== void 0 && rawOnly !== void 0) {
|
|
@@ -7527,6 +7561,7 @@ function parseCliArgs(argv) {
|
|
|
7527
7561
|
let skipArtifacts;
|
|
7528
7562
|
if (rawOnly !== void 0) {
|
|
7529
7563
|
const keep = parseArtifactList(String(rawOnly), "--only-artifacts");
|
|
7564
|
+
onlyNamesMonolith = keep.includes("monolith");
|
|
7530
7565
|
skipArtifacts = ARTIFACT_NAMES.filter(
|
|
7531
7566
|
(name) => !keep.includes(name)
|
|
7532
7567
|
);
|
|
@@ -7581,7 +7616,7 @@ function parseCliArgs(argv) {
|
|
|
7581
7616
|
target: values.target === void 0 ? void 0 : String(values.target),
|
|
7582
7617
|
cwd: values.cwd === void 0 ? process.cwd() : path10__namespace.resolve(String(values.cwd)),
|
|
7583
7618
|
outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
|
|
7584
|
-
includeMonolith: values["include-monolith"] === true ? true : void 0,
|
|
7619
|
+
includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
|
|
7585
7620
|
includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
|
|
7586
7621
|
maxPartBytes: parseByteOption(
|
|
7587
7622
|
values["max-part-bytes"],
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadConfigFileDetailed, resolveConfig, validateSnapshot, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, GENERATOR_VERSION, ARTIFACT_NAMES, getPreset, unknownPresetMessage, GENERATOR_NAME, runInit, PromptCancelled, MIN_MAX_PART_BYTES, SCHEMA_VERSION, PRESETS, parseByteSize, renderExplainText } from './chunk-
|
|
1
|
+
import { loadConfigFileDetailed, resolveConfig, validateSnapshot, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, GENERATOR_VERSION, ARTIFACT_NAMES, getPreset, unknownPresetMessage, GENERATOR_NAME, runInit, PromptCancelled, MIN_MAX_PART_BYTES, SCHEMA_VERSION, PRESETS, parseByteSize, renderExplainText } from './chunk-VRJTXNJV.js';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path2 from 'path';
|
|
4
4
|
import { parseArgs } from 'util';
|
|
@@ -970,6 +970,19 @@ function parseCliArgs(argv) {
|
|
|
970
970
|
}
|
|
971
971
|
command = resolved;
|
|
972
972
|
}
|
|
973
|
+
if (explicitMode !== void 0) {
|
|
974
|
+
const resolvedMode = COMMAND_ALIASES.get(explicitMode);
|
|
975
|
+
if (!resolvedMode) {
|
|
976
|
+
throw new UsageError(
|
|
977
|
+
`Unknown --mode "${explicitMode}". Expected one of: ${Array.from(COMMAND_ALIASES.keys()).join(", ")}.`
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
if (firstPositional !== void 0 && resolvedMode !== command) {
|
|
981
|
+
throw new UsageError(
|
|
982
|
+
`--mode ${explicitMode} contradicts the command "${firstPositional}". Pass one or the other.`
|
|
983
|
+
);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
973
986
|
const expectedArgs = COMMAND_ARITY[command];
|
|
974
987
|
if (args.length !== expectedArgs) {
|
|
975
988
|
if (command === "explain") {
|
|
@@ -988,6 +1001,7 @@ function parseCliArgs(argv) {
|
|
|
988
1001
|
if (rawFormat !== "text" && rawFormat !== "json") {
|
|
989
1002
|
throw new UsageError(`--format must be "text" or "json", received "${rawFormat}".`);
|
|
990
1003
|
}
|
|
1004
|
+
let onlyNamesMonolith = false;
|
|
991
1005
|
const rawSkip = values["skip-artifacts"];
|
|
992
1006
|
const rawOnly = values["only-artifacts"];
|
|
993
1007
|
if (rawSkip !== void 0 && rawOnly !== void 0) {
|
|
@@ -996,6 +1010,7 @@ function parseCliArgs(argv) {
|
|
|
996
1010
|
let skipArtifacts;
|
|
997
1011
|
if (rawOnly !== void 0) {
|
|
998
1012
|
const keep = parseArtifactList(String(rawOnly), "--only-artifacts");
|
|
1013
|
+
onlyNamesMonolith = keep.includes("monolith");
|
|
999
1014
|
skipArtifacts = ARTIFACT_NAMES.filter(
|
|
1000
1015
|
(name) => !keep.includes(name)
|
|
1001
1016
|
);
|
|
@@ -1050,7 +1065,7 @@ function parseCliArgs(argv) {
|
|
|
1050
1065
|
target: values.target === void 0 ? void 0 : String(values.target),
|
|
1051
1066
|
cwd: values.cwd === void 0 ? process.cwd() : path2.resolve(String(values.cwd)),
|
|
1052
1067
|
outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
|
|
1053
|
-
includeMonolith: values["include-monolith"] === true ? true : void 0,
|
|
1068
|
+
includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
|
|
1054
1069
|
includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
|
|
1055
1070
|
maxPartBytes: parseByteOption(
|
|
1056
1071
|
values["max-part-bytes"],
|
package/dist/index.cjs
CHANGED
|
@@ -1758,7 +1758,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
1758
1758
|
},
|
|
1759
1759
|
{
|
|
1760
1760
|
rule: "aws-access-key-id",
|
|
1761
|
-
pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}/
|
|
1761
|
+
pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA|ABIA)[0-9A-Z]{16}/
|
|
1762
1762
|
},
|
|
1763
1763
|
{
|
|
1764
1764
|
// The name is no longer limited to the three snake_case spellings: an
|
|
@@ -1797,7 +1797,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
1797
1797
|
// and batch tokens), `whsec_` (Stripe webhook secret), `dckr_pat_` (Docker
|
|
1798
1798
|
// Hub), `hf_` (HuggingFace), `ya29.` (Google OAuth access token).
|
|
1799
1799
|
rule: "known-vendor-token-prefix",
|
|
1800
|
-
pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128})/
|
|
1800
|
+
pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|glrt-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|hvb\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128}|sk_test_[A-Za-z0-9]{16,64}|1\/\/0[A-Za-z0-9_-]{20,64})/
|
|
1801
1801
|
},
|
|
1802
1802
|
{
|
|
1803
1803
|
rule: "slack-webhook-url",
|
|
@@ -2694,6 +2694,7 @@ function walkDirectory(dir, baseDir, rootReal, visited, isRoot = false) {
|
|
|
2694
2694
|
}
|
|
2695
2695
|
|
|
2696
2696
|
// src/config.ts
|
|
2697
|
+
var CONFIG_DIR_SYMBOL = /* @__PURE__ */ Symbol.for("codebase-snapshot.configDir");
|
|
2697
2698
|
var CONFIG_FILENAMES = [
|
|
2698
2699
|
"snapshot.config.ts",
|
|
2699
2700
|
"snapshot.config.js",
|
|
@@ -2954,6 +2955,13 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
2954
2955
|
}
|
|
2955
2956
|
async function loadConfigFile(cwd) {
|
|
2956
2957
|
const loaded = await loadConfigFileDetailed(cwd);
|
|
2958
|
+
if (loaded.config && loaded.file && typeof loaded.config === "object") {
|
|
2959
|
+
Object.defineProperty(loaded.config, CONFIG_DIR_SYMBOL, {
|
|
2960
|
+
value: path10__namespace.dirname(loaded.file),
|
|
2961
|
+
enumerable: false,
|
|
2962
|
+
configurable: true
|
|
2963
|
+
});
|
|
2964
|
+
}
|
|
2957
2965
|
if (loaded.errors.length > 0) {
|
|
2958
2966
|
throw new Error(`The config file could not be read: ${loaded.errors.join("; ")}`);
|
|
2959
2967
|
}
|
|
@@ -3239,7 +3247,8 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
|
|
|
3239
3247
|
return resolved;
|
|
3240
3248
|
}
|
|
3241
3249
|
function resolveConfig(userConfig, cliOptions, baseDir) {
|
|
3242
|
-
const
|
|
3250
|
+
const configDir = userConfig?.[CONFIG_DIR_SYMBOL];
|
|
3251
|
+
const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir ?? configDir);
|
|
3243
3252
|
const forcedPreset = resolvePresetName(userConfig?.preset);
|
|
3244
3253
|
if (forcedPreset !== void 0 && !getPreset(forcedPreset)) {
|
|
3245
3254
|
throw new Error(unknownPresetMessage(forcedPreset));
|
|
@@ -3339,7 +3348,11 @@ function resolveConfig(userConfig, cliOptions, baseDir) {
|
|
|
3339
3348
|
hooks: resolveHooks(userConfig?.hooks),
|
|
3340
3349
|
layers,
|
|
3341
3350
|
kinds,
|
|
3342
|
-
|
|
3351
|
+
// `exclude` is the flag spelling of the same setting; writing it in a config used to
|
|
3352
|
+
// be ignored without a word.
|
|
3353
|
+
excludePatterns: resolveExcludePatterns(
|
|
3354
|
+
userConfig?.excludePatterns ?? userConfig?.exclude
|
|
3355
|
+
),
|
|
3343
3356
|
secretRules
|
|
3344
3357
|
});
|
|
3345
3358
|
}
|
|
@@ -4106,21 +4119,28 @@ function isBinaryExtension(filePath) {
|
|
|
4106
4119
|
return BINARY_EXTENSIONS.has(ext);
|
|
4107
4120
|
}
|
|
4108
4121
|
function isBinaryBuffer(buffer) {
|
|
4109
|
-
|
|
4110
|
-
for (let index = 0; index < checkLength; index++) {
|
|
4122
|
+
for (let index = 0; index < buffer.length; index++) {
|
|
4111
4123
|
if (buffer[index] === 0) return true;
|
|
4112
4124
|
}
|
|
4113
4125
|
return false;
|
|
4114
4126
|
}
|
|
4127
|
+
var BINARY_SCAN_BYTES = 8 * 1024 * 1024;
|
|
4128
|
+
var CHUNK = 64 * 1024;
|
|
4115
4129
|
function isBinaryFile(absolutePath) {
|
|
4116
4130
|
if (isBinaryExtension(absolutePath)) return true;
|
|
4117
4131
|
let fd;
|
|
4118
4132
|
try {
|
|
4119
4133
|
fd = fs9__namespace.openSync(absolutePath, "r");
|
|
4120
|
-
const buffer = Buffer.alloc(
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4134
|
+
const buffer = Buffer.alloc(CHUNK);
|
|
4135
|
+
let position = 0;
|
|
4136
|
+
while (position < BINARY_SCAN_BYTES) {
|
|
4137
|
+
const wanted = Math.min(CHUNK, BINARY_SCAN_BYTES - position);
|
|
4138
|
+
const bytesRead = fs9__namespace.readSync(fd, buffer, 0, wanted, position);
|
|
4139
|
+
if (bytesRead === 0) return false;
|
|
4140
|
+
if (isBinaryBuffer(buffer.subarray(0, bytesRead))) return true;
|
|
4141
|
+
position += bytesRead;
|
|
4142
|
+
}
|
|
4143
|
+
return false;
|
|
4124
4144
|
} catch {
|
|
4125
4145
|
return false;
|
|
4126
4146
|
} finally {
|
|
@@ -5290,11 +5310,11 @@ function addScripts(cwd, notes) {
|
|
|
5290
5310
|
const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
|
|
5291
5311
|
const added = [];
|
|
5292
5312
|
if (!scripts.snapshot) {
|
|
5293
|
-
scripts.snapshot = "codebase-snapshot generate";
|
|
5313
|
+
scripts.snapshot = "npx @ankurhalder/codebase-snapshot generate";
|
|
5294
5314
|
added.push("snapshot");
|
|
5295
5315
|
}
|
|
5296
5316
|
if (!scripts["snapshot:validate"]) {
|
|
5297
|
-
scripts["snapshot:validate"] = "codebase-snapshot validate";
|
|
5317
|
+
scripts["snapshot:validate"] = "npx @ankurhalder/codebase-snapshot validate";
|
|
5298
5318
|
added.push("snapshot:validate");
|
|
5299
5319
|
}
|
|
5300
5320
|
if (added.length === 0) return [];
|
|
@@ -5490,7 +5510,7 @@ async function runInit(options) {
|
|
|
5490
5510
|
|
|
5491
5511
|
// src/index.ts
|
|
5492
5512
|
var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
5493
|
-
var GENERATOR_VERSION = "4.0.
|
|
5513
|
+
var GENERATOR_VERSION = "4.0.7";
|
|
5494
5514
|
var SCHEMA_VERSION = "3.0.0";
|
|
5495
5515
|
function sha256Hex2(input) {
|
|
5496
5516
|
return crypto__namespace.createHash("sha256").update(input).digest("hex");
|
|
@@ -6257,8 +6277,8 @@ function generateSnapshot(configInput, options) {
|
|
|
6257
6277
|
const lineCount = countLines(rawContent);
|
|
6258
6278
|
totalLines += lineCount;
|
|
6259
6279
|
totalSizeBytes += stats.size;
|
|
6260
|
-
const layer2 = classifyLayer(relativePath, config.layers);
|
|
6261
|
-
const kind = classifyKind(relativePath, config.kinds);
|
|
6280
|
+
const layer2 = maskPathText(classifyLayer(relativePath, config.layers), config.secretRules);
|
|
6281
|
+
const kind = maskPathText(classifyKind(relativePath, config.kinds), config.secretRules);
|
|
6262
6282
|
const language = detectLanguage(relativePath);
|
|
6263
6283
|
bump(layerCounts, layer2);
|
|
6264
6284
|
bump(kindCounts, kind);
|
|
@@ -6351,7 +6371,9 @@ function generateSnapshot(configInput, options) {
|
|
|
6351
6371
|
name: GENERATOR_NAME,
|
|
6352
6372
|
version: GENERATOR_VERSION
|
|
6353
6373
|
},
|
|
6354
|
-
|
|
6374
|
+
// A branch name is user input and can carry a token: it reaches the manifest,
|
|
6375
|
+
// the README and the audit report.
|
|
6376
|
+
git: { ...gitInfo, branch: maskPathText(gitInfo.branch, config.secretRules) },
|
|
6355
6377
|
budgets: {
|
|
6356
6378
|
maxPartBytes: config.maxPartBytes,
|
|
6357
6379
|
largeFileBytes: config.largeFileBytes
|
|
@@ -6368,7 +6390,12 @@ function generateSnapshot(configInput, options) {
|
|
|
6368
6390
|
include: [...config.include].map(maskName),
|
|
6369
6391
|
preset: config.preset,
|
|
6370
6392
|
layersMode: config.layersMode,
|
|
6371
|
-
budgets: {
|
|
6393
|
+
budgets: {
|
|
6394
|
+
default: config.budgets.default,
|
|
6395
|
+
byLayer: Object.fromEntries(
|
|
6396
|
+
Object.entries(config.budgets.byLayer).map(([name, bytes]) => [maskName(name), bytes])
|
|
6397
|
+
)
|
|
6398
|
+
},
|
|
6372
6399
|
excludePatterns: [...config.excludePatterns].map(maskName),
|
|
6373
6400
|
layers: config.layers.map((layer2) => maskName(layer2.name)),
|
|
6374
6401
|
kinds: config.kinds.map((kind) => maskName(kind.kind))
|
package/dist/index.d.cts
CHANGED
|
@@ -495,7 +495,7 @@ declare function matchesExclude(relativePath: string, pattern: string): boolean;
|
|
|
495
495
|
declare function collectFiles(cwd: string, options?: CollectOptions): CollectResult;
|
|
496
496
|
|
|
497
497
|
declare const GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
498
|
-
declare const GENERATOR_VERSION = "4.0.
|
|
498
|
+
declare const GENERATOR_VERSION = "4.0.7";
|
|
499
499
|
declare const SCHEMA_VERSION = "3.0.0";
|
|
500
500
|
interface GenerateOptions {
|
|
501
501
|
/** Compute the full manifest but write nothing to disk. */
|
package/dist/index.d.ts
CHANGED
|
@@ -495,7 +495,7 @@ declare function matchesExclude(relativePath: string, pattern: string): boolean;
|
|
|
495
495
|
declare function collectFiles(cwd: string, options?: CollectOptions): CollectResult;
|
|
496
496
|
|
|
497
497
|
declare const GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
498
|
-
declare const GENERATOR_VERSION = "4.0.
|
|
498
|
+
declare const GENERATOR_VERSION = "4.0.7";
|
|
499
499
|
declare const SCHEMA_VERSION = "3.0.0";
|
|
500
500
|
interface GenerateOptions {
|
|
501
501
|
/** Compute the full manifest but write nothing to disk. */
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countLines, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, isBinaryBuffer, isBinaryExtension, isBinaryFile, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, profileForPath, renderConfig, renderDiffText, renderExplainText, renderMinimalConfig, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-
|
|
1
|
+
export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countLines, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, isBinaryBuffer, isBinaryExtension, isBinaryFile, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, profileForPath, renderConfig, renderDiffText, renderExplainText, renderMinimalConfig, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-VRJTXNJV.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|