@fern-api/replay 0.8.0 → 0.9.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/dist/cli.cjs +496 -127
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +250 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -17
- package/dist/index.d.ts +62 -17
- package/dist/index.js +250 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -189,7 +189,7 @@ function isReplayCommit(commit) {
|
|
|
189
189
|
return commit.message.startsWith("[fern-replay]");
|
|
190
190
|
}
|
|
191
191
|
function isRevertCommit(message) {
|
|
192
|
-
return
|
|
192
|
+
return /^Revert ".+"$/.test(message);
|
|
193
193
|
}
|
|
194
194
|
function parseRevertedSha(fullBody) {
|
|
195
195
|
const match = fullBody.match(/This reverts commit ([0-9a-f]{40})\./);
|
|
@@ -290,6 +290,15 @@ var LockfileManager = class {
|
|
|
290
290
|
this.ensureLoaded();
|
|
291
291
|
this.lock.patches = [];
|
|
292
292
|
}
|
|
293
|
+
addForgottenHash(hash) {
|
|
294
|
+
this.ensureLoaded();
|
|
295
|
+
if (!this.lock.forgotten_hashes) {
|
|
296
|
+
this.lock.forgotten_hashes = [];
|
|
297
|
+
}
|
|
298
|
+
if (!this.lock.forgotten_hashes.includes(hash)) {
|
|
299
|
+
this.lock.forgotten_hashes.push(hash);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
293
302
|
getUnresolvedPatches() {
|
|
294
303
|
this.ensureLoaded();
|
|
295
304
|
return this.lock.patches.filter((p) => p.status === "unresolved");
|
|
@@ -386,6 +395,7 @@ var ReplayDetector = class {
|
|
|
386
395
|
}
|
|
387
396
|
const commits = this.parseGitLog(log);
|
|
388
397
|
const newPatches = [];
|
|
398
|
+
const forgottenHashes = new Set(lock.forgotten_hashes ?? []);
|
|
389
399
|
for (const commit of commits) {
|
|
390
400
|
if (isGenerationCommit(commit)) {
|
|
391
401
|
continue;
|
|
@@ -399,7 +409,7 @@ var ReplayDetector = class {
|
|
|
399
409
|
}
|
|
400
410
|
const patchContent = await this.git.formatPatch(commit.sha);
|
|
401
411
|
const contentHash = this.computeContentHash(patchContent);
|
|
402
|
-
if (lock.patches.find((p) => p.content_hash === contentHash)) {
|
|
412
|
+
if (lock.patches.find((p) => p.content_hash === contentHash) || forgottenHashes.has(contentHash)) {
|
|
403
413
|
continue;
|
|
404
414
|
}
|
|
405
415
|
const filesOutput = await this.git.exec(["diff-tree", "--no-commit-id", "--name-only", "-r", commit.sha]);
|
|
@@ -469,6 +479,9 @@ var ReplayDetector = class {
|
|
|
469
479
|
revertIndicesToRemove.add(idx);
|
|
470
480
|
}
|
|
471
481
|
}
|
|
482
|
+
if (!matchedExisting && !matchedNew) {
|
|
483
|
+
revertIndicesToRemove.add(i);
|
|
484
|
+
}
|
|
472
485
|
}
|
|
473
486
|
const filteredPatches = newPatches.filter((_, i) => !revertIndicesToRemove.has(i));
|
|
474
487
|
return { patches: filteredPatches, revertedPatchIds: [...revertedPatchIdSet] };
|
|
@@ -495,7 +508,7 @@ var ReplayDetector = class {
|
|
|
495
508
|
if (!diff.trim()) return { patches: [], revertedPatchIds: [] };
|
|
496
509
|
const contentHash = this.computeContentHash(diff);
|
|
497
510
|
const lock = this.lockManager.read();
|
|
498
|
-
if (lock.patches.some((p) => p.content_hash === contentHash)) {
|
|
511
|
+
if (lock.patches.some((p) => p.content_hash === contentHash) || (lock.forgotten_hashes ?? []).includes(contentHash)) {
|
|
499
512
|
return { patches: [], revertedPatchIds: [] };
|
|
500
513
|
}
|
|
501
514
|
const headSha = (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
@@ -565,6 +578,36 @@ var import_promises = require("fs/promises");
|
|
|
565
578
|
var import_node_os = require("os");
|
|
566
579
|
var import_node_path2 = require("path");
|
|
567
580
|
var import_minimatch = require("minimatch");
|
|
581
|
+
|
|
582
|
+
// src/conflict-utils.ts
|
|
583
|
+
function stripConflictMarkers(content) {
|
|
584
|
+
const lines = content.split("\n");
|
|
585
|
+
const result = [];
|
|
586
|
+
let inConflict = false;
|
|
587
|
+
let inOurs = false;
|
|
588
|
+
for (const line of lines) {
|
|
589
|
+
if (line.startsWith("<<<<<<< ")) {
|
|
590
|
+
inConflict = true;
|
|
591
|
+
inOurs = true;
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (inConflict && line === "=======") {
|
|
595
|
+
inOurs = false;
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
if (inConflict && line.startsWith(">>>>>>> ")) {
|
|
599
|
+
inConflict = false;
|
|
600
|
+
inOurs = false;
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
if (!inConflict || inOurs) {
|
|
604
|
+
result.push(line);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return result.join("\n");
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// src/ReplayApplicator.ts
|
|
568
611
|
var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
569
612
|
".png",
|
|
570
613
|
".jpg",
|
|
@@ -636,7 +679,8 @@ var ReplayApplicator = class {
|
|
|
636
679
|
async applyPatches(patches) {
|
|
637
680
|
this.resetAccumulator();
|
|
638
681
|
const results = [];
|
|
639
|
-
for (
|
|
682
|
+
for (let i = 0; i < patches.length; i++) {
|
|
683
|
+
const patch = patches[i];
|
|
640
684
|
if (this.isExcluded(patch)) {
|
|
641
685
|
results.push({
|
|
642
686
|
patch,
|
|
@@ -647,6 +691,33 @@ var ReplayApplicator = class {
|
|
|
647
691
|
}
|
|
648
692
|
const result = await this.applyPatchWithFallback(patch);
|
|
649
693
|
results.push(result);
|
|
694
|
+
if (result.status === "conflict" && result.fileResults) {
|
|
695
|
+
const laterFiles = /* @__PURE__ */ new Set();
|
|
696
|
+
for (let j = i + 1; j < patches.length; j++) {
|
|
697
|
+
for (const f of patches[j].files) {
|
|
698
|
+
laterFiles.add(f);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
const resolvedToOriginal = /* @__PURE__ */ new Map();
|
|
702
|
+
if (result.resolvedFiles) {
|
|
703
|
+
for (const [orig, resolved] of Object.entries(result.resolvedFiles)) {
|
|
704
|
+
resolvedToOriginal.set(resolved, orig);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
for (const fileResult of result.fileResults) {
|
|
708
|
+
if (fileResult.status !== "conflict") continue;
|
|
709
|
+
const originalPath = resolvedToOriginal.get(fileResult.file) ?? fileResult.file;
|
|
710
|
+
if (laterFiles.has(fileResult.file) || laterFiles.has(originalPath)) {
|
|
711
|
+
const filePath = (0, import_node_path2.join)(this.outputDir, fileResult.file);
|
|
712
|
+
try {
|
|
713
|
+
const content = await (0, import_promises.readFile)(filePath, "utf-8");
|
|
714
|
+
const stripped = stripConflictMarkers(content);
|
|
715
|
+
await (0, import_promises.writeFile)(filePath, stripped);
|
|
716
|
+
} catch {
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
650
721
|
}
|
|
651
722
|
return results;
|
|
652
723
|
}
|
|
@@ -665,7 +736,7 @@ var ReplayApplicator = class {
|
|
|
665
736
|
const resolvedPath = await this.resolveFilePath(filePath, baseGen.tree_hash, currentTreeHash);
|
|
666
737
|
const base = await this.git.showFile(baseGen.tree_hash, filePath);
|
|
667
738
|
const theirs = await this.applyPatchToContent(base, patch.patch_content, filePath, tempGit, tempDir);
|
|
668
|
-
if (theirs
|
|
739
|
+
if (theirs) {
|
|
669
740
|
this.fileTheirsAccumulator.set(resolvedPath, {
|
|
670
741
|
content: theirs,
|
|
671
742
|
baseGeneration: patch.base_generation
|
|
@@ -797,7 +868,7 @@ var ReplayApplicator = class {
|
|
|
797
868
|
);
|
|
798
869
|
let useAccumulatorAsMergeBase = false;
|
|
799
870
|
const accumulatorEntry = this.fileTheirsAccumulator.get(resolvedPath);
|
|
800
|
-
if (!theirs &&
|
|
871
|
+
if (!theirs && accumulatorEntry) {
|
|
801
872
|
theirs = await this.applyPatchToContent(
|
|
802
873
|
accumulatorEntry.content,
|
|
803
874
|
patch.patch_content,
|
|
@@ -856,7 +927,7 @@ var ReplayApplicator = class {
|
|
|
856
927
|
reason: "missing-content"
|
|
857
928
|
};
|
|
858
929
|
}
|
|
859
|
-
if (!base || !ours) {
|
|
930
|
+
if (!base && !useAccumulatorAsMergeBase || !ours) {
|
|
860
931
|
return {
|
|
861
932
|
file: resolvedPath,
|
|
862
933
|
status: "skipped",
|
|
@@ -864,11 +935,18 @@ var ReplayApplicator = class {
|
|
|
864
935
|
};
|
|
865
936
|
}
|
|
866
937
|
const mergeBase = useAccumulatorAsMergeBase && accumulatorEntry ? accumulatorEntry.content : base;
|
|
938
|
+
if (mergeBase == null) {
|
|
939
|
+
return {
|
|
940
|
+
file: resolvedPath,
|
|
941
|
+
status: "skipped",
|
|
942
|
+
reason: "missing-content"
|
|
943
|
+
};
|
|
944
|
+
}
|
|
867
945
|
const merged = threeWayMerge(mergeBase, ours, effective_theirs);
|
|
868
946
|
const outDir = (0, import_node_path2.dirname)(oursPath);
|
|
869
947
|
await (0, import_promises.mkdir)(outDir, { recursive: true });
|
|
870
948
|
await (0, import_promises.writeFile)(oursPath, merged.content);
|
|
871
|
-
if (effective_theirs
|
|
949
|
+
if (effective_theirs) {
|
|
872
950
|
this.fileTheirsAccumulator.set(resolvedPath, {
|
|
873
951
|
content: effective_theirs,
|
|
874
952
|
baseGeneration: patch.base_generation
|
|
@@ -1111,36 +1189,6 @@ var import_node_fs2 = require("fs");
|
|
|
1111
1189
|
var import_node_path3 = require("path");
|
|
1112
1190
|
var import_minimatch2 = require("minimatch");
|
|
1113
1191
|
init_GitClient();
|
|
1114
|
-
|
|
1115
|
-
// src/conflict-utils.ts
|
|
1116
|
-
function stripConflictMarkers(content) {
|
|
1117
|
-
const lines = content.split("\n");
|
|
1118
|
-
const result = [];
|
|
1119
|
-
let inConflict = false;
|
|
1120
|
-
let inOurs = false;
|
|
1121
|
-
for (const line of lines) {
|
|
1122
|
-
if (line.startsWith("<<<<<<< ")) {
|
|
1123
|
-
inConflict = true;
|
|
1124
|
-
inOurs = true;
|
|
1125
|
-
continue;
|
|
1126
|
-
}
|
|
1127
|
-
if (inConflict && line === "=======") {
|
|
1128
|
-
inOurs = false;
|
|
1129
|
-
continue;
|
|
1130
|
-
}
|
|
1131
|
-
if (inConflict && line.startsWith(">>>>>>> ")) {
|
|
1132
|
-
inConflict = false;
|
|
1133
|
-
inOurs = false;
|
|
1134
|
-
continue;
|
|
1135
|
-
}
|
|
1136
|
-
if (!inConflict || inOurs) {
|
|
1137
|
-
result.push(line);
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
return result.join("\n");
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
|
-
// src/ReplayService.ts
|
|
1144
1192
|
var ReplayService = class {
|
|
1145
1193
|
git;
|
|
1146
1194
|
detector;
|
|
@@ -2108,30 +2156,145 @@ function computeContentHash(patchContent) {
|
|
|
2108
2156
|
|
|
2109
2157
|
// src/commands/forget.ts
|
|
2110
2158
|
var import_minimatch4 = require("minimatch");
|
|
2111
|
-
function
|
|
2159
|
+
function parseDiffStat(patchContent) {
|
|
2160
|
+
let additions = 0;
|
|
2161
|
+
let deletions = 0;
|
|
2162
|
+
let inDiffHunk = false;
|
|
2163
|
+
for (const line of patchContent.split("\n")) {
|
|
2164
|
+
if (line.startsWith("diff --git ")) {
|
|
2165
|
+
inDiffHunk = true;
|
|
2166
|
+
continue;
|
|
2167
|
+
}
|
|
2168
|
+
if (!inDiffHunk) continue;
|
|
2169
|
+
if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
2170
|
+
additions++;
|
|
2171
|
+
} else if (line.startsWith("-") && !line.startsWith("---")) {
|
|
2172
|
+
deletions++;
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
return { additions, deletions };
|
|
2176
|
+
}
|
|
2177
|
+
function toMatchedPatch(patch) {
|
|
2178
|
+
return {
|
|
2179
|
+
id: patch.id,
|
|
2180
|
+
message: patch.original_message,
|
|
2181
|
+
files: patch.files,
|
|
2182
|
+
diffstat: parseDiffStat(patch.patch_content),
|
|
2183
|
+
...patch.status ? { status: patch.status } : {}
|
|
2184
|
+
};
|
|
2185
|
+
}
|
|
2186
|
+
function matchesPatch(patch, pattern) {
|
|
2187
|
+
const fileMatch = patch.files.some(
|
|
2188
|
+
(file) => file === pattern || (0, import_minimatch4.minimatch)(file, pattern)
|
|
2189
|
+
);
|
|
2190
|
+
if (fileMatch) return true;
|
|
2191
|
+
return patch.original_message.toLowerCase().includes(pattern.toLowerCase());
|
|
2192
|
+
}
|
|
2193
|
+
function buildWarnings(patches) {
|
|
2194
|
+
const warnings = [];
|
|
2195
|
+
for (const patch of patches) {
|
|
2196
|
+
if (patch.status === "resolving") {
|
|
2197
|
+
warnings.push(
|
|
2198
|
+
`patch ${patch.id} has conflict markers in these files: ${patch.files.join(", ")}. Run \`git checkout -- <files>\` to restore the generated versions.`
|
|
2199
|
+
);
|
|
2200
|
+
} else if (patch.status === "unresolved") {
|
|
2201
|
+
warnings.push(
|
|
2202
|
+
`patch ${patch.id} had unresolved conflicts (files: ${patch.files.join(", ")}).`
|
|
2203
|
+
);
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
return warnings;
|
|
2207
|
+
}
|
|
2208
|
+
var EMPTY_RESULT = {
|
|
2209
|
+
initialized: false,
|
|
2210
|
+
removed: [],
|
|
2211
|
+
remaining: 0,
|
|
2212
|
+
notFound: false,
|
|
2213
|
+
alreadyForgotten: [],
|
|
2214
|
+
totalPatches: 0,
|
|
2215
|
+
warnings: []
|
|
2216
|
+
};
|
|
2217
|
+
function forget(outputDir, options) {
|
|
2112
2218
|
const lockManager = new LockfileManager(outputDir);
|
|
2113
2219
|
if (!lockManager.exists()) {
|
|
2114
|
-
return {
|
|
2220
|
+
return { ...EMPTY_RESULT };
|
|
2115
2221
|
}
|
|
2116
2222
|
const lock = lockManager.read();
|
|
2117
|
-
const
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2223
|
+
const totalPatches = lock.patches.length;
|
|
2224
|
+
if (options?.all) {
|
|
2225
|
+
const removed = lock.patches.map(toMatchedPatch);
|
|
2226
|
+
const warnings = buildWarnings(lock.patches);
|
|
2227
|
+
if (!options.dryRun) {
|
|
2228
|
+
for (const patch of lock.patches) {
|
|
2229
|
+
lockManager.addForgottenHash(patch.content_hash);
|
|
2230
|
+
}
|
|
2231
|
+
lockManager.clearPatches();
|
|
2232
|
+
lockManager.save();
|
|
2233
|
+
}
|
|
2234
|
+
return {
|
|
2235
|
+
initialized: true,
|
|
2236
|
+
removed,
|
|
2237
|
+
remaining: 0,
|
|
2238
|
+
notFound: false,
|
|
2239
|
+
alreadyForgotten: [],
|
|
2240
|
+
totalPatches,
|
|
2241
|
+
warnings
|
|
2242
|
+
};
|
|
2122
2243
|
}
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2244
|
+
if (options?.patchIds && options.patchIds.length > 0) {
|
|
2245
|
+
const removed = [];
|
|
2246
|
+
const alreadyForgotten = [];
|
|
2247
|
+
const patchesToRemove = [];
|
|
2248
|
+
for (const id of options.patchIds) {
|
|
2249
|
+
const patch = lock.patches.find((p) => p.id === id);
|
|
2250
|
+
if (patch) {
|
|
2251
|
+
removed.push(toMatchedPatch(patch));
|
|
2252
|
+
patchesToRemove.push(patch);
|
|
2253
|
+
} else {
|
|
2254
|
+
alreadyForgotten.push(id);
|
|
2255
|
+
}
|
|
2131
2256
|
}
|
|
2132
|
-
|
|
2257
|
+
const warnings = buildWarnings(patchesToRemove);
|
|
2258
|
+
if (!options.dryRun) {
|
|
2259
|
+
for (const patch of patchesToRemove) {
|
|
2260
|
+
lockManager.addForgottenHash(patch.content_hash);
|
|
2261
|
+
lockManager.removePatch(patch.id);
|
|
2262
|
+
}
|
|
2263
|
+
lockManager.save();
|
|
2264
|
+
}
|
|
2265
|
+
return {
|
|
2266
|
+
initialized: true,
|
|
2267
|
+
removed,
|
|
2268
|
+
remaining: totalPatches - removed.length,
|
|
2269
|
+
notFound: removed.length === 0 && alreadyForgotten.length > 0,
|
|
2270
|
+
alreadyForgotten,
|
|
2271
|
+
totalPatches,
|
|
2272
|
+
warnings
|
|
2273
|
+
};
|
|
2274
|
+
}
|
|
2275
|
+
if (options?.pattern) {
|
|
2276
|
+
const matched = lock.patches.filter((p) => matchesPatch(p, options.pattern)).map(toMatchedPatch);
|
|
2277
|
+
return {
|
|
2278
|
+
initialized: true,
|
|
2279
|
+
removed: [],
|
|
2280
|
+
remaining: totalPatches,
|
|
2281
|
+
notFound: matched.length === 0,
|
|
2282
|
+
alreadyForgotten: [],
|
|
2283
|
+
totalPatches,
|
|
2284
|
+
warnings: [],
|
|
2285
|
+
matched
|
|
2286
|
+
};
|
|
2133
2287
|
}
|
|
2134
|
-
return {
|
|
2288
|
+
return {
|
|
2289
|
+
initialized: true,
|
|
2290
|
+
removed: [],
|
|
2291
|
+
remaining: totalPatches,
|
|
2292
|
+
notFound: totalPatches === 0,
|
|
2293
|
+
alreadyForgotten: [],
|
|
2294
|
+
totalPatches,
|
|
2295
|
+
warnings: [],
|
|
2296
|
+
matched: lock.patches.map(toMatchedPatch)
|
|
2297
|
+
};
|
|
2135
2298
|
}
|
|
2136
2299
|
|
|
2137
2300
|
// src/commands/reset.ts
|
|
@@ -2253,24 +2416,49 @@ async function getChangedFiles(git, currentGen, files) {
|
|
|
2253
2416
|
function status(outputDir) {
|
|
2254
2417
|
const lockManager = new LockfileManager(outputDir);
|
|
2255
2418
|
if (!lockManager.exists()) {
|
|
2256
|
-
return {
|
|
2419
|
+
return {
|
|
2420
|
+
initialized: false,
|
|
2421
|
+
generationCount: 0,
|
|
2422
|
+
lastGeneration: void 0,
|
|
2423
|
+
patches: [],
|
|
2424
|
+
unresolvedCount: 0,
|
|
2425
|
+
excludePatterns: []
|
|
2426
|
+
};
|
|
2257
2427
|
}
|
|
2258
2428
|
const lock = lockManager.read();
|
|
2259
2429
|
const patches = lock.patches.map((patch) => ({
|
|
2260
|
-
|
|
2261
|
-
|
|
2430
|
+
id: patch.id,
|
|
2431
|
+
type: patch.patch_content.includes("new file mode") ? "added" : "modified",
|
|
2262
2432
|
message: patch.original_message,
|
|
2263
|
-
|
|
2433
|
+
author: patch.original_author.split("<")[0]?.trim() || "unknown",
|
|
2434
|
+
sha: patch.original_commit.slice(0, 7),
|
|
2435
|
+
files: patch.files,
|
|
2436
|
+
fileCount: patch.files.length,
|
|
2437
|
+
...patch.status ? { status: patch.status } : {}
|
|
2264
2438
|
}));
|
|
2439
|
+
const unresolvedCount = lock.patches.filter(
|
|
2440
|
+
(p) => p.status === "unresolved" || p.status === "resolving"
|
|
2441
|
+
).length;
|
|
2265
2442
|
let lastGeneration;
|
|
2266
2443
|
const lastGen = lock.generations.find((g) => g.commit_sha === lock.current_generation);
|
|
2267
2444
|
if (lastGen) {
|
|
2268
2445
|
lastGeneration = {
|
|
2269
|
-
sha: lastGen.commit_sha,
|
|
2270
|
-
timestamp: lastGen.timestamp
|
|
2446
|
+
sha: lastGen.commit_sha.slice(0, 7),
|
|
2447
|
+
timestamp: lastGen.timestamp,
|
|
2448
|
+
cliVersion: lastGen.cli_version,
|
|
2449
|
+
generatorVersions: lastGen.generator_versions
|
|
2271
2450
|
};
|
|
2272
2451
|
}
|
|
2273
|
-
|
|
2452
|
+
const config = lockManager.getCustomizationsConfig();
|
|
2453
|
+
const excludePatterns = config.exclude ?? [];
|
|
2454
|
+
return {
|
|
2455
|
+
initialized: true,
|
|
2456
|
+
generationCount: lock.generations.length,
|
|
2457
|
+
lastGeneration,
|
|
2458
|
+
patches,
|
|
2459
|
+
unresolvedCount,
|
|
2460
|
+
excludePatterns
|
|
2461
|
+
};
|
|
2274
2462
|
}
|
|
2275
2463
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2276
2464
|
0 && (module.exports = {
|