@fern-api/generator-cli 0.9.19 → 0.9.20

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.
Files changed (2) hide show
  1. package/dist/cli.js +43 -3
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -22028,7 +22028,7 @@ var init_diff3 = __esm({
22028
22028
  }
22029
22029
  });
22030
22030
 
22031
- // ../../node_modules/.pnpm/@fern-api+replay@0.12.0/node_modules/@fern-api/replay/dist/index.js
22031
+ // ../../node_modules/.pnpm/@fern-api+replay@0.13.0/node_modules/@fern-api/replay/dist/index.js
22032
22032
  var dist_exports = {};
22033
22033
  __export(dist_exports, {
22034
22034
  CREDENTIAL_PATTERNS: () => CREDENTIAL_PATTERNS,
@@ -23043,7 +23043,7 @@ function status(outputDir) {
23043
23043
  }
23044
23044
  var import_fs6, import_path7, import_yaml, import_crypto, import_promises3, import_os, import_path8, import_fs7, import_path9, import_crypto2, import_fs8, import_path10, import_yaml2, import_crypto3, import_fs9, import_path11, import_fs10, __defProp3, __getOwnPropNames3, __esm3, __export3, GitClient_exports, GitClient, init_GitClient, HybridReconstruction_exports, init_HybridReconstruction, CREDENTIAL_PATTERNS, SENSITIVE_FILE_PATTERNS, FERN_BOT_NAME, FERN_BOT_EMAIL, FERN_BOT_LOGIN, FERN_SUPPORT_NAMES, LOCKFILE_HEADER, LockfileNotFoundError, LockfileManager, INFRASTRUCTURE_FILES, ReplayDetector, CONFLICT_OPENER, CONFLICT_SEPARATOR, CONFLICT_CLOSER, BINARY_EXTENSIONS, ReplayApplicator, ReplayCommitter, ReplayService, FernignoreMigrator, REPLAY_FERNIGNORE_ENTRIES, GITATTRIBUTES_ENTRIES, EMPTY_RESULT;
23045
23045
  var init_dist3 = __esm({
23046
- "../../node_modules/.pnpm/@fern-api+replay@0.12.0/node_modules/@fern-api/replay/dist/index.js"() {
23046
+ "../../node_modules/.pnpm/@fern-api+replay@0.13.0/node_modules/@fern-api/replay/dist/index.js"() {
23047
23047
  "use strict";
23048
23048
  init_esm4();
23049
23049
  import_fs6 = require("fs");
@@ -23457,17 +23457,57 @@ var init_dist3 = __esm({
23457
23457
  }
23458
23458
  const isAncestor = await this.git.isAncestor(lastGen.commit_sha, "HEAD");
23459
23459
  if (!isAncestor) {
23460
+ return this.detectPatchesViaMergeBase(lastGen, lock);
23461
+ }
23462
+ return this.detectPatchesInRange(lastGen.commit_sha, lastGen, lock);
23463
+ }
23464
+ /**
23465
+ * FER-10201 — Non-linear-history detection via `merge-base(prevGen, HEAD)`.
23466
+ *
23467
+ * After a squash-merge of a Fern-bot PR, `lastGen.commit_sha` (the previous
23468
+ * `[fern-generated]`) is orphaned but still in git's object database. The
23469
+ * merge-base is the commit on main from which the bot's branch was created —
23470
+ * a reachable ancestor of HEAD. Walking that range and classifying each
23471
+ * commit via `isGenerationCommit` mirrors the linear path and eliminates
23472
+ * the bug class where pipeline-driven changes (autoversion, replay,
23473
+ * generation) get bundled as customer customizations.
23474
+ *
23475
+ * Falls through to the legacy composite path when no common ancestor exists
23476
+ * (truly disjoint history — orphan branches with no shared root).
23477
+ */
23478
+ async detectPatchesViaMergeBase(lastGen, lock) {
23479
+ let mergeBase = "";
23480
+ try {
23481
+ mergeBase = (await this.git.exec(["merge-base", lastGen.commit_sha, "HEAD"])).trim();
23482
+ } catch {
23483
+ }
23484
+ if (!mergeBase) {
23485
+ this.warnings.push(
23486
+ `No common ancestor between previous generation ${lastGen.commit_sha.slice(0, 7)} and HEAD. Falling back to composite tree-diff detection.`
23487
+ );
23460
23488
  return this.detectPatchesViaTreeDiff(
23461
23489
  lastGen,
23462
23490
  /* commitKnownMissing */
23463
23491
  false
23464
23492
  );
23465
23493
  }
23494
+ return this.detectPatchesInRange(mergeBase, lastGen, lock);
23495
+ }
23496
+ /**
23497
+ * FER-10201 — Walk `${rangeStart}..HEAD`, classify each commit, emit one
23498
+ * `StoredPatch` per customer commit. Body shared by the linear path
23499
+ * (rangeStart = lastGen.commit_sha) and the merge-base path.
23500
+ *
23501
+ * Patch `base_generation` is always `lastGen.commit_sha` — the
23502
+ * lockfile-tracked reference the applicator uses to fetch base file
23503
+ * content, regardless of where the walk actually started.
23504
+ */
23505
+ async detectPatchesInRange(rangeStart, lastGen, lock) {
23466
23506
  const log = await this.git.exec([
23467
23507
  "log",
23468
23508
  "--first-parent",
23469
23509
  "--format=%H%x00%an%x00%ae%x00%s",
23470
- `${lastGen.commit_sha}..HEAD`,
23510
+ `${rangeStart}..HEAD`,
23471
23511
  "--",
23472
23512
  this.sdkOutputDir
23473
23513
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fern-api/generator-cli",
3
- "version": "0.9.19",
3
+ "version": "0.9.20",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/fern-api/fern.git",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@boundaryml/baml": "^0.219.0",
26
- "@fern-api/replay": "0.12.0",
26
+ "@fern-api/replay": "0.13.0",
27
27
  "@octokit/rest": "^22.0.1",
28
28
  "es-toolkit": "^1.45.1",
29
29
  "semver": "^7.6.3",