codebase-snapshot 0.9.12 → 0.9.14
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 +379 -0
- package/README.md +1 -1
- package/dist/bin.js +1313 -633
- package/dist/{chunk-3H45YMBG.js → chunk-DUZK5VL2.js} +1413 -767
- package/dist/{chunk-5OR3WVPW.js → chunk-J4W74N4Y.js} +144 -44
- package/dist/cli.cjs +1305 -628
- package/dist/cli.d.cts +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +43 -54
- package/dist/{generate-worker-D5Xgh27c.d.cts → generate-worker-D_mUjgXw.d.cts} +21 -5
- package/dist/{generate-worker-D5Xgh27c.d.ts → generate-worker-D_mUjgXw.d.ts} +21 -5
- package/dist/index.cjs +1389 -760
- package/dist/index.d.cts +58 -35
- package/dist/index.d.ts +58 -35
- package/dist/index.js +1 -1
- package/dist/mcp.cjs +973 -405
- package/dist/mcp.d.cts +67 -67
- package/dist/mcp.d.ts +67 -67
- package/dist/mcp.js +2 -2
- package/dist/{types-CTewen3J.d.cts → types-DIX6zWSt.d.cts} +15 -0
- package/dist/{types-CTewen3J.d.ts → types-DIX6zWSt.d.ts} +15 -0
- package/docs/cli.md +8 -6
- package/docs/configuration.md +44 -10
- package/docs/mcp.md +16 -3
- package/docs/output.md +13 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { GENERATOR_VERSION, anchorForPath, displayPath, MIN_MAX_PART_BYTES, SCHEMA_VERSION, GENERATOR_NAME, ARTIFACT_NAMES, PRESETS, generateSnapshot, generateInWorker, validateSnapshot, buildImportResolver, resolveSpecifier, truncateToBytes, explainPath, renderExplainText, describeManifestShapeProblem, loadConfigFileDetailed, parseByteSize, resolveConfig } from './chunk-
|
|
1
|
+
import { GENERATOR_VERSION, anchorForPath, displayPath, MIN_MAX_PART_BYTES, SCHEMA_VERSION, GENERATOR_NAME, ARTIFACT_NAMES, PRESETS, generateSnapshot, generateInWorker, validateSnapshot, buildImportResolver, resolveSpecifier, truncateToBytes, explainPath, renderExplainText, describeManifestShapeProblem, loadConfigFileDetailed, parseByteSize, resolveConfig } from './chunk-DUZK5VL2.js';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
|
-
import * as
|
|
3
|
+
import * as path from 'path';
|
|
4
4
|
|
|
5
5
|
// src/mcp/protocol.ts
|
|
6
6
|
var LEGACY_PROTOCOL_VERSIONS = ["2025-11-25", "2025-06-18"];
|
|
@@ -617,7 +617,7 @@ function foldForComparison(value) {
|
|
|
617
617
|
return process.platform === "win32" || process.platform === "darwin" ? value.toLowerCase() : value;
|
|
618
618
|
}
|
|
619
619
|
function canonicalPath(value) {
|
|
620
|
-
const absolute =
|
|
620
|
+
const absolute = path.resolve(value);
|
|
621
621
|
try {
|
|
622
622
|
return fs.realpathSync(absolute);
|
|
623
623
|
} catch {
|
|
@@ -627,14 +627,14 @@ function canonicalPath(value) {
|
|
|
627
627
|
function isInside(parent, child) {
|
|
628
628
|
const foldedParent = foldForComparison(parent);
|
|
629
629
|
const foldedChild = foldForComparison(child);
|
|
630
|
-
return foldedChild === foldedParent || foldedChild.startsWith(`${foldedParent}${
|
|
630
|
+
return foldedChild === foldedParent || foldedChild.startsWith(`${foldedParent}${path.sep}`);
|
|
631
631
|
}
|
|
632
632
|
function resolveRoot(requested, context) {
|
|
633
633
|
if (requested !== void 0 && (typeof requested !== "string" || requested.trim().length === 0)) {
|
|
634
634
|
return { ok: false, message: '"root" must be a non-empty string when provided.' };
|
|
635
635
|
}
|
|
636
636
|
const wanted = typeof requested === "string" ? requested.trim() : context.cwd;
|
|
637
|
-
const absolute =
|
|
637
|
+
const absolute = path.resolve(context.cwd, wanted);
|
|
638
638
|
let stats;
|
|
639
639
|
try {
|
|
640
640
|
stats = fs.statSync(absolute);
|
|
@@ -673,12 +673,35 @@ async function openWorkspace(root, overrides = {}) {
|
|
|
673
673
|
}
|
|
674
674
|
cliOptions.maxPartBytes = parsed;
|
|
675
675
|
}
|
|
676
|
+
if (overrides.maxPartTokens !== void 0) {
|
|
677
|
+
const parsed = parseByteSize(overrides.maxPartTokens);
|
|
678
|
+
if (parsed === void 0) {
|
|
679
|
+
return {
|
|
680
|
+
ok: false,
|
|
681
|
+
message: '"maxPartTokens" must be a token count, for example 32000 or "32k".'
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
cliOptions.maxPartTokens = parsed;
|
|
685
|
+
}
|
|
676
686
|
if (overrides.outDir !== void 0) {
|
|
677
687
|
if (typeof overrides.outDir !== "string" || overrides.outDir.trim().length === 0) {
|
|
678
688
|
return { ok: false, message: '"outDir" must be a non-empty string.' };
|
|
679
689
|
}
|
|
680
690
|
cliOptions.outDir = overrides.outDir.trim();
|
|
681
691
|
}
|
|
692
|
+
if (overrides.changedSince !== void 0) {
|
|
693
|
+
if (typeof overrides.changedSince !== "string" || overrides.changedSince.trim().length === 0) {
|
|
694
|
+
return {
|
|
695
|
+
ok: false,
|
|
696
|
+
message: '"changedSince" must be a git ref such as "main" or "HEAD~3".'
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
cliOptions.changedSince = overrides.changedSince.trim();
|
|
700
|
+
}
|
|
701
|
+
if (overrides.skeleton === true) cliOptions.skeleton = true;
|
|
702
|
+
if (overrides.sarif === true) cliOptions.sarif = true;
|
|
703
|
+
if (overrides.staged === true) cliOptions.staged = true;
|
|
704
|
+
if (overrides.withDependents === true) cliOptions.withDependents = true;
|
|
682
705
|
try {
|
|
683
706
|
const config = resolveConfig(loaded.config, cliOptions, root);
|
|
684
707
|
return { ok: true, workspace: { root, config, configFile: loaded.file, cliOptions } };
|
|
@@ -688,11 +711,21 @@ async function openWorkspace(root, overrides = {}) {
|
|
|
688
711
|
}
|
|
689
712
|
var manifestCache = /* @__PURE__ */ new Map();
|
|
690
713
|
function manifestPathFor(workspace) {
|
|
691
|
-
return
|
|
714
|
+
return path.resolve(workspace.root, workspace.config.outDir, "manifest.json");
|
|
715
|
+
}
|
|
716
|
+
function partPathFor(workspace, filename) {
|
|
717
|
+
if (filename.length === 0 || filename.includes("\0")) return null;
|
|
718
|
+
const partsDir = path.resolve(workspace.root, workspace.config.outDir, "parts");
|
|
719
|
+
const resolved = path.resolve(partsDir, filename);
|
|
720
|
+
const relative3 = path.relative(partsDir, resolved);
|
|
721
|
+
if (relative3.length === 0 || relative3.includes(path.sep) || relative3.includes("/") || relative3.includes("\\") || path.isAbsolute(relative3)) {
|
|
722
|
+
return null;
|
|
723
|
+
}
|
|
724
|
+
return resolved;
|
|
692
725
|
}
|
|
693
726
|
function readManifest(workspace) {
|
|
694
727
|
const file = manifestPathFor(workspace);
|
|
695
|
-
const shown =
|
|
728
|
+
const shown = path.relative(workspace.root, file).split(path.sep).join("/") || file;
|
|
696
729
|
let stats;
|
|
697
730
|
try {
|
|
698
731
|
stats = fs.statSync(file);
|
|
@@ -760,6 +793,44 @@ var OUT_DIR_PROPERTY = {
|
|
|
760
793
|
description: "Snapshot directory, relative to the root. Defaults to the project configuration's outDir."
|
|
761
794
|
};
|
|
762
795
|
var outDirOverride = (args) => ({ outDir: args.outDir });
|
|
796
|
+
var SCOPE_PROPERTIES = {
|
|
797
|
+
maxPartTokens: {
|
|
798
|
+
type: "string",
|
|
799
|
+
description: 'Token ceiling per part, for example 32000 or "32k". Narrower than maxPartBytes; it converts at four bytes per token.'
|
|
800
|
+
},
|
|
801
|
+
skeleton: {
|
|
802
|
+
type: "boolean",
|
|
803
|
+
description: "Replace every function body with `{ /* ... */ }`, keeping signatures, imports and exports. Applies to TypeScript, JavaScript and JSX."
|
|
804
|
+
},
|
|
805
|
+
sarif: {
|
|
806
|
+
type: "boolean",
|
|
807
|
+
description: "Also write reports/audit.sarif beside reports/audit.md, for CI code scanning."
|
|
808
|
+
},
|
|
809
|
+
changedSince: {
|
|
810
|
+
type: "string",
|
|
811
|
+
description: 'Only files changed since this git ref, for example "main" or "HEAD~3".'
|
|
812
|
+
},
|
|
813
|
+
staged: {
|
|
814
|
+
type: "boolean",
|
|
815
|
+
description: "Only files staged in the git index."
|
|
816
|
+
},
|
|
817
|
+
withDependents: {
|
|
818
|
+
type: "boolean",
|
|
819
|
+
description: "With staged or changedSince, also include the files that import the changed ones (one hop)."
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
function workspaceOverrides(args) {
|
|
823
|
+
return {
|
|
824
|
+
outDir: args.outDir,
|
|
825
|
+
maxPartBytes: args.maxPartBytes,
|
|
826
|
+
maxPartTokens: args.maxPartTokens,
|
|
827
|
+
skeleton: args.skeleton,
|
|
828
|
+
sarif: args.sarif,
|
|
829
|
+
changedSince: args.changedSince,
|
|
830
|
+
staged: args.staged,
|
|
831
|
+
withDependents: args.withDependents
|
|
832
|
+
};
|
|
833
|
+
}
|
|
763
834
|
function failure(message) {
|
|
764
835
|
return { text: message, isError: true };
|
|
765
836
|
}
|
|
@@ -772,7 +843,7 @@ function formatBytes(bytes) {
|
|
|
772
843
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
773
844
|
}
|
|
774
845
|
function relativeFor(workspace, absolute) {
|
|
775
|
-
return
|
|
846
|
+
return path.relative(workspace.root, absolute).split(path.sep).join("/");
|
|
776
847
|
}
|
|
777
848
|
function capped(values, limit = 20) {
|
|
778
849
|
return { count: values.length, sample: values.slice(0, limit) };
|
|
@@ -790,13 +861,14 @@ function summarizeDrift(drift) {
|
|
|
790
861
|
}
|
|
791
862
|
function toRelativePath(root, value) {
|
|
792
863
|
const cleaned = value.trim();
|
|
793
|
-
if (cleaned.length === 0) return null;
|
|
794
|
-
|
|
795
|
-
|
|
864
|
+
if (cleaned.length === 0 || cleaned.includes("\0")) return null;
|
|
865
|
+
const resolvedRoot = path.resolve(root);
|
|
866
|
+
const absolute = path.resolve(resolvedRoot, cleaned);
|
|
867
|
+
const relative3 = path.relative(resolvedRoot, absolute);
|
|
868
|
+
if (relative3 === "" || relative3 === ".." || relative3.startsWith(`..${path.sep}`) || path.isAbsolute(relative3)) {
|
|
869
|
+
return null;
|
|
796
870
|
}
|
|
797
|
-
|
|
798
|
-
if (relative3.startsWith("..") || path2.isAbsolute(relative3)) return null;
|
|
799
|
-
return relative3.split(path2.sep).join("/");
|
|
871
|
+
return relative3.split(path.sep).join("/");
|
|
800
872
|
}
|
|
801
873
|
function symbolsOf(entry) {
|
|
802
874
|
const summary = entry.summary;
|
|
@@ -931,7 +1003,8 @@ var planTool = {
|
|
|
931
1003
|
maxPartBytes: {
|
|
932
1004
|
type: "string",
|
|
933
1005
|
description: 'Byte budget per part, for example 307200 or "300k". Defaults to the project configuration.'
|
|
934
|
-
}
|
|
1006
|
+
},
|
|
1007
|
+
...SCOPE_PROPERTIES
|
|
935
1008
|
},
|
|
936
1009
|
additionalProperties: false
|
|
937
1010
|
},
|
|
@@ -948,7 +1021,7 @@ var planTool = {
|
|
|
948
1021
|
},
|
|
949
1022
|
annotations: READ_ONLY,
|
|
950
1023
|
async handler(args, context) {
|
|
951
|
-
const prepared = await prepare(args, context,
|
|
1024
|
+
const prepared = await prepare(args, context, workspaceOverrides(args));
|
|
952
1025
|
if (!prepared.ok) return prepared.outcome;
|
|
953
1026
|
const workspace = prepared.workspace;
|
|
954
1027
|
let manifest;
|
|
@@ -1006,7 +1079,8 @@ var generateTool = {
|
|
|
1006
1079
|
maxPartBytes: {
|
|
1007
1080
|
type: "string",
|
|
1008
1081
|
description: 'Byte budget per part, for example 307200 or "300k". Defaults to the project configuration.'
|
|
1009
|
-
}
|
|
1082
|
+
},
|
|
1083
|
+
...SCOPE_PROPERTIES
|
|
1010
1084
|
},
|
|
1011
1085
|
additionalProperties: false
|
|
1012
1086
|
},
|
|
@@ -1022,17 +1096,14 @@ var generateTool = {
|
|
|
1022
1096
|
},
|
|
1023
1097
|
annotations: WRITES,
|
|
1024
1098
|
async handler(args, context) {
|
|
1025
|
-
const prepared = await prepare(args, context,
|
|
1026
|
-
maxPartBytes: args.maxPartBytes,
|
|
1027
|
-
outDir: args.outDir
|
|
1028
|
-
});
|
|
1099
|
+
const prepared = await prepare(args, context, workspaceOverrides(args));
|
|
1029
1100
|
if (!prepared.ok) return prepared.outcome;
|
|
1030
1101
|
const workspace = prepared.workspace;
|
|
1031
1102
|
const result = await generateInWorker(workspace.root, workspace.cliOptions);
|
|
1032
1103
|
if (!result.ok) return failure(result.message);
|
|
1033
1104
|
const summary = result.summary;
|
|
1034
1105
|
forgetManifest(manifestPathFor(workspace));
|
|
1035
|
-
const written = relativeFor(workspace,
|
|
1106
|
+
const written = relativeFor(workspace, path.resolve(workspace.root, workspace.config.outDir));
|
|
1036
1107
|
const lines = [
|
|
1037
1108
|
`Wrote ${written}/`,
|
|
1038
1109
|
`Files: ${summary.totalFiles} included, ${summary.skippedCount} skipped, ${plural(summary.partsCount, "part")}`,
|
|
@@ -1064,7 +1135,7 @@ var validateTool = {
|
|
|
1064
1135
|
description: "Re-read the repository and report whether the snapshot on disk still matches it. Use it before trusting context that came from an earlier session, or after changing the config.",
|
|
1065
1136
|
inputSchema: {
|
|
1066
1137
|
type: "object",
|
|
1067
|
-
properties: { root: ROOT_PROPERTY, outDir: OUT_DIR_PROPERTY },
|
|
1138
|
+
properties: { root: ROOT_PROPERTY, outDir: OUT_DIR_PROPERTY, ...SCOPE_PROPERTIES },
|
|
1068
1139
|
additionalProperties: false
|
|
1069
1140
|
},
|
|
1070
1141
|
outputSchema: {
|
|
@@ -1076,7 +1147,7 @@ var validateTool = {
|
|
|
1076
1147
|
},
|
|
1077
1148
|
annotations: READ_ONLY,
|
|
1078
1149
|
async handler(args, context) {
|
|
1079
|
-
const prepared = await prepare(args, context,
|
|
1150
|
+
const prepared = await prepare(args, context, workspaceOverrides(args));
|
|
1080
1151
|
if (!prepared.ok) return prepared.outcome;
|
|
1081
1152
|
const workspace = prepared.workspace;
|
|
1082
1153
|
let result;
|
|
@@ -1421,7 +1492,12 @@ var readTool = {
|
|
|
1421
1492
|
`${relativePath} is not in the snapshot. Call snapshot_locate to find the path, or snapshot_explain to learn why it was excluded.`
|
|
1422
1493
|
);
|
|
1423
1494
|
}
|
|
1424
|
-
const partPath =
|
|
1495
|
+
const partPath = partPathFor(workspace, entry.part);
|
|
1496
|
+
if (partPath === null) {
|
|
1497
|
+
return failure(
|
|
1498
|
+
`${entry.part} is not a part of this snapshot: its name leaves ${workspace.config.outDir}/parts. Run snapshot_generate to rebuild it.`
|
|
1499
|
+
);
|
|
1500
|
+
}
|
|
1425
1501
|
let partText;
|
|
1426
1502
|
try {
|
|
1427
1503
|
partText = fs.readFileSync(partPath, "utf8");
|
|
@@ -1501,7 +1577,8 @@ var explainTool = {
|
|
|
1501
1577
|
description: "Path relative to the repository root. Directories are explained as a whole."
|
|
1502
1578
|
},
|
|
1503
1579
|
root: ROOT_PROPERTY,
|
|
1504
|
-
outDir: OUT_DIR_PROPERTY
|
|
1580
|
+
outDir: OUT_DIR_PROPERTY,
|
|
1581
|
+
...SCOPE_PROPERTIES
|
|
1505
1582
|
},
|
|
1506
1583
|
required: ["path"],
|
|
1507
1584
|
additionalProperties: false
|
|
@@ -1516,7 +1593,7 @@ var explainTool = {
|
|
|
1516
1593
|
},
|
|
1517
1594
|
annotations: READ_ONLY,
|
|
1518
1595
|
async handler(args, context) {
|
|
1519
|
-
const prepared = await prepare(args, context,
|
|
1596
|
+
const prepared = await prepare(args, context, workspaceOverrides(args));
|
|
1520
1597
|
if (!prepared.ok) return prepared.outcome;
|
|
1521
1598
|
const workspace = prepared.workspace;
|
|
1522
1599
|
if (typeof args.path !== "string") return failure('"path" must be a string.');
|
|
@@ -2298,7 +2375,7 @@ function buildAgentContract() {
|
|
|
2298
2375
|
{ key: "preset", type: "string", default: "detected", summary: "Force a preset. Unknown names are an error." },
|
|
2299
2376
|
{ key: "maxPartBytes", type: "number | string", default: 307200, summary: "Per-part byte budget." },
|
|
2300
2377
|
{ key: "maxPartTokens", type: "number | string | null", default: null, summary: "Per-part token ceiling; narrows maxPartBytes. Minimum 1024." },
|
|
2301
|
-
{ key: "skeleton", type: "boolean", default: false, summary: "Collapse function bodies to `{ /* ... */ }` in
|
|
2378
|
+
{ key: "skeleton", type: "boolean", default: false, summary: "Collapse function bodies to `{ /* ... */ }` in TS, JS, TSX and JSX files." },
|
|
2302
2379
|
{ key: "sarif", type: "boolean", default: false, summary: "Also write reports/audit.sarif." },
|
|
2303
2380
|
{ key: "changedSince", type: "string | null", default: null, summary: "Snapshot only files that differ from this git ref." },
|
|
2304
2381
|
{ key: "staged", type: "boolean", default: false, summary: "Snapshot only files staged in the index." },
|
|
@@ -2671,7 +2748,7 @@ function buildResourceProvider() {
|
|
|
2671
2748
|
const report = REPORT_URIS.get(uri);
|
|
2672
2749
|
if (report) {
|
|
2673
2750
|
const text = readFileIfPresent(
|
|
2674
|
-
|
|
2751
|
+
path.resolve(workspace.root, workspace.config.outDir, "reports", report.file)
|
|
2675
2752
|
);
|
|
2676
2753
|
if (text === null) return null;
|
|
2677
2754
|
return { uri, mimeType: "text/markdown", text: capUtf8(text, MAX_RESOURCE_BYTES).text };
|
|
@@ -2689,9 +2766,9 @@ function buildResourceProvider() {
|
|
|
2689
2766
|
const index = Number(partMatch[1]);
|
|
2690
2767
|
const part = read.manifest.parts.find((candidate) => candidate.index === index);
|
|
2691
2768
|
if (!part) return null;
|
|
2692
|
-
const
|
|
2693
|
-
|
|
2694
|
-
);
|
|
2769
|
+
const partPath = partPathFor(workspace, part.filename);
|
|
2770
|
+
if (partPath === null) return null;
|
|
2771
|
+
const text = readFileIfPresent(partPath);
|
|
2695
2772
|
if (text === null) return null;
|
|
2696
2773
|
return { uri, mimeType: "text/markdown", text: capUtf8(text, MAX_RESOURCE_BYTES).text };
|
|
2697
2774
|
}
|
|
@@ -2735,6 +2812,7 @@ function createWriter(output) {
|
|
|
2735
2812
|
}
|
|
2736
2813
|
function createLineReader(input, options) {
|
|
2737
2814
|
let buffer = "";
|
|
2815
|
+
let bufferBytes = 0;
|
|
2738
2816
|
let discarding = false;
|
|
2739
2817
|
let discardedBytes = 0;
|
|
2740
2818
|
const deliver = (line) => {
|
|
@@ -2747,6 +2825,13 @@ function createLineReader(input, options) {
|
|
|
2747
2825
|
if (trimmed.trim().length === 0) return;
|
|
2748
2826
|
options.onLine(trimmed);
|
|
2749
2827
|
};
|
|
2828
|
+
const discardBuffered = () => {
|
|
2829
|
+
discarding = true;
|
|
2830
|
+
discardedBytes += bufferBytes;
|
|
2831
|
+
buffer = "";
|
|
2832
|
+
bufferBytes = 0;
|
|
2833
|
+
options.onOverflow?.(discardedBytes);
|
|
2834
|
+
};
|
|
2750
2835
|
const drain = () => {
|
|
2751
2836
|
let index = buffer.indexOf("\n");
|
|
2752
2837
|
while (index >= 0) {
|
|
@@ -2754,42 +2839,57 @@ function createLineReader(input, options) {
|
|
|
2754
2839
|
buffer = buffer.slice(index + 1);
|
|
2755
2840
|
if (discarding) {
|
|
2756
2841
|
deliver(line);
|
|
2757
|
-
} else if (line.length > MAX_LINE_BYTES) {
|
|
2758
|
-
options.onOverflow?.(line.length);
|
|
2759
2842
|
} else {
|
|
2760
|
-
|
|
2843
|
+
const lineBytes = Buffer.byteLength(line, "utf8");
|
|
2844
|
+
if (lineBytes > MAX_LINE_BYTES) options.onOverflow?.(lineBytes);
|
|
2845
|
+
else deliver(line);
|
|
2761
2846
|
}
|
|
2762
2847
|
index = buffer.indexOf("\n");
|
|
2763
2848
|
}
|
|
2849
|
+
bufferBytes = Buffer.byteLength(buffer, "utf8");
|
|
2850
|
+
if (!discarding && bufferBytes > MAX_LINE_BYTES) discardBuffered();
|
|
2764
2851
|
};
|
|
2765
2852
|
const onData = (chunk) => {
|
|
2853
|
+
const chunkBytes = Buffer.byteLength(chunk, "utf8");
|
|
2766
2854
|
if (discarding) {
|
|
2767
2855
|
const index = chunk.indexOf("\n");
|
|
2768
2856
|
if (index < 0) {
|
|
2769
|
-
discardedBytes +=
|
|
2857
|
+
discardedBytes += chunkBytes;
|
|
2770
2858
|
return;
|
|
2771
2859
|
}
|
|
2772
2860
|
buffer = chunk.slice(index + 1);
|
|
2861
|
+
bufferBytes = Buffer.byteLength(buffer, "utf8");
|
|
2773
2862
|
deliver("");
|
|
2774
2863
|
drain();
|
|
2775
2864
|
return;
|
|
2776
2865
|
}
|
|
2777
|
-
|
|
2778
|
-
drain();
|
|
2779
|
-
if (buffer.length > MAX_LINE_BYTES) {
|
|
2866
|
+
if (chunk.indexOf("\n") < 0 && bufferBytes + chunkBytes > MAX_LINE_BYTES) {
|
|
2780
2867
|
discarding = true;
|
|
2781
|
-
discardedBytes =
|
|
2868
|
+
discardedBytes = bufferBytes + chunkBytes;
|
|
2782
2869
|
buffer = "";
|
|
2870
|
+
bufferBytes = 0;
|
|
2783
2871
|
options.onOverflow?.(discardedBytes);
|
|
2784
2872
|
return;
|
|
2785
2873
|
}
|
|
2874
|
+
buffer += chunk;
|
|
2875
|
+
drain();
|
|
2786
2876
|
};
|
|
2787
2877
|
const onEnd = () => {
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2878
|
+
const rest = buffer;
|
|
2879
|
+
const restBytes = bufferBytes || Buffer.byteLength(rest, "utf8");
|
|
2880
|
+
buffer = "";
|
|
2881
|
+
bufferBytes = 0;
|
|
2882
|
+
if (rest.length === 0) return;
|
|
2883
|
+
if (discarding) {
|
|
2884
|
+
discarding = false;
|
|
2885
|
+
discardedBytes = 0;
|
|
2886
|
+
return;
|
|
2887
|
+
}
|
|
2888
|
+
if (restBytes > MAX_LINE_BYTES) {
|
|
2889
|
+
options.onOverflow?.(restBytes);
|
|
2890
|
+
return;
|
|
2792
2891
|
}
|
|
2892
|
+
deliver(rest);
|
|
2793
2893
|
};
|
|
2794
2894
|
input.setEncoding("utf8");
|
|
2795
2895
|
input.on("data", onData);
|