@fern-api/fern-api-dev 5.30.4 → 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 +427 -75
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -537109,6 +537109,7 @@ var Package = schemas_exports3.objectWithoutOptionalProperties({
537109
537109
  websocket: WebSocketChannelId.optional(),
537110
537110
  subpackages: schemas_exports3.list(SubpackageId),
537111
537111
  hasEndpointsInTree: schemas_exports3.boolean(),
537112
+ hasWebSocketInTree: schemas_exports3.boolean().optional(),
537112
537113
  navigationConfig: PackageNavigationConfig.optional()
537113
537114
  }).extend(WithDocs);
537114
537115
 
@@ -567334,6 +567335,7 @@ var OpenApiIntermediateRepresentation = schemas_exports9.objectWithoutOptionalPr
567334
567335
  title: schemas_exports9.string().optional(),
567335
567336
  description: schemas_exports9.string().optional(),
567336
567337
  basePath: schemas_exports9.string().optional(),
567338
+ basePathParameters: schemas_exports9.list(PathParameter2).optional(),
567337
567339
  servers: schemas_exports9.list(Server),
567338
567340
  websocketServers: schemas_exports9.list(Server),
567339
567341
  groups: schemas_exports9.record(schemas_exports9.string(), SdkGroupInfo),
@@ -571543,8 +571545,20 @@ function buildEndpointExample({ endpointExample, context: context3 }) {
571543
571545
  if (endpointExample.description != null) {
571544
571546
  example.docs = endpointExample.description;
571545
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
+ }
571546
571557
  if (endpointExample.pathParameters != null && endpointExample.pathParameters.length > 0) {
571547
- 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;
571548
571562
  }
571549
571563
  if (endpointExample.queryParameters != null && endpointExample.queryParameters.length > 0) {
571550
571564
  example["query-parameters"] = convertQueryParameterExample2(endpointExample.queryParameters);
@@ -572135,34 +572149,35 @@ function getRequest({ endpoint: endpoint3, declarationFile, context: context3, r
572135
572149
  declarationDepth: 0,
572136
572150
  variant
572137
572151
  });
572138
- const convertedRequest = {
572139
- schemaIdsToExclude: [],
572140
- value: {
572141
- body: requestTypeReference
572142
- }
572152
+ const requestValue = {
572153
+ body: requestTypeReference
572143
572154
  };
572144
572155
  const hasPathParams = Object.keys(pathParameters ?? {}).length > 0;
572145
572156
  const hasQueryParams = Object.keys(queryParameters ?? {}).length > 0;
572146
572157
  const hasHeaders = Object.keys(headers2 ?? {}).length > 0;
572147
572158
  if (hasPathParams) {
572148
- convertedRequest.value["path-parameters"] = pathParameters;
572159
+ requestValue["path-parameters"] = pathParameters;
572149
572160
  }
572150
572161
  if (hasQueryParams) {
572151
- convertedRequest.value["query-parameters"] = queryParameters;
572162
+ requestValue["query-parameters"] = queryParameters;
572152
572163
  }
572153
572164
  if (hasHeaders) {
572154
- convertedRequest.value.headers = headers2;
572165
+ requestValue.headers = headers2;
572155
572166
  }
572156
572167
  if (hasPathParams || hasQueryParams || hasHeaders) {
572157
- convertedRequest.value.name = requestNameOverride ?? generatedRequestName;
572168
+ requestValue.name = requestNameOverride ?? generatedRequestName;
572158
572169
  }
572159
572170
  if (request7.contentType != null) {
572160
- convertedRequest.value["content-type"] = request7.contentType;
572171
+ requestValue["content-type"] = request7.contentType;
572161
572172
  }
572162
572173
  if (request7.description != null) {
572163
- convertedRequest.value.docs = request7.description;
572174
+ requestValue.docs = request7.description;
572164
572175
  }
572165
- 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
+ };
572166
572181
  }
572167
572182
  const propertyToDeclarationFile = /* @__PURE__ */ new Map();
572168
572183
  for (const allOfRef of resolvedSchema.allOf) {
@@ -573242,6 +573257,22 @@ function buildFernDefinition(context3) {
573242
573257
  if (context3.ir.basePath != null) {
573243
573258
  context3.builder.setBasePath(context3.ir.basePath);
573244
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
+ }
573245
573276
  if (context3.ir.hasEndpointsMarkedInternal) {
573246
573277
  context3.builder.addAudience(EXTERNAL_AUDIENCE);
573247
573278
  }
@@ -573366,6 +573397,7 @@ var FernDefinitionBuilderImpl = class {
573366
573397
  rootApiFile;
573367
573398
  packageMarkerFile = {};
573368
573399
  basePath = void 0;
573400
+ rootPathParameters = void 0;
573369
573401
  constructor(enableUniqueErrorsPerEndpoint) {
573370
573402
  this.enableUniqueErrorsPerEndpoint = enableUniqueErrorsPerEndpoint;
573371
573403
  this.root = new FernDefinitionDirectory();
@@ -573430,6 +573462,12 @@ var FernDefinitionBuilderImpl = class {
573430
573462
  setBasePath(basePath) {
573431
573463
  this.basePath = basePath;
573432
573464
  }
573465
+ setRootPathParameters(parameters2) {
573466
+ if (Object.keys(parameters2).length === 0) {
573467
+ return;
573468
+ }
573469
+ this.rootPathParameters = parameters2;
573470
+ }
573433
573471
  setApiVersion(apiVersionScheme) {
573434
573472
  this.rootApiFile.version = apiVersionScheme;
573435
573473
  }
@@ -573662,7 +573700,9 @@ var FernDefinitionBuilderImpl = class {
573662
573700
  build() {
573663
573701
  const definitionFiles = this.root.getAllFiles();
573664
573702
  const basePath = this.basePath;
573665
- if (basePath != null) {
573703
+ const rootPathParameters = this.rootPathParameters;
573704
+ const shouldInline = basePath != null && rootPathParameters == null && !basePath.includes("{");
573705
+ if (basePath != null && shouldInline) {
573666
573706
  if (this.packageMarkerFile.service != null) {
573667
573707
  this.packageMarkerFile.service = {
573668
573708
  ...this.packageMarkerFile.service,
@@ -573693,6 +573733,11 @@ var FernDefinitionBuilderImpl = class {
573693
573733
  };
573694
573734
  }
573695
573735
  }
573736
+ } else if (basePath != null) {
573737
+ this.rootApiFile["base-path"] = basePath;
573738
+ if (rootPathParameters != null) {
573739
+ this.rootApiFile["path-parameters"] = rootPathParameters;
573740
+ }
573696
573741
  }
573697
573742
  const definition3 = {
573698
573743
  rootApiFile: this.rootApiFile,
@@ -574779,6 +574824,161 @@ var FernOpenAPIExtension = {
574779
574824
  FERN_DEFAULT: "x-fern-default"
574780
574825
  };
574781
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
+
574782
574982
  // ../api-importers/openapi/openapi-ir-parser/lib/options.js
574783
574983
  var DEFAULT_PARSE_OPENAPI_SETTINGS = {
574784
574984
  disableExamples: false,
@@ -574863,31 +575063,6 @@ init_lib6();
574863
575063
  init_lib6();
574864
575064
  init_lodash();
574865
575065
 
574866
- // ../api-importers/openapi/openapi-ir-parser/lib/getExtension.js
574867
- init_lodash();
574868
- function getExtension(object23, extension4) {
574869
- const extensions2 = Array.isArray(extension4) ? extension4 : [extension4];
574870
- for (const extension5 of extensions2) {
574871
- const extensionValue = object23[extension5];
574872
- if (extensionValue != null) {
574873
- return extensionValue;
574874
- }
574875
- }
574876
- return void 0;
574877
- }
574878
- function getExtensionAndValidate(object23, extension4, schema2, logger4, breadcrumbs = []) {
574879
- try {
574880
- const extensionValue = getExtension(object23, extension4);
574881
- if (extensionValue != null) {
574882
- return schema2.parse(extensionValue);
574883
- }
574884
- } catch (e8) {
574885
- const breadcrumb = compact_default(breadcrumbs).join(" -> ");
574886
- logger4.error(`${breadcrumb.length > 0 ? `${breadcrumb}: ` : ""}Failed to parse ${extension4}`);
574887
- }
574888
- return void 0;
574889
- }
574890
-
574891
575066
  // ../api-importers/openapi/openapi-ir-parser/lib/openapi/v3/extensions/getExamples.js
574892
575067
  function getExamples(schema2) {
574893
575068
  const examples = getExtension(schema2, "examples");
@@ -585163,11 +585338,6 @@ function getScopes(oauthSecurityScheme, source2) {
585163
585338
  return void 0;
585164
585339
  }
585165
585340
 
585166
- // ../api-importers/openapi/openapi-ir-parser/lib/openapi/v3/extensions/getFernBasePath.js
585167
- function getFernBasePath(parameter6) {
585168
- return getExtension(parameter6, FernOpenAPIExtension.BASE_PATH);
585169
- }
585170
-
585171
585341
  // ../api-importers/openapi/openapi-ir-parser/lib/openapi/v3/extensions/getFernGroups.js
585172
585342
  init_zod();
585173
585343
  var XFernGroupsSchema = external_exports2.record(external_exports2.string(), external_exports2.object({
@@ -585478,6 +585648,17 @@ function generateIr({ openApi, taskContext, options: options2, source: source2,
585478
585648
  if (context3.filter.hasEndpoints()) {
585479
585649
  taskContext.logger.debug("Endpoint filter applied...");
585480
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
+ }
585481
585662
  Object.entries(openApi.paths ?? {}).forEach(([path113, pathItem]) => {
585482
585663
  if (pathItem == null) {
585483
585664
  return;
@@ -585705,7 +585886,17 @@ function generateIr({ openApi, taskContext, options: options2, source: source2,
585705
585886
  context: context3,
585706
585887
  document: openApi
585707
585888
  }),
585708
- 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
+ })(),
585709
585900
  title: openApi.info.title ?? "",
585710
585901
  description: openApi.info.description,
585711
585902
  groups: Object.fromEntries(Object.entries(groupInfo ?? {}).map(([key2, value2]) => {
@@ -585897,6 +586088,7 @@ function parse8({ context: context3, documents, options: options2 }) {
585897
586088
  title: void 0,
585898
586089
  description: void 0,
585899
586090
  basePath: void 0,
586091
+ basePathParameters: void 0,
585900
586092
  servers: [],
585901
586093
  websocketServers: [],
585902
586094
  tags: {
@@ -586112,6 +586304,7 @@ function merge7(ir1, ir23, options2) {
586112
586304
  title: ir1.title ?? ir23.title,
586113
586305
  description: ir1.description ?? ir23.description,
586114
586306
  basePath: ir1.basePath ?? ir23.basePath,
586307
+ basePathParameters: ir1.basePathParameters ?? ir23.basePathParameters,
586115
586308
  servers: [...ir1.servers, ...ir23.servers],
586116
586309
  websocketServers: [...ir1.websocketServers, ...ir23.websocketServers],
586117
586310
  tags: {
@@ -586242,6 +586435,7 @@ function merge7(ir1, ir23, options2) {
586242
586435
  title: ir1.title ?? ir23.title,
586243
586436
  description: ir1.description ?? ir23.description,
586244
586437
  basePath: ir1.basePath ?? ir23.basePath,
586438
+ basePathParameters: ir1.basePathParameters ?? ir23.basePathParameters,
586245
586439
  // Cast grouped servers to Server[] - buildEnvironments.ts handles the grouped structure
586246
586440
  // biome-ignore lint/suspicious/noExplicitAny: Required to preserve grouped server metadata through type system
586247
586441
  servers: mergedServers,
@@ -586294,6 +586488,7 @@ function merge7(ir1, ir23, options2) {
586294
586488
  title: ir1.title ?? ir23.title,
586295
586489
  description: ir1.description ?? ir23.description,
586296
586490
  basePath: ir1.basePath ?? ir23.basePath,
586491
+ basePathParameters: ir1.basePathParameters ?? ir23.basePathParameters,
586297
586492
  servers: [...ir1.servers, ...ir23.servers],
586298
586493
  websocketServers: [...ir1.websocketServers, ...ir23.websocketServers],
586299
586494
  tags: {
@@ -602931,6 +603126,7 @@ function mergeIntermediateRepresentation(ir1, ir23, casingsGenerator) {
602931
603126
  webhooks: ir1.rootPackage.webhooks ?? ir23.rootPackage.webhooks,
602932
603127
  websocket: ir1.rootPackage.websocket ?? ir23.rootPackage.websocket,
602933
603128
  hasEndpointsInTree: ir1.rootPackage.hasEndpointsInTree || ir23.rootPackage.hasEndpointsInTree,
603129
+ hasWebSocketInTree: (ir1.rootPackage.hasWebSocketInTree ?? false) || (ir23.rootPackage.hasWebSocketInTree ?? false) || void 0,
602934
603130
  navigationConfig: ir1.rootPackage.navigationConfig ?? ir23.rootPackage.navigationConfig,
602935
603131
  docs: ir1.rootPackage.docs ?? ir23.rootPackage.docs
602936
603132
  },
@@ -602963,6 +603159,7 @@ function mergeSubpackages(subpackages1, subpackages2) {
602963
603159
  displayName: subpackage.displayName,
602964
603160
  fernFilepath: subpackage.fernFilepath,
602965
603161
  hasEndpointsInTree: mergedSubpackages[subpackageId].hasEndpointsInTree || subpackage.hasEndpointsInTree,
603162
+ hasWebSocketInTree: (mergedSubpackages[subpackageId].hasWebSocketInTree ?? false) || (subpackage.hasWebSocketInTree ?? false) || void 0,
602966
603163
  navigationConfig: mergedSubpackages[subpackageId].navigationConfig ?? subpackage.navigationConfig,
602967
603164
  docs: mergedSubpackages[subpackageId].docs ?? subpackage.docs,
602968
603165
  service: mergedSubpackages[subpackageId].service ?? subpackage.service,
@@ -606416,17 +606613,16 @@ function convertExampleResponseBody({ endpoint: endpoint3, example, typeResolver
606416
606613
  workspace
606417
606614
  });
606418
606615
  }
606419
- function buildUrl({ file: file4, service, endpoint: endpoint3, example, pathParams }) {
606616
+ function buildUrl({ file: file4, service, endpoint: endpoint3, pathParams }) {
606420
606617
  let url3 = (0, import_url_join6.default)(file4.rootApiFile["base-path"] ?? "", service["base-path"], endpoint3.path);
606421
- if (example["path-parameters"] != null) {
606422
- for (const parameter6 of [
606423
- ...pathParams.endpointPathParameters,
606424
- ...pathParams.servicePathParameters,
606425
- ...pathParams.rootPathParameters
606426
- ]) {
606427
- url3 = url3.replaceAll(`{${getOriginalName(parameter6.name)}}`, encodeURIComponent(`${parameter6.value.jsonExample}`));
606428
- }
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}`));
606429
606624
  }
606625
+ url3 = url3.replace(/\{([^}]+)\}/g, (_7, name2) => encodeURIComponent(name2));
606430
606626
  url3 = url3.replaceAll("//", "/");
606431
606627
  if (!url3.startsWith("/")) {
606432
606628
  url3 = `/${url3}`;
@@ -610163,14 +610359,17 @@ var PackageTreeGenerator = class {
610163
610359
  };
610164
610360
  }
610165
610361
  const allSubpackagesWithEndpoints = new Set(this.getAllChildrenWithEndpoints(this.rootPackage));
610362
+ const allSubpackagesWithWebSocket = new Set(this.getAllChildrenWithWebSocket(this.rootPackage));
610166
610363
  return {
610167
610364
  subpackages: mapValues_default(this.subpackages, (subpackage, subpackageId) => ({
610168
610365
  ...subpackage,
610169
- hasEndpointsInTree: allSubpackagesWithEndpoints.has(subpackageId)
610366
+ hasEndpointsInTree: allSubpackagesWithEndpoints.has(subpackageId),
610367
+ hasWebSocketInTree: allSubpackagesWithWebSocket.has(subpackageId) || subpackage.websocket != null
610170
610368
  })),
610171
610369
  rootPackage: {
610172
610370
  ...this.rootPackage,
610173
- hasEndpointsInTree: allSubpackagesWithEndpoints.size > 0 || this.rootPackage.service != null
610371
+ hasEndpointsInTree: allSubpackagesWithEndpoints.size > 0 || this.rootPackage.service != null,
610372
+ hasWebSocketInTree: allSubpackagesWithWebSocket.size > 0 || this.rootPackage.websocket != null || Object.values(this.subpackages).some((s9) => s9.websocket != null)
610174
610373
  }
610175
610374
  };
610176
610375
  }
@@ -610215,6 +610414,22 @@ var PackageTreeGenerator = class {
610215
610414
  return [...this.getAllSubpackagesWithEndpoints(child)];
610216
610415
  });
610217
610416
  }
610417
+ getAllSubpackagesWithWebSocket(root6) {
610418
+ const subpackage = this.subpackages[root6];
610419
+ if (subpackage == null) {
610420
+ throw new CliError({ message: "Subpackage does not exist: " + root6, code: CliError.Code.ResolutionError });
610421
+ }
610422
+ const subpackagesWithWebSocket = this.getAllChildrenWithWebSocket(subpackage);
610423
+ if (subpackagesWithWebSocket.length > 0 || subpackage.websocket != null) {
610424
+ subpackagesWithWebSocket.push(root6);
610425
+ }
610426
+ return subpackagesWithWebSocket;
610427
+ }
610428
+ getAllChildrenWithWebSocket(package_) {
610429
+ return package_.subpackages.flatMap((child) => {
610430
+ return [...this.getAllSubpackagesWithWebSocket(child)];
610431
+ });
610432
+ }
610218
610433
  getPackageForFernFilepath(fernFilepath, index3 = 0, parent = this.rootPackage) {
610219
610434
  const nextPart = fernFilepath.allParts[index3];
610220
610435
  if (nextPart == null) {
@@ -647779,6 +647994,7 @@ var AbstractSpecConverter = class extends AbstractConverter {
647779
647994
  webhooks: void 0,
647780
647995
  websocket: void 0,
647781
647996
  hasEndpointsInTree: false,
647997
+ hasWebSocketInTree: void 0,
647782
647998
  navigationConfig: void 0
647783
647999
  };
647784
648000
  }
@@ -653715,6 +653931,7 @@ init_lib8();
653715
653931
  var import_openapi_types2 = __toESM(require_dist10(), 1);
653716
653932
 
653717
653933
  // ../api-importers/openapi-to-ir/lib/extensions/x-fern-base-path.js
653934
+ var PLACEHOLDER_REGEX2 = /\{([^}]+)\}/g;
653718
653935
  var FernBasePathExtension = class extends AbstractExtension {
653719
653936
  document;
653720
653937
  key = "x-fern-base-path";
@@ -653723,20 +653940,108 @@ var FernBasePathExtension = class extends AbstractExtension {
653723
653940
  this.document = document4;
653724
653941
  }
653725
653942
  convert() {
653726
- const extensionValue = this.getExtensionValue(this.document);
653727
- if (extensionValue == null) {
653943
+ const value2 = this.getExtensionValue(this.document);
653944
+ if (value2 == null) {
653728
653945
  return void 0;
653729
653946
  }
653730
- 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") {
653731
653968
  this.context.errorCollector.collect({
653732
- message: "Received unexpected non-string value for x-fern-base-path",
653969
+ message: "`x-fern-base-path.path` must be a string",
653733
653970
  path: this.breadcrumbs
653734
653971
  });
653735
653972
  return void 0;
653736
653973
  }
653737
- 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;
653738
654032
  }
653739
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
+ }
653740
654045
 
653741
654046
  // ../api-importers/openapi-to-ir/lib/extensions/x-fern-global-headers.js
653742
654047
  var FernGlobalHeadersExtension = class extends AbstractExtension {
@@ -657000,9 +657305,44 @@ var OpenAPIConverter = class extends AbstractSpecConverter {
657000
657305
  document: this.context.spec,
657001
657306
  context: this.context
657002
657307
  });
657003
- const basePath = basePathExtension.convert();
657004
- if (basePath != null) {
657005
- 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
+ }
657006
657346
  }
657007
657347
  }
657008
657348
  convertSecuritySchemes() {
@@ -657241,6 +657581,18 @@ var OpenAPIConverter = class extends AbstractSpecConverter {
657241
657581
  }
657242
657582
  }
657243
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
+ }
657244
657596
 
657245
657597
  // ../api-importers/openapi-to-ir/lib/extensions/x-display-name.js
657246
657598
  var DisplayNameExtension2 = class extends AbstractExtension {
@@ -668046,7 +668398,7 @@ var AccessTokenPosthogManager = class {
668046
668398
  properties: {
668047
668399
  ...event,
668048
668400
  ...event.properties,
668049
- version: "5.30.4",
668401
+ version: "5.32.0",
668050
668402
  usingAccessToken: true,
668051
668403
  ...getRunIdProperties()
668052
668404
  }
@@ -668110,7 +668462,7 @@ var UserPosthogManager = class {
668110
668462
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
668111
668463
  event: "CLI",
668112
668464
  properties: {
668113
- version: "5.30.4",
668465
+ version: "5.32.0",
668114
668466
  ...event,
668115
668467
  ...event.properties,
668116
668468
  usingAccessToken: false,
@@ -812494,10 +812846,10 @@ var V67_TO_V66_MIGRATION = {
812494
812846
  laterVersion: "v67",
812495
812847
  earlierVersion: "v66",
812496
812848
  firstGeneratorVersionToConsumeNewIR: {
812497
- [GeneratorName.TYPESCRIPT_NODE_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
812498
- [GeneratorName.TYPESCRIPT_BROWSER_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
812499
- [GeneratorName.TYPESCRIPT]: GeneratorWasNeverUpdatedToConsumeNewIR,
812500
- [GeneratorName.TYPESCRIPT_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
812849
+ [GeneratorName.TYPESCRIPT_NODE_SDK]: "3.70.9-rc.0",
812850
+ [GeneratorName.TYPESCRIPT_BROWSER_SDK]: "3.70.9-rc.0",
812851
+ [GeneratorName.TYPESCRIPT]: "3.70.9-rc.0",
812852
+ [GeneratorName.TYPESCRIPT_SDK]: "3.70.9-rc.0",
812501
812853
  [GeneratorName.TYPESCRIPT_EXPRESS]: GeneratorWasNeverUpdatedToConsumeNewIR,
812502
812854
  [GeneratorName.JAVA]: GeneratorWasNeverUpdatedToConsumeNewIR,
812503
812855
  [GeneratorName.JAVA_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
@@ -812507,7 +812859,7 @@ var V67_TO_V66_MIGRATION = {
812507
812859
  [GeneratorName.OPENAPI]: GeneratorWasNeverUpdatedToConsumeNewIR,
812508
812860
  [GeneratorName.PYTHON_FASTAPI]: GeneratorWasNeverUpdatedToConsumeNewIR,
812509
812861
  [GeneratorName.PYTHON_PYDANTIC]: GeneratorWasNeverUpdatedToConsumeNewIR,
812510
- [GeneratorName.PYTHON_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
812862
+ [GeneratorName.PYTHON_SDK]: "5.13.1-rc.0",
812511
812863
  [GeneratorName.STOPLIGHT]: GeneratorWasNeverUpdatedToConsumeNewIR,
812512
812864
  [GeneratorName.POSTMAN]: GeneratorWasNeverUpdatedToConsumeNewIR,
812513
812865
  [GeneratorName.GO_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
@@ -859886,7 +860238,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
859886
860238
  var LOGS_FOLDER_NAME = "logs";
859887
860239
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
859888
860240
  function getCliSource() {
859889
- const version7 = "5.30.4";
860241
+ const version7 = "5.32.0";
859890
860242
  return `cli@${version7}`;
859891
860243
  }
859892
860244
  var DebugLogger = class {
@@ -878718,7 +879070,7 @@ var LegacyDocsPublisher = class {
878718
879070
  previewId,
878719
879071
  disableTemplates: void 0,
878720
879072
  skipUpload,
878721
- cliVersion: "5.30.4",
879073
+ cliVersion: "5.32.0",
878722
879074
  loginCommand: "fern auth login"
878723
879075
  });
878724
879076
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -953128,7 +953480,7 @@ function getAutomationContextFromEnv() {
953128
953480
  config_branch: process.env.FERN_CONFIG_BRANCH,
953129
953481
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
953130
953482
  trigger: process.env.GITHUB_EVENT_NAME,
953131
- cli_version: "5.30.4"
953483
+ cli_version: "5.32.0"
953132
953484
  };
953133
953485
  }
953134
953486
  function isAutomationMode() {
@@ -953954,7 +954306,7 @@ var CliContext = class _CliContext {
953954
954306
  if (false) {
953955
954307
  this.logger.error("CLI_VERSION is not defined");
953956
954308
  }
953957
- return "5.30.4";
954309
+ return "5.32.0";
953958
954310
  }
953959
954311
  getCliName() {
953960
954312
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.30.4",
2
+ "version": "5.32.0",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",