@fern-api/fern-api-dev 5.31.0 → 5.32.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 +397 -68
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -567335,6 +567335,7 @@ var OpenApiIntermediateRepresentation = schemas_exports9.objectWithoutOptionalPr
567335
567335
  title: schemas_exports9.string().optional(),
567336
567336
  description: schemas_exports9.string().optional(),
567337
567337
  basePath: schemas_exports9.string().optional(),
567338
+ basePathParameters: schemas_exports9.list(PathParameter2).optional(),
567338
567339
  servers: schemas_exports9.list(Server),
567339
567340
  websocketServers: schemas_exports9.list(Server),
567340
567341
  groups: schemas_exports9.record(schemas_exports9.string(), SdkGroupInfo),
@@ -571544,8 +571545,20 @@ function buildEndpointExample({ endpointExample, context: context3 }) {
571544
571545
  if (endpointExample.description != null) {
571545
571546
  example.docs = endpointExample.description;
571546
571547
  }
571548
+ const pathParametersForExample = {};
571549
+ if (context3.ir.basePathParameters != null) {
571550
+ for (const param of context3.ir.basePathParameters) {
571551
+ const value2 = param.clientDefault ?? param.name;
571552
+ if (typeof value2 === "string" || typeof value2 === "number" || typeof value2 === "boolean") {
571553
+ pathParametersForExample[param.name] = value2;
571554
+ }
571555
+ }
571556
+ }
571547
571557
  if (endpointExample.pathParameters != null && endpointExample.pathParameters.length > 0) {
571548
- example["path-parameters"] = convertPathParameterExample(endpointExample.pathParameters);
571558
+ Object.assign(pathParametersForExample, convertPathParameterExample(endpointExample.pathParameters));
571559
+ }
571560
+ if (Object.keys(pathParametersForExample).length > 0) {
571561
+ example["path-parameters"] = pathParametersForExample;
571549
571562
  }
571550
571563
  if (endpointExample.queryParameters != null && endpointExample.queryParameters.length > 0) {
571551
571564
  example["query-parameters"] = convertQueryParameterExample2(endpointExample.queryParameters);
@@ -572136,34 +572149,35 @@ function getRequest({ endpoint: endpoint3, declarationFile, context: context3, r
572136
572149
  declarationDepth: 0,
572137
572150
  variant
572138
572151
  });
572139
- const convertedRequest = {
572140
- schemaIdsToExclude: [],
572141
- value: {
572142
- body: requestTypeReference
572143
- }
572152
+ const requestValue = {
572153
+ body: requestTypeReference
572144
572154
  };
572145
572155
  const hasPathParams = Object.keys(pathParameters ?? {}).length > 0;
572146
572156
  const hasQueryParams = Object.keys(queryParameters ?? {}).length > 0;
572147
572157
  const hasHeaders = Object.keys(headers2 ?? {}).length > 0;
572148
572158
  if (hasPathParams) {
572149
- convertedRequest.value["path-parameters"] = pathParameters;
572159
+ requestValue["path-parameters"] = pathParameters;
572150
572160
  }
572151
572161
  if (hasQueryParams) {
572152
- convertedRequest.value["query-parameters"] = queryParameters;
572162
+ requestValue["query-parameters"] = queryParameters;
572153
572163
  }
572154
572164
  if (hasHeaders) {
572155
- convertedRequest.value.headers = headers2;
572165
+ requestValue.headers = headers2;
572156
572166
  }
572157
572167
  if (hasPathParams || hasQueryParams || hasHeaders) {
572158
- convertedRequest.value.name = requestNameOverride ?? generatedRequestName;
572168
+ requestValue.name = requestNameOverride ?? generatedRequestName;
572159
572169
  }
572160
572170
  if (request7.contentType != null) {
572161
- convertedRequest.value["content-type"] = request7.contentType;
572171
+ requestValue["content-type"] = request7.contentType;
572162
572172
  }
572163
572173
  if (request7.description != null) {
572164
- convertedRequest.value.docs = request7.description;
572174
+ requestValue.docs = request7.description;
572165
572175
  }
572166
- return convertedRequest;
572176
+ const canCollapse = typeof requestValue.body === "string" && requestValue["path-parameters"] == null && requestValue["query-parameters"] == null && requestValue.headers == null && requestValue.name == null && requestValue.docs == null && (requestValue["content-type"] == null || requestValue["content-type"] === "application/json");
572177
+ return {
572178
+ schemaIdsToExclude: [],
572179
+ value: canCollapse ? requestValue.body : requestValue
572180
+ };
572167
572181
  }
572168
572182
  const propertyToDeclarationFile = /* @__PURE__ */ new Map();
572169
572183
  for (const allOfRef of resolvedSchema.allOf) {
@@ -573243,6 +573257,22 @@ function buildFernDefinition(context3) {
573243
573257
  if (context3.ir.basePath != null) {
573244
573258
  context3.builder.setBasePath(context3.ir.basePath);
573245
573259
  }
573260
+ if (context3.ir.basePathParameters != null && context3.ir.basePathParameters.length > 0) {
573261
+ const params2 = {};
573262
+ for (const p14 of context3.ir.basePathParameters) {
573263
+ const entry = {
573264
+ type: "string"
573265
+ };
573266
+ if (p14.description != null) {
573267
+ entry.docs = p14.description;
573268
+ }
573269
+ if (p14.clientDefault != null) {
573270
+ entry["client-default"] = p14.clientDefault;
573271
+ }
573272
+ params2[p14.name] = entry;
573273
+ }
573274
+ context3.builder.setRootPathParameters(params2);
573275
+ }
573246
573276
  if (context3.ir.hasEndpointsMarkedInternal) {
573247
573277
  context3.builder.addAudience(EXTERNAL_AUDIENCE);
573248
573278
  }
@@ -573367,6 +573397,7 @@ var FernDefinitionBuilderImpl = class {
573367
573397
  rootApiFile;
573368
573398
  packageMarkerFile = {};
573369
573399
  basePath = void 0;
573400
+ rootPathParameters = void 0;
573370
573401
  constructor(enableUniqueErrorsPerEndpoint) {
573371
573402
  this.enableUniqueErrorsPerEndpoint = enableUniqueErrorsPerEndpoint;
573372
573403
  this.root = new FernDefinitionDirectory();
@@ -573431,6 +573462,12 @@ var FernDefinitionBuilderImpl = class {
573431
573462
  setBasePath(basePath) {
573432
573463
  this.basePath = basePath;
573433
573464
  }
573465
+ setRootPathParameters(parameters2) {
573466
+ if (Object.keys(parameters2).length === 0) {
573467
+ return;
573468
+ }
573469
+ this.rootPathParameters = parameters2;
573470
+ }
573434
573471
  setApiVersion(apiVersionScheme) {
573435
573472
  this.rootApiFile.version = apiVersionScheme;
573436
573473
  }
@@ -573663,7 +573700,9 @@ var FernDefinitionBuilderImpl = class {
573663
573700
  build() {
573664
573701
  const definitionFiles = this.root.getAllFiles();
573665
573702
  const basePath = this.basePath;
573666
- if (basePath != null) {
573703
+ const rootPathParameters = this.rootPathParameters;
573704
+ const shouldInline = basePath != null && rootPathParameters == null && !basePath.includes("{");
573705
+ if (basePath != null && shouldInline) {
573667
573706
  if (this.packageMarkerFile.service != null) {
573668
573707
  this.packageMarkerFile.service = {
573669
573708
  ...this.packageMarkerFile.service,
@@ -573694,6 +573733,11 @@ var FernDefinitionBuilderImpl = class {
573694
573733
  };
573695
573734
  }
573696
573735
  }
573736
+ } else if (basePath != null) {
573737
+ this.rootApiFile["base-path"] = basePath;
573738
+ if (rootPathParameters != null) {
573739
+ this.rootApiFile["path-parameters"] = rootPathParameters;
573740
+ }
573697
573741
  }
573698
573742
  const definition3 = {
573699
573743
  rootApiFile: this.rootApiFile,
@@ -574780,6 +574824,161 @@ var FernOpenAPIExtension = {
574780
574824
  FERN_DEFAULT: "x-fern-default"
574781
574825
  };
574782
574826
 
574827
+ // ../api-importers/openapi/openapi-ir-parser/lib/getExtension.js
574828
+ init_lodash();
574829
+ function getExtension(object23, extension4) {
574830
+ const extensions2 = Array.isArray(extension4) ? extension4 : [extension4];
574831
+ for (const extension5 of extensions2) {
574832
+ const extensionValue = object23[extension5];
574833
+ if (extensionValue != null) {
574834
+ return extensionValue;
574835
+ }
574836
+ }
574837
+ return void 0;
574838
+ }
574839
+ function getExtensionAndValidate(object23, extension4, schema2, logger4, breadcrumbs = []) {
574840
+ try {
574841
+ const extensionValue = getExtension(object23, extension4);
574842
+ if (extensionValue != null) {
574843
+ return schema2.parse(extensionValue);
574844
+ }
574845
+ } catch (e8) {
574846
+ const breadcrumb = compact_default(breadcrumbs).join(" -> ");
574847
+ logger4.error(`${breadcrumb.length > 0 ? `${breadcrumb}: ` : ""}Failed to parse ${extension4}`);
574848
+ }
574849
+ return void 0;
574850
+ }
574851
+
574852
+ // ../api-importers/openapi/openapi-ir-parser/lib/openapi/v3/extensions/getFernBasePath.js
574853
+ var PLACEHOLDER_REGEX = /\{([^}]+)\}/g;
574854
+ function getFernBasePath(document4) {
574855
+ const raw = getExtension(document4, FernOpenAPIExtension.BASE_PATH);
574856
+ if (raw == null) {
574857
+ return void 0;
574858
+ }
574859
+ if (typeof raw === "string") {
574860
+ if (!raw.startsWith("/")) {
574861
+ return void 0;
574862
+ }
574863
+ return { basePath: raw, pathParameters: [], pathsIncludeBasePath: false };
574864
+ }
574865
+ if (typeof raw !== "object" || Array.isArray(raw)) {
574866
+ return void 0;
574867
+ }
574868
+ const obj = raw;
574869
+ const path113 = obj["path"];
574870
+ if (typeof path113 !== "string" || !path113.startsWith("/")) {
574871
+ return void 0;
574872
+ }
574873
+ const placeholders = extractPlaceholders(path113);
574874
+ const rawParameters = obj["parameters"];
574875
+ const parametersMap = rawParameters != null && typeof rawParameters === "object" && !Array.isArray(rawParameters) ? rawParameters : {};
574876
+ const pathParameters = [];
574877
+ for (const name2 of placeholders) {
574878
+ const entry = parametersMap[name2];
574879
+ const docs2 = typeof entry === "object" && entry != null && !Array.isArray(entry) ? typeof entry["docs"] === "string" ? entry["docs"] : void 0 : void 0;
574880
+ const clientDefault = typeof entry === "object" && entry != null && !Array.isArray(entry) ? entry["default"] : void 0;
574881
+ pathParameters.push({
574882
+ name: name2,
574883
+ schema: Schema.primitive({
574884
+ description: docs2,
574885
+ availability: void 0,
574886
+ schema: PrimitiveSchemaValue.string({
574887
+ default: void 0,
574888
+ pattern: void 0,
574889
+ format: void 0,
574890
+ minLength: void 0,
574891
+ maxLength: void 0
574892
+ }),
574893
+ generatedName: name2,
574894
+ nameOverride: void 0,
574895
+ title: void 0,
574896
+ namespace: void 0,
574897
+ groupName: void 0
574898
+ }),
574899
+ description: docs2,
574900
+ availability: void 0,
574901
+ source: void 0,
574902
+ variableReference: void 0,
574903
+ parameterNameOverride: void 0,
574904
+ clientDefault
574905
+ });
574906
+ }
574907
+ const pathsIncludeBasePath = obj["paths-include-base-path"] === true;
574908
+ return { basePath: path113, pathParameters, pathsIncludeBasePath };
574909
+ }
574910
+ function extractPlaceholders(path113) {
574911
+ const result = [];
574912
+ const regex5 = new RegExp(PLACEHOLDER_REGEX.source, "g");
574913
+ let match3;
574914
+ while ((match3 = regex5.exec(path113)) != null) {
574915
+ if (match3[1] != null && !result.includes(match3[1])) {
574916
+ result.push(match3[1]);
574917
+ }
574918
+ }
574919
+ return result;
574920
+ }
574921
+ function stripBasePathFromPaths({ openApi, basePath, rootPathParameterNames }) {
574922
+ if (openApi.paths == null) {
574923
+ return [];
574924
+ }
574925
+ const trimmedBasePath = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
574926
+ const errors4 = [];
574927
+ const newPaths = {};
574928
+ for (const [path113, pathItem] of Object.entries(openApi.paths)) {
574929
+ if (pathItem == null) {
574930
+ newPaths[path113] = pathItem;
574931
+ continue;
574932
+ }
574933
+ if (!path113.startsWith(trimmedBasePath)) {
574934
+ errors4.push(`Expected path '${path113}' to start with base path '${trimmedBasePath}'`);
574935
+ newPaths[path113] = pathItem;
574936
+ continue;
574937
+ }
574938
+ const stripped = path113.slice(trimmedBasePath.length) || "/";
574939
+ const newPathItem = stripPathParametersFromPathItem({
574940
+ pathItem,
574941
+ rootPathParameterNames
574942
+ });
574943
+ newPaths[stripped] = newPathItem;
574944
+ }
574945
+ openApi.paths = newPaths;
574946
+ return errors4;
574947
+ }
574948
+ function stripPathParametersFromPathItem({ pathItem, rootPathParameterNames }) {
574949
+ const result = { ...pathItem };
574950
+ if (Array.isArray(result.parameters)) {
574951
+ result.parameters = result.parameters.filter((p14) => !isStrippablePathParameter(p14, rootPathParameterNames));
574952
+ }
574953
+ const operationKeys = [
574954
+ "get",
574955
+ "put",
574956
+ "post",
574957
+ "delete",
574958
+ "options",
574959
+ "head",
574960
+ "patch",
574961
+ "trace"
574962
+ ];
574963
+ for (const opKey of operationKeys) {
574964
+ const op4 = result[opKey];
574965
+ if (op4 == null || !Array.isArray(op4.parameters)) {
574966
+ continue;
574967
+ }
574968
+ result[opKey] = {
574969
+ ...op4,
574970
+ parameters: op4.parameters.filter((p14) => !isStrippablePathParameter(p14, rootPathParameterNames))
574971
+ };
574972
+ }
574973
+ return result;
574974
+ }
574975
+ function isStrippablePathParameter(parameter6, rootPathParameterNames) {
574976
+ if ("$ref" in parameter6) {
574977
+ return false;
574978
+ }
574979
+ return parameter6.in === "path" && rootPathParameterNames.has(parameter6.name);
574980
+ }
574981
+
574783
574982
  // ../api-importers/openapi/openapi-ir-parser/lib/options.js
574784
574983
  var DEFAULT_PARSE_OPENAPI_SETTINGS = {
574785
574984
  disableExamples: false,
@@ -574864,31 +575063,6 @@ init_lib6();
574864
575063
  init_lib6();
574865
575064
  init_lodash();
574866
575065
 
574867
- // ../api-importers/openapi/openapi-ir-parser/lib/getExtension.js
574868
- init_lodash();
574869
- function getExtension(object23, extension4) {
574870
- const extensions2 = Array.isArray(extension4) ? extension4 : [extension4];
574871
- for (const extension5 of extensions2) {
574872
- const extensionValue = object23[extension5];
574873
- if (extensionValue != null) {
574874
- return extensionValue;
574875
- }
574876
- }
574877
- return void 0;
574878
- }
574879
- function getExtensionAndValidate(object23, extension4, schema2, logger4, breadcrumbs = []) {
574880
- try {
574881
- const extensionValue = getExtension(object23, extension4);
574882
- if (extensionValue != null) {
574883
- return schema2.parse(extensionValue);
574884
- }
574885
- } catch (e8) {
574886
- const breadcrumb = compact_default(breadcrumbs).join(" -> ");
574887
- logger4.error(`${breadcrumb.length > 0 ? `${breadcrumb}: ` : ""}Failed to parse ${extension4}`);
574888
- }
574889
- return void 0;
574890
- }
574891
-
574892
575066
  // ../api-importers/openapi/openapi-ir-parser/lib/openapi/v3/extensions/getExamples.js
574893
575067
  function getExamples(schema2) {
574894
575068
  const examples = getExtension(schema2, "examples");
@@ -585164,11 +585338,6 @@ function getScopes(oauthSecurityScheme, source2) {
585164
585338
  return void 0;
585165
585339
  }
585166
585340
 
585167
- // ../api-importers/openapi/openapi-ir-parser/lib/openapi/v3/extensions/getFernBasePath.js
585168
- function getFernBasePath(parameter6) {
585169
- return getExtension(parameter6, FernOpenAPIExtension.BASE_PATH);
585170
- }
585171
-
585172
585341
  // ../api-importers/openapi/openapi-ir-parser/lib/openapi/v3/extensions/getFernGroups.js
585173
585342
  init_zod();
585174
585343
  var XFernGroupsSchema = external_exports2.record(external_exports2.string(), external_exports2.object({
@@ -585479,6 +585648,17 @@ function generateIr({ openApi, taskContext, options: options2, source: source2,
585479
585648
  if (context3.filter.hasEndpoints()) {
585480
585649
  taskContext.logger.debug("Endpoint filter applied...");
585481
585650
  }
585651
+ const fernBasePathParsed = getFernBasePath(openApi);
585652
+ if (fernBasePathParsed?.pathsIncludeBasePath) {
585653
+ const stripErrors = stripBasePathFromPaths({
585654
+ openApi,
585655
+ basePath: fernBasePathParsed.basePath,
585656
+ rootPathParameterNames: new Set(fernBasePathParsed.pathParameters.map((p14) => p14.name))
585657
+ });
585658
+ for (const message of stripErrors) {
585659
+ taskContext.logger.warn(message);
585660
+ }
585661
+ }
585482
585662
  Object.entries(openApi.paths ?? {}).forEach(([path113, pathItem]) => {
585483
585663
  if (pathItem == null) {
585484
585664
  return;
@@ -585706,7 +585886,17 @@ function generateIr({ openApi, taskContext, options: options2, source: source2,
585706
585886
  context: context3,
585707
585887
  document: openApi
585708
585888
  }),
585709
- basePath: getFernBasePath(openApi),
585889
+ basePath: (() => {
585890
+ const parsed = getFernBasePath(openApi);
585891
+ return parsed?.basePath;
585892
+ })(),
585893
+ basePathParameters: (() => {
585894
+ const parsed = getFernBasePath(openApi);
585895
+ if (parsed == null || parsed.pathParameters.length === 0) {
585896
+ return void 0;
585897
+ }
585898
+ return parsed.pathParameters;
585899
+ })(),
585710
585900
  title: openApi.info.title ?? "",
585711
585901
  description: openApi.info.description,
585712
585902
  groups: Object.fromEntries(Object.entries(groupInfo ?? {}).map(([key2, value2]) => {
@@ -585898,6 +586088,7 @@ function parse8({ context: context3, documents, options: options2 }) {
585898
586088
  title: void 0,
585899
586089
  description: void 0,
585900
586090
  basePath: void 0,
586091
+ basePathParameters: void 0,
585901
586092
  servers: [],
585902
586093
  websocketServers: [],
585903
586094
  tags: {
@@ -586113,6 +586304,7 @@ function merge7(ir1, ir23, options2) {
586113
586304
  title: ir1.title ?? ir23.title,
586114
586305
  description: ir1.description ?? ir23.description,
586115
586306
  basePath: ir1.basePath ?? ir23.basePath,
586307
+ basePathParameters: ir1.basePathParameters ?? ir23.basePathParameters,
586116
586308
  servers: [...ir1.servers, ...ir23.servers],
586117
586309
  websocketServers: [...ir1.websocketServers, ...ir23.websocketServers],
586118
586310
  tags: {
@@ -586243,6 +586435,7 @@ function merge7(ir1, ir23, options2) {
586243
586435
  title: ir1.title ?? ir23.title,
586244
586436
  description: ir1.description ?? ir23.description,
586245
586437
  basePath: ir1.basePath ?? ir23.basePath,
586438
+ basePathParameters: ir1.basePathParameters ?? ir23.basePathParameters,
586246
586439
  // Cast grouped servers to Server[] - buildEnvironments.ts handles the grouped structure
586247
586440
  // biome-ignore lint/suspicious/noExplicitAny: Required to preserve grouped server metadata through type system
586248
586441
  servers: mergedServers,
@@ -586295,6 +586488,7 @@ function merge7(ir1, ir23, options2) {
586295
586488
  title: ir1.title ?? ir23.title,
586296
586489
  description: ir1.description ?? ir23.description,
586297
586490
  basePath: ir1.basePath ?? ir23.basePath,
586491
+ basePathParameters: ir1.basePathParameters ?? ir23.basePathParameters,
586298
586492
  servers: [...ir1.servers, ...ir23.servers],
586299
586493
  websocketServers: [...ir1.websocketServers, ...ir23.websocketServers],
586300
586494
  tags: {
@@ -606419,17 +606613,16 @@ function convertExampleResponseBody({ endpoint: endpoint3, example, typeResolver
606419
606613
  workspace
606420
606614
  });
606421
606615
  }
606422
- function buildUrl({ file: file4, service, endpoint: endpoint3, example, pathParams }) {
606616
+ function buildUrl({ file: file4, service, endpoint: endpoint3, pathParams }) {
606423
606617
  let url3 = (0, import_url_join6.default)(file4.rootApiFile["base-path"] ?? "", service["base-path"], endpoint3.path);
606424
- if (example["path-parameters"] != null) {
606425
- for (const parameter6 of [
606426
- ...pathParams.endpointPathParameters,
606427
- ...pathParams.servicePathParameters,
606428
- ...pathParams.rootPathParameters
606429
- ]) {
606430
- url3 = url3.replaceAll(`{${getOriginalName(parameter6.name)}}`, encodeURIComponent(`${parameter6.value.jsonExample}`));
606431
- }
606618
+ for (const parameter6 of [
606619
+ ...pathParams.endpointPathParameters,
606620
+ ...pathParams.servicePathParameters,
606621
+ ...pathParams.rootPathParameters
606622
+ ]) {
606623
+ url3 = url3.replaceAll(`{${getOriginalName(parameter6.name)}}`, encodeURIComponent(`${parameter6.value.jsonExample}`));
606432
606624
  }
606625
+ url3 = url3.replace(/\{([^}]+)\}/g, (_7, name2) => encodeURIComponent(name2));
606433
606626
  url3 = url3.replaceAll("//", "/");
606434
606627
  if (!url3.startsWith("/")) {
606435
606628
  url3 = `/${url3}`;
@@ -653738,6 +653931,7 @@ init_lib8();
653738
653931
  var import_openapi_types2 = __toESM(require_dist10(), 1);
653739
653932
 
653740
653933
  // ../api-importers/openapi-to-ir/lib/extensions/x-fern-base-path.js
653934
+ var PLACEHOLDER_REGEX2 = /\{([^}]+)\}/g;
653741
653935
  var FernBasePathExtension = class extends AbstractExtension {
653742
653936
  document;
653743
653937
  key = "x-fern-base-path";
@@ -653746,20 +653940,108 @@ var FernBasePathExtension = class extends AbstractExtension {
653746
653940
  this.document = document4;
653747
653941
  }
653748
653942
  convert() {
653749
- const extensionValue = this.getExtensionValue(this.document);
653750
- if (extensionValue == null) {
653943
+ const value2 = this.getExtensionValue(this.document);
653944
+ if (value2 == null) {
653751
653945
  return void 0;
653752
653946
  }
653753
- if (typeof extensionValue !== "string") {
653947
+ if (typeof value2 === "string") {
653948
+ return this.parseString(value2);
653949
+ }
653950
+ if (typeof value2 === "object" && !Array.isArray(value2)) {
653951
+ return this.parseStructured(value2);
653952
+ }
653953
+ this.context.errorCollector.collect({
653954
+ message: "Expected `x-fern-base-path` to be a string or object",
653955
+ path: this.breadcrumbs
653956
+ });
653957
+ return void 0;
653958
+ }
653959
+ parseString(path113) {
653960
+ if (!this.validatePath(path113)) {
653961
+ return void 0;
653962
+ }
653963
+ return { path: path113, parameters: [], pathsIncludeBasePath: false };
653964
+ }
653965
+ parseStructured(obj) {
653966
+ const path113 = obj["path"];
653967
+ if (typeof path113 !== "string") {
653754
653968
  this.context.errorCollector.collect({
653755
- message: "Received unexpected non-string value for x-fern-base-path",
653969
+ message: "`x-fern-base-path.path` must be a string",
653756
653970
  path: this.breadcrumbs
653757
653971
  });
653758
653972
  return void 0;
653759
653973
  }
653760
- return extensionValue;
653974
+ if (!this.validatePath(path113)) {
653975
+ return void 0;
653976
+ }
653977
+ const placeholders = extractPlaceholders2(path113);
653978
+ const rawParameters = obj["parameters"];
653979
+ if (rawParameters != null && (typeof rawParameters !== "object" || Array.isArray(rawParameters))) {
653980
+ this.context.errorCollector.collect({
653981
+ message: "`x-fern-base-path.parameters` must be an object map",
653982
+ path: [...this.breadcrumbs, "parameters"]
653983
+ });
653984
+ return void 0;
653985
+ }
653986
+ const parametersMap = rawParameters ?? {};
653987
+ for (const name2 of Object.keys(parametersMap)) {
653988
+ if (!placeholders.has(name2)) {
653989
+ this.context.errorCollector.collect({
653990
+ message: `Parameter '${name2}' does not appear in the base path '${path113}'`,
653991
+ path: [...this.breadcrumbs, "parameters", name2]
653992
+ });
653993
+ return void 0;
653994
+ }
653995
+ }
653996
+ const parameters2 = [];
653997
+ for (const name2 of placeholders) {
653998
+ const raw = parametersMap[name2];
653999
+ if (raw == null) {
654000
+ parameters2.push({ name: name2, type: "string", default: void 0, docs: void 0 });
654001
+ continue;
654002
+ }
654003
+ if (typeof raw !== "object" || Array.isArray(raw)) {
654004
+ this.context.errorCollector.collect({
654005
+ message: `Parameter '${name2}' must be an object`,
654006
+ path: [...this.breadcrumbs, "parameters", name2]
654007
+ });
654008
+ return void 0;
654009
+ }
654010
+ const entry = raw;
654011
+ const type8 = typeof entry["type"] === "string" ? entry["type"] : "string";
654012
+ const docs2 = typeof entry["docs"] === "string" ? entry["docs"] : void 0;
654013
+ parameters2.push({
654014
+ name: name2,
654015
+ type: type8,
654016
+ default: entry["default"],
654017
+ docs: docs2
654018
+ });
654019
+ }
654020
+ const pathsIncludeBasePath = obj["paths-include-base-path"] === true;
654021
+ return { path: path113, parameters: parameters2, pathsIncludeBasePath };
654022
+ }
654023
+ validatePath(path113) {
654024
+ if (!path113.startsWith("/")) {
654025
+ this.context.errorCollector.collect({
654026
+ message: "`x-fern-base-path` path must start with '/'",
654027
+ path: this.breadcrumbs
654028
+ });
654029
+ return false;
654030
+ }
654031
+ return true;
653761
654032
  }
653762
654033
  };
654034
+ function extractPlaceholders2(path113) {
654035
+ const result = /* @__PURE__ */ new Set();
654036
+ let match3;
654037
+ const regex5 = new RegExp(PLACEHOLDER_REGEX2.source, "g");
654038
+ while ((match3 = regex5.exec(path113)) != null) {
654039
+ if (match3[1] != null) {
654040
+ result.add(match3[1]);
654041
+ }
654042
+ }
654043
+ return result;
654044
+ }
653763
654045
 
653764
654046
  // ../api-importers/openapi-to-ir/lib/extensions/x-fern-global-headers.js
653765
654047
  var FernGlobalHeadersExtension = class extends AbstractExtension {
@@ -657023,9 +657305,44 @@ var OpenAPIConverter = class extends AbstractSpecConverter {
657023
657305
  document: this.context.spec,
657024
657306
  context: this.context
657025
657307
  });
657026
- const basePath = basePathExtension.convert();
657027
- if (basePath != null) {
657028
- this.ir.basePath = constructHttpPath(basePath);
657308
+ const parsed = basePathExtension.convert();
657309
+ if (parsed == null) {
657310
+ return;
657311
+ }
657312
+ this.ir.basePath = constructHttpPath(parsed.path);
657313
+ for (const param of parsed.parameters) {
657314
+ if (param.type !== "string") {
657315
+ this.context.errorCollector.collect({
657316
+ message: `x-fern-base-path parameter '${param.name}' uses type '${param.type}' which is not yet supported; treating as string`,
657317
+ path: ["x-fern-base-path", "parameters", param.name]
657318
+ });
657319
+ }
657320
+ this.ir.pathParameters.push({
657321
+ name: this.context.casingsGenerator.generateName(param.name),
657322
+ valueType: AbstractConverter.STRING,
657323
+ docs: param.docs,
657324
+ location: api_exports.PathParameterLocation.Root,
657325
+ variable: void 0,
657326
+ clientDefault: convertExtensionDefaultToLiteral(param.default),
657327
+ v2Examples: {
657328
+ userSpecifiedExamples: {},
657329
+ autogeneratedExamples: {}
657330
+ },
657331
+ explode: void 0
657332
+ });
657333
+ }
657334
+ if (parsed.pathsIncludeBasePath) {
657335
+ const stripErrors = stripBasePathFromPaths({
657336
+ openApi: this.context.spec,
657337
+ basePath: parsed.path,
657338
+ rootPathParameterNames: new Set(parsed.parameters.map((p14) => p14.name))
657339
+ });
657340
+ for (const message of stripErrors) {
657341
+ this.context.errorCollector.collect({
657342
+ message,
657343
+ path: ["x-fern-base-path", "paths-include-base-path"]
657344
+ });
657345
+ }
657029
657346
  }
657030
657347
  }
657031
657348
  convertSecuritySchemes() {
@@ -657264,6 +657581,18 @@ var OpenAPIConverter = class extends AbstractSpecConverter {
657264
657581
  }
657265
657582
  }
657266
657583
  };
657584
+ function convertExtensionDefaultToLiteral(value2) {
657585
+ if (value2 == null) {
657586
+ return void 0;
657587
+ }
657588
+ if (typeof value2 === "string") {
657589
+ return Literal.string(value2);
657590
+ }
657591
+ if (typeof value2 === "boolean") {
657592
+ return Literal.boolean(value2);
657593
+ }
657594
+ return void 0;
657595
+ }
657267
657596
 
657268
657597
  // ../api-importers/openapi-to-ir/lib/extensions/x-display-name.js
657269
657598
  var DisplayNameExtension2 = class extends AbstractExtension {
@@ -668069,7 +668398,7 @@ var AccessTokenPosthogManager = class {
668069
668398
  properties: {
668070
668399
  ...event,
668071
668400
  ...event.properties,
668072
- version: "5.31.0",
668401
+ version: "5.32.0",
668073
668402
  usingAccessToken: true,
668074
668403
  ...getRunIdProperties()
668075
668404
  }
@@ -668133,7 +668462,7 @@ var UserPosthogManager = class {
668133
668462
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
668134
668463
  event: "CLI",
668135
668464
  properties: {
668136
- version: "5.31.0",
668465
+ version: "5.32.0",
668137
668466
  ...event,
668138
668467
  ...event.properties,
668139
668468
  usingAccessToken: false,
@@ -859909,7 +860238,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
859909
860238
  var LOGS_FOLDER_NAME = "logs";
859910
860239
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
859911
860240
  function getCliSource() {
859912
- const version7 = "5.31.0";
860241
+ const version7 = "5.32.0";
859913
860242
  return `cli@${version7}`;
859914
860243
  }
859915
860244
  var DebugLogger = class {
@@ -878741,7 +879070,7 @@ var LegacyDocsPublisher = class {
878741
879070
  previewId,
878742
879071
  disableTemplates: void 0,
878743
879072
  skipUpload,
878744
- cliVersion: "5.31.0",
879073
+ cliVersion: "5.32.0",
878745
879074
  loginCommand: "fern auth login"
878746
879075
  });
878747
879076
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -953151,7 +953480,7 @@ function getAutomationContextFromEnv() {
953151
953480
  config_branch: process.env.FERN_CONFIG_BRANCH,
953152
953481
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
953153
953482
  trigger: process.env.GITHUB_EVENT_NAME,
953154
- cli_version: "5.31.0"
953483
+ cli_version: "5.32.0"
953155
953484
  };
953156
953485
  }
953157
953486
  function isAutomationMode() {
@@ -953977,7 +954306,7 @@ var CliContext = class _CliContext {
953977
954306
  if (false) {
953978
954307
  this.logger.error("CLI_VERSION is not defined");
953979
954308
  }
953980
- return "5.31.0";
954309
+ return "5.32.0";
953981
954310
  }
953982
954311
  getCliName() {
953983
954312
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.31.0",
2
+ "version": "5.32.0",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",