@fern-api/fern-api-dev 5.68.0 → 5.69.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.
Files changed (2) hide show
  1. package/cli.cjs +131 -18
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -83938,10 +83938,16 @@ function parseIdempotencyKeyMethods(value2) {
83938
83938
  return methods.length > 0 ? methods : DEFAULT_IDEMPOTENCY_KEY_METHODS;
83939
83939
  }
83940
83940
  function getIdempotencyKeyGenerationFromGeneratorConfig(generatorInvocation) {
83941
+ const value2 = generatorInvocation.idempotencyKeyGenerationConfig ?? getRawPerGeneratorIdempotencyKeyConfig(generatorInvocation);
83942
+ return resolveIdempotencyKeyGeneration(value2);
83943
+ }
83944
+ function getRawPerGeneratorIdempotencyKeyConfig(generatorInvocation) {
83941
83945
  if (typeof generatorInvocation.raw?.config !== "object" || generatorInvocation.raw?.config === null) {
83942
83946
  return void 0;
83943
83947
  }
83944
- const value2 = generatorInvocation.raw.config["auto-generate-idempotency-key"];
83948
+ return generatorInvocation.raw.config["auto-generate-idempotency-key"];
83949
+ }
83950
+ function resolveIdempotencyKeyGeneration(value2) {
83945
83951
  if (value2 === true) {
83946
83952
  return { headerName: DEFAULT_IDEMPOTENCY_KEY_HEADER, methods: DEFAULT_IDEMPOTENCY_KEY_METHODS };
83947
83953
  }
@@ -129759,7 +129765,9 @@ var init_ApiConfigurationV2SettingsSchema2 = __esm({
129759
129765
  init_core6();
129760
129766
  init_AsyncApiSettingsSchema2();
129761
129767
  init_OpenApiSettingsSchema2();
129762
- ApiConfigurationV2SettingsSchema = schemas_exports8.object({}).extend(OpenApiSettingsSchema).extend(AsyncApiSettingsSchema);
129768
+ ApiConfigurationV2SettingsSchema = schemas_exports8.object({
129769
+ "auto-generate-idempotency-key": schemas_exports8.unknown().optional()
129770
+ }).extend(OpenApiSettingsSchema).extend(AsyncApiSettingsSchema);
129763
129771
  }
129764
129772
  });
129765
129773
 
@@ -259646,6 +259654,8 @@ async function convertGeneratorsConfiguration({ absolutePathToGeneratorsConfigur
259646
259654
  const readme = rawGeneratorsConfiguration.readme;
259647
259655
  warnForDeprecatedConfiguration(context3, rawGeneratorsConfiguration);
259648
259656
  const parsedApiConfiguration = await parseAPIConfiguration(rawGeneratorsConfiguration);
259657
+ const apiConfiguration = rawGeneratorsConfiguration.api;
259658
+ const globalIdempotencyKeyGeneration = apiConfiguration != null && generators_yml_exports.isApiConfigurationV2Schema(apiConfiguration) ? apiConfiguration.settings?.["auto-generate-idempotency-key"] : void 0;
259649
259659
  return {
259650
259660
  absolutePathToConfiguration: absolutePathToGeneratorsConfiguration,
259651
259661
  api: parsedApiConfiguration,
@@ -259660,6 +259670,7 @@ async function convertGeneratorsConfiguration({ absolutePathToGeneratorsConfigur
259660
259670
  maybeTopLevelMetadata,
259661
259671
  maybeTopLevelReviewers: rawGeneratorsConfiguration.reviewers,
259662
259672
  maybeRootAutomation: rawGeneratorsConfiguration.automation,
259673
+ globalIdempotencyKeyGeneration,
259663
259674
  readme,
259664
259675
  context: context3
259665
259676
  }))) : [],
@@ -260044,7 +260055,7 @@ async function parseAPIConfiguration(rawGeneratorsConfiguration) {
260044
260055
  definitions: await parseAPIConfigurationToApiLocations(apiConfiguration, rawGeneratorsConfiguration, emptySettings)
260045
260056
  };
260046
260057
  }
260047
- async function convertGroup({ absolutePathToGeneratorsConfiguration, groupName, group, maybeTopLevelMetadata, maybeTopLevelReviewers, maybeRootAutomation, readme, context: context3 }) {
260058
+ async function convertGroup({ absolutePathToGeneratorsConfiguration, groupName, group, maybeTopLevelMetadata, maybeTopLevelReviewers, maybeRootAutomation, globalIdempotencyKeyGeneration, readme, context: context3 }) {
260048
260059
  const maybeGroupLevelMetadata = getOutputMetadata(group.metadata);
260049
260060
  return {
260050
260061
  groupName,
@@ -260059,6 +260070,7 @@ async function convertGroup({ absolutePathToGeneratorsConfiguration, groupName,
260059
260070
  maybeGroupLevelReviewers: group.reviewers,
260060
260071
  maybeRootAutomation,
260061
260072
  maybeGroupAutomation: group.automation,
260073
+ globalIdempotencyKeyGeneration,
260062
260074
  readme,
260063
260075
  context: context3
260064
260076
  })))
@@ -260080,10 +260092,12 @@ function getGeneratorNameAndImage(generator, context3) {
260080
260092
  containerImage: void 0
260081
260093
  };
260082
260094
  }
260083
- async function convertGenerator({ absolutePathToGeneratorsConfiguration, generator, maybeGroupLevelMetadata, maybeTopLevelMetadata, maybeGroupLevelReviewers, maybeTopLevelReviewers, maybeRootAutomation, maybeGroupAutomation, readme, context: context3 }) {
260095
+ async function convertGenerator({ absolutePathToGeneratorsConfiguration, generator, maybeGroupLevelMetadata, maybeTopLevelMetadata, maybeGroupLevelReviewers, maybeTopLevelReviewers, maybeRootAutomation, maybeGroupAutomation, globalIdempotencyKeyGeneration, readme, context: context3 }) {
260084
260096
  const { normalizedName, containerImage } = getGeneratorNameAndImage(generator, context3);
260097
+ const perGeneratorIdempotencyKeyGeneration = typeof generator.config === "object" && generator.config !== null ? generator.config["auto-generate-idempotency-key"] : void 0;
260085
260098
  return {
260086
260099
  raw: generator,
260100
+ idempotencyKeyGenerationConfig: perGeneratorIdempotencyKeyGeneration ?? globalIdempotencyKeyGeneration,
260087
260101
  automation: generators_yml_exports.resolveAutomationConfig({
260088
260102
  rootAutomation: maybeRootAutomation,
260089
260103
  groupAutomation: maybeGroupAutomation,
@@ -565872,7 +565886,8 @@ var require_AutoVersionStep = __commonJS({
565872
565886
  }
565873
565887
  async handleNormalFlow(params2) {
565874
565888
  const { prepared, service, language, mappedMagicVersion, previousGenerationSha } = params2;
565875
- const rawDiff = this.gitDiff(previousGenerationSha, prepared.currentGenerationSha);
565889
+ const diffBase = this.resolveReachableGenerationBase(previousGenerationSha, prepared.currentGenerationSha);
565890
+ const rawDiff = diffBase != null ? this.safeGitDiff(diffBase, prepared.currentGenerationSha) : "";
565876
565891
  const previousVersion = await this.resolvePreviousVersion({
565877
565892
  service,
565878
565893
  rawDiff,
@@ -566269,6 +566284,91 @@ var require_AutoVersionStep = __commonJS({
566269
566284
  maxBuffer: 256 * 1024 * 1024
566270
566285
  });
566271
566286
  }
566287
+ /**
566288
+ * Resolves a reachable base commit for the autoversion diff.
566289
+ *
566290
+ * `recordedSha` (the previous generation from replay.lock) is preferred when it exists
566291
+ * in this clone. When it doesn't — e.g. the signed-commit push recreated the
566292
+ * [fern-generated] commit under a new SHA, or the branch was squash-merged — we re-anchor
566293
+ * on the most recent reachable [fern-generated] commit in history. Returns null when no
566294
+ * generation baseline is reachable at all, in which case the caller resolves the previous
566295
+ * version from metadata/git-tags and still rewrites the placeholder.
566296
+ */
566297
+ resolveReachableGenerationBase(recordedSha, currentGenerationSha) {
566298
+ if (this.commitExists(recordedSha)) {
566299
+ return recordedSha;
566300
+ }
566301
+ this.logger.warn(`AutoVersionStep: recorded previous generation ${recordedSha.slice(0, 7)} is unreachable in this clone; deriving the baseline from history.`);
566302
+ const derived = this.findPreviousGenerationFromHistory(currentGenerationSha);
566303
+ if (derived != null) {
566304
+ this.logger.info(`AutoVersionStep: re-anchored autoversion baseline on ${derived.slice(0, 7)}.`);
566305
+ return derived;
566306
+ }
566307
+ this.logger.warn("AutoVersionStep: no reachable [fern-generated] baseline found; falling back to metadata/git-tags.");
566308
+ return null;
566309
+ }
566310
+ commitExists(sha) {
566311
+ if (!/^[0-9a-f]{7,40}$/.test(sha)) {
566312
+ return false;
566313
+ }
566314
+ try {
566315
+ (0, child_process_1.execFileSync)("git", ["cat-file", "-e", `${sha}^{commit}`], {
566316
+ cwd: this.outputDir,
566317
+ stdio: "pipe"
566318
+ });
566319
+ return true;
566320
+ } catch {
566321
+ return false;
566322
+ }
566323
+ }
566324
+ /**
566325
+ * Walks first-parent history from the current generation commit and returns the most
566326
+ * recent prior [fern-generated] commit — the reachable equivalent of replay.lock's
566327
+ * recorded baseline. Mirrors @fern-api/replay's `findPreviousGenerationFromHistory`.
566328
+ */
566329
+ findPreviousGenerationFromHistory(currentGenerationSha) {
566330
+ const start2 = this.commitExists(currentGenerationSha) ? currentGenerationSha : "HEAD";
566331
+ let log4;
566332
+ try {
566333
+ log4 = (0, child_process_1.execFileSync)("git", ["log", "--first-parent", "--format=%H%x00%s", start2], {
566334
+ cwd: this.outputDir,
566335
+ encoding: "utf-8",
566336
+ stdio: "pipe",
566337
+ maxBuffer: 64 * 1024 * 1024
566338
+ });
566339
+ } catch (error50) {
566340
+ this.logger.debug(`AutoVersionStep: git log history walk failed (${String(error50)}); no baseline derived.`);
566341
+ return null;
566342
+ }
566343
+ for (const line of log4.split("\n")) {
566344
+ if (line.trim().length === 0) {
566345
+ continue;
566346
+ }
566347
+ const [sha, subject = ""] = line.split("\0");
566348
+ if (sha == null || sha === currentGenerationSha) {
566349
+ continue;
566350
+ }
566351
+ if (subject.startsWith("[fern-generated]")) {
566352
+ return sha;
566353
+ }
566354
+ }
566355
+ return null;
566356
+ }
566357
+ /**
566358
+ * `gitDiff` that degrades to an empty diff instead of throwing. Both endpoints are
566359
+ * expected to be reachable (the base is resolved via resolveReachableGenerationBase and
566360
+ * `to` is this run's freshly-created HEAD), but we never want a `git diff` failure to
566361
+ * abort autoversion and leave the magic placeholder in the shipped SDK — the empty diff
566362
+ * routes version resolution to baseVersion/metadata/git-tags, which still rewrites it.
566363
+ */
566364
+ safeGitDiff(from4, to2) {
566365
+ try {
566366
+ return this.gitDiff(from4, to2);
566367
+ } catch (error50) {
566368
+ this.logger.warn(`AutoVersionStep: git diff ${from4.slice(0, 7)}..${to2.slice(0, 7)} failed (${error50 instanceof Error ? error50.message : String(error50)}); proceeding with an empty diff.`);
566369
+ return "";
566370
+ }
566371
+ }
566272
566372
  gitDiff(from4, to2) {
566273
566373
  return (0, child_process_1.execFileSync)("git", ["diff", from4, to2, "--", ".", ":(exclude).fern/metadata.json"], {
566274
566374
  cwd: this.outputDir,
@@ -689143,7 +689243,7 @@ var AccessTokenPosthogManager = class {
689143
689243
  properties: {
689144
689244
  ...event,
689145
689245
  ...event.properties,
689146
- version: "5.68.0",
689246
+ version: "5.69.0",
689147
689247
  usingAccessToken: true,
689148
689248
  ...getRunIdProperties()
689149
689249
  }
@@ -689209,7 +689309,7 @@ var UserPosthogManager = class {
689209
689309
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
689210
689310
  event: "CLI",
689211
689311
  properties: {
689212
- version: "5.68.0",
689312
+ version: "5.69.0",
689213
689313
  ...event,
689214
689314
  ...event.properties,
689215
689315
  usingAccessToken: false,
@@ -834305,8 +834405,8 @@ var V67_TO_V66_MIGRATION = {
834305
834405
  [GeneratorName.TYPESCRIPT_SDK]: "3.70.9-rc.0",
834306
834406
  [GeneratorName.TYPESCRIPT_EXPRESS]: GeneratorWasNeverUpdatedToConsumeNewIR,
834307
834407
  [GeneratorName.JAVA]: GeneratorWasNeverUpdatedToConsumeNewIR,
834308
- [GeneratorName.JAVA_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
834309
- [GeneratorName.JAVA_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
834408
+ [GeneratorName.JAVA_MODEL]: "1.9.0-rc.1",
834409
+ [GeneratorName.JAVA_SDK]: "4.13.3-rc.0",
834310
834410
  [GeneratorName.JAVA_SPRING]: GeneratorWasNeverUpdatedToConsumeNewIR,
834311
834411
  [GeneratorName.OPENAPI_PYTHON_CLIENT]: GeneratorWasNeverUpdatedToConsumeNewIR,
834312
834412
  [GeneratorName.OPENAPI]: GeneratorWasNeverUpdatedToConsumeNewIR,
@@ -834317,13 +834417,13 @@ var V67_TO_V66_MIGRATION = {
834317
834417
  [GeneratorName.POSTMAN]: GeneratorWasNeverUpdatedToConsumeNewIR,
834318
834418
  [GeneratorName.GO_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
834319
834419
  [GeneratorName.GO_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
834320
- [GeneratorName.RUBY_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
834420
+ [GeneratorName.RUBY_SDK]: "1.16.0-rc.0",
834321
834421
  [GeneratorName.CSHARP_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
834322
834422
  [GeneratorName.CSHARP_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
834323
834423
  [GeneratorName.SWIFT_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
834324
834424
  [GeneratorName.SWIFT_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
834325
834425
  [GeneratorName.PHP_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
834326
- [GeneratorName.PHP_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
834426
+ [GeneratorName.PHP_SDK]: "2.11.2-rc.0",
834327
834427
  [GeneratorName.RUST_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
834328
834428
  [GeneratorName.RUST_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
834329
834429
  [GeneratorName.CLI]: "0.0.1"
@@ -870310,7 +870410,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
870310
870410
  var LOGS_FOLDER_NAME = "logs";
870311
870411
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
870312
870412
  function getCliSource() {
870313
- const version7 = "5.68.0";
870413
+ const version7 = "5.69.0";
870314
870414
  return `cli@${version7}`;
870315
870415
  }
870316
870416
  var DebugLogger = class {
@@ -902871,7 +902971,7 @@ var LegacyDocsPublisher = class {
902871
902971
  previewId,
902872
902972
  disableTemplates: void 0,
902873
902973
  skipUpload,
902874
- cliVersion: "5.68.0",
902974
+ cliVersion: "5.69.0",
902875
902975
  loginCommand: "fern auth login"
902876
902976
  });
902877
902977
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -938718,6 +938818,19 @@ var DynamicSnippetsGeneratorContext5 = class _DynamicSnippetsGeneratorContext ex
938718
938818
  }
938719
938819
  return name2.snakeCase.safeName;
938720
938820
  }
938821
+ /**
938822
+ * Module/subpackage directory name, preserving any leading/trailing underscores
938823
+ * from the original name that the casing functions would otherwise strip. This
938824
+ * keeps snippet accessors and module paths consistent with the generated module
938825
+ * directories (e.g. a group named `_agents` yields `client._agents`). It is scoped
938826
+ * to namespace/module names and intentionally not applied to property or method names.
938827
+ */
938828
+ getModuleName(name2) {
938829
+ const leading = name2.originalName.match(/^(_+)/)?.[1] ?? "";
938830
+ const core2 = name2.originalName.slice(leading.length);
938831
+ const trailing = core2.match(/(_+)$/)?.[1] ?? "";
938832
+ return `${leading}${name2.snakeCase.safeName}${trailing}`;
938833
+ }
938721
938834
  getRootClientClassReference() {
938722
938835
  return python_exports.reference({
938723
938836
  name: this.getRootClientClassName(),
@@ -938728,7 +938841,7 @@ var DynamicSnippetsGeneratorContext5 = class _DynamicSnippetsGeneratorContext ex
938728
938841
  const className = this.getClassName(declaration.name);
938729
938842
  const modulePath = [
938730
938843
  ...this.getRootModulePath(),
938731
- ...declaration.fernFilepath.allParts.map((part) => part.snakeCase.safeName)
938844
+ ...declaration.fernFilepath.allParts.map((part) => this.getModuleName(part))
938732
938845
  ];
938733
938846
  return python_exports.reference({ name: className, modulePath });
938734
938847
  }
@@ -938737,7 +938850,7 @@ var DynamicSnippetsGeneratorContext5 = class _DynamicSnippetsGeneratorContext ex
938737
938850
  const variantName = discriminantValue.name.pascalCase.safeName;
938738
938851
  const modulePath = [
938739
938852
  ...this.getRootModulePath(),
938740
- ...unionDeclaration.fernFilepath.allParts.map((part) => part.snakeCase.safeName)
938853
+ ...unionDeclaration.fernFilepath.allParts.map((part) => this.getModuleName(part))
938741
938854
  ];
938742
938855
  const name2 = this.customConfig.pydantic_config?.union_naming === "v1" ? `${variantName}${unionClassName}` : `${unionClassName}_${variantName}`;
938743
938856
  return python_exports.reference({ name: name2, modulePath });
@@ -939543,7 +939656,7 @@ var EndpointSnippetGenerator5 = class {
939543
939656
  }
939544
939657
  getMethod({ endpoint: endpoint3 }) {
939545
939658
  if (endpoint3.declaration.fernFilepath.allParts.length > 0) {
939546
- return `${endpoint3.declaration.fernFilepath.allParts.map((val) => this.context.getMethodName(val)).join(".")}.${this.context.getMethodName(endpoint3.declaration.name)}`;
939659
+ return `${endpoint3.declaration.fernFilepath.allParts.map((val) => this.context.getModuleName(val)).join(".")}.${this.context.getMethodName(endpoint3.declaration.name)}`;
939547
939660
  }
939548
939661
  return this.context.getMethodName(endpoint3.declaration.name);
939549
939662
  }
@@ -969219,7 +969332,7 @@ function getAutomationContextFromEnv() {
969219
969332
  config_branch: process.env.FERN_CONFIG_BRANCH,
969220
969333
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
969221
969334
  trigger: process.env.GITHUB_EVENT_NAME,
969222
- cli_version: "5.68.0"
969335
+ cli_version: "5.69.0"
969223
969336
  };
969224
969337
  }
969225
969338
  function isAutomationMode() {
@@ -970051,7 +970164,7 @@ var CliContext = class _CliContext {
970051
970164
  if (false) {
970052
970165
  this.logger.error("CLI_VERSION is not defined");
970053
970166
  }
970054
- return "5.68.0";
970167
+ return "5.69.0";
970055
970168
  }
970056
970169
  getCliName() {
970057
970170
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.68.0",
2
+ "version": "5.69.0",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",