@fern-api/fern-api-dev 5.110.1 → 5.112.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 +1229 -250
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -25708,6 +25708,116 @@ var init_addPrefixToString = __esm({
25708
25708
  }
25709
25709
  });
25710
25710
 
25711
+ // ../../commons/core-utils/lib/anyOfPresenceConstraint.js
25712
+ function isRecord(value2) {
25713
+ return typeof value2 === "object" && value2 != null && !Array.isArray(value2);
25714
+ }
25715
+ function isObjectTypeOrAbsent(type7) {
25716
+ if (type7 == null) {
25717
+ return true;
25718
+ }
25719
+ if (typeof type7 === "string") {
25720
+ return type7 === "object";
25721
+ }
25722
+ if (Array.isArray(type7)) {
25723
+ const nonNull = type7.filter((entry) => entry !== "null");
25724
+ return nonNull.length === 1 && nonNull[0] === "object";
25725
+ }
25726
+ return false;
25727
+ }
25728
+ function restatesSiblingSubschema(branchSubschema, siblingSubschema) {
25729
+ if (branchSubschema === true) {
25730
+ return true;
25731
+ }
25732
+ if (!isRecord(branchSubschema)) {
25733
+ return false;
25734
+ }
25735
+ const sibling2 = isRecord(siblingSubschema) ? siblingSubschema : void 0;
25736
+ for (const [keyword, value2] of Object.entries(branchSubschema)) {
25737
+ if (ANNOTATION_KEYWORDS.has(keyword)) {
25738
+ continue;
25739
+ }
25740
+ if (sibling2 == null || !(keyword in sibling2) || !deepEquals(value2, sibling2[keyword])) {
25741
+ return false;
25742
+ }
25743
+ }
25744
+ return true;
25745
+ }
25746
+ function deepEquals(a3, b5) {
25747
+ if (a3 === b5) {
25748
+ return true;
25749
+ }
25750
+ if (Array.isArray(a3) && Array.isArray(b5)) {
25751
+ return a3.length === b5.length && a3.every((entry, index3) => deepEquals(entry, b5[index3]));
25752
+ }
25753
+ if (isRecord(a3) && isRecord(b5)) {
25754
+ const aKeys = Object.keys(a3).sort();
25755
+ const bKeys = Object.keys(b5).sort();
25756
+ return aKeys.length === bKeys.length && aKeys.every((key2, index3) => key2 === bKeys[index3]) && aKeys.every((key2) => deepEquals(a3[key2], b5[key2]));
25757
+ }
25758
+ return false;
25759
+ }
25760
+ function isPresenceConstraintBranch(branch, siblingProperties) {
25761
+ if (!isRecord(branch) || "$ref" in branch) {
25762
+ return false;
25763
+ }
25764
+ if (branch.allOf != null || branch.oneOf != null || branch.anyOf != null || branch.additionalProperties != null || !isObjectTypeOrAbsent(branch.type)) {
25765
+ return false;
25766
+ }
25767
+ const branchProperties = isRecord(branch.properties) ? branch.properties : {};
25768
+ const branchRequired = Array.isArray(branch.required) ? branch.required : [];
25769
+ if (Object.keys(branchProperties).length === 0 && branchRequired.length === 0) {
25770
+ return false;
25771
+ }
25772
+ for (const name2 of branchRequired) {
25773
+ if (typeof name2 !== "string" || !(name2 in siblingProperties)) {
25774
+ return false;
25775
+ }
25776
+ }
25777
+ for (const [name2, subschema] of Object.entries(branchProperties)) {
25778
+ if (!(name2 in siblingProperties)) {
25779
+ return false;
25780
+ }
25781
+ if (!restatesSiblingSubschema(subschema, siblingProperties[name2])) {
25782
+ return false;
25783
+ }
25784
+ }
25785
+ return true;
25786
+ }
25787
+ function anyOfIsPresenceConstraint(schema) {
25788
+ const anyOf = schema.anyOf;
25789
+ if (!Array.isArray(anyOf) || anyOf.length === 0) {
25790
+ return false;
25791
+ }
25792
+ if (schema.oneOf != null || schema.allOf != null) {
25793
+ return false;
25794
+ }
25795
+ if (!isRecord(schema.properties) || Object.keys(schema.properties).length === 0) {
25796
+ return false;
25797
+ }
25798
+ const siblingProperties = schema.properties;
25799
+ return anyOf.every((branch) => isPresenceConstraintBranch(branch, siblingProperties));
25800
+ }
25801
+ var ANNOTATION_KEYWORDS;
25802
+ var init_anyOfPresenceConstraint = __esm({
25803
+ "../../commons/core-utils/lib/anyOfPresenceConstraint.js"() {
25804
+ "use strict";
25805
+ ANNOTATION_KEYWORDS = /* @__PURE__ */ new Set([
25806
+ "title",
25807
+ "description",
25808
+ "default",
25809
+ "deprecated",
25810
+ "example",
25811
+ "examples",
25812
+ "readOnly",
25813
+ "writeOnly",
25814
+ "externalDocs",
25815
+ "xml",
25816
+ "$comment"
25817
+ ]);
25818
+ }
25819
+ });
25820
+
25711
25821
  // ../../../node_modules/.pnpm/jsonpath-plus@10.4.0/node_modules/jsonpath-plus/dist/index-node-esm.js
25712
25822
  function push(arr, item) {
25713
25823
  arr = arr.slice();
@@ -44690,6 +44800,7 @@ __export(lib_exports, {
44690
44800
  SKIP_MARKER: () => SKIP_MARKER,
44691
44801
  SymbolRegistry: () => SymbolRegistry,
44692
44802
  addPrefixToString: () => addPrefixToString,
44803
+ anyOfIsPresenceConstraint: () => anyOfIsPresenceConstraint,
44693
44804
  applyOpenAPIOverlay: () => applyOpenAPIOverlay,
44694
44805
  assert: () => assert2,
44695
44806
  assertDefined: () => assertDefined,
@@ -44710,6 +44821,7 @@ __export(lib_exports, {
44710
44821
  isGitAvailable: () => isGitAvailable,
44711
44822
  isNonNullish: () => isNonNullish,
44712
44823
  isPlainObject: () => isPlainObject4,
44824
+ isPresenceConstraintBranch: () => isPresenceConstraintBranch,
44713
44825
  keys: () => keys2,
44714
44826
  mapValues: () => mapValues2,
44715
44827
  mergeWithOverrides: () => mergeWithOverrides,
@@ -44737,6 +44849,7 @@ var init_lib4 = __esm({
44737
44849
  "../../commons/core-utils/lib/index.js"() {
44738
44850
  "use strict";
44739
44851
  init_addPrefixToString();
44852
+ init_anyOfPresenceConstraint();
44740
44853
  init_applyOpenAPIOverlay();
44741
44854
  init_assert();
44742
44855
  init_delay();
@@ -101228,9 +101341,9 @@ var require_graceful_fs = __commonJS({
101228
101341
  }
101229
101342
  }
101230
101343
  var fs$readdir = fs35.readdir;
101231
- fs35.readdir = readdir23;
101344
+ fs35.readdir = readdir24;
101232
101345
  var noReaddirOptionVersions = /^v[0-5]\./;
101233
- function readdir23(path122, options2, cb) {
101346
+ function readdir24(path122, options2, cb) {
101234
101347
  if (typeof options2 === "function")
101235
101348
  cb = options2, options2 = null;
101236
101349
  var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path123, options3, cb2, startTime) {
@@ -131124,6 +131237,7 @@ var init_OpenApiSettingsSchema2 = __esm({
131124
131237
  "type-dates-as-strings": schemas_exports8.boolean().optional(),
131125
131238
  "preserve-single-schema-oneof": schemas_exports8.boolean().optional(),
131126
131239
  "preserve-one-of-in-all-of": schemas_exports8.boolean().optional(),
131240
+ "any-of-sibling-properties-as-object": schemas_exports8.boolean().optional(),
131127
131241
  "inline-all-of-schemas": schemas_exports8.boolean().optional(),
131128
131242
  "resolve-aliases": ResolveAliases.optional(),
131129
131243
  "group-multi-api-environments": schemas_exports8.boolean().optional(),
@@ -152982,6 +153096,7 @@ var init_options2 = __esm({
152982
153096
  typeDatesAsStrings: false,
152983
153097
  preserveSingleSchemaOneOf: false,
152984
153098
  preserveOneOfInAllOf: false,
153099
+ anyOfSiblingPropertiesAsObject: false,
152985
153100
  inlineAllOfSchemas: false,
152986
153101
  resolveAliases: false,
152987
153102
  groupMultiApiEnvironments: false,
@@ -156641,6 +156756,12 @@ function convertSchemaObject(schema, wrapAsOptional, wrapAsNullable, context3, b
156641
156756
  }
156642
156757
  }
156643
156758
  if (schema.anyOf != null && schema.anyOf.length > 0) {
156759
+ if (context3.options.anyOfSiblingPropertiesAsObject && anyOfIsPresenceConstraint(schema)) {
156760
+ context3.logger.debug(`Treating the anyOf at ${breadcrumbs.join(".")} as an "at least one of" constraint over its sibling properties rather than a union, and converting the schema as an object.`);
156761
+ const { anyOf: _constraint, ...schemaWithoutAnyOf } = schema;
156762
+ const convertedSchema = convertSchema2(schemaWithoutAnyOf, wrapAsOptional, wrapAsNullable, context3, breadcrumbs, source2, namespace, referencedAsRequest);
156763
+ return maybeInjectDescriptionOrGroupName(convertedSchema, description, namespace, groupName);
156764
+ }
156644
156765
  if (schema.anyOf.length === 1 && schema.anyOf[0] != null) {
156645
156766
  const convertedSchema = convertSchema2(schema.anyOf[0], wrapAsOptional, wrapAsNullable, context3, breadcrumbs, source2, namespace, referencedAsRequest);
156646
156767
  return maybeInjectDescriptionOrGroupName(convertedSchema, description, namespace, groupName);
@@ -157251,6 +157372,7 @@ var SCHEMA_REFERENCE_PREFIX, globalTitleCollisionTracker;
157251
157372
  var init_convertSchemas = __esm({
157252
157373
  "../api-importers/openapi/openapi-ir-parser/lib/schema/convertSchemas.js"() {
157253
157374
  "use strict";
157375
+ init_lib4();
157254
157376
  init_lib13();
157255
157377
  init_lib6();
157256
157378
  init_lodash();
@@ -200202,6 +200324,7 @@ var init_getAPIDefinitionSettings = __esm({
200202
200324
  typeDatesAsStrings: "typeDatesAsStrings",
200203
200325
  preserveSingleSchemaOneOf: "preserveSingleSchemaOneOf",
200204
200326
  preserveOneOfInAllOf: "preserveOneOfInAllOf",
200327
+ anyOfSiblingPropertiesAsObject: "anyOfSiblingPropertiesAsObject",
200205
200328
  inlineAllOfSchemas: "inlineAllOfSchemas",
200206
200329
  resolveAliases: "resolveAliases",
200207
200330
  groupMultiApiEnvironments: "groupMultiApiEnvironments",
@@ -200287,6 +200410,13 @@ var init_openapi = __esm({
200287
200410
  }
200288
200411
  });
200289
200412
 
200413
+ // ../../commons/api-workspace-commons/lib/RawSpecs.js
200414
+ var init_RawSpecs = __esm({
200415
+ "../../commons/api-workspace-commons/lib/RawSpecs.js"() {
200416
+ "use strict";
200417
+ }
200418
+ });
200419
+
200290
200420
  // ../../commons/api-workspace-commons/lib/Source.js
200291
200421
  var init_Source5 = __esm({
200292
200422
  "../../commons/api-workspace-commons/lib/Source.js"() {
@@ -200445,6 +200575,7 @@ var init_lib17 = __esm({
200445
200575
  init_getFilesystemPublishTarget();
200446
200576
  init_getOriginGitCommit();
200447
200577
  init_openapi();
200578
+ init_RawSpecs();
200448
200579
  init_Source5();
200449
200580
  init_Spec();
200450
200581
  init_utils11();
@@ -264823,6 +264954,7 @@ function parseOpenApiDefinitionSettingsSchema(settings) {
264823
264954
  typeDatesAsStrings: settings?.["type-dates-as-strings"],
264824
264955
  preserveSingleSchemaOneOf: settings?.["preserve-single-schema-oneof"],
264825
264956
  preserveOneOfInAllOf: settings?.["preserve-one-of-in-all-of"],
264957
+ anyOfSiblingPropertiesAsObject: settings?.["any-of-sibling-properties-as-object"],
264826
264958
  inlineAllOfSchemas: settings?.["inline-all-of-schemas"],
264827
264959
  resolveAliases: settings?.["resolve-aliases"],
264828
264960
  groupMultiApiEnvironments: settings?.["group-multi-api-environments"],
@@ -265685,6 +265817,7 @@ var init_convertGeneratorsConfiguration = __esm({
265685
265817
  typeDatesAsStrings: void 0,
265686
265818
  preserveSingleSchemaOneOf: void 0,
265687
265819
  preserveOneOfInAllOf: void 0,
265820
+ anyOfSiblingPropertiesAsObject: void 0,
265688
265821
  inlineAllOfSchemas: void 0,
265689
265822
  resolveAliases: void 0,
265690
265823
  groupMultiApiEnvironments: void 0,
@@ -343851,7 +343984,7 @@ var require_oas_kit_common = __commonJS({
343851
343984
  function allSame(array3) {
343852
343985
  return new Set(array3).size <= 1;
343853
343986
  }
343854
- function deepEquals(obj1, obj2) {
343987
+ function deepEquals2(obj1, obj2) {
343855
343988
  function _equals(obj12, obj22) {
343856
343989
  return sjs.stringify(obj12) === sjs.stringify(Object.assign({}, obj12, obj22));
343857
343990
  }
@@ -343861,7 +343994,7 @@ var require_oas_kit_common = __commonJS({
343861
343994
  let result = [];
343862
343995
  for (let candidate of arr) {
343863
343996
  let dupe = result.find(function(e2, i5, a3) {
343864
- return deepEquals(e2, candidate);
343997
+ return deepEquals2(e2, candidate);
343865
343998
  });
343866
343999
  if (!dupe) result.push(candidate);
343867
344000
  }
@@ -346319,7 +346452,7 @@ async function parseOverlayFile(absoluteFilePathToOverlay, context3) {
346319
346452
  }
346320
346453
  }
346321
346454
  function validateOverlay(overlay, context3) {
346322
- if (!isRecord(overlay)) {
346455
+ if (!isRecord2(overlay)) {
346323
346456
  context3.logger.error("Overlay file must be a YAML or JSON object");
346324
346457
  return false;
346325
346458
  }
@@ -346328,7 +346461,7 @@ function validateOverlay(overlay, context3) {
346328
346461
  return false;
346329
346462
  }
346330
346463
  const info = overlay.info;
346331
- if (!isRecord(info) || typeof info.title !== "string" || info.title.length === 0 || typeof info.version !== "string" || info.version.length === 0) {
346464
+ if (!isRecord2(info) || typeof info.title !== "string" || info.title.length === 0 || typeof info.version !== "string" || info.version.length === 0) {
346332
346465
  context3.logger.error("Overlay file missing required 'info.title' or 'info.version' field");
346333
346466
  return false;
346334
346467
  }
@@ -346339,7 +346472,7 @@ function validateOverlay(overlay, context3) {
346339
346472
  }
346340
346473
  for (let i5 = 0; i5 < actions.length; i5++) {
346341
346474
  const action = actions[i5];
346342
- if (!isRecord(action) || !action.target) {
346475
+ if (!isRecord2(action) || !action.target) {
346343
346476
  context3.logger.error(`Overlay action at index ${i5} missing required 'target' field`);
346344
346477
  return false;
346345
346478
  }
@@ -346350,7 +346483,7 @@ function validateOverlay(overlay, context3) {
346350
346483
  }
346351
346484
  return true;
346352
346485
  }
346353
- function isRecord(value2) {
346486
+ function isRecord2(value2) {
346354
346487
  return typeof value2 === "object" && value2 != null && !Array.isArray(value2);
346355
346488
  }
346356
346489
  var import_promises28, import_path36, import_tmp_promise6, tempDir;
@@ -351696,6 +351829,7 @@ var TYPE_INVARIANT_KEYS, SchemaConverter;
351696
351829
  var init_SchemaConverter = __esm({
351697
351830
  "../api-importers/v3-importer-commons/lib/converters/schema/SchemaConverter.js"() {
351698
351831
  "use strict";
351832
+ init_lib4();
351699
351833
  init_lib9();
351700
351834
  init_lib30();
351701
351835
  init_CreateTypeReferenceFromFernType();
@@ -351769,6 +351903,10 @@ var init_SchemaConverter = __esm({
351769
351903
  if (maybeConvertedTypeArraySchema != null) {
351770
351904
  return maybeConvertedTypeArraySchema;
351771
351905
  }
351906
+ const maybeConvertedSiblingAnyOfConstraint = this.tryConvertSiblingAnyOfConstraint();
351907
+ if (maybeConvertedSiblingAnyOfConstraint != null) {
351908
+ return maybeConvertedSiblingAnyOfConstraint;
351909
+ }
351772
351910
  const maybeConvertedOneOfAnyOfSchema = this.tryConvertOneOfAnyOfSchema();
351773
351911
  if (maybeConvertedOneOfAnyOfSchema != null) {
351774
351912
  return maybeConvertedOneOfAnyOfSchema;
@@ -352109,6 +352247,50 @@ var init_SchemaConverter = __esm({
352109
352247
  }
352110
352248
  return void 0;
352111
352249
  }
352250
+ /**
352251
+ * A schema may declare `properties` alongside an `anyOf` whose branches only
352252
+ * re-declare some of those same properties as required, for example:
352253
+ *
352254
+ * type: object
352255
+ * properties: { a: {...}, b: {...} }
352256
+ * anyOf:
352257
+ * - { properties: { a: {...} }, required: [a] }
352258
+ * - { properties: { b: {...} }, required: [b] }
352259
+ *
352260
+ * Per JSON Schema an instance must satisfy both keywords, so the `anyOf` here
352261
+ * is a validation constraint -- "at least one of a, b" -- and not a set of
352262
+ * variants. Converting it as a union discards the sibling `properties`
352263
+ * entirely and makes the variants mutually exclusive, so a body carrying both
352264
+ * `a` and `b` silently loses one on the wire.
352265
+ *
352266
+ * Drop the `anyOf` and convert the schema as the object it declares. The "at
352267
+ * least one" constraint is not expressible in the IR and is not enforced.
352268
+ *
352269
+ * This only applies when every branch is an inline object whose properties are
352270
+ * a subset of the sibling `properties`. A branch that introduces a property,
352271
+ * or is a reference, is a genuine variant and is left to the union converter.
352272
+ *
352273
+ * Gated behind the `any-of-sibling-properties-as-object` setting.
352274
+ */
352275
+ tryConvertSiblingAnyOfConstraint() {
352276
+ if (!this.context.settings.anyOfSiblingPropertiesAsObject) {
352277
+ return void 0;
352278
+ }
352279
+ if (!anyOfIsPresenceConstraint(this.schema)) {
352280
+ return void 0;
352281
+ }
352282
+ this.context.logger.debug(`Treating the anyOf at ${this.breadcrumbs.join(".")} as an "at least one of" constraint over its sibling properties rather than a union, and converting the schema as an object.`);
352283
+ const { anyOf: _constraint, ...schemaWithoutAnyOf } = this.schema;
352284
+ return new _SchemaConverter({
352285
+ id: this.id,
352286
+ context: this.context,
352287
+ breadcrumbs: this.breadcrumbs,
352288
+ schema: schemaWithoutAnyOf,
352289
+ inlined: this.inlined,
352290
+ nameOverride: this.nameOverride,
352291
+ visitedRefs: this.visitedRefs
352292
+ }).convert();
352293
+ }
352112
352294
  tryConvertOneOfAnyOfSchema() {
352113
352295
  if (this.schema.oneOf != null || this.schema.anyOf != null) {
352114
352296
  const oneOfConverter = new OneOfSchemaConverter({
@@ -374091,6 +374273,7 @@ var init_OSSWorkspace = __esm({
374091
374273
  init_lib31();
374092
374274
  init_lib21();
374093
374275
  init_lib12();
374276
+ init_lib20();
374094
374277
  init_lib4();
374095
374278
  init_lib8();
374096
374279
  init_lib9();
@@ -374492,6 +374675,13 @@ var init_OSSWorkspace = __esm({
374492
374675
  sources: this.sources
374493
374676
  });
374494
374677
  }
374678
+ async getAllSpecsForGenerator(specsOverride) {
374679
+ if (specsOverride == null) {
374680
+ return this.allSpecs;
374681
+ }
374682
+ const overrideSpecs = await this.convertSpecsOverrideToSpecs(specsOverride);
374683
+ return overrideSpecs.filter((spec) => spec.type !== "protobuf" || !spec.fromOpenAPI);
374684
+ }
374495
374685
  async createWorkspaceWithSpecsOverride({ context: context3 }, specsOverride, settings) {
374496
374686
  const overrideSpecs = await this.convertSpecsOverrideToSpecs(specsOverride);
374497
374687
  const overrideAllSpecs = overrideSpecs.filter((spec) => spec.type !== "protobuf" || !spec.fromOpenAPI);
@@ -374550,8 +374740,9 @@ var init_OSSWorkspace = __esm({
374550
374740
  absoluteFilepath,
374551
374741
  absoluteFilepathToOverrides,
374552
374742
  absoluteFilepathToOverlays,
374553
- // Use default settings from existing specs for compatibility
374554
- settings: this.specs.length > 0 ? this.specs[0]?.settings : void 0,
374743
+ settings: getOpenAPISettings({
374744
+ options: mergeSettings(this.generatorsConfiguration?.api?.settings ?? parseOpenApiDefinitionSettingsSchema(void 0), parseOpenApiDefinitionSettingsSchema(spec.settings))
374745
+ }),
374555
374746
  source: {
374556
374747
  type: "openapi",
374557
374748
  file: absoluteFilepath
@@ -494397,9 +494588,9 @@ var require_graceful_fs2 = __commonJS({
494397
494588
  }
494398
494589
  }
494399
494590
  var fs$readdir = fs35.readdir;
494400
- fs35.readdir = readdir23;
494591
+ fs35.readdir = readdir24;
494401
494592
  var noReaddirOptionVersions = /^v[0-5]\./;
494402
- function readdir23(path122, options2, cb) {
494593
+ function readdir24(path122, options2, cb) {
494403
494594
  if (typeof options2 === "function")
494404
494595
  cb = options2, options2 = null;
494405
494596
  var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path123, options3, cb2, startTime) {
@@ -503252,10 +503443,10 @@ var require_make_dir = __commonJS({
503252
503443
  module4.exports = (input3, opts) => Promise.resolve().then(() => {
503253
503444
  checkPath(input3);
503254
503445
  opts = Object.assign({}, defaults3, opts);
503255
- const mkdir49 = pify(opts.fs.mkdir);
503446
+ const mkdir50 = pify(opts.fs.mkdir);
503256
503447
  const stat8 = pify(opts.fs.stat);
503257
503448
  const make = (pth) => {
503258
- return mkdir49(pth, opts.mode).then(() => pth).catch((err) => {
503449
+ return mkdir50(pth, opts.mode).then(() => pth).catch((err) => {
503259
503450
  if (err.code === "ENOENT") {
503260
503451
  if (err.message.includes("null bytes") || path122.dirname(pth) === pth) {
503261
503452
  throw err;
@@ -637279,14 +637470,14 @@ var require_empty2 = __commonJS({
637279
637470
  var u5 = require_universalify().fromPromise;
637280
637471
  var fs34 = require_fs();
637281
637472
  var path122 = require("path");
637282
- var mkdir49 = require_mkdirs();
637473
+ var mkdir50 = require_mkdirs();
637283
637474
  var remove3 = require_remove3();
637284
637475
  var emptyDir = u5(async function emptyDir2(dir) {
637285
637476
  let items;
637286
637477
  try {
637287
637478
  items = await fs34.readdir(dir);
637288
637479
  } catch {
637289
- return mkdir49.mkdirs(dir);
637480
+ return mkdir50.mkdirs(dir);
637290
637481
  }
637291
637482
  return Promise.all(items.map((item) => remove3.remove(path122.join(dir, item))));
637292
637483
  });
@@ -637295,7 +637486,7 @@ var require_empty2 = __commonJS({
637295
637486
  try {
637296
637487
  items = fs34.readdirSync(dir);
637297
637488
  } catch {
637298
- return mkdir49.mkdirsSync(dir);
637489
+ return mkdir50.mkdirsSync(dir);
637299
637490
  }
637300
637491
  items.forEach((item) => {
637301
637492
  item = path122.join(dir, item);
@@ -637318,7 +637509,7 @@ var require_file2 = __commonJS({
637318
637509
  var u5 = require_universalify().fromPromise;
637319
637510
  var path122 = require("path");
637320
637511
  var fs34 = require_fs();
637321
- var mkdir49 = require_mkdirs();
637512
+ var mkdir50 = require_mkdirs();
637322
637513
  async function createFile(file4) {
637323
637514
  let stats;
637324
637515
  try {
@@ -637332,7 +637523,7 @@ var require_file2 = __commonJS({
637332
637523
  dirStats = await fs34.stat(dir);
637333
637524
  } catch (err) {
637334
637525
  if (err.code === "ENOENT") {
637335
- await mkdir49.mkdirs(dir);
637526
+ await mkdir50.mkdirs(dir);
637336
637527
  await fs34.writeFile(file4, "");
637337
637528
  return;
637338
637529
  } else {
@@ -637358,7 +637549,7 @@ var require_file2 = __commonJS({
637358
637549
  fs34.readdirSync(dir);
637359
637550
  }
637360
637551
  } catch (err) {
637361
- if (err && err.code === "ENOENT") mkdir49.mkdirsSync(dir);
637552
+ if (err && err.code === "ENOENT") mkdir50.mkdirsSync(dir);
637362
637553
  else throw err;
637363
637554
  }
637364
637555
  fs34.writeFileSync(file4, "");
@@ -637377,7 +637568,7 @@ var require_link = __commonJS({
637377
637568
  var u5 = require_universalify().fromPromise;
637378
637569
  var path122 = require("path");
637379
637570
  var fs34 = require_fs();
637380
- var mkdir49 = require_mkdirs();
637571
+ var mkdir50 = require_mkdirs();
637381
637572
  var { pathExists: pathExists2 } = require_path_exists();
637382
637573
  var { areIdentical } = require_stat();
637383
637574
  async function createLink(srcpath, dstpath) {
@@ -637397,7 +637588,7 @@ var require_link = __commonJS({
637397
637588
  const dir = path122.dirname(dstpath);
637398
637589
  const dirExists = await pathExists2(dir);
637399
637590
  if (!dirExists) {
637400
- await mkdir49.mkdirs(dir);
637591
+ await mkdir50.mkdirs(dir);
637401
637592
  }
637402
637593
  await fs34.link(srcpath, dstpath);
637403
637594
  }
@@ -637417,7 +637608,7 @@ var require_link = __commonJS({
637417
637608
  const dir = path122.dirname(dstpath);
637418
637609
  const dirExists = fs34.existsSync(dir);
637419
637610
  if (dirExists) return fs34.linkSync(srcpath, dstpath);
637420
- mkdir49.mkdirsSync(dir);
637611
+ mkdir50.mkdirsSync(dir);
637421
637612
  return fs34.linkSync(srcpath, dstpath);
637422
637613
  }
637423
637614
  module4.exports = {
@@ -637753,19 +637944,19 @@ var require_output_file = __commonJS({
637753
637944
  var u5 = require_universalify().fromPromise;
637754
637945
  var fs34 = require_fs();
637755
637946
  var path122 = require("path");
637756
- var mkdir49 = require_mkdirs();
637947
+ var mkdir50 = require_mkdirs();
637757
637948
  var pathExists2 = require_path_exists().pathExists;
637758
637949
  async function outputFile(file4, data2, encoding = "utf-8") {
637759
637950
  const dir = path122.dirname(file4);
637760
637951
  if (!await pathExists2(dir)) {
637761
- await mkdir49.mkdirs(dir);
637952
+ await mkdir50.mkdirs(dir);
637762
637953
  }
637763
637954
  return fs34.writeFile(file4, data2, encoding);
637764
637955
  }
637765
637956
  function outputFileSync(file4, ...args) {
637766
637957
  const dir = path122.dirname(file4);
637767
637958
  if (!fs34.existsSync(dir)) {
637768
- mkdir49.mkdirsSync(dir);
637959
+ mkdir50.mkdirsSync(dir);
637769
637960
  }
637770
637961
  fs34.writeFileSync(file4, ...args);
637771
637962
  }
@@ -696678,6 +696869,14 @@ var OpenApiSettingsSchema2 = BaseApiSettingsSchema2.extend({
696678
696869
  * Defaults to false.
696679
696870
  */
696680
696871
  preserveOneOfInAllOf: external_exports.boolean().optional(),
696872
+ /**
696873
+ * When a schema declares `properties` alongside an `anyOf` that only marks
696874
+ * some of those same properties required, the `anyOf` is a constraint rather
696875
+ * than a set of variants. Set to true to convert such a schema as an object.
696876
+ * Defaults to false, converting it to a union, which drops the sibling
696877
+ * `properties`.
696878
+ */
696879
+ anyOfSiblingPropertiesAsObject: external_exports.boolean().optional(),
696681
696880
  /**
696682
696881
  * Whether to inline allOf schemas. If false, allOf schemas will be
696683
696882
  * extended in the code generation.
@@ -705322,7 +705521,7 @@ var AccessTokenPosthogManager = class {
705322
705521
  properties: {
705323
705522
  ...event,
705324
705523
  ...event.properties,
705325
- version: "5.110.1",
705524
+ version: "5.112.0",
705326
705525
  usingAccessToken: true,
705327
705526
  ...getRunIdProperties()
705328
705527
  }
@@ -705388,7 +705587,7 @@ var UserPosthogManager = class {
705388
705587
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
705389
705588
  event: "CLI",
705390
705589
  properties: {
705391
- version: "5.110.1",
705590
+ version: "5.112.0",
705392
705591
  ...event,
705393
705592
  ...event.properties,
705394
705593
  usingAccessToken: false,
@@ -712197,6 +712396,7 @@ var LegacyApiSpecAdapter = class {
712197
712396
  typeDatesAsStrings: settings.typeDatesAsStrings,
712198
712397
  preserveSingleSchemaOneOf: settings.preserveSingleSchemaOneof,
712199
712398
  preserveOneOfInAllOf: settings.preserveOneOfInAllOf,
712399
+ anyOfSiblingPropertiesAsObject: settings.anyOfSiblingPropertiesAsObject,
712200
712400
  inlineAllOfSchemas: settings.inlineAllOfSchemas,
712201
712401
  resolveAliases: settings.resolveAliases,
712202
712402
  groupMultiApiEnvironments: settings.groupMultiApiEnvironments,
@@ -885153,6 +885353,7 @@ var SETTINGS_KEY_MAP = {
885153
885353
  "type-dates-as-strings": "typeDatesAsStrings",
885154
885354
  "preserve-single-schema-oneof": "preserveSingleSchemaOneof",
885155
885355
  "preserve-one-of-in-all-of": "preserveOneOfInAllOf",
885356
+ "any-of-sibling-properties-as-object": "anyOfSiblingPropertiesAsObject",
885156
885357
  "inline-all-of-schemas": "inlineAllOfSchemas",
885157
885358
  "resolve-aliases": "resolveAliases",
885158
885359
  "group-multi-api-environments": "groupMultiApiEnvironments",
@@ -887062,7 +887263,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
887062
887263
  var LOGS_FOLDER_NAME = "logs";
887063
887264
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
887064
887265
  function getCliSource() {
887065
- const version7 = "5.110.1";
887266
+ const version7 = "5.112.0";
887066
887267
  return `cli@${version7}`;
887067
887268
  }
887068
887269
  var DebugLogger = class {
@@ -908719,6 +908920,28 @@ function getGeneratorLanguage(generatorId) {
908719
908920
  return getGeneratorPolicy(generatorId)?.language;
908720
908921
  }
908721
908922
  function validateGeneratorConfigCompatibility(input3) {
908923
+ const route = selectGeneratorConfigRoute(input3);
908924
+ const receivedConfigKind = input3.configKind;
908925
+ if (!isGenerationConfigKind(receivedConfigKind)) {
908926
+ throw compatibilityError(input3, {
908927
+ code: "INVALID_CONFIG_KIND",
908928
+ message: "Configuration kind must be legacy-fern or sdk-config-v1",
908929
+ cutoverVersion: route.cutoverVersion,
908930
+ expectedLanguage: route.language,
908931
+ expectedConfigKind: route.configKind,
908932
+ recommendedAction: "USE_SUPPORTED_CONFIG_KIND"
908933
+ }, receivedConfigKind);
908934
+ }
908935
+ if (receivedConfigKind !== route.configKind) {
908936
+ const policy = getGeneratorPolicy(input3.generatorId);
908937
+ if (policy === void 0) {
908938
+ throw new Error(`Missing validated generator policy for ${input3.generatorId}`);
908939
+ }
908940
+ throw configKindError(input3, policy, route.configKind, receivedConfigKind);
908941
+ }
908942
+ return route;
908943
+ }
908944
+ function selectGeneratorConfigRoute(input3) {
908722
908945
  const policy = getGeneratorPolicy(input3.generatorId);
908723
908946
  if (policy === void 0) {
908724
908947
  throw compatibilityError(input3, {
@@ -908753,27 +908976,13 @@ function validateGeneratorConfigCompatibility(input3) {
908753
908976
  }
908754
908977
  const isBeforeCutover = compareSemver(requestedVersion, policy.parsedCutoverVersion) < 0;
908755
908978
  const expectedConfigKind = isBeforeCutover ? "legacy-fern" : "sdk-config-v1";
908756
- const receivedConfigKind = input3.configKind;
908757
- if (!isGenerationConfigKind(receivedConfigKind)) {
908758
- throw compatibilityError(input3, {
908759
- code: "INVALID_CONFIG_KIND",
908760
- message: "Configuration kind must be legacy-fern or sdk-config-v1",
908761
- cutoverVersion: policy.cutoverVersion,
908762
- expectedLanguage: policy.language,
908763
- expectedConfigKind,
908764
- recommendedAction: "USE_SUPPORTED_CONFIG_KIND"
908765
- }, receivedConfigKind);
908766
- }
908767
- if (receivedConfigKind !== expectedConfigKind) {
908768
- throw configKindError(input3, policy, expectedConfigKind, receivedConfigKind);
908769
- }
908770
908979
  return {
908771
908980
  generatorId: input3.generatorId,
908772
908981
  language: policy.language,
908773
908982
  requestedVersion: input3.requestedVersion,
908774
908983
  cutoverVersion: policy.cutoverVersion,
908775
- configKind: receivedConfigKind,
908776
- payloadKind: isBeforeCutover ? "fern-runtime-bundle" : "sdk-config-ir-v1"
908984
+ configKind: expectedConfigKind,
908985
+ payloadKind: isBeforeCutover ? "fern-runtime-bundle" : "sdk-config-v1"
908777
908986
  };
908778
908987
  }
908779
908988
  function compatibilityError(input3, details, receivedConfigKind = input3.configKind) {
@@ -908804,13 +909013,15 @@ function isGenerationConfigKind(value2) {
908804
909013
  var POLL_INTERVAL_MS2 = 2e3;
908805
909014
  var POLL_TIMEOUT_MS2 = 15 * 60 * 1e3;
908806
909015
  var REQUEST_TIMEOUT_MS = 6e4;
908807
- var MAX_BUNDLES = 64;
909016
+ var MAX_PAYLOADS = 64;
908808
909017
  var MAX_SOURCE_COMPRESSED_BYTES = 25 * 1024 * 1024;
908809
909018
  var MAX_SOURCE_DECOMPRESSED_BYTES = 25 * 1024 * 1024;
908810
- var MAX_BUNDLE_COMPRESSED_BYTES = 5 * 1024 * 1024;
908811
- var MAX_BUNDLE_DECOMPRESSED_BYTES = 25 * 1024 * 1024;
908812
- var MAX_TOTAL_BUNDLE_COMPRESSED_BYTES = 25 * 1024 * 1024;
908813
- var MAX_TOTAL_BUNDLE_DECOMPRESSED_BYTES = 100 * 1024 * 1024;
909019
+ var MAX_RUNTIME_BUNDLE_COMPRESSED_BYTES = 5 * 1024 * 1024;
909020
+ var MAX_PAYLOAD_BYTES = 25 * 1024 * 1024;
909021
+ var MAX_TOTAL_RUNTIME_BUNDLE_COMPRESSED_BYTES = 25 * 1024 * 1024;
909022
+ var MAX_TOTAL_PAYLOAD_BYTES = 100 * 1024 * 1024;
909023
+ var MAX_TOTAL_UPLOAD_FILE_BYTES = 50 * 1024 * 1024;
909024
+ var MAX_REQUEST_FIELD_BYTES = 1024 * 1024;
908814
909025
  var MAX_MULTIPART_BODY_BYTES = 60 * 1024 * 1024;
908815
909026
  var LOOPBACK_HOSTNAMES2 = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
908816
909027
  var TARGET_ID_SEED_COLLATOR = new Intl.Collator("en", { numeric: true });
@@ -908841,6 +909052,18 @@ function getFernSdkGenApiOrigin() {
908841
909052
  function getFernSdkGenApiLanguage(generatorName) {
908842
909053
  return getGeneratorLanguage(generatorName);
908843
909054
  }
909055
+ function selectFernSdkGenApiRoute(generatorInvocation) {
909056
+ const language = getFernSdkGenApiLanguage(generatorInvocation.name);
909057
+ if (language == null) {
909058
+ return void 0;
909059
+ }
909060
+ return validateGeneratorConfigCompatibility({
909061
+ generatorId: generatorInvocation.name,
909062
+ language: generatorInvocation.language ?? language,
909063
+ requestedVersion: generatorInvocation.version,
909064
+ configKind: "legacy-fern"
909065
+ });
909066
+ }
908844
909067
  function mapFernSdkGenApiOutput(generatorInvocation) {
908845
909068
  const outputMode = generatorInvocation.outputMode;
908846
909069
  switch (outputMode.type) {
@@ -909042,6 +909265,7 @@ function isEligibleForFernSdkGenApi(candidate) {
909042
909265
  var FernSdkGenApiBatch = class {
909043
909266
  expectedTargets;
909044
909267
  participants = [];
909268
+ removedTargetIds = /* @__PURE__ */ new Set();
909045
909269
  terminalError;
909046
909270
  dispatched = false;
909047
909271
  constructor(expectedTargets) {
@@ -909054,6 +909278,9 @@ var FernSdkGenApiBatch = class {
909054
909278
  if (this.terminalError != null) {
909055
909279
  return Promise.reject(this.terminalError);
909056
909280
  }
909281
+ if (parameters2.targetIdSeed != null && this.removedTargetIds.has(parameters2.targetIdSeed)) {
909282
+ return Promise.reject(new Error(`Fern sdk-gen-api target ${parameters2.targetIdSeed} was removed`));
909283
+ }
909057
909284
  if (this.dispatched) {
909058
909285
  return Promise.reject(new Error("The Fern sdk-gen-api batch was already dispatched"));
909059
909286
  }
@@ -909070,6 +909297,22 @@ var FernSdkGenApiBatch = class {
909070
909297
  this.expectedTargets -= 1;
909071
909298
  this.dispatchIfReady();
909072
909299
  }
909300
+ /** Removes one failed automation target while preserving undispatched siblings. */
909301
+ remove(targetIdSeed, error50) {
909302
+ if (this.dispatched || this.terminalError != null) {
909303
+ return false;
909304
+ }
909305
+ if (this.removedTargetIds.has(targetIdSeed)) {
909306
+ return false;
909307
+ }
909308
+ this.removedTargetIds.add(targetIdSeed);
909309
+ const participantIndex = this.participants.findIndex((participant2) => participant2.targetIdSeed === targetIdSeed);
909310
+ const [participant] = participantIndex >= 0 ? this.participants.splice(participantIndex, 1) : [];
909311
+ participant?.reject(error50);
909312
+ this.expectedTargets -= 1;
909313
+ this.dispatchIfReady();
909314
+ return true;
909315
+ }
909073
909316
  /** Prevents siblings waiting at the batch barrier from hanging if preparation of one fails. */
909074
909317
  cancel(error50) {
909075
909318
  if (this.dispatched || this.terminalError != null) {
@@ -909081,7 +909324,7 @@ var FernSdkGenApiBatch = class {
909081
909324
  }
909082
909325
  }
909083
909326
  dispatchIfReady() {
909084
- if (this.dispatched || this.terminalError != null || this.participants.length !== this.expectedTargets) {
909327
+ if (this.dispatched || this.terminalError != null || this.expectedTargets === 0 || this.participants.length !== this.expectedTargets) {
909085
909328
  return;
909086
909329
  }
909087
909330
  this.dispatched = true;
@@ -909107,6 +909350,72 @@ var FernSdkGenApiBatch = class {
909107
909350
  }
909108
909351
  }
909109
909352
  };
909353
+ var FernSdkGenApiPreparationBatch = class {
909354
+ expectedTargetIds;
909355
+ settledTargetIds = /* @__PURE__ */ new Set();
909356
+ waiters = [];
909357
+ preflightParticipants = [];
909358
+ terminalError;
909359
+ didRunPreflight = false;
909360
+ constructor(targetIds) {
909361
+ this.expectedTargetIds = new Set(targetIds);
909362
+ if (this.expectedTargetIds.size !== targetIds.length) {
909363
+ throw new Error("Fern sdk-gen-api preparation target IDs must be unique");
909364
+ }
909365
+ }
909366
+ ready(targetId, preflightParameters) {
909367
+ this.assertExpected(targetId);
909368
+ if (this.settledTargetIds.has(targetId)) {
909369
+ throw new Error(`Fern sdk-gen-api target ${targetId} prepared more than once`);
909370
+ }
909371
+ this.settledTargetIds.add(targetId);
909372
+ if (preflightParameters != null) {
909373
+ this.preflightParticipants.push(preflightParameters);
909374
+ }
909375
+ return new Promise((resolve15, reject) => {
909376
+ this.waiters.push({ resolve: resolve15, reject });
909377
+ this.finishIfSettled();
909378
+ });
909379
+ }
909380
+ /** Returns true only when this call newly settles a target that failed before preparation. */
909381
+ fail(targetId, error50, isolateFailure) {
909382
+ this.assertExpected(targetId);
909383
+ if (this.settledTargetIds.has(targetId)) {
909384
+ return false;
909385
+ }
909386
+ this.settledTargetIds.add(targetId);
909387
+ if (!isolateFailure) {
909388
+ this.terminalError = error50;
909389
+ }
909390
+ this.finishIfSettled();
909391
+ return true;
909392
+ }
909393
+ assertExpected(targetId) {
909394
+ if (!this.expectedTargetIds.has(targetId)) {
909395
+ throw new Error(`Unexpected Fern sdk-gen-api preparation target ${targetId}`);
909396
+ }
909397
+ }
909398
+ finishIfSettled() {
909399
+ if (this.settledTargetIds.size !== this.expectedTargetIds.size) {
909400
+ return;
909401
+ }
909402
+ if (!this.didRunPreflight && this.terminalError == null && this.preflightParticipants.length > 0) {
909403
+ this.didRunPreflight = true;
909404
+ try {
909405
+ prepareFernSdkGenApiSubmission(this.preflightParticipants);
909406
+ } catch (error50) {
909407
+ this.terminalError = error50;
909408
+ }
909409
+ }
909410
+ for (const waiter of this.waiters) {
909411
+ if (this.terminalError != null) {
909412
+ waiter.reject(this.terminalError);
909413
+ } else {
909414
+ waiter.resolve();
909415
+ }
909416
+ }
909417
+ }
909418
+ };
909110
909419
  async function runFernSdkGenApiBuild(parameters2) {
909111
909420
  const [result] = await executeFernSdkGenApiBuild([parameters2]);
909112
909421
  if (result?.status === "fulfilled") {
@@ -909114,7 +909423,12 @@ async function runFernSdkGenApiBuild(parameters2) {
909114
909423
  }
909115
909424
  throw result?.reason ?? new Error("sdk-gen-api did not return the requested target");
909116
909425
  }
909117
- async function executeFernSdkGenApiBuild(participants) {
909426
+ function validateFernSdkGenApiTargetCount(targetCount) {
909427
+ if (targetCount > MAX_PAYLOADS) {
909428
+ throw new Error(`sdk-gen-api supports at most ${MAX_PAYLOADS} target payloads per build; received ${targetCount}`);
909429
+ }
909430
+ }
909431
+ function prepareFernSdkGenApiSubmission(participants) {
909118
909432
  const first3 = participants[0];
909119
909433
  if (first3 == null) {
909120
909434
  throw new Error("Cannot submit an empty Fern sdk-gen-api build");
@@ -909141,13 +909455,20 @@ async function executeFernSdkGenApiBuild(participants) {
909141
909455
  targets: participants.map((participant) => ({
909142
909456
  generatorInvocation: participant.generatorInvocation,
909143
909457
  sdkVersion: participant.sdkVersion,
909458
+ apiVersion: participant.apiVersion,
909144
909459
  targetIdSeed: participant.targetIdSeed,
909460
+ sourceSpecIndexes: participant.sourceSpecIndexes,
909145
909461
  audiences: participant.audiences,
909146
- runtimeBundle: participant.runtimeBundle
909462
+ payload: participant.payload
909147
909463
  }))
909148
909464
  });
909465
+ const serializedRequest = JSON.stringify(request7);
909466
+ const serializedRequestBytes = Buffer.byteLength(serializedRequest, "utf8");
909467
+ if (serializedRequestBytes > MAX_REQUEST_FIELD_BYTES) {
909468
+ return first3.context.failAndThrow(`sdk-gen-api serialized request field is ${formatMiB(serializedRequestBytes)}, exceeding the 1 MiB UTF-8 field limit; reduce generator customConfig, readme, settings, or API override metadata`, void 0, { code: CliError.Code.ConfigError });
909469
+ }
909149
909470
  const form = new import_form_data4.default();
909150
- form.append("request", JSON.stringify(request7));
909471
+ form.append("request", serializedRequest);
909151
909472
  form.append("sources", first3.specsTarGzBuffer, {
909152
909473
  filename: "specs.tar.gz",
909153
909474
  contentType: "application/gzip"
@@ -909155,17 +909476,22 @@ async function executeFernSdkGenApiBuild(participants) {
909155
909476
  participants.forEach((participant, index3) => {
909156
909477
  const target = request7.targets[index3];
909157
909478
  if (target == null) {
909158
- throw new Error(`Cannot pair sdk-gen-api runtime bundle at index ${index3} with a target`);
909479
+ throw new Error(`Cannot pair sdk-gen-api payload at index ${index3} with a target`);
909159
909480
  }
909160
- form.append("bundles", participant.runtimeBundle, {
909161
- filename: `${target.targetId}.json.gz`,
909162
- contentType: "application/gzip"
909481
+ const isRuntimeBundle = participant.payload.payloadKind === "fern-runtime-bundle";
909482
+ form.append("payloads", participant.payload.body, {
909483
+ filename: `${target.targetId}.json${isRuntimeBundle ? ".gz" : ""}`,
909484
+ contentType: isRuntimeBundle ? "application/gzip" : "application/json"
909163
909485
  });
909164
909486
  });
909165
909487
  const multipartBodyLength = form.getLengthSync();
909166
909488
  if (multipartBodyLength > MAX_MULTIPART_BODY_BYTES) {
909167
- return first3.context.failAndThrow(`sdk-gen-api multipart request is ${formatMiB(multipartBodyLength)}, exceeding the 60 MiB limit; reduce source or target bundle size`, void 0, { code: CliError.Code.ConfigError });
909489
+ return first3.context.failAndThrow(`sdk-gen-api multipart request is ${formatMiB(multipartBodyLength)}, exceeding the 60 MiB limit; reduce source or target payload size`, void 0, { code: CliError.Code.ConfigError });
909168
909490
  }
909491
+ return { first: first3, origin: origin2, request: request7, form };
909492
+ }
909493
+ async function executeFernSdkGenApiBuild(participants) {
909494
+ const { first: first3, origin: origin2, request: request7, form } = prepareFernSdkGenApiSubmission(participants);
909169
909495
  let buildId;
909170
909496
  try {
909171
909497
  const response = await axios_default.post(`${origin2}/v1/fern/build`, form, {
@@ -909243,7 +909569,7 @@ function assertGeneratorConfigCompatibility(participants) {
909243
909569
  generatorId: generatorInvocation.name,
909244
909570
  language,
909245
909571
  requestedVersion: generatorInvocation.version,
909246
- configKind: "legacy-fern"
909572
+ configKind: participant.payload.payloadKind === "fern-runtime-bundle" ? "legacy-fern" : "sdk-config-v1"
909247
909573
  });
909248
909574
  } catch (error50) {
909249
909575
  if (!(error50 instanceof GeneratorConfigCompatibilityError)) {
@@ -909268,8 +909594,8 @@ function formatGeneratorConfigCompatibilityError(error50) {
909268
909594
  `retryable=${error50.retryable}`,
909269
909595
  `recommendedAction=${error50.recommendedAction}`
909270
909596
  ].join("; ");
909271
- const remediation = error50.code === "SDK_CONFIG_V1_REQUIRED" ? " Run `fern sdk-config migrate` to create SDK Config v1 for this target." : "";
909272
- return `Cannot submit SDK generation to sdk-gen-api: ${error50.message} [${diagnostic}].${remediation}`;
909597
+ const migrationHint = error50.recommendedAction === "USE_SDK_CONFIG_V1" ? " Run `fern sdk migrate --output <path>` to migrate this SDK configuration before using this generator version." : "";
909598
+ return `Cannot submit SDK generation to sdk-gen-api: ${error50.message} [${diagnostic}].${migrationHint}`;
909273
909599
  }
909274
909600
  function compareFernSdkGenApiParticipants(left3, right3) {
909275
909601
  const seedComparison = TARGET_ID_SEED_COLLATOR.compare(left3.targetIdSeed ?? "", right3.targetIdSeed ?? "");
@@ -909287,20 +909613,25 @@ function compareFernSdkGenApiParticipants(left3, right3) {
909287
909613
  return left3.sdkVersion.localeCompare(right3.sdkVersion);
909288
909614
  }
909289
909615
  function validateProtocolInputs(participants, first3) {
909290
- if (participants.length > MAX_BUNDLES) {
909291
- first3.context.failAndThrow(`sdk-gen-api supports at most ${MAX_BUNDLES} runtime bundles per build; received ${participants.length}`, void 0, { code: CliError.Code.ConfigError });
909616
+ if (participants.length > MAX_PAYLOADS) {
909617
+ first3.context.failAndThrow(`sdk-gen-api supports at most ${MAX_PAYLOADS} target payloads per build; received ${participants.length}`, void 0, { code: CliError.Code.ConfigError });
909292
909618
  }
909293
909619
  if (first3.specsTarGzBuffer.length > MAX_SOURCE_COMPRESSED_BYTES) {
909294
909620
  first3.context.failAndThrow(`sdk-gen-api source archive is ${formatMiB(first3.specsTarGzBuffer.length)}, exceeding the 25 MiB compressed limit`, void 0, { code: CliError.Code.ConfigError });
909295
909621
  }
909296
- const oversizedBundleIndex = participants.findIndex((participant) => participant.runtimeBundle.length > MAX_BUNDLE_COMPRESSED_BYTES);
909297
- if (oversizedBundleIndex >= 0) {
909298
- const participant = participants[oversizedBundleIndex];
909299
- first3.context.failAndThrow(`sdk-gen-api runtime bundle ${participant?.targetIdSeed ?? oversizedBundleIndex.toString()} is ${formatMiB(participant?.runtimeBundle.length ?? 0)}, exceeding the 5 MiB compressed limit`, void 0, { code: CliError.Code.ConfigError });
909622
+ const oversizedPayloadIndex = participants.findIndex((participant) => participant.payload.body.length > (participant.payload.payloadKind === "fern-runtime-bundle" ? MAX_RUNTIME_BUNDLE_COMPRESSED_BYTES : MAX_PAYLOAD_BYTES));
909623
+ if (oversizedPayloadIndex >= 0) {
909624
+ const participant = participants[oversizedPayloadIndex];
909625
+ const maxBytes = participant?.payload.payloadKind === "fern-runtime-bundle" ? MAX_RUNTIME_BUNDLE_COMPRESSED_BYTES : MAX_PAYLOAD_BYTES;
909626
+ first3.context.failAndThrow(`sdk-gen-api ${payloadLabel(participant, oversizedPayloadIndex)} is ${formatMiB(participant?.payload.body.length ?? 0)}, exceeding the ${formatMiB(maxBytes)} upload limit`, void 0, { code: CliError.Code.ConfigError });
909300
909627
  }
909301
- const totalBundleBytes = participants.reduce((total, participant) => total + participant.runtimeBundle.length, 0);
909302
- if (totalBundleBytes > MAX_TOTAL_BUNDLE_COMPRESSED_BYTES) {
909303
- first3.context.failAndThrow(`sdk-gen-api runtime bundles total ${formatMiB(totalBundleBytes)}, exceeding the 25 MiB compressed limit; reduce the number or size of targets`, void 0, { code: CliError.Code.ConfigError });
909628
+ const totalUploadFileBytes = participants.reduce((total, participant) => total + participant.payload.body.length, first3.specsTarGzBuffer.length);
909629
+ if (totalUploadFileBytes > MAX_TOTAL_UPLOAD_FILE_BYTES) {
909630
+ first3.context.failAndThrow(`sdk-gen-api source archive and target payloads total ${formatMiB(totalUploadFileBytes)}, exceeding the 50 MiB in-memory upload limit; reduce the source archive size, target payload size, or number of targets`, void 0, { code: CliError.Code.ConfigError });
909631
+ }
909632
+ const totalRuntimeBundleBytes = participants.reduce((total, participant) => participant.payload.payloadKind === "fern-runtime-bundle" ? total + participant.payload.body.length : total, 0);
909633
+ if (totalRuntimeBundleBytes > MAX_TOTAL_RUNTIME_BUNDLE_COMPRESSED_BYTES) {
909634
+ first3.context.failAndThrow(`sdk-gen-api runtime bundles total ${formatMiB(totalRuntimeBundleBytes)}, exceeding the 25 MiB compressed limit; reduce the number or size of targets`, void 0, { code: CliError.Code.ConfigError });
909304
909635
  }
909305
909636
  getBoundedGzipSize({
909306
909637
  buffer: first3.specsTarGzBuffer,
@@ -909308,19 +909639,23 @@ function validateProtocolInputs(participants, first3) {
909308
909639
  label: "source archive",
909309
909640
  context: first3.context
909310
909641
  });
909311
- let totalDecompressedBundleBytes = 0;
909642
+ let totalPayloadBytes = 0;
909312
909643
  for (const [index3, participant] of participants.entries()) {
909313
- totalDecompressedBundleBytes += getBoundedGzipSize({
909314
- buffer: participant.runtimeBundle,
909315
- maxBytes: MAX_BUNDLE_DECOMPRESSED_BYTES,
909316
- label: `runtime bundle ${participant.targetIdSeed ?? index3.toString()}`,
909644
+ totalPayloadBytes += participant.payload.payloadKind === "fern-runtime-bundle" ? getBoundedGzipSize({
909645
+ buffer: participant.payload.body,
909646
+ maxBytes: MAX_PAYLOAD_BYTES,
909647
+ label: payloadLabel(participant, index3),
909317
909648
  context: first3.context
909318
- });
909319
- if (totalDecompressedBundleBytes > MAX_TOTAL_BUNDLE_DECOMPRESSED_BYTES) {
909320
- first3.context.failAndThrow(`sdk-gen-api runtime bundles total ${formatMiB(totalDecompressedBundleBytes)} decompressed, exceeding the 100 MiB decompressed limit; reduce the number or size of targets`, void 0, { code: CliError.Code.ConfigError });
909649
+ }) : participant.payload.body.length;
909650
+ if (totalPayloadBytes > MAX_TOTAL_PAYLOAD_BYTES) {
909651
+ first3.context.failAndThrow(`sdk-gen-api target payloads total ${formatMiB(totalPayloadBytes)}, exceeding the 100 MiB decoded limit; reduce the number or size of targets`, void 0, { code: CliError.Code.ConfigError });
909321
909652
  }
909322
909653
  }
909323
909654
  }
909655
+ function payloadLabel(participant, index3) {
909656
+ const kind = participant?.payload.payloadKind ?? "target payload";
909657
+ return `${kind} ${participant?.targetIdSeed ?? index3.toString()}`;
909658
+ }
909324
909659
  function getBoundedGzipSize({ buffer, maxBytes, label, context: context3 }) {
909325
909660
  let decompressed;
909326
909661
  try {
@@ -909403,23 +909738,41 @@ function createFernSdkGenApiBatchRequest({ apiName, organization, cliVersion, sp
909403
909738
  if (targets2.length === 0) {
909404
909739
  throw new Error("Cannot create an empty Fern sdk-gen-api request");
909405
909740
  }
909406
- const requestTargets = targets2.map(({ generatorInvocation, sdkVersion, targetIdSeed, audiences }, index3) => {
909741
+ const apiInputs = [];
909742
+ const apiInputIds = targets2.map(({ targetIdSeed, sourceSpecIndexes }, index3) => {
909743
+ if (sourceSpecIndexes == null) {
909744
+ if (!apiInputs.some((input3) => input3.id === "default")) {
909745
+ apiInputs.push({ id: "default", specIndexes: "all" });
909746
+ }
909747
+ return "default";
909748
+ }
909749
+ const id = `target-${targetIdSeed ?? index3.toString()}`;
909750
+ apiInputs.push({ id, specIndexes: sourceSpecIndexes });
909751
+ return id;
909752
+ });
909753
+ const requestTargets = targets2.map(({ generatorInvocation, sdkVersion, apiVersion, targetIdSeed, audiences, payload }, index3) => {
909407
909754
  const language = getFernSdkGenApiLanguage(generatorInvocation.name);
909408
909755
  if (language == null) {
909409
909756
  throw new Error(`Unsupported Fern SDK generator: ${generatorInvocation.name}`);
909410
909757
  }
909411
909758
  const output2 = mapFernSdkGenApiOutput(generatorInvocation);
909759
+ const packageConfig = payload.package ?? output2.package;
909412
909760
  const targetId = (0, import_crypto10.createHash)("sha256").update(`${apiName}:${generatorInvocation.name}:${generatorInvocation.version}:${targetIdSeed ?? index3.toString()}`).digest("hex").slice(0, 20);
909413
909761
  return {
909414
909762
  targetId,
909415
- apiInputId: "default",
909763
+ apiInputId: apiInputIds[index3] ?? "default",
909416
909764
  language,
909417
- sdk: { name: apiName, version: sdkVersion },
909765
+ sdk: {
909766
+ name: apiName,
909767
+ version: sdkVersion,
909768
+ ...apiVersion != null ? { apiVersion } : {}
909769
+ },
909418
909770
  fernGenerator: {
909419
909771
  id: generatorInvocation.name,
909420
909772
  version: generatorInvocation.version
909421
909773
  },
909422
- ...output2.package != null ? { package: output2.package } : {},
909774
+ payloadKind: payload.payloadKind,
909775
+ ...packageConfig != null ? { package: packageConfig } : {},
909423
909776
  invocation: {
909424
909777
  customConfig: stripCliConfigKeys(generatorInvocation.config) ?? {},
909425
909778
  keywords: generatorInvocation.keywords ?? [],
@@ -909438,15 +909791,14 @@ function createFernSdkGenApiBatchRequest({ apiName, organization, cliVersion, sp
909438
909791
  requestedOutput: output2.requestedOutput
909439
909792
  };
909440
909793
  });
909441
- const apiInputs = [{ id: "default", specIndexes: "all" }];
909442
- const runtimeBundleHashes = targets2.map((target) => (0, import_crypto10.createHash)("sha256").update(target.runtimeBundle).digest("hex"));
909794
+ const payloadHashes = targets2.map((target) => (0, import_crypto10.createHash)("sha256").update(target.payload.body).digest("hex"));
909443
909795
  const idempotencyKey = (0, import_crypto10.createHash)("sha256").update(specsTarGzBuffer).update(JSON.stringify({
909444
909796
  protocolVersion: 2,
909445
909797
  organization,
909446
909798
  apiName,
909447
909799
  apiInputs,
909448
909800
  targets: requestTargets,
909449
- runtimeBundleHashes
909801
+ payloadHashes
909450
909802
  })).digest("hex");
909451
909803
  return {
909452
909804
  protocolVersion: 2,
@@ -910574,6 +910926,33 @@ async function downloadFileForTask({ s3PreSignedReadUrl, absolutePathToLocalOutp
910574
910926
  await (0, import_promises122.pipeline)(request7.data, (0, import_fs37.createWriteStream)(absolutePathToLocalOutput));
910575
910927
  }
910576
910928
 
910929
+ // ../generation/remote-generation/remote-workspace-runner/lib/fernSdkGenApiSourceArchive.js
910930
+ function validateFernSdkGenApiSourceCompatibility(route, sourceArchive) {
910931
+ if (route.payloadKind !== "sdk-config-v1" || route.configKind !== "sdk-config-v1") {
910932
+ return;
910933
+ }
910934
+ if (sourceArchive.specIndexes.length === 0) {
910935
+ throw new Error("SDK Config v1 requires at least one effective Fern source spec");
910936
+ }
910937
+ const seenIndexes = /* @__PURE__ */ new Set();
910938
+ for (const manifestIndex of sourceArchive.specIndexes) {
910939
+ if (seenIndexes.has(manifestIndex)) {
910940
+ throw new Error(`Fern target source selection contains duplicate manifest index ${manifestIndex}`);
910941
+ }
910942
+ seenIndexes.add(manifestIndex);
910943
+ const source2 = sourceArchive.manifest.specs[manifestIndex];
910944
+ if (source2 == null) {
910945
+ throw new Error(`Fern source manifest does not contain selected index ${manifestIndex}`);
910946
+ }
910947
+ if (!isSupportedSourceType(source2.type)) {
910948
+ throw new Error(`Generator ${route.generatorId} ${route.requestedVersion} requires SDK Config v1, but selected source ${manifestIndex} cannot be represented downstream: SDK Config generation does not support Fern source type ${source2.type} (${source2.specPath}). Use an OpenAPI, AsyncAPI, or GraphQL source for this generator version.`);
910949
+ }
910950
+ }
910951
+ }
910952
+ function isSupportedSourceType(type7) {
910953
+ return type7 === "openapi" || type7 === "asyncapi" || type7 === "graphql";
910954
+ }
910955
+
910577
910956
  // ../generation/remote-generation/remote-workspace-runner/lib/resolveAutoDiscoveredFernignorePath.js
910578
910957
  init_lib12();
910579
910958
  init_lib8();
@@ -911133,26 +911512,25 @@ var SourceUploader = class {
911133
911512
  };
911134
911513
 
911135
911514
  // ../generation/remote-generation/remote-workspace-runner/lib/runRemoteGenerationForGenerator.js
911136
- async function runRemoteGenerationForGenerator({ projectConfig, organization, workspace, interactiveTaskContext, generatorInvocation, version: version7, audiences, shouldLogS3Url, token, whitelabel, replay, irVersionOverride, absolutePathToPreview, isPreview: isPreviewOverride, fiddlePreview, pushPreviewBranch, readme, fernignorePath, skipFernignore, dynamicIrOnly, retryRateLimited, requireEnvVars, automationMode, autoMerge, skipIfNoDiff, verify: verify2, noReplay, disableTelemetry, loginCommand, specsTarGzBuffer, sdkGenApiBatch, sdkGenApiTargetIdSeed, generateFullProject }) {
911515
+ async function runRemoteGenerationForGenerator({ projectConfig, organization, workspace, interactiveTaskContext, generatorInvocation, version: version7, audiences, shouldLogS3Url, token, whitelabel, replay, irVersionOverride, absolutePathToPreview, isPreview: isPreviewOverride, fiddlePreview, pushPreviewBranch, readme, fernignorePath, skipFernignore, dynamicIrOnly, retryRateLimited, requireEnvVars, automationMode, autoMerge, skipIfNoDiff, verify: verify2, noReplay, disableTelemetry, loginCommand, specsTarGzBuffer, sdkGenApiSourceArchive, sdkGenApiRoute, sdkGenApiPreparationBatch, sdkGenApiBatch, sdkGenApiTargetIdSeed, generateFullProject }) {
911137
911516
  const fdr = createFdrService({ token: token.value });
911138
911517
  const fdrOrigin = "https://registry-dev2.buildwithfern.com";
911139
911518
  const isAirGapped = await detectAirGappedMode(`${fdrOrigin}/health`, interactiveTaskContext.logger);
911140
911519
  const packageName = generators_yml_exports.getPackageName({ generatorInvocation }) ?? (generatorInvocation.outputMode.type === "downloadFiles" ? getPackageNameFromGeneratorConfig(generatorInvocation) : void 0);
911141
911520
  const isPreview = isPreviewOverride ?? absolutePathToPreview != null;
911142
- const substituteEnvVars = (stringOrObject) => replaceEnvVariables(stringOrObject, {
911143
- onError: (e2) => {
911521
+ const resolvedWhitelabel = whitelabel == null ? void 0 : replaceEnvVariables(whitelabel, {
911522
+ onError: (error50) => {
911144
911523
  if (!isPreview && requireEnvVars) {
911145
- interactiveTaskContext.failAndThrow(void 0, e2, {
911524
+ interactiveTaskContext.failAndThrow(void 0, error50, {
911146
911525
  code: CliError.Code.EnvironmentError
911147
911526
  });
911148
911527
  }
911149
911528
  }
911150
911529
  }, { substituteAsEmpty: isPreview });
911151
- const generatorInvocationWithEnvVarSubstitutions = substituteEnvVars(generatorInvocation);
911152
911530
  const dynamicGeneratorConfig = getDynamicGeneratorConfig({
911153
911531
  apiName: workspace.definition.rootApiFile.contents.name,
911154
911532
  organization,
911155
- generatorInvocation: generatorInvocationWithEnvVarSubstitutions
911533
+ generatorInvocation
911156
911534
  });
911157
911535
  const resolvedVersion = version7 ?? await computeSemanticVersion({ packageName, generatorInvocation });
911158
911536
  if (version7 != null) {
@@ -911203,10 +911581,43 @@ async function runRemoteGenerationForGenerator({ projectConfig, organization, wo
911203
911581
  ciProvider: detectCiProvider()
911204
911582
  }
911205
911583
  });
911206
- const venus = createVenusService({ token: token.value });
911584
+ let sdkGenApiCandidate;
911585
+ const sdkGenApiLanguage = getFernSdkGenApiLanguage(generatorInvocation.name);
911586
+ if (sdkGenApiRoute != null) {
911587
+ if (replay?.enabled === true) {
911588
+ return interactiveTaskContext.failAndThrow("sdk-gen-api does not yet support replay", void 0, {
911589
+ code: CliError.Code.ConfigError
911590
+ });
911591
+ }
911592
+ if (generateFullProject === true) {
911593
+ return interactiveTaskContext.failAndThrow("sdk-gen-api does not yet support full-project generation", void 0, { code: CliError.Code.ConfigError });
911594
+ }
911595
+ const candidate = {
911596
+ generatorInvocation,
911597
+ sdkVersion: resolvedVersion,
911598
+ specsTarGzBuffer,
911599
+ whitelabel
911600
+ };
911601
+ if (!isEligibleForFernSdkGenApi(candidate)) {
911602
+ const reason = resolvedVersion == null ? "the SDK version could not be resolved" : (0, import_autoversion2.isAutoVersion)(resolvedVersion) ? "automatic SDK versioning has not yet moved from Fiddle to the shared pipeline" : whitelabel != null ? "whitelabel generation has not yet moved from Fiddle to the shared pipeline" : specsTarGzBuffer == null ? "the source archive is unavailable" : `generator language ${generatorInvocation.language ?? "unknown"} does not match ${sdkGenApiLanguage}`;
911603
+ return interactiveTaskContext.failAndThrow(`Cannot submit SDK generation to sdk-gen-api: ${reason}`, void 0, {
911604
+ code: CliError.Code.ConfigError
911605
+ });
911606
+ }
911607
+ sdkGenApiCandidate = candidate;
911608
+ if (sdkGenApiRoute.payloadKind === "sdk-config-v1") {
911609
+ return interactiveTaskContext.failAndThrow(`Cannot submit ${candidate.generatorInvocation.name} ${candidate.generatorInvocation.version} from legacy Fern configuration. Run \`fern sdk migrate --output <path>\` to create SDK Config v1 before using this generator version.`, void 0, { code: CliError.Code.ConfigError });
911610
+ }
911611
+ if (sdkGenApiTargetIdSeed == null) {
911612
+ throw new Error("sdk-gen-api target is missing its preparation ID");
911613
+ }
911614
+ await sdkGenApiPreparationBatch?.ready(sdkGenApiTargetIdSeed);
911615
+ }
911616
+ const requiresFdrRegistration = sdkGenApiRoute?.payloadKind !== "sdk-config-v1";
911207
911617
  let generateOauthClients = false;
911208
911618
  let generatePaginatedClients = false;
911209
- if (!isAirGapped) {
911619
+ if (!isAirGapped && requiresFdrRegistration) {
911620
+ const venus = createVenusService({ token: token.value });
911210
911621
  const orgResponse = await venus.organization.get({ orgId: projectConfig.organization });
911211
911622
  if (orgResponse.ok) {
911212
911623
  if (orgResponse.body.isWhitelabled) {
@@ -911220,50 +911631,52 @@ async function runRemoteGenerationForGenerator({ projectConfig, organization, wo
911220
911631
  generatePaginatedClients = orgResponse.body.paginationEnabled ?? false;
911221
911632
  }
911222
911633
  }
911223
- const sources = workspace.getSources();
911224
911634
  let fdrApiDefinitionId;
911225
- let sourceUploads;
911226
- const apiDefinition = convertIrToFdrApi({
911227
- ir: ir3,
911228
- snippetsConfig: {
911229
- typescriptSdk: void 0,
911230
- pythonSdk: void 0,
911231
- javaSdk: void 0,
911232
- rubySdk: void 0,
911233
- goSdk: void 0,
911234
- csharpSdk: void 0,
911235
- phpSdk: void 0,
911236
- swiftSdk: void 0,
911237
- rustSdk: void 0
911238
- },
911239
- context: interactiveTaskContext
911240
- });
911241
- try {
911242
- const response = await fdr.api.register.registerApiDefinition({
911243
- orgId: FdrAPI_exports.OrgId(organization),
911244
- apiId: FdrAPI_exports.ApiId(getOriginalName(ir3.apiName)),
911245
- definition: apiDefinition,
911246
- sources: sources.length > 0 ? convertToFdrApiDefinitionSources(sources) : void 0
911635
+ if (requiresFdrRegistration) {
911636
+ const sources = workspace.getSources();
911637
+ let sourceUploads;
911638
+ const apiDefinition = convertIrToFdrApi({
911639
+ ir: ir3,
911640
+ snippetsConfig: {
911641
+ typescriptSdk: void 0,
911642
+ pythonSdk: void 0,
911643
+ javaSdk: void 0,
911644
+ rubySdk: void 0,
911645
+ goSdk: void 0,
911646
+ csharpSdk: void 0,
911647
+ phpSdk: void 0,
911648
+ swiftSdk: void 0,
911649
+ rustSdk: void 0
911650
+ },
911651
+ context: interactiveTaskContext
911247
911652
  });
911248
- fdrApiDefinitionId = response.apiDefinitionId;
911249
- sourceUploads = response.sources ?? void 0;
911250
- } catch (error50) {
911251
- const sourceUploader2 = new SourceUploader(interactiveTaskContext, sources);
911252
- if (sourceUploader2.sourceTypes.has("protobuf")) {
911253
- interactiveTaskContext.failAndThrow(`Failed to register API definition: ${JSON.stringify(error50)}`);
911653
+ try {
911654
+ const response = await fdr.api.register.registerApiDefinition({
911655
+ orgId: FdrAPI_exports.OrgId(organization),
911656
+ apiId: FdrAPI_exports.ApiId(getOriginalName(ir3.apiName)),
911657
+ definition: apiDefinition,
911658
+ sources: sources.length > 0 ? convertToFdrApiDefinitionSources(sources) : void 0
911659
+ });
911660
+ fdrApiDefinitionId = response.apiDefinitionId;
911661
+ sourceUploads = response.sources ?? void 0;
911662
+ } catch (error50) {
911663
+ const sourceUploader2 = new SourceUploader(interactiveTaskContext, sources);
911664
+ if (sourceUploader2.sourceTypes.has("protobuf")) {
911665
+ interactiveTaskContext.failAndThrow(`Failed to register API definition: ${JSON.stringify(error50)}`);
911666
+ }
911667
+ }
911668
+ const sourceUploader = new SourceUploader(interactiveTaskContext, sources);
911669
+ if (sourceUploads == null && sourceUploader.sourceTypes.has("protobuf")) {
911670
+ interactiveTaskContext.failAndThrow("Did not successfully upload Protobuf source files.", void 0, {
911671
+ code: CliError.Code.NetworkError
911672
+ });
911673
+ }
911674
+ if (sourceUploads != null) {
911675
+ interactiveTaskContext.logger.debug("Uploading source files ...");
911676
+ const sourceConfig = await sourceUploader.uploadSources(sourceUploads);
911677
+ interactiveTaskContext.logger.debug("Setting IR source configuration ...");
911678
+ ir3.sourceConfig = sourceConfig;
911254
911679
  }
911255
- }
911256
- const sourceUploader = new SourceUploader(interactiveTaskContext, sources);
911257
- if (sourceUploads == null && sourceUploader.sourceTypes.has("protobuf")) {
911258
- interactiveTaskContext.failAndThrow("Did not successfully upload Protobuf source files.", void 0, {
911259
- code: CliError.Code.NetworkError
911260
- });
911261
- }
911262
- if (sourceUploads != null) {
911263
- interactiveTaskContext.logger.debug("Uploading source files ...");
911264
- const sourceConfig = await sourceUploader.uploadSources(sourceUploads);
911265
- interactiveTaskContext.logger.debug("Setting IR source configuration ...");
911266
- ir3.sourceConfig = sourceConfig;
911267
911680
  }
911268
911681
  if (dynamicIrOnly) {
911269
911682
  interactiveTaskContext.logger.info("Dynamic IR only mode: skipping SDK generation and uploading dynamic IR only");
@@ -911314,7 +911727,7 @@ async function runRemoteGenerationForGenerator({ projectConfig, organization, wo
911314
911727
  ...ir3,
911315
911728
  fdrApiDefinitionId,
911316
911729
  publishConfig: getPublishConfig({
911317
- generatorInvocation: generatorInvocationWithEnvVarSubstitutions,
911730
+ generatorInvocation,
911318
911731
  version: resolvedVersion,
911319
911732
  userProvidedVersion: version7,
911320
911733
  packageName,
@@ -911324,76 +911737,56 @@ async function runRemoteGenerationForGenerator({ projectConfig, organization, wo
911324
911737
  })
911325
911738
  };
911326
911739
  let result;
911327
- let usedSdkGenApi = false;
911328
- const sdkGenApiEnabled = isFernSdkGenApiEnabled();
911329
- const sdkGenApiLanguage = getFernSdkGenApiLanguage(generatorInvocationWithEnvVarSubstitutions.name);
911330
- if (sdkGenApiEnabled && sdkGenApiLanguage != null) {
911331
- if (replay?.enabled === true) {
911332
- return interactiveTaskContext.failAndThrow("sdk-gen-api does not yet support replay", void 0, {
911333
- code: CliError.Code.ConfigError
911334
- });
911335
- }
911336
- if (generateFullProject === true) {
911337
- return interactiveTaskContext.failAndThrow("sdk-gen-api does not yet support full-project generation", void 0, { code: CliError.Code.ConfigError });
911338
- }
911339
- const candidate = {
911340
- generatorInvocation: generatorInvocationWithEnvVarSubstitutions,
911341
- sdkVersion: resolvedVersion,
911342
- specsTarGzBuffer,
911343
- whitelabel
911344
- };
911345
- if (!isEligibleForFernSdkGenApi(candidate)) {
911346
- const reason = resolvedVersion == null ? "the SDK version could not be resolved" : (0, import_autoversion2.isAutoVersion)(resolvedVersion) ? "automatic SDK versioning has not yet moved from Fiddle to the shared pipeline" : whitelabel != null ? "whitelabel generation has not yet moved from Fiddle to the shared pipeline" : specsTarGzBuffer == null ? "the source archive is unavailable" : `generator language ${generatorInvocationWithEnvVarSubstitutions.language ?? "unknown"} does not match ${sdkGenApiLanguage}`;
911347
- return interactiveTaskContext.failAndThrow(`Cannot submit SDK generation to sdk-gen-api: ${reason}`, void 0, {
911348
- code: CliError.Code.ConfigError
911349
- });
911740
+ if (sdkGenApiRoute != null) {
911741
+ if (sdkGenApiCandidate == null) {
911742
+ throw new Error("sdk-gen-api target passed preflight without an eligible candidate");
911350
911743
  }
911351
- if (verify2 === true) {
911352
- interactiveTaskContext.logger.warn("sdk-gen-api does not yet run Fern's post-generation verification step");
911744
+ if (sdkGenApiRoute.payloadKind !== "fern-runtime-bundle") {
911745
+ throw new Error("Legacy Fern generation reached sdk-gen-api without a Fern runtime bundle route");
911353
911746
  }
911354
- const runtimeBundle = await prepareFernSdkGenApiRuntimeBundle({
911355
- apiName: getOriginalName(ir3.apiName),
911356
- organization,
911357
- generatorInvocation: candidate.generatorInvocation,
911358
- sdkVersion: candidate.sdkVersion,
911359
- intermediateRepresentation: enrichedIntermediateRepresentation,
911360
- irVersionOverride,
911361
- generateOauthClients,
911362
- generatePaginatedClients,
911363
- context: interactiveTaskContext
911364
- });
911365
911747
  const parameters2 = {
911366
911748
  apiName: getOriginalName(ir3.apiName),
911367
911749
  organization,
911368
911750
  cliVersion: workspace.cliVersion,
911369
- generatorInvocation: candidate.generatorInvocation,
911370
- sdkVersion: candidate.sdkVersion,
911751
+ generatorInvocation: sdkGenApiCandidate.generatorInvocation,
911752
+ sdkVersion: sdkGenApiCandidate.sdkVersion,
911753
+ apiVersion: ir3.specVersion,
911371
911754
  token,
911372
- specsTarGzBuffer: candidate.specsTarGzBuffer,
911373
- runtimeBundle,
911755
+ specsTarGzBuffer: sdkGenApiCandidate.specsTarGzBuffer,
911756
+ payload: {
911757
+ payloadKind: sdkGenApiRoute.payloadKind,
911758
+ body: await prepareFernSdkGenApiRuntimeBundle({
911759
+ apiName: getOriginalName(ir3.apiName),
911760
+ organization,
911761
+ generatorInvocation: sdkGenApiCandidate.generatorInvocation,
911762
+ sdkVersion: sdkGenApiCandidate.sdkVersion,
911763
+ intermediateRepresentation: enrichedIntermediateRepresentation,
911764
+ irVersionOverride,
911765
+ generateOauthClients,
911766
+ generatePaginatedClients,
911767
+ context: interactiveTaskContext
911768
+ })
911769
+ },
911374
911770
  absolutePathToPreview,
911375
911771
  context: interactiveTaskContext,
911376
911772
  targetIdSeed: sdkGenApiTargetIdSeed,
911773
+ sourceSpecIndexes: sdkGenApiSourceArchive?.specIndexes,
911377
911774
  audiences: audiences.type === "select" ? audiences.audiences : void 0,
911378
911775
  skipFernignore
911379
911776
  };
911380
911777
  result = await (sdkGenApiBatch?.run(parameters2) ?? runFernSdkGenApiBuild(parameters2));
911381
- usedSdkGenApi = true;
911382
911778
  } else {
911383
- sdkGenApiBatch?.skip();
911384
- }
911385
- if (!usedSdkGenApi) {
911386
911779
  const job = await createAndStartJob({
911387
911780
  projectConfig,
911388
911781
  workspace,
911389
911782
  organization,
911390
- generatorInvocation: generatorInvocationWithEnvVarSubstitutions,
911783
+ generatorInvocation,
911391
911784
  context: interactiveTaskContext,
911392
911785
  version: resolvedVersion,
911393
911786
  intermediateRepresentation: enrichedIntermediateRepresentation,
911394
911787
  shouldLogS3Url,
911395
911788
  token,
911396
- whitelabel: whitelabel != null ? substituteEnvVars(whitelabel) : void 0,
911789
+ whitelabel: resolvedWhitelabel,
911397
911790
  replay,
911398
911791
  irVersionOverride,
911399
911792
  absolutePathToPreview,
@@ -911600,10 +911993,51 @@ async function runRemoteGenerationForAPIWorkspace({ projectConfig, organization,
911600
911993
  effectiveOccurrenceTracker.recordOccurrences(generatorGroup.generators);
911601
911994
  }
911602
911995
  const generatorsYmlAbsolutePath = workspace.generatorsConfiguration?.absolutePathToConfiguration;
911603
- const sdkGenApiCandidateIndexes = new Set(isFernSdkGenApiEnabled() ? generatorGroup.generators.flatMap((generator, index3) => getFernSdkGenApiLanguage(generator.name) != null ? [index3] : []) : []);
911996
+ const routePreparation = prepareFernSdkGenApiRoutes({
911997
+ generators: generatorGroup.generators,
911998
+ enabled: isFernSdkGenApiEnabled(),
911999
+ requireEnvVars,
912000
+ isPreview: isPreview ?? absolutePathToPreview != null,
912001
+ verify: verify2,
912002
+ skipIfNoDiff,
912003
+ autoMerge
912004
+ });
912005
+ const sdkGenApiRoutes = routePreparation.map((result) => result.route);
912006
+ const resolvedGenerators = routePreparation.map((result) => result.generatorInvocation);
912007
+ const routeErrors = routePreparation.map((result) => result.error);
912008
+ if (automation == null) {
912009
+ throwFirstPreflightError(routeErrors, generatorGroup.generators);
912010
+ }
912011
+ const sourceRequests = resolvedGenerators.flatMap((generatorInvocation, generatorIndex) => routePreparation[generatorIndex]?.error == null ? [{ generatorIndex, generatorInvocation, sdkGenApiRoute: sdkGenApiRoutes[generatorIndex] }] : []);
912012
+ let sourceResolution = { sourceArchives: /* @__PURE__ */ new Map(), errors: /* @__PURE__ */ new Map() };
912013
+ if (sourceRequests.length > 0) {
912014
+ try {
912015
+ sourceResolution = await getSpecsTarGzBuffer?.(sourceRequests) ?? sourceResolution;
912016
+ } catch (error50) {
912017
+ sourceResolution = {
912018
+ sourceArchives: /* @__PURE__ */ new Map(),
912019
+ errors: new Map(sourceRequests.map((request7) => [request7.generatorIndex, error50]))
912020
+ };
912021
+ }
912022
+ }
912023
+ const sourcePreflight = preflightFernSdkGenApiSources({
912024
+ generators: resolvedGenerators,
912025
+ routes: sdkGenApiRoutes,
912026
+ routeErrors,
912027
+ sourceResolution
912028
+ });
912029
+ const sourceArchives = sourcePreflight.sourceArchives;
912030
+ const preflightErrors = routePreparation.map((result, index3) => result.error ?? sourcePreflight.preflightErrors[index3]);
912031
+ if (automation == null) {
912032
+ throwFirstPreflightError(preflightErrors, generatorGroup.generators);
912033
+ }
912034
+ const sdkGenApiCandidateIndexes = getFernSdkGenApiCandidateIndexes(sdkGenApiRoutes, preflightErrors);
912035
+ validateFernSdkGenApiTargetCount(sdkGenApiCandidateIndexes.size);
911604
912036
  const sdkGenApiBatch = sdkGenApiCandidateIndexes.size > 1 ? new FernSdkGenApiBatch(sdkGenApiCandidateIndexes.size) : void 0;
912037
+ const sdkGenApiPreparationBatch = sdkGenApiCandidateIndexes.size > 0 ? new FernSdkGenApiPreparationBatch([...sdkGenApiCandidateIndexes].map(String)) : void 0;
911605
912038
  const results = await Promise.all(generatorGroup.generators.map((generatorInvocation, generatorIndex) => context3.runInteractiveTask({ name: generatorInvocation.name }, (interactiveTaskContext) => generateOne({
911606
912039
  generatorInvocation,
912040
+ resolvedGeneratorInvocation: resolvedGenerators[generatorIndex] ?? generatorInvocation,
911607
912041
  interactiveTaskContext,
911608
912042
  // Closed-over state + params passed through to the per-generator worker.
911609
912043
  projectConfig,
@@ -911637,7 +912071,10 @@ async function runRemoteGenerationForAPIWorkspace({ projectConfig, organization,
911637
912071
  generatorsYmlAbsolutePath,
911638
912072
  occurrenceTracker: effectiveOccurrenceTracker,
911639
912073
  loginCommand,
911640
- getSpecsTarGzBuffer,
912074
+ specsTarGzArchive: sourceArchives[generatorIndex],
912075
+ sdkGenApiPreflightError: preflightErrors[generatorIndex],
912076
+ sdkGenApiRoute: sdkGenApiRoutes[generatorIndex],
912077
+ sdkGenApiPreparationBatch: sdkGenApiCandidateIndexes.has(generatorIndex) ? sdkGenApiPreparationBatch : void 0,
911641
912078
  sdkGenApiBatch: sdkGenApiCandidateIndexes.has(generatorIndex) ? sdkGenApiBatch : void 0,
911642
912079
  sdkGenApiTargetIdSeed: generatorIndex.toString(),
911643
912080
  generateFullProject,
@@ -911650,11 +912087,105 @@ async function runRemoteGenerationForAPIWorkspace({ projectConfig, organization,
911650
912087
  snippetsProducedBy
911651
912088
  };
911652
912089
  }
911653
- async function generateOne({ generatorInvocation, interactiveTaskContext, projectConfig, organization, workspace, context: context3, generatorGroup, version: version7, shouldLogS3Url, token, whitelabel, replay, absolutePathToPreview, isPreview, fiddlePreview, pushPreviewBranch, mode, fernignorePath, skipFernignore, dynamicIrOnly, validateWorkspace, retryRateLimited, requireEnvVars, automationMode, autoMerge, skipIfNoDiff, verify: verify2, noReplay, disableTelemetry, automation, generatorsYmlAbsolutePath, occurrenceTracker, loginCommand, getSpecsTarGzBuffer, sdkGenApiBatch, sdkGenApiTargetIdSeed, generateFullProject, onSnippetsProduced }) {
912090
+ function prepareFernSdkGenApiRoutes({ generators, enabled, requireEnvVars, isPreview, verify: verify2, skipIfNoDiff, autoMerge }) {
912091
+ return generators.map((generatorInvocation) => {
912092
+ let resolved = generatorInvocation;
912093
+ try {
912094
+ resolved = replaceEnvVariables(generatorInvocation, {
912095
+ onError: (error50) => {
912096
+ if (!isPreview && requireEnvVars) {
912097
+ throw error50;
912098
+ }
912099
+ }
912100
+ }, { substituteAsEmpty: isPreview });
912101
+ const route = selectFernSdkGenApiRoute(resolved);
912102
+ if (!enabled) {
912103
+ return { generatorInvocation: resolved, route: void 0, error: void 0 };
912104
+ }
912105
+ const unsupportedOutput = getFernSdkGenApiUnsupportedOutput({
912106
+ generatorInvocation: resolved,
912107
+ verify: verify2,
912108
+ skipIfNoDiff,
912109
+ autoMerge
912110
+ });
912111
+ if (route != null && unsupportedOutput != null) {
912112
+ if (route.configKind === "legacy-fern") {
912113
+ return { generatorInvocation: resolved, route: void 0, error: void 0 };
912114
+ }
912115
+ throw new Error(`Cannot route ${resolved.name} ${resolved.version} through sdk-gen-api: ${unsupportedOutput}. This generator version requires SDK Config v1, so Fern cannot fall back to legacy Fiddle generation.`);
912116
+ }
912117
+ return {
912118
+ generatorInvocation: resolved,
912119
+ route,
912120
+ error: void 0
912121
+ };
912122
+ } catch (error50) {
912123
+ if (!enabled && error50 instanceof GeneratorConfigCompatibilityError && error50.code === "INVALID_GENERATOR_VERSION") {
912124
+ return { generatorInvocation: resolved, route: void 0, error: void 0 };
912125
+ }
912126
+ const routeError = error50 instanceof GeneratorConfigCompatibilityError ? new CliError({
912127
+ message: formatGeneratorConfigCompatibilityError(error50),
912128
+ code: CliError.Code.ConfigError
912129
+ }) : error50;
912130
+ return { generatorInvocation: resolved, route: void 0, error: routeError };
912131
+ }
912132
+ });
912133
+ }
912134
+ function getFernSdkGenApiUnsupportedOutput({ generatorInvocation, verify: verify2, skipIfNoDiff, autoMerge }) {
912135
+ const unsupported = [];
912136
+ if (generatorInvocation.outputMode.type !== "downloadFiles") {
912137
+ unsupported.push(`${generatorInvocation.outputMode.type} delivery requires Fern-managed GitHub or registry credentials that sdk-gen-api cannot resolve`);
912138
+ }
912139
+ if (verify2 === true) {
912140
+ unsupported.push("verify=true is not implemented by sdk-gen-api");
912141
+ }
912142
+ if (skipIfNoDiff === true) {
912143
+ unsupported.push("skipIfNoDiff=true is not implemented by sdk-gen-api");
912144
+ }
912145
+ if (autoMerge === true) {
912146
+ unsupported.push("autoMerge=true is not implemented by sdk-gen-api");
912147
+ }
912148
+ return unsupported.length > 0 ? unsupported.join("; ") : void 0;
912149
+ }
912150
+ function preflightFernSdkGenApiSources({ generators, routes, routeErrors, sourceResolution }) {
912151
+ return {
912152
+ sourceArchives: generators.map((_5, index3) => sourceResolution.sourceArchives.get(index3)),
912153
+ preflightErrors: generators.map((_5, index3) => {
912154
+ if (routeErrors?.[index3] != null) {
912155
+ return void 0;
912156
+ }
912157
+ const route = routes[index3];
912158
+ if (route == null) {
912159
+ return void 0;
912160
+ }
912161
+ const sourceError = sourceResolution.errors.get(index3);
912162
+ if (sourceError != null) {
912163
+ return sourceError;
912164
+ }
912165
+ const sourceArchive = sourceResolution.sourceArchives.get(index3);
912166
+ if (sourceArchive == null) {
912167
+ return new Error(`Resolved source archive is unavailable for ${route.generatorId}`);
912168
+ }
912169
+ try {
912170
+ validateFernSdkGenApiSourceCompatibility(route, sourceArchive);
912171
+ return void 0;
912172
+ } catch (error50) {
912173
+ return error50;
912174
+ }
912175
+ })
912176
+ };
912177
+ }
912178
+ function getFernSdkGenApiCandidateIndexes(routes, preflightErrors) {
912179
+ return new Set(routes.flatMap((route, index3) => route != null && preflightErrors[index3] == null ? [index3] : []));
912180
+ }
912181
+ async function generateOne({ generatorInvocation, resolvedGeneratorInvocation, interactiveTaskContext, projectConfig, organization, workspace, context: context3, generatorGroup, version: version7, shouldLogS3Url, token, whitelabel, replay, absolutePathToPreview, isPreview, fiddlePreview, pushPreviewBranch, mode, fernignorePath, skipFernignore, dynamicIrOnly, validateWorkspace, retryRateLimited, requireEnvVars, automationMode, autoMerge, skipIfNoDiff, verify: verify2, noReplay, disableTelemetry, automation, generatorsYmlAbsolutePath, occurrenceTracker, loginCommand, specsTarGzArchive, sdkGenApiPreflightError, sdkGenApiRoute, sdkGenApiPreparationBatch, sdkGenApiBatch, sdkGenApiTargetIdSeed, generateFullProject, onSnippetsProduced }) {
911654
912182
  const startedAt = Date.now();
911655
912183
  try {
911656
- const settings = getBaseOpenAPIWorkspaceSettingsFromGeneratorInvocation(generatorInvocation);
911657
- const fernWorkspace = await workspace.toFernWorkspace({ context: context3 }, settings, generatorInvocation.apiOverride?.specs);
912184
+ if (sdkGenApiPreflightError != null) {
912185
+ throw sdkGenApiPreflightError;
912186
+ }
912187
+ const settings = getBaseOpenAPIWorkspaceSettingsFromGeneratorInvocation(resolvedGeneratorInvocation);
912188
+ const fernWorkspace = await workspace.toFernWorkspace({ context: context3 }, settings, resolvedGeneratorInvocation.apiOverride?.specs);
911658
912189
  if (validateWorkspace) {
911659
912190
  await validateAPIWorkspaceAndLogIssues({
911660
912191
  workspace: fernWorkspace,
@@ -911664,7 +912195,7 @@ async function generateOne({ generatorInvocation, interactiveTaskContext, projec
911664
912195
  });
911665
912196
  }
911666
912197
  const effectiveFernignorePath = skipFernignore ? void 0 : fernignorePath ?? await resolveAutoDiscoveredFernignorePath({
911667
- generatorInvocation,
912198
+ generatorInvocation: resolvedGeneratorInvocation,
911668
912199
  context: interactiveTaskContext
911669
912200
  });
911670
912201
  const remoteTaskHandlerResponse = await runRemoteGenerationForGenerator({
@@ -911673,9 +912204,9 @@ async function generateOne({ generatorInvocation, interactiveTaskContext, projec
911673
912204
  workspace: fernWorkspace,
911674
912205
  interactiveTaskContext,
911675
912206
  generatorInvocation: {
911676
- ...generatorInvocation,
911677
- outputMode: generatorInvocation.outputMode._visit({
911678
- downloadFiles: () => generatorInvocation.outputMode,
912207
+ ...resolvedGeneratorInvocation,
912208
+ outputMode: resolvedGeneratorInvocation.outputMode._visit({
912209
+ downloadFiles: () => resolvedGeneratorInvocation.outputMode,
911679
912210
  github: (val) => {
911680
912211
  return api_exports4.OutputMode.github({
911681
912212
  ...val,
@@ -911686,11 +912217,11 @@ async function generateOne({ generatorInvocation, interactiveTaskContext, projec
911686
912217
  if (mode === "pull-request") {
911687
912218
  return api_exports4.OutputMode.githubV2(api_exports4.GithubOutputModeV2.pullRequest(val));
911688
912219
  }
911689
- return generatorInvocation.outputMode;
912220
+ return resolvedGeneratorInvocation.outputMode;
911690
912221
  },
911691
- publish: () => generatorInvocation.outputMode,
911692
- publishV2: () => generatorInvocation.outputMode,
911693
- _other: () => generatorInvocation.outputMode
912222
+ publish: () => resolvedGeneratorInvocation.outputMode,
912223
+ publishV2: () => resolvedGeneratorInvocation.outputMode,
912224
+ _other: () => resolvedGeneratorInvocation.outputMode
911694
912225
  })
911695
912226
  },
911696
912227
  version: version7,
@@ -911699,8 +912230,8 @@ async function generateOne({ generatorInvocation, interactiveTaskContext, projec
911699
912230
  token,
911700
912231
  whitelabel,
911701
912232
  replay,
911702
- readme: generatorInvocation.readme,
911703
- irVersionOverride: generatorInvocation.irVersionOverride,
912233
+ readme: resolvedGeneratorInvocation.readme,
912234
+ irVersionOverride: resolvedGeneratorInvocation.irVersionOverride,
911704
912235
  absolutePathToPreview,
911705
912236
  isPreview,
911706
912237
  fiddlePreview,
@@ -911717,7 +912248,10 @@ async function generateOne({ generatorInvocation, interactiveTaskContext, projec
911717
912248
  noReplay,
911718
912249
  disableTelemetry,
911719
912250
  loginCommand,
911720
- specsTarGzBuffer: await getSpecsTarGzBuffer?.(generatorInvocation.name),
912251
+ specsTarGzBuffer: specsTarGzArchive?.buffer,
912252
+ sdkGenApiSourceArchive: specsTarGzArchive,
912253
+ sdkGenApiRoute,
912254
+ sdkGenApiPreparationBatch,
911721
912255
  sdkGenApiBatch,
911722
912256
  sdkGenApiTargetIdSeed,
911723
912257
  generateFullProject
@@ -911759,7 +912293,12 @@ async function generateOne({ generatorInvocation, interactiveTaskContext, projec
911759
912293
  isAutomation: automation != null
911760
912294
  });
911761
912295
  } catch (error50) {
911762
- sdkGenApiBatch?.cancel(error50);
912296
+ sdkGenApiPreparationBatch?.fail(sdkGenApiTargetIdSeed, error50, automation != null);
912297
+ if (automation != null) {
912298
+ sdkGenApiBatch?.remove(sdkGenApiTargetIdSeed, error50);
912299
+ } else {
912300
+ sdkGenApiBatch?.cancel(error50);
912301
+ }
911763
912302
  if (automation == null) {
911764
912303
  throw error50;
911765
912304
  }
@@ -911794,6 +912333,17 @@ async function generateOne({ generatorInvocation, interactiveTaskContext, projec
911794
912333
  });
911795
912334
  }
911796
912335
  }
912336
+ function throwFirstPreflightError(errors4, generators) {
912337
+ const failedIndex = errors4.findIndex((error51) => error51 != null);
912338
+ if (failedIndex < 0) {
912339
+ return;
912340
+ }
912341
+ const error50 = errors4[failedIndex];
912342
+ if (error50 instanceof CliError) {
912343
+ throw error50;
912344
+ }
912345
+ throw new Error(`Cannot prepare sdk-gen-api target ${generators[failedIndex]?.name ?? failedIndex.toString()}: ${extractErrorMessage(error50)}`, { cause: error50 });
912346
+ }
911797
912347
  async function emitGenerationAnnotations(ctx) {
911798
912348
  if (!shouldEmitGithubAnnotations()) {
911799
912349
  return;
@@ -914026,7 +914576,7 @@ var LegacyDocsPublisher = class {
914026
914576
  previewId,
914027
914577
  disableTemplates: void 0,
914028
914578
  skipUpload,
914029
- cliVersion: "5.110.1",
914579
+ cliVersion: "5.112.0",
914030
914580
  loginCommand: "fern auth login"
914031
914581
  });
914032
914582
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -930503,16 +931053,16 @@ var TestClass = class extends Node5 {
930503
931053
  };
930504
931054
 
930505
931055
  // ../../../generators/csharp/codegen/lib/context/filesystem-nuget-publish-target.js
930506
- function isRecord2(value2) {
931056
+ function isRecord3(value2) {
930507
931057
  return typeof value2 === "object" && value2 != null;
930508
931058
  }
930509
931059
  function getFilesystemNugetPublishTarget(ir3) {
930510
931060
  const publishConfig = ir3.publishConfig;
930511
- if (!isRecord2(publishConfig) || publishConfig.type !== "filesystem") {
931061
+ if (!isRecord3(publishConfig) || publishConfig.type !== "filesystem") {
930512
931062
  return void 0;
930513
931063
  }
930514
931064
  const publishTarget = publishConfig.publishTarget;
930515
- if (!isRecord2(publishTarget) || publishTarget.type !== "nuget") {
931065
+ if (!isRecord3(publishTarget) || publishTarget.type !== "nuget") {
930516
931066
  return void 0;
930517
931067
  }
930518
931068
  return {
@@ -968321,6 +968871,8 @@ async function copySnippetJsonIfNonEmpty({ src, dest }) {
968321
968871
  }
968322
968872
 
968323
968873
  // ../generation/local-generation/local-workspace-runner/lib/rawSpecs.js
968874
+ var import_node_util10 = require("util");
968875
+ init_lib17();
968324
968876
  init_lib4();
968325
968877
  init_lib8();
968326
968878
  init_lib35();
@@ -968363,7 +968915,14 @@ async function collectRawSpecs({ specs, hostOutputDir, containerBaseDir, context
968363
968915
  async function resolveAndWriteSpec({ spec, hostOutputDir, containerBaseDir, context: context3, index: index3, audiences }) {
968364
968916
  switch (spec.type) {
968365
968917
  case "openapi":
968366
- return resolveOpenAPIOrAsyncAPI({ spec, hostOutputDir, containerBaseDir, context: context3, index: index3, audiences });
968918
+ return resolveOpenAPIOrAsyncAPI({
968919
+ spec,
968920
+ hostOutputDir,
968921
+ containerBaseDir,
968922
+ context: context3,
968923
+ index: index3,
968924
+ audiences
968925
+ });
968367
968926
  case "openrpc":
968368
968927
  return resolveOpenRPC({ spec, hostOutputDir, containerBaseDir, context: context3, index: index3 });
968369
968928
  case "protobuf":
@@ -968398,9 +968957,41 @@ async function resolveOpenAPIOrAsyncAPI({ spec, hostOutputDir, containerBaseDir,
968398
968957
  return {
968399
968958
  type: isAsync2 ? "asyncapi" : "openapi",
968400
968959
  specPath: toContainerPath(filename, containerBaseDir),
968401
- namespace: spec.namespace
968960
+ namespace: spec.namespace,
968961
+ apiImportSettings: mapApiImportSettings(getOpenAPISettings({ overrides: spec.settings }))
968402
968962
  };
968403
968963
  }
968964
+ var SDK_CONFIG_IMPORT_SETTING_MAPPERS = {
968965
+ respectNullableSchemas: (settings) => ({ respectNullableSchemas: settings.respectNullableSchemas }),
968966
+ useTitlesAsName: (settings) => ({ titleAsSchemaName: settings.useTitlesAsName }),
968967
+ coerceEnumsToLiterals: (settings) => ({ coerceEnumsToLiterals: settings.coerceEnumsToLiterals }),
968968
+ shouldUseIdiomaticRequestNames: (settings) => ({
968969
+ idiomaticRequestNames: settings.shouldUseIdiomaticRequestNames
968970
+ }),
968971
+ wrapReferencesToNullableInOptional: (settings) => ({
968972
+ wrapReferencesToNullableInOptional: settings.wrapReferencesToNullableInOptional
968973
+ }),
968974
+ coerceOptionalSchemasToNullable: (settings) => ({
968975
+ coerceOptionalSchemasToNullable: settings.coerceOptionalSchemasToNullable
968976
+ }),
968977
+ pathParameterOrder: (settings) => ({ pathParameterOrder: settings.pathParameterOrder }),
968978
+ onlyIncludeReferencedSchemas: (settings) => ({
968979
+ onlyIncludeReferencedSchemas: settings.onlyIncludeReferencedSchemas
968980
+ }),
968981
+ objectQueryParameters: (settings) => ({ objectQueryParameters: settings.objectQueryParameters }),
968982
+ typeDatesAsStrings: (settings) => ({ typeDatesAsStrings: settings.typeDatesAsStrings }),
968983
+ groupMultiApiEnvironments: (settings) => ({
968984
+ groupMultiApiEnvironments: settings.groupMultiApiEnvironments
968985
+ }),
968986
+ defaultIntegerFormat: (settings) => ({ defaultIntegerFormat: settings.defaultIntegerFormat })
968987
+ };
968988
+ function mapApiImportSettings(settings) {
968989
+ const mappedSettings = {};
968990
+ for (const mapSetting of Object.values(SDK_CONFIG_IMPORT_SETTING_MAPPERS)) {
968991
+ Object.assign(mappedSettings, mapSetting(settings));
968992
+ }
968993
+ return mappedSettings;
968994
+ }
968404
968995
  async function resolveOpenRPC({ spec, hostOutputDir, containerBaseDir, context: context3, index: index3 }) {
968405
968996
  const filename = `openrpc${index3}.json`;
968406
968997
  const rawContent = await (0, import_promises143.readFile)(spec.absoluteFilepath, "utf-8");
@@ -968574,30 +969165,318 @@ function matchesAudiences(operation, selectedAudiences) {
968574
969165
  function hasOperations(pathItem) {
968575
969166
  return Object.keys(pathItem).some((key2) => HTTP_METHODS3.has(key2.toLowerCase()));
968576
969167
  }
968577
- async function createSpecsTarGzBuffer({ specs, context: context3, audiences }) {
969168
+ async function createGroupedSpecsTarGzArchiveSettled({ generatorSelections, context: context3, audiences }) {
969169
+ const deduplicated = deduplicateGeneratorSelections(generatorSelections);
969170
+ const errorsByGeneratorIndex = /* @__PURE__ */ new Map();
968578
969171
  const tmpDir = await import_tmp_promise17.default.dir({ unsafeCleanup: true });
968579
969172
  try {
969173
+ const materializedRoot = import_path99.default.join(tmpDir.path, "materialized");
969174
+ await (0, import_promises143.mkdir)(materializedRoot);
969175
+ const materializedSpecs = await Promise.allSettled(deduplicated.uniqueSpecs.map(async (spec, uniqueSpecIndex) => {
969176
+ const directory = import_path99.default.join(materializedRoot, uniqueSpecIndex.toString());
969177
+ await (0, import_promises143.mkdir)(directory);
969178
+ const manifest = await collectRawSpecs({
969179
+ specs: [spec],
969180
+ hostOutputDir: AbsoluteFilePath2.of(directory),
969181
+ containerBaseDir: "/fern/specs",
969182
+ context: context3,
969183
+ audiences
969184
+ });
969185
+ const manifestEntry = manifest.specs[0];
969186
+ if (manifestEntry == null) {
969187
+ throw new Error(`Materialized source ${uniqueSpecIndex} did not produce a manifest entry`);
969188
+ }
969189
+ return { directory, manifestEntry };
969190
+ }));
969191
+ materializedSpecs.forEach((result, uniqueSpecIndex) => {
969192
+ if (result.status === "fulfilled") {
969193
+ return;
969194
+ }
969195
+ for (const generatorIndex of deduplicated.generatorIndexesByUniqueSpecIndex[uniqueSpecIndex] ?? []) {
969196
+ if (!errorsByGeneratorIndex.has(generatorIndex)) {
969197
+ errorsByGeneratorIndex.set(generatorIndex, result.reason);
969198
+ }
969199
+ }
969200
+ });
969201
+ const successfulGeneratorIndexes = new Set(generatorSelections.map((selection) => selection.generatorIndex).filter((generatorIndex) => !errorsByGeneratorIndex.has(generatorIndex)));
969202
+ if (successfulGeneratorIndexes.size === 0) {
969203
+ return { archive: void 0, errorsByGeneratorIndex };
969204
+ }
969205
+ try {
969206
+ const archive3 = await createArchiveFromMaterializedSpecs({
969207
+ materializedSpecs,
969208
+ deduplicated,
969209
+ successfulGeneratorIndexes,
969210
+ root: tmpDir.path
969211
+ });
969212
+ assertGeneratorSelectionOutcomes({ generatorSelections, archive: archive3, errorsByGeneratorIndex });
969213
+ return { archive: archive3, errorsByGeneratorIndex };
969214
+ } catch (error50) {
969215
+ for (const generatorIndex of successfulGeneratorIndexes) {
969216
+ errorsByGeneratorIndex.set(generatorIndex, error50);
969217
+ }
969218
+ return { archive: void 0, errorsByGeneratorIndex };
969219
+ }
969220
+ } finally {
969221
+ await tmpDir.cleanup();
969222
+ }
969223
+ }
969224
+ function deduplicateGeneratorSelections(generatorSelections) {
969225
+ const uniqueSpecs = [];
969226
+ const indexesBySpecKey = /* @__PURE__ */ new Map();
969227
+ const uniqueSpecIndexesByGeneratorIndex = /* @__PURE__ */ new Map();
969228
+ const generatorIndexesByUniqueSpecIndex = [];
969229
+ const orderedSelections = [...generatorSelections].sort((left3, right3) => left3.generatorIndex - right3.generatorIndex);
969230
+ for (const selection of orderedSelections) {
969231
+ if (uniqueSpecIndexesByGeneratorIndex.has(selection.generatorIndex)) {
969232
+ throw new Error(`Duplicate source selection for generator index ${selection.generatorIndex}`);
969233
+ }
969234
+ const indexes = selection.specs.map((spec) => {
969235
+ const key2 = createSpecDeduplicationKey(spec);
969236
+ const existingIndex = indexesBySpecKey.get(key2);
969237
+ if (existingIndex != null) {
969238
+ return existingIndex;
969239
+ }
969240
+ const index3 = uniqueSpecs.length;
969241
+ uniqueSpecs.push(spec);
969242
+ indexesBySpecKey.set(key2, index3);
969243
+ generatorIndexesByUniqueSpecIndex[index3] = /* @__PURE__ */ new Set();
969244
+ return index3;
969245
+ });
969246
+ for (const index3 of new Set(indexes)) {
969247
+ generatorIndexesByUniqueSpecIndex[index3]?.add(selection.generatorIndex);
969248
+ }
969249
+ uniqueSpecIndexesByGeneratorIndex.set(selection.generatorIndex, [...new Set(indexes)]);
969250
+ }
969251
+ return { uniqueSpecs, uniqueSpecIndexesByGeneratorIndex, generatorIndexesByUniqueSpecIndex };
969252
+ }
969253
+ async function createArchiveFromMaterializedSpecs({ materializedSpecs, deduplicated, successfulGeneratorIndexes, root: root6 }) {
969254
+ const contentDirectory = import_path99.default.join(root6, "content");
969255
+ await (0, import_promises143.mkdir)(contentDirectory);
969256
+ const manifest = { specs: [] };
969257
+ const archiveSpecIndexByUniqueSpecIndex = /* @__PURE__ */ new Map();
969258
+ const typeCounters = /* @__PURE__ */ new Map();
969259
+ for (const [uniqueSpecIndex, generatorIndexes] of deduplicated.generatorIndexesByUniqueSpecIndex.entries()) {
969260
+ if (![...generatorIndexes].some((generatorIndex) => successfulGeneratorIndexes.has(generatorIndex))) {
969261
+ continue;
969262
+ }
969263
+ const materialized = materializedSpecs[uniqueSpecIndex];
969264
+ if (materialized?.status !== "fulfilled") {
969265
+ throw new Error(`Successful generator references source ${uniqueSpecIndex}, which was not materialized`);
969266
+ }
969267
+ const type7 = materialized.value.manifestEntry.type;
969268
+ const typeIndex = typeCounters.get(type7) ?? 0;
969269
+ typeCounters.set(type7, typeIndex + 1);
969270
+ const manifestEntry = await copyMaterializedSpec({
969271
+ materialized: materialized.value,
969272
+ contentDirectory,
969273
+ typeIndex
969274
+ });
969275
+ archiveSpecIndexByUniqueSpecIndex.set(uniqueSpecIndex, manifest.specs.length);
969276
+ manifest.specs.push(manifestEntry);
969277
+ }
969278
+ const specIndexesByGeneratorIndex = /* @__PURE__ */ new Map();
969279
+ for (const [generatorIndex, uniqueSpecIndexes] of deduplicated.uniqueSpecIndexesByGeneratorIndex) {
969280
+ if (!successfulGeneratorIndexes.has(generatorIndex)) {
969281
+ continue;
969282
+ }
969283
+ specIndexesByGeneratorIndex.set(generatorIndex, uniqueSpecIndexes.map((uniqueSpecIndex) => {
969284
+ const archiveSpecIndex = archiveSpecIndexByUniqueSpecIndex.get(uniqueSpecIndex);
969285
+ if (archiveSpecIndex == null) {
969286
+ throw new Error(`Source ${uniqueSpecIndex} is unavailable for generator index ${generatorIndex}`);
969287
+ }
969288
+ return archiveSpecIndex;
969289
+ }));
969290
+ }
969291
+ const archive3 = await createArchiveFromDirectory({
969292
+ contentDirectory,
969293
+ tarGzPath: import_path99.default.join(root6, "specs.tar.gz"),
969294
+ manifest
969295
+ });
969296
+ return { ...archive3, specIndexesByGeneratorIndex };
969297
+ }
969298
+ async function copyMaterializedSpec({ materialized, contentDirectory, typeIndex }) {
969299
+ const sourcePrefix = `${materialized.manifestEntry.type}0`;
969300
+ const targetPrefix = `${materialized.manifestEntry.type}${typeIndex}`;
969301
+ assertSupportedMaterializedManifestEntry(materialized.manifestEntry);
969302
+ for (const entry of await (0, import_promises143.readdir)(materialized.directory, { withFileTypes: true })) {
969303
+ if (!hasSourcePrefix(entry.name) || !entry.isFile() && !entry.isDirectory()) {
969304
+ throw new Error(`Unsupported materialized source entry: ${entry.name}`);
969305
+ }
969306
+ await (0, import_promises143.cp)(import_path99.default.join(materialized.directory, entry.name), import_path99.default.join(contentDirectory, replacePrefix(entry.name)), {
969307
+ recursive: entry.isDirectory()
969308
+ });
969309
+ }
969310
+ return {
969311
+ ...materialized.manifestEntry,
969312
+ specPath: replaceContainerPathPrefix(materialized.manifestEntry.specPath),
969313
+ ...materialized.manifestEntry.overridePaths == null ? {} : {
969314
+ overridePaths: materialized.manifestEntry.overridePaths.map(replaceContainerPathPrefix)
969315
+ }
969316
+ };
969317
+ function replacePrefix(value2) {
969318
+ return `${targetPrefix}${value2.slice(sourcePrefix.length)}`;
969319
+ }
969320
+ function hasSourcePrefix(value2) {
969321
+ return value2 === sourcePrefix || value2.startsWith(`${sourcePrefix}.`) || value2.startsWith(`${sourcePrefix}-`);
969322
+ }
969323
+ function replaceContainerPathPrefix(value2) {
969324
+ const basename8 = import_path99.default.posix.basename(value2);
969325
+ if (!hasSourcePrefix(basename8)) {
969326
+ throw new Error(`Unexpected materialized source path: ${value2}`);
969327
+ }
969328
+ return import_path99.default.posix.join(import_path99.default.posix.dirname(value2), replacePrefix(basename8));
969329
+ }
969330
+ }
969331
+ var SUPPORTED_MATERIALIZED_MANIFEST_ENTRY_KEYS = /* @__PURE__ */ new Set([
969332
+ "type",
969333
+ "specPath",
969334
+ "overridePaths",
969335
+ "namespace",
969336
+ "apiImportSettings"
969337
+ ]);
969338
+ function assertSupportedMaterializedManifestEntry(entry) {
969339
+ for (const key2 of Object.keys(entry)) {
969340
+ if (!SUPPORTED_MATERIALIZED_MANIFEST_ENTRY_KEYS.has(key2)) {
969341
+ throw new Error(`Unsupported materialized manifest entry field: ${key2}`);
969342
+ }
969343
+ }
969344
+ }
969345
+ function assertGeneratorSelectionOutcomes({ generatorSelections, archive: archive3, errorsByGeneratorIndex }) {
969346
+ for (const { generatorIndex } of generatorSelections) {
969347
+ const hasArchive = archive3.specIndexesByGeneratorIndex.has(generatorIndex);
969348
+ const hasError = errorsByGeneratorIndex.has(generatorIndex);
969349
+ if (hasArchive === hasError) {
969350
+ throw new Error(`Generator index ${generatorIndex} must have exactly one source archive or materialization error outcome`);
969351
+ }
969352
+ }
969353
+ }
969354
+ var SDK_CONFIG_IMPORT_SETTING_KEYS = new Set(Object.keys(SDK_CONFIG_IMPORT_SETTING_MAPPERS));
969355
+ var DEFAULT_OPENAPI_SETTINGS = getOpenAPISettings();
969356
+ function validateSdkConfigImportSettings(specs) {
969357
+ for (const spec of specs) {
969358
+ if (spec.type !== "openapi") {
969359
+ continue;
969360
+ }
969361
+ const settings = getOpenAPISettings({ overrides: spec.settings });
969362
+ for (const key2 of Object.getOwnPropertyNames(settings)) {
969363
+ const value2 = Reflect.get(settings, key2);
969364
+ if (SDK_CONFIG_IMPORT_SETTING_KEYS.has(key2) || key2 === "audiences" && Array.isArray(value2) && value2.length === 0 || (0, import_node_util10.isDeepStrictEqual)(value2, Reflect.get(DEFAULT_OPENAPI_SETTINGS, key2))) {
969365
+ continue;
969366
+ }
969367
+ throw new Error(`SDK Config v1 cannot preserve effective OpenAPI import setting ${key2}=${JSON.stringify(value2)} for ${spec.absoluteFilepath}. Remove that setting or use a pre-cutover generator version until the shared SDK Config contract supports it.`);
969368
+ }
969369
+ }
969370
+ }
969371
+ async function createSpecsTarGzArchive({ specs, context: context3, audiences }) {
969372
+ const tmpDir = await import_tmp_promise17.default.dir({ unsafeCleanup: true });
969373
+ try {
969374
+ const contentDirectory = import_path99.default.join(tmpDir.path, "content");
969375
+ await (0, import_promises143.mkdir)(contentDirectory);
968580
969376
  const manifest = await collectRawSpecs({
968581
969377
  specs,
968582
- hostOutputDir: AbsoluteFilePath2.of(tmpDir.path),
969378
+ hostOutputDir: AbsoluteFilePath2.of(contentDirectory),
968583
969379
  containerBaseDir: "/fern/specs",
968584
969380
  context: context3,
968585
969381
  audiences
968586
969382
  });
968587
- await (0, import_promises143.writeFile)(join8(AbsoluteFilePath2.of(tmpDir.path), RelativeFilePath2.of(SPECS_MANIFEST_FILENAME)), JSON.stringify(manifest, void 0, 4));
968588
- const tarGzPath = join8(AbsoluteFilePath2.of(tmpDir.path), RelativeFilePath2.of("specs.tar.gz"));
968589
- await Kn({
968590
- gzip: true,
968591
- cwd: tmpDir.path,
968592
- file: tarGzPath,
968593
- portable: true,
968594
- filter: (entryPath) => entryPath !== "./specs.tar.gz"
968595
- }, ["."]);
968596
- return await (0, import_promises143.readFile)(tarGzPath);
969383
+ return await createArchiveFromDirectory({
969384
+ contentDirectory,
969385
+ tarGzPath: import_path99.default.join(tmpDir.path, "specs.tar.gz"),
969386
+ manifest
969387
+ });
968597
969388
  } finally {
968598
969389
  await tmpDir.cleanup();
968599
969390
  }
968600
969391
  }
969392
+ async function createArchiveFromDirectory({ contentDirectory, tarGzPath, manifest }) {
969393
+ await (0, import_promises143.writeFile)(join8(AbsoluteFilePath2.of(contentDirectory), RelativeFilePath2.of(SPECS_MANIFEST_FILENAME)), JSON.stringify(manifest, void 0, 4));
969394
+ const archiveEntries = await listDeterministicArchiveEntries(contentDirectory);
969395
+ await Kn({
969396
+ gzip: true,
969397
+ cwd: contentDirectory,
969398
+ file: tarGzPath,
969399
+ portable: true,
969400
+ mtime: /* @__PURE__ */ new Date(0),
969401
+ onWriteEntry: (entry) => {
969402
+ if (entry.stat != null) {
969403
+ entry.stat.mode = 420;
969404
+ }
969405
+ }
969406
+ }, archiveEntries);
969407
+ return { buffer: await (0, import_promises143.readFile)(tarGzPath), manifest };
969408
+ }
969409
+ async function listDeterministicArchiveEntries(root6, relativeDirectory = "") {
969410
+ const absoluteDirectory = relativeDirectory === "" ? root6 : import_path99.default.join(root6, ...relativeDirectory.split(import_path99.default.posix.sep));
969411
+ const directoryEntries = await (0, import_promises143.readdir)(absoluteDirectory, { withFileTypes: true });
969412
+ const archiveEntries = [];
969413
+ for (const entry of directoryEntries.sort((left3, right3) => compareStrings(left3.name, right3.name))) {
969414
+ const relativePath = import_path99.default.posix.join(relativeDirectory, entry.name);
969415
+ if (entry.isDirectory()) {
969416
+ archiveEntries.push(...await listDeterministicArchiveEntries(root6, relativePath));
969417
+ continue;
969418
+ }
969419
+ if (!entry.isFile()) {
969420
+ throw new Error(`Unsupported generated source archive entry: ${relativePath}`);
969421
+ }
969422
+ archiveEntries.push(relativePath);
969423
+ }
969424
+ return archiveEntries;
969425
+ }
969426
+ function compareStrings(left3, right3) {
969427
+ return left3 < right3 ? -1 : left3 > right3 ? 1 : 0;
969428
+ }
969429
+ function createSpecDeduplicationKey(spec) {
969430
+ switch (spec.type) {
969431
+ case "openapi":
969432
+ return stableStringify3({
969433
+ type: spec.type,
969434
+ path: spec.absoluteFilepath,
969435
+ overrides: normalizeOverrides(spec.absoluteFilepathToOverrides),
969436
+ overlay: spec.absoluteFilepathToOverlays,
969437
+ namespace: spec.namespace,
969438
+ settings: getOpenAPISettings({ overrides: spec.settings })
969439
+ });
969440
+ case "openrpc":
969441
+ return stableStringify3({
969442
+ type: spec.type,
969443
+ path: spec.absoluteFilepath,
969444
+ overrides: normalizeOverrides(spec.absoluteFilepathToOverrides),
969445
+ namespace: spec.namespace
969446
+ });
969447
+ case "protobuf":
969448
+ return stableStringify3({
969449
+ type: spec.type,
969450
+ root: spec.absoluteFilepathToProtobufRoot,
969451
+ target: spec.absoluteFilepathToProtobufTarget,
969452
+ overrides: normalizeOverrides(spec.absoluteFilepathToOverrides),
969453
+ dependencies: spec.dependencies,
969454
+ settings: getOpenAPISettings({ overrides: spec.settings })
969455
+ });
969456
+ case "graphql":
969457
+ return stableStringify3({
969458
+ type: spec.type,
969459
+ path: spec.absoluteFilepath,
969460
+ overrides: normalizeOverrides(spec.absoluteFilepathToOverrides),
969461
+ examples: spec.absoluteFilepathToExamples,
969462
+ namespace: spec.namespace
969463
+ });
969464
+ default:
969465
+ assertNever(spec);
969466
+ }
969467
+ }
969468
+ function stableStringify3(value2) {
969469
+ return JSON.stringify(sortJsonValue(value2));
969470
+ }
969471
+ function sortJsonValue(value2) {
969472
+ if (Array.isArray(value2)) {
969473
+ return value2.map(sortJsonValue);
969474
+ }
969475
+ if (value2 == null || typeof value2 !== "object") {
969476
+ return value2;
969477
+ }
969478
+ return Object.fromEntries(Object.entries(value2).sort(([left3], [right3]) => compareStrings(left3, right3)).map(([key2, child]) => [key2, sortJsonValue(child)]));
969479
+ }
968601
969480
 
968602
969481
  // ../generation/local-generation/local-workspace-runner/lib/runGenerator.js
968603
969482
  function extractLicenseFilePath(generatorInvocation, absolutePathToFernConfig) {
@@ -973201,11 +974080,11 @@ function getFirstUrlSegment({ path: path122 }) {
973201
974080
  }
973202
974081
 
973203
974082
  // ../docs-importers/mintlify/lib/MintlifyImporter.js
973204
- function isRecord3(value2) {
974083
+ function isRecord4(value2) {
973205
974084
  return typeof value2 === "object" && value2 != null && !Array.isArray(value2);
973206
974085
  }
973207
974086
  function hasNavigationArray(value2) {
973208
- return isRecord3(value2) && Array.isArray(value2.navigation);
974087
+ return isRecord4(value2) && Array.isArray(value2.navigation);
973209
974088
  }
973210
974089
  var MintlifyImporter = class extends DocsImporter {
973211
974090
  documentationTab = void 0;
@@ -979497,7 +980376,7 @@ var {
979497
980376
  } = signalExitWrap(processOk(process21) ? new SignalExit(process21) : new SignalExitFallback());
979498
980377
 
979499
980378
  // ../../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@22.19.17/node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
979500
- var import_node_util10 = require("util");
980379
+ var import_node_util11 = require("util");
979501
980380
 
979502
980381
  // ../../../node_modules/.pnpm/@inquirer+ansi@1.0.2/node_modules/@inquirer/ansi/dist/esm/index.js
979503
980382
  var ESC2 = "\x1B[";
@@ -979535,7 +980414,7 @@ var ScreenManager2 = class {
979535
980414
  }
979536
980415
  render(content5, bottomContent = "") {
979537
980416
  const promptLine = lastLine2(content5);
979538
- const rawPromptLine = (0, import_node_util10.stripVTControlCharacters)(promptLine);
980417
+ const rawPromptLine = (0, import_node_util11.stripVTControlCharacters)(promptLine);
979539
980418
  let prompt2 = rawPromptLine;
979540
980419
  if (this.rl.line.length > 0) {
979541
980420
  prompt2 = prompt2.slice(0, -this.rl.line.length);
@@ -980946,7 +981825,7 @@ function getAutomationContextFromEnv() {
980946
981825
  config_branch: process.env.FERN_CONFIG_BRANCH,
980947
981826
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
980948
981827
  trigger: process.env.GITHUB_EVENT_NAME,
980949
- cli_version: "5.110.1"
981828
+ cli_version: "5.112.0"
980950
981829
  };
980951
981830
  }
980952
981831
  function isAutomationMode() {
@@ -981778,7 +982657,7 @@ var CliContext = class _CliContext {
981778
982657
  if (false) {
981779
982658
  this.logger.error("CLI_VERSION is not defined");
981780
982659
  }
981781
- return "5.110.1";
982660
+ return "5.112.0";
981782
982661
  }
981783
982662
  getCliName() {
981784
982663
  if (false) {
@@ -983421,18 +984300,118 @@ function expandGroupFilter(groupNames, generatorsConfiguration) {
983421
984300
  // src/commands/generate/generateAPIWorkspace.ts
983422
984301
  init_lib20();
983423
984302
  init_lib8();
983424
- init_lib35();
983425
984303
  init_lib6();
983426
984304
  init_esm18();
983427
984305
 
983428
- // src/commands/generate/createSpecsTarGzCache.ts
983429
- function createSpecsTarGzCache(createArchive) {
983430
- let archivePromise;
983431
- return () => {
983432
- archivePromise ??= createArchive();
983433
- return archivePromise;
984306
+ // src/commands/generate/createFernSourceArchiveResolver.ts
984307
+ init_lib35();
984308
+ function createFernSourceArchiveResolver({
984309
+ workspace,
984310
+ context: context3,
984311
+ group
984312
+ }) {
984313
+ return async (requests3) => {
984314
+ const sourceArchives = /* @__PURE__ */ new Map();
984315
+ const errors4 = /* @__PURE__ */ new Map();
984316
+ if (!(workspace instanceof OSSWorkspace)) {
984317
+ for (const request7 of requests3) {
984318
+ if (requestRequiresSourceArchive(request7)) {
984319
+ errors4.set(
984320
+ request7.generatorIndex,
984321
+ new Error(
984322
+ `Generator index ${request7.generatorIndex} (${request7.generatorInvocation.name}) requires a source archive, but workspace type ${workspace.type} does not expose source specs`
984323
+ )
984324
+ );
984325
+ }
984326
+ }
984327
+ return { sourceArchives, errors: errors4 };
984328
+ }
984329
+ const settledSelections = await Promise.allSettled(
984330
+ requests3.map(async (request7) => {
984331
+ if (request7.sdkGenApiRoute == null) {
984332
+ return void 0;
984333
+ }
984334
+ const specs = await workspace.getAllSpecsForGenerator(request7.generatorInvocation.apiOverride?.specs);
984335
+ if (request7.sdkGenApiRoute.payloadKind === "sdk-config-v1") {
984336
+ validateSdkConfigImportSettings(specs);
984337
+ }
984338
+ return specs;
984339
+ })
984340
+ );
984341
+ const generatorSelections = settledSelections.flatMap((result, index3) => {
984342
+ const request7 = requests3[index3];
984343
+ if (request7 == null) {
984344
+ throw new Error(`Missing source archive request at settled index ${index3}`);
984345
+ }
984346
+ if (result.status === "rejected") {
984347
+ errors4.set(request7.generatorIndex, result.reason);
984348
+ return [];
984349
+ }
984350
+ return result.value == null ? [] : [{ generatorIndex: request7.generatorIndex, specs: result.value }];
984351
+ });
984352
+ if (generatorSelections.length > 0) {
984353
+ const settledArchive = await createGroupedSpecsTarGzArchiveSettled({
984354
+ generatorSelections,
984355
+ context: context3,
984356
+ audiences: group.audiences
984357
+ });
984358
+ for (const [generatorIndex, error50] of settledArchive.errorsByGeneratorIndex) {
984359
+ errors4.set(generatorIndex, error50);
984360
+ }
984361
+ if (settledArchive.archive != null) {
984362
+ const { specIndexesByGeneratorIndex, ...sourceArchive } = settledArchive.archive;
984363
+ for (const [generatorIndex, specIndexes] of specIndexesByGeneratorIndex) {
984364
+ sourceArchives.set(generatorIndex, { ...sourceArchive, specIndexes });
984365
+ }
984366
+ }
984367
+ }
984368
+ const rootRequests = requests3.filter(
984369
+ (request7) => request7.sdkGenApiRoute == null && generatorWantsSpecs(request7.generatorInvocation.name) && !errors4.has(request7.generatorIndex)
984370
+ );
984371
+ if (rootRequests.length > 0) {
984372
+ try {
984373
+ const archive3 = await createSpecsTarGzArchive({
984374
+ specs: workspace.allSpecs,
984375
+ context: context3,
984376
+ audiences: group.audiences
984377
+ });
984378
+ const specIndexes = archive3.manifest.specs.map((_5, index3) => index3);
984379
+ for (const request7 of rootRequests) {
984380
+ sourceArchives.set(request7.generatorIndex, { ...archive3, specIndexes });
984381
+ }
984382
+ } catch (error50) {
984383
+ for (const request7 of rootRequests) {
984384
+ errors4.set(request7.generatorIndex, error50);
984385
+ }
984386
+ }
984387
+ }
984388
+ for (const request7 of requests3) {
984389
+ if (!requestRequiresSourceArchive(request7)) {
984390
+ continue;
984391
+ }
984392
+ const hasArchive = sourceArchives.has(request7.generatorIndex);
984393
+ const hasError = errors4.has(request7.generatorIndex);
984394
+ if (hasArchive && hasError) {
984395
+ throw new Error(
984396
+ `Generator index ${request7.generatorIndex} produced both a source archive and a source preparation error`,
984397
+ { cause: errors4.get(request7.generatorIndex) }
984398
+ );
984399
+ }
984400
+ if (!hasArchive && !hasError) {
984401
+ errors4.set(
984402
+ request7.generatorIndex,
984403
+ new Error(
984404
+ `Generator index ${request7.generatorIndex} did not produce a source archive or source preparation error`
984405
+ )
984406
+ );
984407
+ }
984408
+ }
984409
+ return { sourceArchives, errors: errors4 };
983434
984410
  };
983435
984411
  }
984412
+ function requestRequiresSourceArchive(request7) {
984413
+ return request7.sdkGenApiRoute != null || generatorWantsSpecs(request7.generatorInvocation.name);
984414
+ }
983436
984415
 
983437
984416
  // src/commands/generate/packLocalOutput.ts
983438
984417
  init_lib20();
@@ -984089,21 +985068,11 @@ async function generateWorkspace({
984089
985068
  disableTelemetry: isTelemetryDisabled()
984090
985069
  });
984091
985070
  } else if (token != null) {
984092
- const ossWorkspace = workspace instanceof OSSWorkspace ? workspace : void 0;
984093
- const getCachedSpecsTarGz = ossWorkspace == null ? void 0 : createSpecsTarGzCache(
984094
- () => createSpecsTarGzBuffer({
984095
- specs: ossWorkspace.allSpecs,
984096
- context: groupContext,
984097
- audiences: group.audiences
984098
- })
984099
- );
984100
- const getSpecsTarGz = async (generatorName2) => {
984101
- const sdkGenApiNeedsSpecs = isFernSdkGenApiEnabled() && getFernSdkGenApiLanguage(generatorName2) != null;
984102
- if (getCachedSpecsTarGz == null || !generatorWantsSpecs(generatorName2) && !sdkGenApiNeedsSpecs) {
984103
- return void 0;
984104
- }
984105
- return getCachedSpecsTarGz();
984106
- };
985071
+ const getSpecsTarGz = createFernSourceArchiveResolver({
985072
+ workspace,
985073
+ context: groupContext,
985074
+ group
985075
+ });
984107
985076
  await runRemoteGenerationForAPIWorkspace({
984108
985077
  projectConfig,
984109
985078
  organization,
@@ -994994,7 +995963,7 @@ function upsertServerInJsonConfig({
994994
995963
  includeTransportType
994995
995964
  }) {
994996
995965
  const config5 = parseJsonConfig(existingContents);
994997
- const mcpServers = isRecord4(config5.mcpServers) ? config5.mcpServers : {};
995966
+ const mcpServers = isRecord5(config5.mcpServers) ? config5.mcpServers : {};
994998
995967
  config5.mcpServers = {
994999
995968
  ...mcpServers,
995000
995969
  [MCP_SERVER_NAME]: {
@@ -995011,12 +995980,12 @@ function parseJsonConfig(existingContents) {
995011
995980
  return {};
995012
995981
  }
995013
995982
  const parsed = JSON.parse(existingContents);
995014
- if (!isRecord4(parsed)) {
995983
+ if (!isRecord5(parsed)) {
995015
995984
  throw new Error("Expected the config to contain a JSON object");
995016
995985
  }
995017
995986
  return parsed;
995018
995987
  }
995019
- function isRecord4(value2) {
995988
+ function isRecord5(value2) {
995020
995989
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
995021
995990
  }
995022
995991
  var CODEX_SERVER_TABLE_PATH = `mcp_servers.${MCP_SERVER_NAME}`;
@@ -996571,7 +997540,12 @@ async function sdkPreview({
996571
997540
  absolutePathToPreview: absolutePathToOutput,
996572
997541
  isPreview: true,
996573
997542
  fiddlePreview: false,
996574
- pushPreviewBranch: false
997543
+ pushPreviewBranch: false,
997544
+ getSpecsTarGzBuffer: createFernSourceArchiveResolver({
997545
+ workspace,
997546
+ context: context3,
997547
+ group: publishGroup
997548
+ })
996575
997549
  });
996576
997550
  });
996577
997551
  if (shouldRunTwoJobs) {
@@ -996586,7 +997560,12 @@ async function sdkPreview({
996586
997560
  absolutePathToPreview: void 0,
996587
997561
  isPreview: true,
996588
997562
  fiddlePreview: true,
996589
- pushPreviewBranch: true
997563
+ pushPreviewBranch: true,
997564
+ getSpecsTarGzBuffer: createFernSourceArchiveResolver({
997565
+ workspace,
997566
+ context: context3,
997567
+ group: diffGroup
997568
+ })
996590
997569
  });
996591
997570
  });
996592
997571
  }