@fern-api/fern-api-dev 5.46.0 → 5.46.1
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/cli.cjs +362 -67
- package/package.json +1 -1
package/cli.cjs
CHANGED
|
@@ -422153,30 +422153,30 @@ var require_AutoVersionStep = __commonJS({
|
|
|
422153
422153
|
}
|
|
422154
422154
|
async execute(context3) {
|
|
422155
422155
|
const prepared = context3.previousStepResults.generationCommit?.preparedReplay;
|
|
422156
|
-
if (
|
|
422157
|
-
|
|
422158
|
-
|
|
422159
|
-
|
|
422160
|
-
|
|
422161
|
-
|
|
422162
|
-
|
|
422163
|
-
|
|
422164
|
-
|
|
422165
|
-
|
|
422166
|
-
|
|
422167
|
-
|
|
422168
|
-
|
|
422156
|
+
if (prepared) {
|
|
422157
|
+
if (prepared.flow === "skip-application") {
|
|
422158
|
+
this.logger.info("AutoVersionStep: replay flow is skip-application; skipping autoversion.");
|
|
422159
|
+
return { executed: true, success: true };
|
|
422160
|
+
}
|
|
422161
|
+
const language = this.config.language;
|
|
422162
|
+
const mappedMagicVersion = (0, index_1.mapMagicVersionForLanguage)(index_1.MAGIC_VERSION, language);
|
|
422163
|
+
const service = new index_1.AutoVersioningService({ logger: this.toTaskLogger() });
|
|
422164
|
+
if (prepared.previousGenerationSha == null) {
|
|
422165
|
+
return await this.handleFirstGeneration({ service, language, mappedMagicVersion, commit: true });
|
|
422166
|
+
}
|
|
422167
|
+
return await this.handleNormalFlow({
|
|
422168
|
+
prepared,
|
|
422169
|
+
service,
|
|
422170
|
+
language,
|
|
422171
|
+
mappedMagicVersion,
|
|
422172
|
+
previousGenerationSha: prepared.previousGenerationSha
|
|
422173
|
+
});
|
|
422169
422174
|
}
|
|
422170
|
-
|
|
422171
|
-
|
|
422172
|
-
service,
|
|
422173
|
-
language,
|
|
422174
|
-
mappedMagicVersion,
|
|
422175
|
-
previousGenerationSha: prepared.previousGenerationSha
|
|
422176
|
-
});
|
|
422175
|
+
this.logger.info("AutoVersionStep: running in non-replay mode (git diff HEAD).");
|
|
422176
|
+
return await this.handleNonReplayFlow();
|
|
422177
422177
|
}
|
|
422178
422178
|
async handleFirstGeneration(params2) {
|
|
422179
|
-
const { service, language, mappedMagicVersion } = params2;
|
|
422179
|
+
const { service, language, mappedMagicVersion, commit } = params2;
|
|
422180
422180
|
const initialVersion = this.config.baseVersion ?? (mappedMagicVersion.startsWith("v") ? "v0.0.1" : "0.0.1");
|
|
422181
422181
|
if (!(0, index_1.isValidSemver)(initialVersion)) {
|
|
422182
422182
|
const errorMessage = `AutoVersionStep: baseVersion ${JSON.stringify(initialVersion)} is not a valid semver string (expected e.g. "1.2.3" or "v1.2.3"). Refusing to run to avoid shell injection into the placeholder-rewrite step.`;
|
|
@@ -422193,7 +422193,7 @@ var require_AutoVersionStep = __commonJS({
|
|
|
422193
422193
|
await service.addGoMajorVersionSuffix(this.outputDir, initialVersion);
|
|
422194
422194
|
}
|
|
422195
422195
|
const commitMessage = this.brandMessage("Initial SDK generation");
|
|
422196
|
-
const commitSha = this.commitAutoversion(commitMessage);
|
|
422196
|
+
const commitSha = commit ? this.commitAutoversion(commitMessage) : void 0;
|
|
422197
422197
|
return {
|
|
422198
422198
|
executed: true,
|
|
422199
422199
|
success: true,
|
|
@@ -422212,7 +422212,7 @@ var require_AutoVersionStep = __commonJS({
|
|
|
422212
422212
|
baseVersion: this.config.baseVersion
|
|
422213
422213
|
});
|
|
422214
422214
|
if (previousVersion == null) {
|
|
422215
|
-
return await this.handleFirstGeneration({ service, language, mappedMagicVersion });
|
|
422215
|
+
return await this.handleFirstGeneration({ service, language, mappedMagicVersion, commit: true });
|
|
422216
422216
|
}
|
|
422217
422217
|
if (rawDiff.trim().length === 0) {
|
|
422218
422218
|
this.logger.info(`AutoVersionStep: empty diff between generations; rewriting placeholder to ${previousVersion}.`);
|
|
@@ -422283,6 +422283,94 @@ var require_AutoVersionStep = __commonJS({
|
|
|
422283
422283
|
analysis
|
|
422284
422284
|
});
|
|
422285
422285
|
}
|
|
422286
|
+
/**
|
|
422287
|
+
* Non-replay autoversion: diffs HEAD (committed SDK) vs the working tree
|
|
422288
|
+
* (freshly generated files). Does NOT commit — GithubStep will commit all
|
|
422289
|
+
* changes (including the rewritten placeholder) in a single generation commit.
|
|
422290
|
+
*/
|
|
422291
|
+
async handleNonReplayFlow() {
|
|
422292
|
+
const language = this.config.language;
|
|
422293
|
+
const mappedMagicVersion = (0, index_1.mapMagicVersionForLanguage)(index_1.MAGIC_VERSION, language);
|
|
422294
|
+
const service = new index_1.AutoVersioningService({ logger: this.toTaskLogger() });
|
|
422295
|
+
const rawDiff = this.gitDiffHead();
|
|
422296
|
+
const previousVersion = await this.resolvePreviousVersionNonReplay({
|
|
422297
|
+
service,
|
|
422298
|
+
rawDiff,
|
|
422299
|
+
mappedMagicVersion,
|
|
422300
|
+
baseVersion: this.config.baseVersion
|
|
422301
|
+
});
|
|
422302
|
+
if (previousVersion == null) {
|
|
422303
|
+
return await this.handleFirstGeneration({ service, language, mappedMagicVersion, commit: false });
|
|
422304
|
+
}
|
|
422305
|
+
if (rawDiff.trim().length === 0) {
|
|
422306
|
+
this.logger.info(`AutoVersionStep: empty diff (non-replay); rewriting placeholder to ${previousVersion}.`);
|
|
422307
|
+
return await this.finalizeNoChangeNonReplay({
|
|
422308
|
+
service,
|
|
422309
|
+
language,
|
|
422310
|
+
mappedMagicVersion,
|
|
422311
|
+
previousVersion,
|
|
422312
|
+
reason: "no diff between generations"
|
|
422313
|
+
});
|
|
422314
|
+
}
|
|
422315
|
+
const cleanedDiff = service.cleanDiffForAI(rawDiff, mappedMagicVersion);
|
|
422316
|
+
const rawBytes = Buffer.byteLength(rawDiff, "utf-8");
|
|
422317
|
+
const cleanedBytes = Buffer.byteLength(cleanedDiff, "utf-8");
|
|
422318
|
+
this.logger.debug(`AutoVersionStep (non-replay): raw=${(0, index_1.formatSizeKB)(rawBytes)}KB (${(0, index_1.countFilesInDiff)(rawDiff)} files), cleaned=${(0, index_1.formatSizeKB)(cleanedBytes)}KB (${(0, index_1.countFilesInDiff)(cleanedDiff)} files)`);
|
|
422319
|
+
if (cleanedDiff.trim().length === 0) {
|
|
422320
|
+
this.logger.info(`AutoVersionStep: cleaned diff empty (non-replay); rewriting placeholder to ${previousVersion}.`);
|
|
422321
|
+
return await this.finalizeNoChangeNonReplay({
|
|
422322
|
+
service,
|
|
422323
|
+
language,
|
|
422324
|
+
mappedMagicVersion,
|
|
422325
|
+
previousVersion,
|
|
422326
|
+
reason: "no semantic changes"
|
|
422327
|
+
});
|
|
422328
|
+
}
|
|
422329
|
+
if (cleanedBytes > index_1.MAX_RAW_DIFF_BYTES) {
|
|
422330
|
+
this.logger.warn(`AutoVersionStep (non-replay): diff too large (${(0, index_1.formatSizeKB)(cleanedBytes)}KB). Falling back to PATCH.`);
|
|
422331
|
+
return await this.finalizeWithBumpNonReplay({
|
|
422332
|
+
service,
|
|
422333
|
+
language,
|
|
422334
|
+
mappedMagicVersion,
|
|
422335
|
+
previousVersion,
|
|
422336
|
+
analysis: { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") }
|
|
422337
|
+
});
|
|
422338
|
+
}
|
|
422339
|
+
let analysis;
|
|
422340
|
+
try {
|
|
422341
|
+
if (this.config.ai == null && this.config.fernToken != null) {
|
|
422342
|
+
analysis = await this.analyzeViaFaiService(cleanedDiff, language, previousVersion);
|
|
422343
|
+
} else {
|
|
422344
|
+
const chunks = service.chunkDiff(cleanedDiff, index_1.MAX_AI_DIFF_BYTES);
|
|
422345
|
+
const cappedChunks = chunks.slice(0, index_1.MAX_CHUNKS);
|
|
422346
|
+
const skippedChunks = chunks.length - cappedChunks.length;
|
|
422347
|
+
if (chunks.length > 1) {
|
|
422348
|
+
this.logger.info(`AutoVersionStep (non-replay): split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${index_1.MAX_CHUNKS}, skipping ${skippedChunks})` : ""));
|
|
422349
|
+
}
|
|
422350
|
+
analysis = cappedChunks.length <= 1 ? await this.analyzeSingle(cleanedDiff, language, previousVersion) : await this.analyzeChunks(cappedChunks, language, previousVersion);
|
|
422351
|
+
}
|
|
422352
|
+
} catch (error50) {
|
|
422353
|
+
this.logger.warn(`AutoVersionStep (non-replay): FAI analysis failed (${String(error50)}); falling back to PATCH bump.`);
|
|
422354
|
+
analysis = { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
|
|
422355
|
+
}
|
|
422356
|
+
if (analysis == null) {
|
|
422357
|
+
this.logger.info(`AutoVersionStep (non-replay): FAI returned NO_CHANGE; rewriting placeholder to ${previousVersion}.`);
|
|
422358
|
+
return await this.finalizeNoChangeNonReplay({
|
|
422359
|
+
service,
|
|
422360
|
+
language,
|
|
422361
|
+
mappedMagicVersion,
|
|
422362
|
+
previousVersion,
|
|
422363
|
+
reason: "FAI returned NO_CHANGE"
|
|
422364
|
+
});
|
|
422365
|
+
}
|
|
422366
|
+
return await this.finalizeWithBumpNonReplay({
|
|
422367
|
+
service,
|
|
422368
|
+
language,
|
|
422369
|
+
mappedMagicVersion,
|
|
422370
|
+
previousVersion,
|
|
422371
|
+
analysis
|
|
422372
|
+
});
|
|
422373
|
+
}
|
|
422286
422374
|
/**
|
|
422287
422375
|
* Terminal path for runs that determine no semver bump is needed. The
|
|
422288
422376
|
* current working tree still contains `0.0.0-fern-placeholder` from this
|
|
@@ -422340,6 +422428,94 @@ var require_AutoVersionStep = __commonJS({
|
|
|
422340
422428
|
commitSha
|
|
422341
422429
|
};
|
|
422342
422430
|
}
|
|
422431
|
+
/**
|
|
422432
|
+
* Non-replay variant of finalizeNoChange. Rewrites the placeholder to
|
|
422433
|
+
* `previousVersion` but does NOT commit — GithubStep handles the commit.
|
|
422434
|
+
*/
|
|
422435
|
+
async finalizeNoChangeNonReplay(params2) {
|
|
422436
|
+
const { service, language, mappedMagicVersion, previousVersion, reason } = params2;
|
|
422437
|
+
if (!(0, index_1.isValidSemver)(previousVersion)) {
|
|
422438
|
+
const errorMessage = `AutoVersionStep: resolved previousVersion ${JSON.stringify(previousVersion)} is not a valid semver string. Refusing to rewrite placeholder to avoid shell injection.`;
|
|
422439
|
+
this.logger.error(errorMessage);
|
|
422440
|
+
return { executed: true, success: false, errorMessage };
|
|
422441
|
+
}
|
|
422442
|
+
await service.replaceMagicVersion(this.outputDir, mappedMagicVersion, previousVersion);
|
|
422443
|
+
if (language === "go") {
|
|
422444
|
+
await service.addGoMajorVersionSuffix(this.outputDir, previousVersion);
|
|
422445
|
+
}
|
|
422446
|
+
const commitMessage = this.brandMessage(`SDK regeneration (no semver change: ${reason})`);
|
|
422447
|
+
return {
|
|
422448
|
+
executed: true,
|
|
422449
|
+
success: true,
|
|
422450
|
+
version: previousVersion,
|
|
422451
|
+
previousVersion,
|
|
422452
|
+
versionBump: "NO_CHANGE",
|
|
422453
|
+
commitMessage
|
|
422454
|
+
};
|
|
422455
|
+
}
|
|
422456
|
+
/**
|
|
422457
|
+
* Non-replay variant of finalizeWithBump. Rewrites the placeholder to
|
|
422458
|
+
* the bumped version but does NOT commit — GithubStep handles the commit.
|
|
422459
|
+
*/
|
|
422460
|
+
async finalizeWithBumpNonReplay(params2) {
|
|
422461
|
+
const { service, language, mappedMagicVersion, previousVersion, analysis } = params2;
|
|
422462
|
+
const newVersion = (0, index_1.incrementVersion)(previousVersion, analysis.versionBump);
|
|
422463
|
+
this.logger.info(`AutoVersionStep (non-replay): ${analysis.versionBump} bump: ${previousVersion} \u2192 ${newVersion}`);
|
|
422464
|
+
await service.replaceMagicVersion(this.outputDir, mappedMagicVersion, newVersion);
|
|
422465
|
+
if (language === "go") {
|
|
422466
|
+
await service.addGoMajorVersionSuffix(this.outputDir, newVersion);
|
|
422467
|
+
}
|
|
422468
|
+
if (analysis.changelogEntry && analysis.changelogEntry.trim().length > 0) {
|
|
422469
|
+
await this.prependChangelogEntry({ version: newVersion, entry: analysis.changelogEntry });
|
|
422470
|
+
}
|
|
422471
|
+
return {
|
|
422472
|
+
executed: true,
|
|
422473
|
+
success: true,
|
|
422474
|
+
version: newVersion,
|
|
422475
|
+
commitMessage: analysis.message,
|
|
422476
|
+
changelogEntry: analysis.changelogEntry,
|
|
422477
|
+
previousVersion,
|
|
422478
|
+
versionBump: analysis.versionBump,
|
|
422479
|
+
prDescription: analysis.prDescription,
|
|
422480
|
+
versionBumpReason: analysis.versionBumpReason
|
|
422481
|
+
};
|
|
422482
|
+
}
|
|
422483
|
+
/**
|
|
422484
|
+
* Resolves the previous version for non-replay mode. Reads HEAD:.fern/metadata.json
|
|
422485
|
+
* (not HEAD~1, since no generation commit exists yet) as the primary fallback.
|
|
422486
|
+
*/
|
|
422487
|
+
async resolvePreviousVersionNonReplay(params2) {
|
|
422488
|
+
const { service, rawDiff, mappedMagicVersion, baseVersion } = params2;
|
|
422489
|
+
if (baseVersion != null && (0, index_1.isValidSemver)(baseVersion)) {
|
|
422490
|
+
this.logger.debug(`AutoVersionStep (non-replay): previous version from pipeline baseVersion: ${baseVersion}`);
|
|
422491
|
+
return this.normalizeVersionPrefix(baseVersion, mappedMagicVersion);
|
|
422492
|
+
}
|
|
422493
|
+
try {
|
|
422494
|
+
const extracted = service.extractPreviousVersion(rawDiff, mappedMagicVersion);
|
|
422495
|
+
if (extracted != null) {
|
|
422496
|
+
this.logger.debug(`AutoVersionStep (non-replay): previous version from diff: ${extracted}`);
|
|
422497
|
+
return extracted;
|
|
422498
|
+
}
|
|
422499
|
+
} catch (error50) {
|
|
422500
|
+
if (!(error50 instanceof index_1.AutoVersioningException) || !error50.magicVersionAbsent) {
|
|
422501
|
+
throw error50;
|
|
422502
|
+
}
|
|
422503
|
+
this.logger.info("AutoVersionStep (non-replay): magic version not in diff; trying metadata + git tags.");
|
|
422504
|
+
}
|
|
422505
|
+
const metadataVersion = this.readVersionFromMetadataAtHead();
|
|
422506
|
+
if (metadataVersion != null) {
|
|
422507
|
+
return this.normalizeVersionPrefix(metadataVersion, mappedMagicVersion);
|
|
422508
|
+
}
|
|
422509
|
+
try {
|
|
422510
|
+
const tagVersion = await service.getLatestVersionFromGitTags(this.outputDir);
|
|
422511
|
+
if (tagVersion != null) {
|
|
422512
|
+
return this.normalizeVersionPrefix(tagVersion, mappedMagicVersion);
|
|
422513
|
+
}
|
|
422514
|
+
} catch (error50) {
|
|
422515
|
+
this.logger.debug(`AutoVersionStep (non-replay): git-tags fallback failed (${String(error50)}); ignoring.`);
|
|
422516
|
+
}
|
|
422517
|
+
return null;
|
|
422518
|
+
}
|
|
422343
422519
|
async resolvePreviousVersion(params2) {
|
|
422344
422520
|
const { service, rawDiff, mappedMagicVersion, baseVersion } = params2;
|
|
422345
422521
|
if (baseVersion != null && (0, index_1.isValidSemver)(baseVersion)) {
|
|
@@ -422389,6 +422565,42 @@ var require_AutoVersionStep = __commonJS({
|
|
|
422389
422565
|
const stripped = version7.startsWith("v") ? version7.slice(1) : version7;
|
|
422390
422566
|
return mappedMagicVersion.startsWith("v") ? `v${stripped}` : stripped;
|
|
422391
422567
|
}
|
|
422568
|
+
/**
|
|
422569
|
+
* Reads the sdkVersion from the committed (HEAD) .fern/metadata.json.
|
|
422570
|
+
* Used by the non-replay path where no generation commit exists yet,
|
|
422571
|
+
* so HEAD is the unmodified SDK repository.
|
|
422572
|
+
*/
|
|
422573
|
+
readVersionFromMetadataAtHead() {
|
|
422574
|
+
try {
|
|
422575
|
+
const output2 = (0, child_process_1.execFileSync)("git", ["show", "HEAD:.fern/metadata.json"], {
|
|
422576
|
+
cwd: this.outputDir,
|
|
422577
|
+
encoding: "utf-8",
|
|
422578
|
+
stdio: "pipe"
|
|
422579
|
+
});
|
|
422580
|
+
const parsed = JSON.parse(output2);
|
|
422581
|
+
return parsed.sdkVersion ?? void 0;
|
|
422582
|
+
} catch (error50) {
|
|
422583
|
+
this.logger.debug(`AutoVersionStep: failed to read HEAD:.fern/metadata.json (${String(error50)})`);
|
|
422584
|
+
return void 0;
|
|
422585
|
+
}
|
|
422586
|
+
}
|
|
422587
|
+
/**
|
|
422588
|
+
* Computes a diff between HEAD (committed SDK) and the working tree (new
|
|
422589
|
+
* generation). Marks untracked files as intent-to-add so they appear in
|
|
422590
|
+
* the diff, matching LocalTaskHandler.generateDiffFile() behavior.
|
|
422591
|
+
*/
|
|
422592
|
+
gitDiffHead() {
|
|
422593
|
+
(0, child_process_1.execFileSync)("git", ["add", "-N", "."], {
|
|
422594
|
+
cwd: this.outputDir,
|
|
422595
|
+
stdio: "pipe"
|
|
422596
|
+
});
|
|
422597
|
+
return (0, child_process_1.execFileSync)("git", ["diff", "HEAD", "--", ".", ":(exclude).fern/metadata.json"], {
|
|
422598
|
+
cwd: this.outputDir,
|
|
422599
|
+
encoding: "utf-8",
|
|
422600
|
+
stdio: "pipe",
|
|
422601
|
+
maxBuffer: 256 * 1024 * 1024
|
|
422602
|
+
});
|
|
422603
|
+
}
|
|
422392
422604
|
gitDiff(from4, to10) {
|
|
422393
422605
|
return (0, child_process_1.execFileSync)("git", ["diff", from4, to10, "--", ".", ":(exclude).fern/metadata.json"], {
|
|
422394
422606
|
cwd: this.outputDir,
|
|
@@ -428120,9 +428332,9 @@ var require_diff3 = __commonJS({
|
|
|
428120
428332
|
}
|
|
428121
428333
|
});
|
|
428122
428334
|
|
|
428123
|
-
// ../../../node_modules/.pnpm/@fern-api+replay@0.
|
|
428335
|
+
// ../../../node_modules/.pnpm/@fern-api+replay@0.18.0/node_modules/@fern-api/replay/dist/index.cjs
|
|
428124
428336
|
var require_dist24 = __commonJS({
|
|
428125
|
-
"../../../node_modules/.pnpm/@fern-api+replay@0.
|
|
428337
|
+
"../../../node_modules/.pnpm/@fern-api+replay@0.18.0/node_modules/@fern-api/replay/dist/index.cjs"(exports2, module4) {
|
|
428126
428338
|
"use strict";
|
|
428127
428339
|
var __defProp4 = Object.defineProperty;
|
|
428128
428340
|
var __getOwnPropDesc3 = Object.getOwnPropertyDescriptor;
|
|
@@ -428176,6 +428388,11 @@ var require_dist24 = __commonJS({
|
|
|
428176
428388
|
proc2.stderr.on("data", (data2) => {
|
|
428177
428389
|
stderr += data2.toString();
|
|
428178
428390
|
});
|
|
428391
|
+
proc2.on("error", (err) => {
|
|
428392
|
+
reject(new Error(`git ${args.join(" ")} failed to spawn: ${err.message}`));
|
|
428393
|
+
});
|
|
428394
|
+
proc2.stdin.on("error", () => {
|
|
428395
|
+
});
|
|
428179
428396
|
proc2.on("close", (code5) => {
|
|
428180
428397
|
if (code5 === 0) {
|
|
428181
428398
|
resolve22(stdout);
|
|
@@ -428959,7 +429176,8 @@ var require_dist24 = __commonJS({
|
|
|
428959
429176
|
var INFRASTRUCTURE_FILES = /* @__PURE__ */ new Set([".fernignore"]);
|
|
428960
429177
|
function matchesFernignorePattern(filePath, patterns) {
|
|
428961
429178
|
if (patterns.length === 0) return false;
|
|
428962
|
-
return patterns.some((
|
|
429179
|
+
return patterns.some((rawPattern) => {
|
|
429180
|
+
const p14 = rawPattern.endsWith("/") ? rawPattern.slice(0, -1) : rawPattern;
|
|
428963
429181
|
if (filePath === p14) return true;
|
|
428964
429182
|
if ((0, import_minimatch22.minimatch)(filePath, p14)) return true;
|
|
428965
429183
|
if (!p14.includes("*") && !p14.includes("?") && filePath.startsWith(p14 + "/")) return true;
|
|
@@ -429059,6 +429277,22 @@ var require_dist24 = __commonJS({
|
|
|
429059
429277
|
return commit.sha;
|
|
429060
429278
|
}
|
|
429061
429279
|
}
|
|
429280
|
+
let fullLog;
|
|
429281
|
+
try {
|
|
429282
|
+
fullLog = await this.git.exec([
|
|
429283
|
+
"log",
|
|
429284
|
+
"--no-merges",
|
|
429285
|
+
"--format=%H%x00%an%x00%ae%x00%s",
|
|
429286
|
+
"HEAD"
|
|
429287
|
+
]);
|
|
429288
|
+
} catch {
|
|
429289
|
+
return null;
|
|
429290
|
+
}
|
|
429291
|
+
for (const commit of this.parseGitLog(fullLog)) {
|
|
429292
|
+
if (isGenerationBoundary(commit)) {
|
|
429293
|
+
return commit.sha;
|
|
429294
|
+
}
|
|
429295
|
+
}
|
|
429062
429296
|
return null;
|
|
429063
429297
|
}
|
|
429064
429298
|
async detectNewPatches() {
|
|
@@ -429070,6 +429304,11 @@ var require_dist24 = __commonJS({
|
|
|
429070
429304
|
}
|
|
429071
429305
|
const lastGen = this.getLastGeneration(lock);
|
|
429072
429306
|
if (!lastGen) {
|
|
429307
|
+
if (lock.current_generation) {
|
|
429308
|
+
this.warnings.push(
|
|
429309
|
+
`No generation boundary found in git history and the lockfile's recorded generation (${lock.current_generation.slice(0, 7)}) matches no entry in its generation records. Customer customizations may differ from the last known generation and could be lost on the next regeneration. Run \`fern-replay bootstrap --force\` to re-initialize tracking.`
|
|
429310
|
+
);
|
|
429311
|
+
}
|
|
429073
429312
|
return { patches: [], revertedPatchIds: [] };
|
|
429074
429313
|
}
|
|
429075
429314
|
const exists2 = await this.git.commitExists(lastGen.commit_sha);
|
|
@@ -429117,20 +429356,15 @@ var require_dist24 = __commonJS({
|
|
|
429117
429356
|
continue;
|
|
429118
429357
|
}
|
|
429119
429358
|
const parents = await this.git.getCommitParents(commit.sha);
|
|
429120
|
-
let
|
|
429359
|
+
let filesOutput;
|
|
429121
429360
|
try {
|
|
429122
|
-
|
|
429361
|
+
filesOutput = await this.git.exec(["diff-tree", "--no-commit-id", "--name-only", "-r", commit.sha]);
|
|
429123
429362
|
} catch {
|
|
429124
429363
|
this.warnings.push(
|
|
429125
429364
|
`Could not generate patch for commit ${commit.sha.slice(0, 7)} \u2014 it may be unreachable in a shallow clone. Skipping.`
|
|
429126
429365
|
);
|
|
429127
429366
|
continue;
|
|
429128
429367
|
}
|
|
429129
|
-
let contentHash = this.computeContentHash(patchContent);
|
|
429130
|
-
if (lock.patches.find((p14) => p14.content_hash === contentHash) || forgottenHashes.has(contentHash)) {
|
|
429131
|
-
continue;
|
|
429132
|
-
}
|
|
429133
|
-
const filesOutput = await this.git.exec(["diff-tree", "--no-commit-id", "--name-only", "-r", commit.sha]);
|
|
429134
429368
|
const { files, sensitiveFiles, fernignoredFiles } = filterInfrastructureAndSensitiveFiles(
|
|
429135
429369
|
filesOutput,
|
|
429136
429370
|
this.fernignorePatterns
|
|
@@ -429145,19 +429379,31 @@ var require_dist24 = __commonJS({
|
|
|
429145
429379
|
`.fernignore-protected file(s) excluded from patch for commit ${commit.sha.slice(0, 7)}: ${fernignoredFiles.join(", ")}. These files are managed by .fernignore, not Replay.`
|
|
429146
429380
|
);
|
|
429147
429381
|
}
|
|
429148
|
-
if (
|
|
429149
|
-
|
|
429150
|
-
|
|
429151
|
-
|
|
429152
|
-
|
|
429153
|
-
|
|
429154
|
-
|
|
429155
|
-
|
|
429156
|
-
|
|
429157
|
-
|
|
429382
|
+
if (files.length === 0) {
|
|
429383
|
+
continue;
|
|
429384
|
+
}
|
|
429385
|
+
const wasFiltered = sensitiveFiles.length > 0 || fernignoredFiles.length > 0;
|
|
429386
|
+
const parentSha = parents[0];
|
|
429387
|
+
let patchContent;
|
|
429388
|
+
if (wasFiltered && parentSha) {
|
|
429389
|
+
try {
|
|
429390
|
+
patchContent = await this.git.exec(["diff", parentSha, commit.sha, "--", ...files]);
|
|
429391
|
+
} catch {
|
|
429392
|
+
continue;
|
|
429393
|
+
}
|
|
429394
|
+
if (!patchContent.trim()) continue;
|
|
429395
|
+
} else {
|
|
429396
|
+
try {
|
|
429397
|
+
patchContent = await this.git.formatPatch(commit.sha);
|
|
429398
|
+
} catch {
|
|
429399
|
+
this.warnings.push(
|
|
429400
|
+
`Could not generate patch for commit ${commit.sha.slice(0, 7)} \u2014 it may be unreachable in a shallow clone. Skipping.`
|
|
429401
|
+
);
|
|
429402
|
+
continue;
|
|
429158
429403
|
}
|
|
429159
429404
|
}
|
|
429160
|
-
|
|
429405
|
+
const contentHash = this.computeContentHash(patchContent);
|
|
429406
|
+
if (lock.patches.find((p14) => p14.content_hash === contentHash) || forgottenHashes.has(contentHash)) {
|
|
429161
429407
|
continue;
|
|
429162
429408
|
}
|
|
429163
429409
|
const theirsSnapshot = await capturePatchSnapshot(this.git, files, commit.sha);
|
|
@@ -429816,16 +430062,20 @@ var require_dist24 = __commonJS({
|
|
|
429816
430062
|
const oursPath = (0, import_node_path310.join)(outputDir, resolvedPath);
|
|
429817
430063
|
const ours = await (0, import_promises208.readFile)(oursPath, "utf-8").catch(() => null);
|
|
429818
430064
|
let ghostTheirs = null;
|
|
429819
|
-
|
|
430065
|
+
let baseTreeUnreachable = false;
|
|
430066
|
+
if (!base4 && !renameSourcePath) {
|
|
429820
430067
|
const treeReachable = await isTreeReachable(baseGen.tree_hash);
|
|
429821
430068
|
if (!treeReachable) {
|
|
429822
|
-
|
|
429823
|
-
if (
|
|
429824
|
-
const
|
|
429825
|
-
|
|
429826
|
-
|
|
429827
|
-
|
|
429828
|
-
|
|
430069
|
+
baseTreeUnreachable = true;
|
|
430070
|
+
if (ours) {
|
|
430071
|
+
const fileDiff = extractFileDiff2(patch5.patch_content, filePath);
|
|
430072
|
+
if (fileDiff) {
|
|
430073
|
+
const { reconstructFromGhostPatch: reconstructFromGhostPatch2 } = await Promise.resolve().then(() => (init_HybridReconstruction(), HybridReconstruction_exports));
|
|
430074
|
+
const result = reconstructFromGhostPatch2(fileDiff, ours);
|
|
430075
|
+
if (result) {
|
|
430076
|
+
base4 = result.base;
|
|
430077
|
+
ghostTheirs = result.theirs;
|
|
430078
|
+
}
|
|
429829
430079
|
}
|
|
429830
430080
|
}
|
|
429831
430081
|
}
|
|
@@ -429837,7 +430087,11 @@ var require_dist24 = __commonJS({
|
|
|
429837
430087
|
ours,
|
|
429838
430088
|
oursPath,
|
|
429839
430089
|
renameSourcePath,
|
|
429840
|
-
ghostTheirs
|
|
430090
|
+
ghostTheirs,
|
|
430091
|
+
// Only meaningful when ghost reconstruction did NOT recover a base; if it
|
|
430092
|
+
// did, `base` is non-null and the merge proceeds normally. We still set
|
|
430093
|
+
// the flag truthfully (the tree IS unreachable) so Phase 3 can decide.
|
|
430094
|
+
baseTreeUnreachable
|
|
429841
430095
|
};
|
|
429842
430096
|
}
|
|
429843
430097
|
var CONFLICT_OPENER = "<<<<<<< Generated";
|
|
@@ -430016,7 +430270,11 @@ var require_dist24 = __commonJS({
|
|
|
430016
430270
|
return { kind: "new-file-only-user", theirs: effective_theirs };
|
|
430017
430271
|
}
|
|
430018
430272
|
if (base4 == null && ours != null && effective_theirs != null && !useAccumulatorAsMergeBase) {
|
|
430019
|
-
return {
|
|
430273
|
+
return {
|
|
430274
|
+
kind: "new-file-both",
|
|
430275
|
+
theirs: effective_theirs,
|
|
430276
|
+
...inputs.baseTreeUnreachable ? { baseTreeUnreachable: true } : {}
|
|
430277
|
+
};
|
|
430020
430278
|
}
|
|
430021
430279
|
if (effective_theirs == null) {
|
|
430022
430280
|
return { kind: "skipped", reason: "missing-content" };
|
|
@@ -430062,17 +430320,19 @@ var require_dist24 = __commonJS({
|
|
|
430062
430320
|
const merged2 = threeWayMerge("", ours, plan.theirs);
|
|
430063
430321
|
await (0, import_promises210.mkdir)((0, import_node_path44.dirname)(oursPath), { recursive: true });
|
|
430064
430322
|
await (0, import_promises210.writeFile)(oursPath, merged2.content);
|
|
430323
|
+
const unreachableFlag = plan.baseTreeUnreachable ? { baseTreeUnreachable: true } : {};
|
|
430065
430324
|
if (merged2.hasConflicts) {
|
|
430066
430325
|
return {
|
|
430067
430326
|
file: resolvedPath,
|
|
430068
430327
|
status: "conflict",
|
|
430069
430328
|
conflicts: merged2.conflicts,
|
|
430070
430329
|
conflictReason: "new-file-both",
|
|
430071
|
-
conflictMetadata: metadata
|
|
430330
|
+
conflictMetadata: metadata,
|
|
430331
|
+
...unreachableFlag
|
|
430072
430332
|
};
|
|
430073
430333
|
}
|
|
430074
430334
|
accumulator.recordMerge(resolvedPath, merged2.content, patch5.base_generation);
|
|
430075
|
-
return { file: resolvedPath, status: "merged" };
|
|
430335
|
+
return { file: resolvedPath, status: "merged", ...unreachableFlag };
|
|
430076
430336
|
}
|
|
430077
430337
|
const merged = threeWayMerge(plan.mergeBase, ours, plan.theirs);
|
|
430078
430338
|
await (0, import_promises210.mkdir)((0, import_node_path44.dirname)(oursPath), { recursive: true });
|
|
@@ -431272,6 +431532,7 @@ Patches absorbed by generator (${buckets.absorbed.length}):`;
|
|
|
431272
431532
|
results = await this.service.applicator.applyPatches(newPatches);
|
|
431273
431533
|
this.service._lastApplyResults = results;
|
|
431274
431534
|
this.service.recordDroppedContextLineWarnings(results);
|
|
431535
|
+
this.service.recordUnreachableBaseWarnings(results);
|
|
431275
431536
|
this.service.revertConflictingFiles(results);
|
|
431276
431537
|
for (const result of results) {
|
|
431277
431538
|
if (result.status === "conflict") {
|
|
@@ -431425,6 +431686,7 @@ Patches absorbed by generator (${buckets.absorbed.length}):`;
|
|
|
431425
431686
|
const results = await this.service.applicator.applyPatches(allPatches);
|
|
431426
431687
|
this.service._lastApplyResults = results;
|
|
431427
431688
|
this.service.recordDroppedContextLineWarnings(results);
|
|
431689
|
+
this.service.recordUnreachableBaseWarnings(results);
|
|
431428
431690
|
this.service.revertConflictingFiles(results);
|
|
431429
431691
|
for (const result of results) {
|
|
431430
431692
|
if (result.status === "conflict") {
|
|
@@ -432342,6 +432604,37 @@ If you want to keep these lines, restore them in a follow-up commit and re-run r
|
|
|
432342
432604
|
}
|
|
432343
432605
|
}
|
|
432344
432606
|
}
|
|
432607
|
+
/**
|
|
432608
|
+
* After applyPatches(), surface a warning for each (patch × file) where a
|
|
432609
|
+
* customization's BASE could not be read because the patch's
|
|
432610
|
+
* base-generation tree is unreachable in this clone (shallow-clone window
|
|
432611
|
+
* too small / pruned history). In that state the merge pipeline falls
|
|
432612
|
+
* through to `new-file-both` and the customer's edit can be dropped with NO
|
|
432613
|
+
* conflict and NO error — the INC-866 silent-loss class. This converts that
|
|
432614
|
+
* silence into an explicit, actionable warning naming the file and the
|
|
432615
|
+
* likely cause (insufficient clone window).
|
|
432616
|
+
*
|
|
432617
|
+
* Mirrors `recordDroppedContextLineWarnings`'s "surface, never silently
|
|
432618
|
+
* drop" contract. De-duplicated per file path so a single insufficient
|
|
432619
|
+
* window doesn't spam one warning per touched file repeatedly.
|
|
432620
|
+
*/
|
|
432621
|
+
/** @internal Used by Flow implementations in `src/flows/`. */
|
|
432622
|
+
recordUnreachableBaseWarnings(results) {
|
|
432623
|
+
const warned2 = /* @__PURE__ */ new Set();
|
|
432624
|
+
for (const result of results) {
|
|
432625
|
+
if (!result.fileResults) continue;
|
|
432626
|
+
for (const fr9 of result.fileResults) {
|
|
432627
|
+
if (!fr9.baseTreeUnreachable) continue;
|
|
432628
|
+
if (warned2.has(fr9.file)) continue;
|
|
432629
|
+
warned2.add(fr9.file);
|
|
432630
|
+
const base4 = fr9.conflictMetadata?.baseGeneration;
|
|
432631
|
+
const baseRef = base4 ? ` (base generation ${base4.slice(0, 7)})` : "";
|
|
432632
|
+
this.warnings.push(
|
|
432633
|
+
`${fr9.file}: could not read the prior generation's version of this file${baseRef} because that generation's tree is outside the clone window (insufficient shallow-clone depth or pruned history). The customization was treated as a new file, which can drop your edits silently. Re-run with the prior generation in the clone window \u2014 e.g. \`git fetch --shallow-since=<date just before the prior [fern-generated] commit>\` or \`git fetch --unshallow\` \u2014 then re-run replay.`
|
|
432634
|
+
);
|
|
432635
|
+
}
|
|
432636
|
+
}
|
|
432637
|
+
}
|
|
432345
432638
|
/**
|
|
432346
432639
|
* After applyPatches(), strip conflict markers from conflicting files
|
|
432347
432640
|
* so only clean content is committed. Keeps the Generated (OURS) side.
|
|
@@ -438844,10 +439137,6 @@ var require_PostGenerationPipeline = __commonJS({
|
|
|
438844
439137
|
this.logger.warn(`Replay is not supported with GitHub ${config5.github.mode} mode. Disabling replay to prevent push to base branch.`);
|
|
438845
439138
|
replayEnabled = false;
|
|
438846
439139
|
}
|
|
438847
|
-
if (autoVersionEnabled && !replayEnabled) {
|
|
438848
|
-
this.logger.warn("AutoVersion requires Replay to be enabled. Disabling AutoVersion for this run.");
|
|
438849
|
-
autoVersionEnabled = false;
|
|
438850
|
-
}
|
|
438851
439140
|
if (replayEnabled && config5.replay != null) {
|
|
438852
439141
|
this.steps.push(new GenerationCommitStep_1.GenerationCommitStep(config5.outputDir, this.logger, { enabled: true, skipApplication: config5.replay.skipApplication }, config5.cliVersion, config5.generatorVersions));
|
|
438853
439142
|
}
|
|
@@ -669270,7 +669559,7 @@ var AccessTokenPosthogManager = class {
|
|
|
669270
669559
|
properties: {
|
|
669271
669560
|
...event,
|
|
669272
669561
|
...event.properties,
|
|
669273
|
-
version: "5.46.
|
|
669562
|
+
version: "5.46.1",
|
|
669274
669563
|
usingAccessToken: true,
|
|
669275
669564
|
...getRunIdProperties()
|
|
669276
669565
|
}
|
|
@@ -669334,7 +669623,7 @@ var UserPosthogManager = class {
|
|
|
669334
669623
|
distinctId: this.userId ?? await this.getPersistedDistinctId(),
|
|
669335
669624
|
event: "CLI",
|
|
669336
669625
|
properties: {
|
|
669337
|
-
version: "5.46.
|
|
669626
|
+
version: "5.46.1",
|
|
669338
669627
|
...event,
|
|
669339
669628
|
...event.properties,
|
|
669340
669629
|
usingAccessToken: false,
|
|
@@ -861072,7 +861361,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
|
|
|
861072
861361
|
var LOGS_FOLDER_NAME = "logs";
|
|
861073
861362
|
var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
|
|
861074
861363
|
function getCliSource() {
|
|
861075
|
-
const version7 = "5.46.
|
|
861364
|
+
const version7 = "5.46.1";
|
|
861076
861365
|
return `cli@${version7}`;
|
|
861077
861366
|
}
|
|
861078
861367
|
var DebugLogger = class {
|
|
@@ -892164,7 +892453,7 @@ var LegacyDocsPublisher = class {
|
|
|
892164
892453
|
previewId,
|
|
892165
892454
|
disableTemplates: void 0,
|
|
892166
892455
|
skipUpload,
|
|
892167
|
-
cliVersion: "5.46.
|
|
892456
|
+
cliVersion: "5.46.1",
|
|
892168
892457
|
loginCommand: "fern auth login"
|
|
892169
892458
|
});
|
|
892170
892459
|
if (taskContext.getResult() === TaskResult.Failure) {
|
|
@@ -916378,6 +916667,11 @@ var DynamicTypeInstantiationMapper = class {
|
|
|
916378
916667
|
writer2.writeNode(collectionLiteral);
|
|
916379
916668
|
}));
|
|
916380
916669
|
}
|
|
916670
|
+
// Materializes a literal value (e.g. a literal path parameter), as opposed to
|
|
916671
|
+
// convert(), which treats literals as a no-op since they are usually omitted.
|
|
916672
|
+
convertLiteral(literal3) {
|
|
916673
|
+
return this.convertLiteralValue(literal3);
|
|
916674
|
+
}
|
|
916381
916675
|
convertLiteralValue(literal3) {
|
|
916382
916676
|
switch (literal3.type) {
|
|
916383
916677
|
case "boolean":
|
|
@@ -917749,9 +918043,10 @@ var EndpointSnippetGenerator3 = class {
|
|
|
917749
918043
|
values: snippet2.pathParameters ?? {}
|
|
917750
918044
|
});
|
|
917751
918045
|
for (const parameter6 of pathParameters) {
|
|
918046
|
+
const value2 = parameter6.typeReference.type === "literal" ? this.context.dynamicTypeInstantiationMapper.convertLiteral(parameter6.typeReference.value) : asPointer ? this.context.dynamicTypeInstantiationMapper.convertToPointerIfPossible(parameter6) : this.context.dynamicTypeInstantiationMapper.convert(parameter6);
|
|
917752
918047
|
args.push({
|
|
917753
918048
|
name: this.context.getTypeName(parameter6.name.name),
|
|
917754
|
-
value:
|
|
918049
|
+
value: value2
|
|
917755
918050
|
});
|
|
917756
918051
|
}
|
|
917757
918052
|
return args;
|
|
@@ -957348,7 +957643,7 @@ function getAutomationContextFromEnv() {
|
|
|
957348
957643
|
config_branch: process.env.FERN_CONFIG_BRANCH,
|
|
957349
957644
|
config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
|
|
957350
957645
|
trigger: process.env.GITHUB_EVENT_NAME,
|
|
957351
|
-
cli_version: "5.46.
|
|
957646
|
+
cli_version: "5.46.1"
|
|
957352
957647
|
};
|
|
957353
957648
|
}
|
|
957354
957649
|
function isAutomationMode() {
|
|
@@ -958174,7 +958469,7 @@ var CliContext = class _CliContext {
|
|
|
958174
958469
|
if (false) {
|
|
958175
958470
|
this.logger.error("CLI_VERSION is not defined");
|
|
958176
958471
|
}
|
|
958177
|
-
return "5.46.
|
|
958472
|
+
return "5.46.1";
|
|
958178
958473
|
}
|
|
958179
958474
|
getCliName() {
|
|
958180
958475
|
if (false) {
|
package/package.json
CHANGED