@fern-api/fern-api-dev 5.57.0 → 5.59.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 +259 -141
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -76219,6 +76219,7 @@ var init_V2HttpEndpointExample2 = __esm({
76219
76219
  init_V2HttpEndpointResponse2();
76220
76220
  V2HttpEndpointExample = schemas_exports3.objectWithoutOptionalProperties({
76221
76221
  displayName: schemas_exports3.string().optional(),
76222
+ contentType: schemas_exports3.string().optional(),
76222
76223
  request: V2HttpEndpointRequest.optional(),
76223
76224
  response: V2HttpEndpointResponse.optional(),
76224
76225
  codeSamples: schemas_exports3.list(V2HttpEndpointCodeSample).optional()
@@ -263778,6 +263779,7 @@ function maybeCreateAndStoreExample({ key: key2, displayName, request: request7,
263778
263779
  if (!exampleStore.has(key2)) {
263779
263780
  const example = {
263780
263781
  displayName,
263782
+ contentType: void 0,
263781
263783
  request: request7,
263782
263784
  response,
263783
263785
  codeSamples: void 0
@@ -350712,6 +350714,19 @@ var init_OperationConverter = __esm({
350712
350714
  }
350713
350715
  }
350714
350716
  }
350717
+ if (Object.keys(fernExamples.examples).length === 0 && Object.keys(fernExamples.streamExamples).length === 0 && convertedRequestBodies != null && convertedRequestBodies.length > 1) {
350718
+ const perContentTypeExamples = this.synthesizeEndpointExamplesFromPerContentTypeRequestBodies({
350719
+ convertedRequestBodies,
350720
+ httpPath: path119,
350721
+ httpMethod,
350722
+ baseUrl
350723
+ });
350724
+ if (perContentTypeExamples != null) {
350725
+ for (const [name2, example] of Object.entries(perContentTypeExamples)) {
350726
+ fernExamples.examples[name2] = example;
350727
+ }
350728
+ }
350729
+ }
350715
350730
  const endpointLevelSecuritySchemes = new Set(this.operation.security?.flatMap((securityRequirement) => Object.keys(securityRequirement)) ?? []);
350716
350731
  const securityHeaders = this.authSchemeToHeaders(Array.from(endpointLevelSecuritySchemes));
350717
350732
  if (securityHeaders.length > 0) {
@@ -351235,6 +351250,7 @@ var init_OperationConverter = __esm({
351235
351250
  if (resolvedValue != null) {
351236
351251
  result[name2] = {
351237
351252
  displayName: void 0,
351253
+ contentType: void 0,
351238
351254
  request: {
351239
351255
  docs: void 0,
351240
351256
  endpoint: {
@@ -351298,6 +351314,104 @@ var init_OperationConverter = __esm({
351298
351314
  }
351299
351315
  return void 0;
351300
351316
  }
351317
+ /**
351318
+ * Synthesizes endpoint-level v2Examples from per-content-type request body
351319
+ * examples that have already been extracted by the RequestBodyConverter.
351320
+ *
351321
+ * This handles the case where multiple content types (e.g. application/json
351322
+ * and application/ld+json) reference the same schema but have distinct
351323
+ * per-content-type examples. The RequestBodyConverter correctly extracts
351324
+ * these into each body's v2Examples, but they need to be elevated to
351325
+ * endpoint-level examples (tagged with contentType) for docs rendering.
351326
+ */
351327
+ synthesizeEndpointExamplesFromPerContentTypeRequestBodies({ convertedRequestBodies, httpPath, httpMethod, baseUrl }) {
351328
+ const result = {};
351329
+ const responseExamplesByContentType = this.extractNativeResponseExamplesByContentType();
351330
+ for (const convertedBody of convertedRequestBodies) {
351331
+ const body = convertedBody.requestBody;
351332
+ const bodyContentType = body.contentType;
351333
+ const bodyV2Examples = body.v2Examples;
351334
+ if (bodyV2Examples == null) {
351335
+ continue;
351336
+ }
351337
+ const userExamples = bodyV2Examples.userSpecifiedExamples;
351338
+ if (Object.keys(userExamples).length === 0) {
351339
+ continue;
351340
+ }
351341
+ const matchedResponse = bodyContentType != null ? responseExamplesByContentType.get(bodyContentType) : void 0;
351342
+ for (const [exampleName, exampleValue] of Object.entries(userExamples)) {
351343
+ const key2 = convertedRequestBodies.length > 1 && bodyContentType != null ? `${exampleName} (${bodyContentType})` : exampleName;
351344
+ result[key2] = {
351345
+ displayName: convertedRequestBodies.length > 1 ? key2 : void 0,
351346
+ contentType: bodyContentType ?? void 0,
351347
+ request: {
351348
+ docs: void 0,
351349
+ endpoint: {
351350
+ method: httpMethod,
351351
+ path: this.buildExamplePath(httpPath, {})
351352
+ },
351353
+ baseUrl: void 0,
351354
+ environment: baseUrl,
351355
+ auth: void 0,
351356
+ pathParameters: {},
351357
+ queryParameters: {},
351358
+ headers: {},
351359
+ requestBody: exampleValue
351360
+ },
351361
+ response: matchedResponse ?? this.extractNativeResponseExample() ?? void 0,
351362
+ codeSamples: void 0
351363
+ };
351364
+ }
351365
+ }
351366
+ return Object.keys(result).length > 0 ? result : void 0;
351367
+ }
351368
+ /**
351369
+ * Extracts native response examples grouped by content type from the
351370
+ * operation's successful (2xx) responses. Used by
351371
+ * synthesizeEndpointExamplesFromPerContentTypeRequestBodies to match
351372
+ * response examples to their corresponding request content types.
351373
+ */
351374
+ extractNativeResponseExamplesByContentType() {
351375
+ const responsesByContentType = /* @__PURE__ */ new Map();
351376
+ if (this.operation.responses == null) {
351377
+ return responsesByContentType;
351378
+ }
351379
+ for (const [statusCode, response] of Object.entries(this.operation.responses)) {
351380
+ const statusCodeNum = parseInt(statusCode);
351381
+ if (isNaN(statusCodeNum) || statusCodeNum < 200 || statusCodeNum >= 300) {
351382
+ continue;
351383
+ }
351384
+ const resolvedResponse = this.context.resolveMaybeReference({
351385
+ schemaOrReference: response,
351386
+ breadcrumbs: [...this.breadcrumbs, "responses", statusCode]
351387
+ });
351388
+ if (resolvedResponse?.content == null) {
351389
+ continue;
351390
+ }
351391
+ for (const [responseContentType, responseMediaType] of Object.entries(resolvedResponse.content)) {
351392
+ if (responsesByContentType.has(responseContentType)) {
351393
+ continue;
351394
+ }
351395
+ const namedExamples = this.context.getNamedExamplesFromMediaTypeObject({
351396
+ mediaTypeObject: responseMediaType,
351397
+ breadcrumbs: [...this.breadcrumbs, "responses", statusCode],
351398
+ defaultExampleName: "Example"
351399
+ });
351400
+ for (const [, example] of namedExamples) {
351401
+ const resolvedValue = this.context.resolveExampleWithValue(example);
351402
+ if (resolvedValue != null) {
351403
+ responsesByContentType.set(responseContentType, {
351404
+ docs: void 0,
351405
+ statusCode: statusCodeNum,
351406
+ body: api_exports.V2HttpEndpointResponseBody.json(resolvedValue)
351407
+ });
351408
+ break;
351409
+ }
351410
+ }
351411
+ }
351412
+ }
351413
+ return responsesByContentType;
351414
+ }
351301
351415
  convertStreamConditionExamples({ httpPath, httpMethod, baseUrl, fernExamples }) {
351302
351416
  const filteredJsonExamples = fernExamples.filter((example) => !(example.response != null && "stream" in example.response));
351303
351417
  const filteredStreamExamples = fernExamples.filter((example) => example.response != null && "stream" in example.response);
@@ -351321,6 +351435,7 @@ var init_OperationConverter = __esm({
351321
351435
  this.getExampleName({ example, exampleIndex }),
351322
351436
  {
351323
351437
  displayName: void 0,
351438
+ contentType: void 0,
351324
351439
  request: example.request != null || example["path-parameters"] != null || example["query-parameters"] != null || example.headers != null ? {
351325
351440
  docs: void 0,
351326
351441
  endpoint: {
@@ -352776,6 +352891,7 @@ var init_MethodConverter = __esm({
352776
352891
  }
352777
352892
  examples[exampleName] = {
352778
352893
  displayName: void 0,
352894
+ contentType: void 0,
352779
352895
  request: {
352780
352896
  docs: void 0,
352781
352897
  endpoint: {
@@ -454802,20 +454918,129 @@ var init_lib65 = __esm({
454802
454918
  }
454803
454919
  });
454804
454920
 
454805
- // ../register/lib/ai-example-enhancer/faiClient.js
454806
- var DEFAULT_AI_ENHANCEMENT_MAX_RETRIES, DEFAULT_AI_ENHANCEMENT_TIMEOUT_MS, FaiExampleEnhancer;
454807
- var init_faiClient = __esm({
454808
- "../register/lib/ai-example-enhancer/faiClient.js"() {
454921
+ // ../register/lib/ai-example-enhancer/filterHelpers.js
454922
+ function isFdrTypedValueWrapper(value2) {
454923
+ if (value2 === null || value2 === void 0 || typeof value2 !== "object" || Array.isArray(value2)) {
454924
+ return false;
454925
+ }
454926
+ const obj = value2;
454927
+ const keys25 = Object.keys(obj);
454928
+ if (keys25.length === 0 || keys25.length > 2) {
454929
+ return false;
454930
+ }
454931
+ const hasType = "type" in obj && typeof obj.type === "string";
454932
+ const hasValue = "value" in obj;
454933
+ return hasType && keys25.length === 1 || hasType && hasValue && keys25.length === 2 || hasValue && keys25.length === 1;
454934
+ }
454935
+ function unwrapExampleValue(value2) {
454936
+ if (value2 === null || value2 === void 0) {
454937
+ return value2;
454938
+ }
454939
+ if (Array.isArray(value2)) {
454940
+ return value2.map(unwrapExampleValue);
454941
+ }
454942
+ if (typeof value2 !== "object") {
454943
+ return value2;
454944
+ }
454945
+ const obj = value2;
454946
+ if (isFdrTypedValueWrapper(obj)) {
454947
+ if ("value" in obj) {
454948
+ return unwrapExampleValue(obj.value);
454949
+ }
454950
+ return void 0;
454951
+ }
454952
+ const result = {};
454953
+ for (const [key2, val] of Object.entries(obj)) {
454954
+ const unwrapped = unwrapExampleValue(val);
454955
+ if (unwrapped !== void 0) {
454956
+ result[key2] = unwrapped;
454957
+ }
454958
+ }
454959
+ return result;
454960
+ }
454961
+ function isEmptyObject3(value2) {
454962
+ if (value2 === null || value2 === void 0) {
454963
+ return true;
454964
+ }
454965
+ if (typeof value2 !== "object") {
454966
+ return false;
454967
+ }
454968
+ if (Array.isArray(value2)) {
454969
+ return value2.length === 0;
454970
+ }
454971
+ return Object.keys(value2).length === 0;
454972
+ }
454973
+ function filterRequestBody(requestBody, pathParameters, queryParameters, headers2) {
454974
+ const extractedPathParams = {};
454975
+ const extractedQueryParams = {};
454976
+ const extractedHeaders = {};
454977
+ if (requestBody === null || requestBody === void 0 || typeof requestBody !== "object" || Array.isArray(requestBody)) {
454978
+ return { filteredBody: requestBody, extractedPathParams, extractedQueryParams, extractedHeaders };
454979
+ }
454980
+ const bodyRecord = requestBody;
454981
+ const filteredBody = {};
454982
+ const pathParamKeys = new Set(Object.keys(pathParameters ?? {}));
454983
+ const queryParamKeys = new Set(Object.keys(queryParameters ?? {}));
454984
+ const headerKeys = new Set(Object.keys(headers2 ?? {}));
454985
+ for (const [key2, value2] of Object.entries(bodyRecord)) {
454986
+ const normalizedKey = key2.toLowerCase().replace(/[-_]/g, "");
454987
+ let isPathParam = false;
454988
+ let isQueryParam = false;
454989
+ let isHeader = false;
454990
+ for (const pathKey of pathParamKeys) {
454991
+ const normalizedPathKey = pathKey.toLowerCase().replace(/[-_]/g, "");
454992
+ if (normalizedKey === normalizedPathKey) {
454993
+ isPathParam = true;
454994
+ extractedPathParams[pathKey] = value2;
454995
+ break;
454996
+ }
454997
+ }
454998
+ if (!isPathParam) {
454999
+ for (const queryKey of queryParamKeys) {
455000
+ const normalizedQueryKey = queryKey.toLowerCase().replace(/[-_]/g, "");
455001
+ if (normalizedKey === normalizedQueryKey) {
455002
+ isQueryParam = true;
455003
+ extractedQueryParams[queryKey] = value2;
455004
+ break;
455005
+ }
455006
+ }
455007
+ }
455008
+ if (!isPathParam && !isQueryParam) {
455009
+ for (const headerKey of headerKeys) {
455010
+ const normalizedHeaderKey = headerKey.toLowerCase().replace(/[-_]/g, "");
455011
+ if (normalizedKey === normalizedHeaderKey) {
455012
+ isHeader = true;
455013
+ extractedHeaders[headerKey] = value2;
455014
+ break;
455015
+ }
455016
+ }
455017
+ }
455018
+ if (!isPathParam && !isQueryParam && !isHeader) {
455019
+ filteredBody[key2] = value2;
455020
+ }
455021
+ }
455022
+ return { filteredBody, extractedPathParams, extractedQueryParams, extractedHeaders };
455023
+ }
455024
+ var init_filterHelpers = __esm({
455025
+ "../register/lib/ai-example-enhancer/filterHelpers.js"() {
455026
+ "use strict";
455027
+ }
455028
+ });
455029
+
455030
+ // ../register/lib/ai-example-enhancer/lambdaClient.js
455031
+ var DEFAULT_AI_ENHANCEMENT_MAX_RETRIES, DEFAULT_AI_ENHANCEMENT_TIMEOUT_MS, LambdaExampleEnhancer;
455032
+ var init_lambdaClient = __esm({
455033
+ "../register/lib/ai-example-enhancer/lambdaClient.js"() {
454809
455034
  "use strict";
454810
455035
  init_lib4();
454811
455036
  init_lib35();
454812
455037
  init_lib6();
454813
455038
  DEFAULT_AI_ENHANCEMENT_MAX_RETRIES = 0;
454814
455039
  DEFAULT_AI_ENHANCEMENT_TIMEOUT_MS = 15e3;
454815
- FaiExampleEnhancer = class {
455040
+ LambdaExampleEnhancer = class {
454816
455041
  config;
454817
455042
  context;
454818
- faiOrigin;
455043
+ lambdaOrigin;
454819
455044
  venusOrigin;
454820
455045
  token;
454821
455046
  jwtPromise;
@@ -454831,14 +455056,14 @@ var init_faiClient = __esm({
454831
455056
  styleInstructions: config5.styleInstructions
454832
455057
  };
454833
455058
  this.context = context3;
454834
- const faiOrigin = "https://fai-dev2.buildwithfern.com";
454835
- if (!faiOrigin) {
455059
+ const lambdaOrigin = "https://ykq45y6fvnszd35iv5yuuatkze0rpwuz.lambda-url.us-east-1.on.aws";
455060
+ if (!lambdaOrigin) {
454836
455061
  throw new CliError({
454837
- message: "DEFAULT_FAI_ORIGIN environment variable is not set. AI example enhancement requires this to be configured.",
455062
+ message: "DEFAULT_FDR_LAMBDA_DOCS_ORIGIN environment variable is not set. AI example enhancement requires this to be configured.",
454838
455063
  code: CliError.Code.EnvironmentError
454839
455064
  });
454840
455065
  }
454841
- this.faiOrigin = faiOrigin;
455066
+ this.lambdaOrigin = lambdaOrigin;
454842
455067
  this.venusOrigin = "https://venus-dev2.buildwithfern.com";
454843
455068
  this.token = token;
454844
455069
  this.organizationId = organizationId;
@@ -454943,7 +455168,7 @@ var init_faiClient = __esm({
454943
455168
  const maxAttempts = this.config.maxRetries + 1;
454944
455169
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
454945
455170
  try {
454946
- this.context.logger.debug(`Enhancing example for ${request7.method} ${request7.endpointPath} via FAI (attempt ${attempt}/${maxAttempts})`);
455171
+ this.context.logger.debug(`Enhancing example for ${request7.method} ${request7.endpointPath} via lambda (attempt ${attempt}/${maxAttempts})`);
454947
455172
  const requestBody = {
454948
455173
  method: request7.method,
454949
455174
  endpointPath: request7.endpointPath,
@@ -454959,7 +455184,7 @@ var init_faiClient = __esm({
454959
455184
  ...requestBody,
454960
455185
  openApiSpec: request7.openApiSpec ? `[OpenAPI spec present: ${request7.openApiSpec.length} chars]` : "[No OpenAPI spec]"
454961
455186
  }, null, 2)}`);
454962
- const response = await fetch(`${this.faiOrigin}/examples/enhance`, {
455187
+ const response = await fetch(`${this.lambdaOrigin}/v2/registry/ai/enhance-example`, {
454963
455188
  method: "POST",
454964
455189
  headers: {
454965
455190
  "Content-Type": "application/json",
@@ -454971,7 +455196,7 @@ var init_faiClient = __esm({
454971
455196
  if (!response.ok) {
454972
455197
  const errorText = await response.text();
454973
455198
  throw new CliError({
454974
- message: `FAI returned ${response.status}: ${errorText || response.statusText}`,
455199
+ message: `Lambda returned ${response.status}: ${errorText || response.statusText}`,
454975
455200
  code: CliError.Code.NetworkError
454976
455201
  });
454977
455202
  }
@@ -454999,115 +455224,6 @@ var init_faiClient = __esm({
454999
455224
  }
455000
455225
  });
455001
455226
 
455002
- // ../register/lib/ai-example-enhancer/filterHelpers.js
455003
- function isFdrTypedValueWrapper(value2) {
455004
- if (value2 === null || value2 === void 0 || typeof value2 !== "object" || Array.isArray(value2)) {
455005
- return false;
455006
- }
455007
- const obj = value2;
455008
- const keys25 = Object.keys(obj);
455009
- if (keys25.length === 0 || keys25.length > 2) {
455010
- return false;
455011
- }
455012
- const hasType = "type" in obj && typeof obj.type === "string";
455013
- const hasValue = "value" in obj;
455014
- return hasType && keys25.length === 1 || hasType && hasValue && keys25.length === 2 || hasValue && keys25.length === 1;
455015
- }
455016
- function unwrapExampleValue(value2) {
455017
- if (value2 === null || value2 === void 0) {
455018
- return value2;
455019
- }
455020
- if (Array.isArray(value2)) {
455021
- return value2.map(unwrapExampleValue);
455022
- }
455023
- if (typeof value2 !== "object") {
455024
- return value2;
455025
- }
455026
- const obj = value2;
455027
- if (isFdrTypedValueWrapper(obj)) {
455028
- if ("value" in obj) {
455029
- return unwrapExampleValue(obj.value);
455030
- }
455031
- return void 0;
455032
- }
455033
- const result = {};
455034
- for (const [key2, val] of Object.entries(obj)) {
455035
- const unwrapped = unwrapExampleValue(val);
455036
- if (unwrapped !== void 0) {
455037
- result[key2] = unwrapped;
455038
- }
455039
- }
455040
- return result;
455041
- }
455042
- function isEmptyObject3(value2) {
455043
- if (value2 === null || value2 === void 0) {
455044
- return true;
455045
- }
455046
- if (typeof value2 !== "object") {
455047
- return false;
455048
- }
455049
- if (Array.isArray(value2)) {
455050
- return value2.length === 0;
455051
- }
455052
- return Object.keys(value2).length === 0;
455053
- }
455054
- function filterRequestBody(requestBody, pathParameters, queryParameters, headers2) {
455055
- const extractedPathParams = {};
455056
- const extractedQueryParams = {};
455057
- const extractedHeaders = {};
455058
- if (requestBody === null || requestBody === void 0 || typeof requestBody !== "object" || Array.isArray(requestBody)) {
455059
- return { filteredBody: requestBody, extractedPathParams, extractedQueryParams, extractedHeaders };
455060
- }
455061
- const bodyRecord = requestBody;
455062
- const filteredBody = {};
455063
- const pathParamKeys = new Set(Object.keys(pathParameters ?? {}));
455064
- const queryParamKeys = new Set(Object.keys(queryParameters ?? {}));
455065
- const headerKeys = new Set(Object.keys(headers2 ?? {}));
455066
- for (const [key2, value2] of Object.entries(bodyRecord)) {
455067
- const normalizedKey = key2.toLowerCase().replace(/[-_]/g, "");
455068
- let isPathParam = false;
455069
- let isQueryParam = false;
455070
- let isHeader = false;
455071
- for (const pathKey of pathParamKeys) {
455072
- const normalizedPathKey = pathKey.toLowerCase().replace(/[-_]/g, "");
455073
- if (normalizedKey === normalizedPathKey) {
455074
- isPathParam = true;
455075
- extractedPathParams[pathKey] = value2;
455076
- break;
455077
- }
455078
- }
455079
- if (!isPathParam) {
455080
- for (const queryKey of queryParamKeys) {
455081
- const normalizedQueryKey = queryKey.toLowerCase().replace(/[-_]/g, "");
455082
- if (normalizedKey === normalizedQueryKey) {
455083
- isQueryParam = true;
455084
- extractedQueryParams[queryKey] = value2;
455085
- break;
455086
- }
455087
- }
455088
- }
455089
- if (!isPathParam && !isQueryParam) {
455090
- for (const headerKey of headerKeys) {
455091
- const normalizedHeaderKey = headerKey.toLowerCase().replace(/[-_]/g, "");
455092
- if (normalizedKey === normalizedHeaderKey) {
455093
- isHeader = true;
455094
- extractedHeaders[headerKey] = value2;
455095
- break;
455096
- }
455097
- }
455098
- }
455099
- if (!isPathParam && !isQueryParam && !isHeader) {
455100
- filteredBody[key2] = value2;
455101
- }
455102
- }
455103
- return { filteredBody, extractedPathParams, extractedQueryParams, extractedHeaders };
455104
- }
455105
- var init_filterHelpers = __esm({
455106
- "../register/lib/ai-example-enhancer/filterHelpers.js"() {
455107
- "use strict";
455108
- }
455109
- });
455110
-
455111
455227
  // ../register/lib/ai-example-enhancer/spinnerStatusCoordinator.js
455112
455228
  var SpinnerStatusCoordinator;
455113
455229
  var init_spinnerStatusCoordinator = __esm({
@@ -455713,7 +455829,7 @@ async function enhanceExamplesWithAI(apiDefinition, config5, context3, token, or
455713
455829
  }
455714
455830
  }
455715
455831
  async function performAIEnhancement(apiDefinition, config5, context3, token, organizationId, sourceSpecs, apiName) {
455716
- const enhancer = new FaiExampleEnhancer(config5, context3, token, organizationId);
455832
+ const enhancer = new LambdaExampleEnhancer(config5, context3, token, organizationId);
455717
455833
  const circuitBreaker = new CircuitBreaker();
455718
455834
  let openApiSpec;
455719
455835
  let endpointsNeedingRegeneration = /* @__PURE__ */ new Set();
@@ -455926,7 +456042,7 @@ function collectWorkItems(pkg2, coveredEndpoints, endpointsNeedingRegeneration,
455926
456042
  }
455927
456043
  async function processEndpointsConcurrently(allWorkItems, enhancer, context3, organizationId, stats, enhancedExampleRecords, openApiSpec, sourceFilePath, statusId, apiStats, circuitBreaker) {
455928
456044
  const maxConcurrentRequests = parseInt(process.env.FERN_AI_MAX_CONCURRENT || "25", 10);
455929
- context3.logger.debug(`Processing ${allWorkItems.length} endpoints with max ${maxConcurrentRequests} concurrent FAI calls using rolling window queue`);
456045
+ context3.logger.debug(`Processing ${allWorkItems.length} endpoints with max ${maxConcurrentRequests} concurrent Lambda calls using rolling window queue`);
455930
456046
  if (circuitBreaker?.shouldSkip()) {
455931
456047
  context3.logger.debug(`Circuit breaker is open after ${circuitBreaker.getFailureCount()} failures (threshold: ${circuitBreaker.getThreshold()}). Skipping AI enhancement for remaining endpoints.`);
455932
456048
  return /* @__PURE__ */ new Map();
@@ -456043,7 +456159,7 @@ async function processEndpoint(workItem, enhancer, context3, organizationId, sta
456043
456159
  const result = await enhancer.enhanceExample(request7);
456044
456160
  circuitBreaker?.recordSuccess();
456045
456161
  if (result.enhancedRequestExample != null && request7.originalRequestExample != null) {
456046
- const unwrapped = unwrapBodyEnvelope(result.enhancedRequestExample);
456162
+ const unwrapped = unwrapLambdaBodyEnvelope(result.enhancedRequestExample);
456047
456163
  const originalHasBody = isObjectWithKey(request7.originalRequestExample, "body");
456048
456164
  if (unwrapped.wasWrapped && !originalHasBody) {
456049
456165
  result.enhancedRequestExample = backfillMissingFields(unwrapped.inner, request7.originalRequestExample);
@@ -456327,7 +456443,7 @@ function extractExampleValue(bodyV3) {
456327
456443
  function isObjectWithKey(value2, key2) {
456328
456444
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && key2 in value2;
456329
456445
  }
456330
- function unwrapBodyEnvelope(value2) {
456446
+ function unwrapLambdaBodyEnvelope(value2) {
456331
456447
  if (typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && "body" in value2) {
456332
456448
  return { wasWrapped: true, inner: value2.body };
456333
456449
  }
@@ -456365,8 +456481,8 @@ var init_enhanceExamplesWithAI = __esm({
456365
456481
  init_lib65();
456366
456482
  import_promises72 = require("fs/promises");
456367
456483
  init_js_yaml();
456368
- init_faiClient();
456369
456484
  init_filterHelpers();
456485
+ init_lambdaClient();
456370
456486
  init_spinnerStatusCoordinator();
456371
456487
  init_validateAiExamples();
456372
456488
  init_writeAiExamplesOverride();
@@ -459852,7 +459968,7 @@ https://buildwithfern.com/learn/docs/getting-started/project-structure#api-defin
459852
459968
  navigationConfig: tabbed,
459853
459969
  parentSlug: slug
459854
459970
  }),
459855
- versioned: (versioned) => this.toVersionedNode(versioned, slug),
459971
+ versioned: (versioned) => this.toVersionedNode(versioned, slug, this.parsedDocsConfig.landingPage),
459856
459972
  productgroup: (productGroup) => this.toProductGroupNode({
459857
459973
  landingPageConfig: this.parsedDocsConfig.landingPage,
459858
459974
  productGroup,
@@ -459888,7 +460004,7 @@ https://buildwithfern.com/learn/docs/getting-started/project-structure#api-defin
459888
460004
  const child = navigationConfig.type === "tabbed" ? await this.convertTabbedNavigation(id, navigationConfig.items, parentSlug) : await this.toSidebarRootNode(id, navigationConfig.items, parentSlug);
459889
460005
  return { type: "unversioned", id, collapsed: void 0, landingPage, child };
459890
460006
  }
459891
- async toVersionedNode(versioned, parentSlug) {
460007
+ async toVersionedNode(versioned, parentSlug, landingPage) {
459892
460008
  const id = this.#idgen.get("versioned");
459893
460009
  const defaultVersion = versioned.versions[0];
459894
460010
  if (defaultVersion?.hidden === true) {
@@ -459901,7 +460017,7 @@ https://buildwithfern.com/learn/docs/getting-started/project-structure#api-defin
459901
460017
  const children2 = [];
459902
460018
  for (let i5 = 0; i5 < versioned.versions.length; i5 += BATCH_SIZE2) {
459903
460019
  const batch = versioned.versions.slice(i5, i5 + BATCH_SIZE2);
459904
- const batchResults = await Promise.all(batch.map((item, batchIdx) => this.toVersionNode(item, parentSlug, i5 + batchIdx === 0)));
460020
+ const batchResults = await Promise.all(batch.map((item, batchIdx) => this.toVersionNode(item, parentSlug, i5 + batchIdx === 0, landingPage)));
459905
460021
  children2.push(...batchResults);
459906
460022
  }
459907
460023
  return {
@@ -459932,7 +460048,7 @@ https://buildwithfern.com/learn/docs/getting-started/project-structure#api-defin
459932
460048
  type: "unversioned",
459933
460049
  id: this.#idgen.get(product.product),
459934
460050
  collapsed: void 0,
459935
- landingPage: void 0,
460051
+ landingPage: product.landingPage != null ? this.toLandingPageNode(product.landingPage, slug) : void 0,
459936
460052
  child: await this.convertTabbedNavigation(this.#idgen.get(product.product), product.navigation.items, slug)
459937
460053
  };
459938
460054
  break;
@@ -459941,12 +460057,12 @@ https://buildwithfern.com/learn/docs/getting-started/project-structure#api-defin
459941
460057
  type: "unversioned",
459942
460058
  id: this.#idgen.get(product.product),
459943
460059
  collapsed: void 0,
459944
- landingPage: void 0,
460060
+ landingPage: product.landingPage != null ? this.toLandingPageNode(product.landingPage, slug) : void 0,
459945
460061
  child: await this.toSidebarRootNode(this.#idgen.get(product.product), product.navigation.items, slug)
459946
460062
  };
459947
460063
  break;
459948
460064
  case "versioned":
459949
- child = await this.toVersionedNode(product.navigation, slug);
460065
+ child = await this.toVersionedNode(product.navigation, slug, product.landingPage ?? this.parsedDocsConfig.landingPage);
459950
460066
  break;
459951
460067
  default:
459952
460068
  assertNever(product.navigation);
@@ -459991,10 +460107,11 @@ https://buildwithfern.com/learn/docs/getting-started/project-structure#api-defin
459991
460107
  };
459992
460108
  }
459993
460109
  }
459994
- async toVersionNode(version7, parentSlug, isDefault) {
460110
+ async toVersionNode(version7, parentSlug, isDefault, landingPage) {
459995
460111
  const id = this.#idgen.get(version7.version);
459996
460112
  const slug = parentSlug.setVersionSlug(version7.slug ?? kebabCase_default(version7.version));
459997
460113
  const child = version7.navigation.type === "tabbed" ? await this.convertTabbedNavigation(id, version7.navigation.items, slug) : await this.toSidebarRootNode(id, version7.navigation.items, slug);
460114
+ const resolvedLandingPage = version7.landingPage ?? landingPage;
459998
460115
  return {
459999
460116
  type: "version",
460000
460117
  id,
@@ -460006,7 +460123,7 @@ https://buildwithfern.com/learn/docs/getting-started/project-structure#api-defin
460006
460123
  // TODO: the `default` property should be deprecated, and moved to the parent `versioned` node
460007
460124
  default: isDefault,
460008
460125
  availability: version7.availability != null ? convertAvailability5(version7.availability) : void 0,
460009
- landingPage: version7.landingPage ? this.toLandingPageNode(version7.landingPage, slug) : void 0,
460126
+ landingPage: resolvedLandingPage != null ? this.toLandingPageNode(resolvedLandingPage, slug) : void 0,
460010
460127
  hidden: version7.hidden,
460011
460128
  authed: void 0,
460012
460129
  viewers: version7.viewers,
@@ -686971,7 +687088,7 @@ var AccessTokenPosthogManager = class {
686971
687088
  properties: {
686972
687089
  ...event,
686973
687090
  ...event.properties,
686974
- version: "5.57.0",
687091
+ version: "5.59.0",
686975
687092
  usingAccessToken: true,
686976
687093
  ...getRunIdProperties()
686977
687094
  }
@@ -687037,7 +687154,7 @@ var UserPosthogManager = class {
687037
687154
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
687038
687155
  event: "CLI",
687039
687156
  properties: {
687040
- version: "5.57.0",
687157
+ version: "5.59.0",
687041
687158
  ...event,
687042
687159
  ...event.properties,
687043
687160
  usingAccessToken: false,
@@ -868132,7 +868249,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
868132
868249
  var LOGS_FOLDER_NAME = "logs";
868133
868250
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
868134
868251
  function getCliSource() {
868135
- const version7 = "5.57.0";
868252
+ const version7 = "5.59.0";
868136
868253
  return `cli@${version7}`;
868137
868254
  }
868138
868255
  var DebugLogger = class {
@@ -900613,7 +900730,7 @@ var LegacyDocsPublisher = class {
900613
900730
  previewId,
900614
900731
  disableTemplates: void 0,
900615
900732
  skipUpload,
900616
- cliVersion: "5.57.0",
900733
+ cliVersion: "5.59.0",
900617
900734
  loginCommand: "fern auth login"
900618
900735
  });
900619
900736
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -964454,6 +964571,7 @@ init_lib9();
964454
964571
  function initializeEmptyServiceExample() {
964455
964572
  return {
964456
964573
  displayName: void 0,
964574
+ contentType: void 0,
964457
964575
  request: {
964458
964576
  endpoint: {
964459
964577
  method: V2EndpointLocationHttpMethod.Post,
@@ -966882,7 +967000,7 @@ function getAutomationContextFromEnv() {
966882
967000
  config_branch: process.env.FERN_CONFIG_BRANCH,
966883
967001
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
966884
967002
  trigger: process.env.GITHUB_EVENT_NAME,
966885
- cli_version: "5.57.0"
967003
+ cli_version: "5.59.0"
966886
967004
  };
966887
967005
  }
966888
967006
  function isAutomationMode() {
@@ -967714,7 +967832,7 @@ var CliContext = class _CliContext {
967714
967832
  if (false) {
967715
967833
  this.logger.error("CLI_VERSION is not defined");
967716
967834
  }
967717
- return "5.57.0";
967835
+ return "5.59.0";
967718
967836
  }
967719
967837
  getCliName() {
967720
967838
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.57.0",
2
+ "version": "5.59.0",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",