@fern-api/fern-api-dev 4.106.3-6-ga791f2f555d → 4.107.0-11-g58f57e9e0ec

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/cli.cjs +233 -63
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -340394,9 +340394,9 @@ var require_diff3 = __commonJS({
340394
340394
  }
340395
340395
  });
340396
340396
 
340397
- // ../../../node_modules/.pnpm/@fern-api+replay@0.12.0/node_modules/@fern-api/replay/dist/index.cjs
340397
+ // ../../../node_modules/.pnpm/@fern-api+replay@0.13.0/node_modules/@fern-api/replay/dist/index.cjs
340398
340398
  var require_dist14 = __commonJS({
340399
- "../../../node_modules/.pnpm/@fern-api+replay@0.12.0/node_modules/@fern-api/replay/dist/index.cjs"(exports2, module4) {
340399
+ "../../../node_modules/.pnpm/@fern-api+replay@0.13.0/node_modules/@fern-api/replay/dist/index.cjs"(exports2, module4) {
340400
340400
  "use strict";
340401
340401
  var __defProp4 = Object.defineProperty;
340402
340402
  var __getOwnPropDesc4 = Object.getOwnPropertyDescriptor;
@@ -341136,17 +341136,57 @@ var require_dist14 = __commonJS({
341136
341136
  }
341137
341137
  const isAncestor = await this.git.isAncestor(lastGen.commit_sha, "HEAD");
341138
341138
  if (!isAncestor) {
341139
+ return this.detectPatchesViaMergeBase(lastGen, lock);
341140
+ }
341141
+ return this.detectPatchesInRange(lastGen.commit_sha, lastGen, lock);
341142
+ }
341143
+ /**
341144
+ * FER-10201 — Non-linear-history detection via `merge-base(prevGen, HEAD)`.
341145
+ *
341146
+ * After a squash-merge of a Fern-bot PR, `lastGen.commit_sha` (the previous
341147
+ * `[fern-generated]`) is orphaned but still in git's object database. The
341148
+ * merge-base is the commit on main from which the bot's branch was created —
341149
+ * a reachable ancestor of HEAD. Walking that range and classifying each
341150
+ * commit via `isGenerationCommit` mirrors the linear path and eliminates
341151
+ * the bug class where pipeline-driven changes (autoversion, replay,
341152
+ * generation) get bundled as customer customizations.
341153
+ *
341154
+ * Falls through to the legacy composite path when no common ancestor exists
341155
+ * (truly disjoint history — orphan branches with no shared root).
341156
+ */
341157
+ async detectPatchesViaMergeBase(lastGen, lock) {
341158
+ let mergeBase = "";
341159
+ try {
341160
+ mergeBase = (await this.git.exec(["merge-base", lastGen.commit_sha, "HEAD"])).trim();
341161
+ } catch {
341162
+ }
341163
+ if (!mergeBase) {
341164
+ this.warnings.push(
341165
+ `No common ancestor between previous generation ${lastGen.commit_sha.slice(0, 7)} and HEAD. Falling back to composite tree-diff detection.`
341166
+ );
341139
341167
  return this.detectPatchesViaTreeDiff(
341140
341168
  lastGen,
341141
341169
  /* commitKnownMissing */
341142
341170
  false
341143
341171
  );
341144
341172
  }
341173
+ return this.detectPatchesInRange(mergeBase, lastGen, lock);
341174
+ }
341175
+ /**
341176
+ * FER-10201 — Walk `${rangeStart}..HEAD`, classify each commit, emit one
341177
+ * `StoredPatch` per customer commit. Body shared by the linear path
341178
+ * (rangeStart = lastGen.commit_sha) and the merge-base path.
341179
+ *
341180
+ * Patch `base_generation` is always `lastGen.commit_sha` — the
341181
+ * lockfile-tracked reference the applicator uses to fetch base file
341182
+ * content, regardless of where the walk actually started.
341183
+ */
341184
+ async detectPatchesInRange(rangeStart, lastGen, lock) {
341145
341185
  const log4 = await this.git.exec([
341146
341186
  "log",
341147
341187
  "--first-parent",
341148
341188
  "--format=%H%x00%an%x00%ae%x00%s",
341149
- `${lastGen.commit_sha}..HEAD`,
341189
+ `${rangeStart}..HEAD`,
341150
341190
  "--",
341151
341191
  this.sdkOutputDir
341152
341192
  ]);
@@ -621265,7 +621305,7 @@ var AccessTokenPosthogManager = class {
621265
621305
  properties: {
621266
621306
  ...event,
621267
621307
  ...event.properties,
621268
- version: "4.106.3-6-ga791f2f555d",
621308
+ version: "4.107.0-11-g58f57e9e0ec",
621269
621309
  usingAccessToken: true
621270
621310
  }
621271
621311
  });
@@ -621319,7 +621359,7 @@ var UserPosthogManager = class {
621319
621359
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
621320
621360
  event: "CLI",
621321
621361
  properties: {
621322
- version: "4.106.3-6-ga791f2f555d",
621362
+ version: "4.107.0-11-g58f57e9e0ec",
621323
621363
  ...event,
621324
621364
  ...event.properties,
621325
621365
  usingAccessToken: false,
@@ -832962,7 +833002,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
832962
833002
  var LOGS_FOLDER_NAME = "logs";
832963
833003
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
832964
833004
  function getCliSource() {
832965
- const version7 = "4.106.3-6-ga791f2f555d";
833005
+ const version7 = "4.107.0-11-g58f57e9e0ec";
832966
833006
  return `cli@${version7}`;
832967
833007
  }
832968
833008
  var DebugLogger = class {
@@ -845371,7 +845411,7 @@ var LegacyDocsPublisher = class {
845371
845411
  previewId,
845372
845412
  disableTemplates: void 0,
845373
845413
  skipUpload,
845374
- cliVersion: "4.106.3-6-ga791f2f555d",
845414
+ cliVersion: "4.107.0-11-g58f57e9e0ec",
845375
845415
  loginCommand: "fern auth login"
845376
845416
  });
845377
845417
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -881444,52 +881484,6 @@ var Begin = class extends AstNode6 {
881444
881484
  }
881445
881485
  };
881446
881486
 
881447
- // ../../../generators/ruby-v2/ast/lib/ast/IfElse.js
881448
- var IfElse = class extends AstNode6 {
881449
- ifBranch;
881450
- elseIfs;
881451
- elseBody;
881452
- constructor({ if: ifBranch, elseIf, elseBody }) {
881453
- super();
881454
- this.ifBranch = ifBranch;
881455
- this.elseIfs = elseIf ?? [];
881456
- this.elseBody = elseBody ? Array.isArray(elseBody) ? elseBody : [elseBody] : void 0;
881457
- }
881458
- write(writer2) {
881459
- writer2.write("if ");
881460
- this.ifBranch.condition.write(writer2);
881461
- writer2.writeLine();
881462
- writer2.indent();
881463
- for (const stmt of this.ifBranch.thenBody) {
881464
- stmt.write(writer2);
881465
- writer2.writeNewLineIfLastLineNot();
881466
- }
881467
- writer2.dedent();
881468
- for (const elseIf of this.elseIfs) {
881469
- writer2.write("elsif ");
881470
- elseIf.condition.write(writer2);
881471
- writer2.writeLine();
881472
- writer2.indent();
881473
- for (const stmt of elseIf.thenBody) {
881474
- stmt.write(writer2);
881475
- writer2.writeNewLineIfLastLineNot();
881476
- }
881477
- writer2.dedent();
881478
- }
881479
- if (this.elseBody && this.elseBody.length > 0) {
881480
- writer2.writeLine("else");
881481
- writer2.indent();
881482
- for (const stmt of this.elseBody) {
881483
- stmt.write(writer2);
881484
- writer2.writeNewLineIfLastLineNot();
881485
- }
881486
- writer2.dedent();
881487
- }
881488
- writer2.write("end");
881489
- writer2.writeNewLineIfLastLineNot();
881490
- }
881491
- };
881492
-
881493
881487
  // ../../../generators/ruby-v2/ast/lib/ast/Comment.js
881494
881488
  var MAX_LINE_LENGTH2 = 120;
881495
881489
  var COMMENT_PREFIX_LENGTH = 2;
@@ -882136,19 +882130,20 @@ var Class_ = class extends Module_ {
882136
882130
  writer2.writeLine("; end");
882137
882131
  return;
882138
882132
  }
882139
- if (this.statements.length) {
882133
+ if (this.statements.length || this.methods.length) {
882140
882134
  writer2.newLine();
882141
882135
  writer2.indent();
882142
882136
  this.statements.forEach((statement, index3) => {
882143
882137
  statement.write(writer2);
882144
- writer2.newLine();
882138
+ writer2.writeNewLineIfLastLineNot();
882139
+ if (index3 < this.statements.length - 1) {
882140
+ writer2.newLine();
882141
+ }
882145
882142
  });
882146
- writer2.dedent();
882147
- }
882148
- if (this.methods.length) {
882149
- writer2.newLine();
882150
- writer2.indent();
882151
- this.methods.forEach((method8) => {
882143
+ this.methods.forEach((method8, index3) => {
882144
+ if (index3 > 0 || this.statements.length > 0) {
882145
+ writer2.newLine();
882146
+ }
882152
882147
  method8.write(writer2);
882153
882148
  });
882154
882149
  writer2.dedent();
@@ -882186,6 +882181,112 @@ var Class_ = class extends Module_ {
882186
882181
  }
882187
882182
  };
882188
882183
 
882184
+ // ../../../generators/ruby-v2/ast/lib/ast/IfElse.js
882185
+ var IfElse = class extends AstNode6 {
882186
+ ifBranch;
882187
+ elseIfs;
882188
+ elseBody;
882189
+ constructor({ if: ifBranch, elseIf, elseBody }) {
882190
+ super();
882191
+ this.ifBranch = ifBranch;
882192
+ this.elseIfs = elseIf ?? [];
882193
+ this.elseBody = elseBody ? Array.isArray(elseBody) ? elseBody : [elseBody] : void 0;
882194
+ }
882195
+ write(writer2) {
882196
+ const modifier = this.renderAsModifier(writer2);
882197
+ if (modifier != null) {
882198
+ writer2.write(modifier);
882199
+ writer2.writeNewLineIfLastLineNot();
882200
+ return;
882201
+ }
882202
+ writer2.write("if ");
882203
+ this.ifBranch.condition.write(writer2);
882204
+ writer2.writeLine();
882205
+ writer2.indent();
882206
+ for (const stmt of this.ifBranch.thenBody) {
882207
+ stmt.write(writer2);
882208
+ writer2.writeNewLineIfLastLineNot();
882209
+ }
882210
+ writer2.dedent();
882211
+ for (const elseIf of this.elseIfs) {
882212
+ writer2.write("elsif ");
882213
+ elseIf.condition.write(writer2);
882214
+ writer2.writeLine();
882215
+ writer2.indent();
882216
+ for (const stmt of elseIf.thenBody) {
882217
+ stmt.write(writer2);
882218
+ writer2.writeNewLineIfLastLineNot();
882219
+ }
882220
+ writer2.dedent();
882221
+ }
882222
+ if (this.elseBody && this.elseBody.length > 0) {
882223
+ writer2.writeLine("else");
882224
+ writer2.indent();
882225
+ for (const stmt of this.elseBody) {
882226
+ stmt.write(writer2);
882227
+ writer2.writeNewLineIfLastLineNot();
882228
+ }
882229
+ writer2.dedent();
882230
+ }
882231
+ writer2.write("end");
882232
+ writer2.writeNewLineIfLastLineNot();
882233
+ }
882234
+ /**
882235
+ * Returns the modifier-form rendering (`stmt if cond`) when this if is
882236
+ * eligible:
882237
+ * - exactly one statement in the then-body
882238
+ * - no elsif and no else
882239
+ * - the single statement is not an intrinsically multi-line AST node
882240
+ * (Class, Module, Method, Begin, IfElse)
882241
+ * - the rendered statement and condition each fit on a single line
882242
+ *
882243
+ * Returns undefined when the shape isn't eligible, in which case the caller
882244
+ * falls back to explicit if/end form.
882245
+ *
882246
+ * The generator's .rubocop.yml disables Layout/LineLength, so rubocop's
882247
+ * Style/IfUnlessModifier accepts modifier form at any line length. Shape
882248
+ * eligibility is therefore sufficient; we don't gate on a max-line-length
882249
+ * budget here.
882250
+ */
882251
+ renderAsModifier(writer2) {
882252
+ if (this.ifBranch.thenBody.length !== 1) {
882253
+ return void 0;
882254
+ }
882255
+ if (this.elseIfs.length > 0) {
882256
+ return void 0;
882257
+ }
882258
+ if (this.elseBody != null && this.elseBody.length > 0) {
882259
+ return void 0;
882260
+ }
882261
+ const stmt = this.ifBranch.thenBody[0];
882262
+ if (stmt == null) {
882263
+ return void 0;
882264
+ }
882265
+ if (isKnownMultiLineNode(stmt) || isKnownMultiLineNode(this.ifBranch.condition)) {
882266
+ return void 0;
882267
+ }
882268
+ const stmtRendered = renderNode(stmt, writer2);
882269
+ const conditionRendered = renderNode(this.ifBranch.condition, writer2);
882270
+ if (stmtRendered.length === 0 || conditionRendered.length === 0) {
882271
+ return void 0;
882272
+ }
882273
+ if (stmtRendered.includes("\n") || conditionRendered.includes("\n")) {
882274
+ return void 0;
882275
+ }
882276
+ return `${stmtRendered} if ${conditionRendered}`;
882277
+ }
882278
+ };
882279
+ function isKnownMultiLineNode(node4) {
882280
+ return node4 instanceof Class_ || node4 instanceof Module_ || node4 instanceof Method6 || node4 instanceof Begin || node4 instanceof IfElse;
882281
+ }
882282
+ function renderNode(node4, parentWriter) {
882283
+ const rendered = node4.toString({
882284
+ customConfig: parentWriter.customConfig,
882285
+ formatter: parentWriter.formatter
882286
+ });
882287
+ return rendered.replace(/\n+$/, "");
882288
+ }
882289
+
882189
882290
  // ../../../generators/ruby-v2/ast/lib/ast/ClassInstantiation.js
882190
882291
  var ClassInstantiation5 = class extends AstNode6 {
882191
882292
  classReference;
@@ -882446,9 +882547,36 @@ var TypeLiteral3 = class _TypeLiteral extends AstNode6 {
882446
882547
  super();
882447
882548
  this.internalType = internalType;
882448
882549
  }
882550
+ /**
882551
+ * Returns a stable string representation of this literal suitable for
882552
+ * deduplicating hash keys (see Lint/DuplicateHashKey). Returns undefined
882553
+ * for compound/dynamic shapes where value equality isn't decidable at
882554
+ * emit time.
882555
+ */
882556
+ getDedupKey() {
882557
+ switch (this.internalType.type) {
882558
+ case "str":
882559
+ return `str:${this.internalType.value}`;
882560
+ case "interpolatedStr":
882561
+ return `istr:${this.internalType.value}`;
882562
+ case "int":
882563
+ return `int:${this.internalType.value}`;
882564
+ case "float":
882565
+ return `float:${this.internalType.value}`;
882566
+ case "bool":
882567
+ return `bool:${this.internalType.value}`;
882568
+ case "nil":
882569
+ return "nil";
882570
+ default:
882571
+ return void 0;
882572
+ }
882573
+ }
882449
882574
  static string(value2) {
882450
882575
  return new this({ type: "str", value: value2 });
882451
882576
  }
882577
+ static interpolatedString(value2) {
882578
+ return new this({ type: "interpolatedStr", value: value2 });
882579
+ }
882452
882580
  static integer(value2) {
882453
882581
  return new this({ type: "int", value: value2 });
882454
882582
  }
@@ -882485,6 +882613,11 @@ var TypeLiteral3 = class _TypeLiteral extends AstNode6 {
882485
882613
  write(writer2) {
882486
882614
  switch (this.internalType.type) {
882487
882615
  case "str": {
882616
+ const value2 = this.internalType.value.replaceAll("\r\n", "\n");
882617
+ writer2.write(`"${value2.replaceAll("\\", "\\\\").replaceAll('"', '\\"').replace(/#(?=[{$@])/g, "\\#")}"`);
882618
+ break;
882619
+ }
882620
+ case "interpolatedStr": {
882488
882621
  const value2 = this.internalType.value.replaceAll("\r\n", "\n");
882489
882622
  writer2.write(`"${value2.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`);
882490
882623
  break;
@@ -882502,7 +882635,21 @@ var TypeLiteral3 = class _TypeLiteral extends AstNode6 {
882502
882635
  break;
882503
882636
  }
882504
882637
  case "hash": {
882505
- const entries23 = this.internalType.entries.filter((entry) => !_TypeLiteral.isNop(entry.key) && !_TypeLiteral.isNop(entry.value));
882638
+ const filteredEntries = this.internalType.entries.filter((entry) => !_TypeLiteral.isNop(entry.key) && !_TypeLiteral.isNop(entry.value));
882639
+ const seenKeys = /* @__PURE__ */ new Map();
882640
+ filteredEntries.forEach((entry, index3) => {
882641
+ const rendered = renderKeyForDedup(entry.key);
882642
+ if (rendered != null) {
882643
+ seenKeys.set(rendered, index3);
882644
+ }
882645
+ });
882646
+ const entries23 = filteredEntries.filter((entry, index3) => {
882647
+ const rendered = renderKeyForDedup(entry.key);
882648
+ if (rendered == null) {
882649
+ return true;
882650
+ }
882651
+ return seenKeys.get(rendered) === index3;
882652
+ });
882506
882653
  if (entries23.length === 0) {
882507
882654
  writer2.write("{}");
882508
882655
  break;
@@ -882582,6 +882729,12 @@ var TypeLiteral3 = class _TypeLiteral extends AstNode6 {
882582
882729
  }
882583
882730
  }
882584
882731
  };
882732
+ function renderKeyForDedup(key2) {
882733
+ if (!(key2 instanceof TypeLiteral3)) {
882734
+ return void 0;
882735
+ }
882736
+ return key2.getDedupKey();
882737
+ }
882585
882738
 
882586
882739
  // ../../../generators/ruby-v2/ast/lib/ast/TypeParameter.js
882587
882740
  var Variance;
@@ -883544,6 +883697,7 @@ var EndpointSnippetGenerator7 = class {
883544
883697
  invokeMethodArgs.keywordArguments = invokeMethodArgs.keywordArguments ?? [];
883545
883698
  invokeMethodArgs.keywordArguments.push(requestOptions);
883546
883699
  }
883700
+ invokeMethodArgs.keywordArguments = dedupeKeywordArguments(invokeMethodArgs.keywordArguments);
883547
883701
  return ruby_exports.invokeMethod(invokeMethodArgs);
883548
883702
  }
883549
883703
  /**
@@ -883577,6 +883731,7 @@ var EndpointSnippetGenerator7 = class {
883577
883731
  invokeMethodArgs.keywordArguments = invokeMethodArgs.keywordArguments ?? [];
883578
883732
  invokeMethodArgs.keywordArguments.push(requestOptions);
883579
883733
  }
883734
+ invokeMethodArgs.keywordArguments = dedupeKeywordArguments(invokeMethodArgs.keywordArguments);
883580
883735
  return ruby_exports.invokeMethod(invokeMethodArgs);
883581
883736
  }
883582
883737
  /**
@@ -883913,6 +884068,21 @@ var EndpointSnippetGenerator7 = class {
883913
884068
  return this.context.getMethodName(endpoint3.declaration.name);
883914
884069
  }
883915
884070
  };
884071
+ function dedupeKeywordArguments(kwargs) {
884072
+ if (kwargs == null || kwargs.length <= 1) {
884073
+ return kwargs;
884074
+ }
884075
+ const lastIndexByName = /* @__PURE__ */ new Map();
884076
+ kwargs.forEach((arg, index3) => {
884077
+ lastIndexByName.set(arg.name, index3);
884078
+ });
884079
+ const deduped = kwargs.filter((arg, index3) => lastIndexByName.get(arg.name) === index3);
884080
+ if (deduped.length !== kwargs.length) {
884081
+ const droppedNames = Array.from(new Set(kwargs.map((arg) => arg.name).filter((name2, index3) => lastIndexByName.get(name2) !== index3)));
884082
+ console.warn(`[ruby-v2 dynamic-snippets] duplicate keyword argument name(s) [${droppedNames.join(", ")}] in a generated snippet; keeping last occurrence to match **params runtime behavior. This indicates a latent name collision in the Ruby SDK method signature that should be disambiguated at the generator level.`);
884083
+ }
884084
+ return deduped;
884085
+ }
883916
884086
 
883917
884087
  // ../../../generators/ruby-v2/dynamic-snippets/lib/DynamicSnippetsGenerator.js
883918
884088
  var DynamicSnippetsGenerator6 = class extends AbstractDynamicSnippetsGenerator {
@@ -919472,7 +919642,7 @@ var CliContext = class _CliContext {
919472
919642
  if (false) {
919473
919643
  this.logger.error("CLI_VERSION is not defined");
919474
919644
  }
919475
- return "4.106.3-6-ga791f2f555d";
919645
+ return "4.107.0-11-g58f57e9e0ec";
919476
919646
  }
919477
919647
  getCliName() {
919478
919648
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.106.3-6-ga791f2f555d",
2
+ "version": "4.107.0-11-g58f57e9e0ec",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",