@fern-api/fern-api-dev 5.7.6 → 5.7.7

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 +77 -59
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -535141,7 +535141,7 @@ var ExampleTypeFactory = class _ExampleTypeFactory {
535141
535141
  if (example != null) {
535142
535142
  const allowed = schema2.values.map((v9) => v9.value);
535143
535143
  const exampleStr = _ExampleTypeFactory.truncateExample(example);
535144
- this.context.logger.warn(`Example value ${exampleStr} is not a valid enum value${options2.name != null ? ` for '${options2.name}'` : ""}. Allowed values: [${allowed.join(", ")}]. Using fallback value instead.`);
535144
+ this.context.logger.debug(`Example value ${exampleStr} is not a valid enum value${options2.name != null ? ` for '${options2.name}'` : ""}. Allowed values: [${allowed.join(", ")}]. Using fallback value instead.`);
535145
535145
  }
535146
535146
  return schema2.values[0] != null ? FullExample.enum(schema2.values[0]?.value) : void 0;
535147
535147
  case "literal":
@@ -535973,7 +535973,7 @@ var ExampleTypeFactory = class _ExampleTypeFactory {
535973
535973
  const fieldDesc = options2.name != null ? ` for '${options2.name}'` : "";
535974
535974
  const actualType = typeof example;
535975
535975
  const exampleStr = _ExampleTypeFactory.truncateExample(example);
535976
- this.context.logger.warn(`Invalid example${fieldDesc}: expected ${expected} but got ${actualType} (${exampleStr}). The provided example does not match the '${schemaType}' schema and will be replaced with a generated value.`);
535976
+ this.context.logger.debug(`Invalid example${fieldDesc}: expected ${expected} but got ${actualType} (${exampleStr}). The provided example does not match the '${schemaType}' schema and will be replaced with a generated value.`);
535977
535977
  }
535978
535978
  static truncateExample(example, maxLength = 100) {
535979
535979
  const str3 = JSON.stringify(example);
@@ -541476,7 +541476,6 @@ function replaceWithSchemaReference({ openapi, replaceReference, schemaReference
541476
541476
  // ../api-importers/openapi/openapi-ir-parser/lib/openapi/v3/generateIr.js
541477
541477
  function generateIr({ openApi, taskContext, options: options2, source: source2, namespace }) {
541478
541478
  openApi = runResolutions({ openapi: openApi });
541479
- validateOpenApiSpecForDocsCompat({ openApi, taskContext });
541480
541479
  resetTitleCollisionTracker();
541481
541480
  const tempContext = new OpenAPIV3ParserContext({
541482
541481
  document: openApi,
@@ -541911,35 +541910,6 @@ function getAllParentSchemaIds({ schema: schema2, schemas }) {
541911
541910
  function distinct(array3) {
541912
541911
  return [...new Set(array3)];
541913
541912
  }
541914
- var NON_ASCII_REGEX = new RegExp("[^\\x00-\\x7F]");
541915
- var FRONTMATTER_DELIMITER_REGEX = /(?:^|\n)\s*---\s*(?:\n|$)/;
541916
- function validateOpenApiSpecForDocsCompat({ openApi, taskContext }) {
541917
- for (const tag2 of openApi.tags ?? []) {
541918
- if (NON_ASCII_REGEX.test(tag2.name)) {
541919
- const nonAsciiChars = [...tag2.name].filter((c5) => NON_ASCII_REGEX.test(c5));
541920
- taskContext.logger.error(`Tag name "${tag2.name}" contains non-ASCII characters: ${nonAsciiChars.join(", ")}. Non-ASCII characters in tag names will be included in URL paths and HTTP headers, which only support ASCII characters. This will cause runtime errors (ERR_INVALID_CHAR). Remove non-ASCII characters from the tag name.`);
541921
- }
541922
- }
541923
- for (const [path106, pathItem] of Object.entries(openApi.paths ?? {})) {
541924
- if (pathItem == null) {
541925
- continue;
541926
- }
541927
- for (const method8 of ["get", "post", "put", "delete", "patch", "options", "head", "trace"]) {
541928
- const operation = pathItem[method8];
541929
- if (operation?.description != null && FRONTMATTER_DELIMITER_REGEX.test(operation.description)) {
541930
- taskContext.logger.error(`Description at paths.${path106}.${method8} contains "---" frontmatter delimiters which will cause YAML parsing failures in the generated docs site. Remove the "---" delimiters from the description.`);
541931
- }
541932
- if (operation?.tags != null && (openApi.tags == null || openApi.tags.length === 0)) {
541933
- for (const tag2 of operation.tags) {
541934
- if (NON_ASCII_REGEX.test(tag2)) {
541935
- const nonAsciiChars = [...tag2].filter((c5) => NON_ASCII_REGEX.test(c5));
541936
- taskContext.logger.error(`Tag name "${tag2}" at paths.${path106}.${method8} contains non-ASCII characters: ${nonAsciiChars.join(", ")}. Remove non-ASCII characters from the tag name.`);
541937
- }
541938
- }
541939
- }
541940
- }
541941
- }
541942
- }
541943
541913
  function getAudiences({ operation }) {
541944
541914
  let endpointAudiences = [];
541945
541915
  switch (operation.type) {
@@ -607103,23 +607073,23 @@ var ExampleValidator = class {
607103
607073
  };
607104
607074
 
607105
607075
  // ../api-importers/v3-importer-commons/lib/OpenApiSpecValidations.js
607106
- var NON_ASCII_REGEX2 = new RegExp("[^\\x00-\\x7F]");
607107
- var FRONTMATTER_DELIMITER_REGEX2 = /(?:^|\n)\s*---\s*(?:\n|$)/;
607076
+ var NON_ASCII_REGEX = new RegExp("[^\\x00-\\x7F]");
607077
+ var FRONTMATTER_DELIMITER_REGEX = /(?:^|\n)\s*---\s*(?:\n|$)/;
607108
607078
  function validateTagNames({ tags, errorCollector }) {
607109
607079
  for (const tag2 of tags) {
607110
- if (NON_ASCII_REGEX2.test(tag2.name)) {
607111
- const nonAsciiChars = [...tag2.name].filter((c5) => NON_ASCII_REGEX2.test(c5));
607080
+ if (NON_ASCII_REGEX.test(tag2.name)) {
607081
+ const nonAsciiChars = [...tag2.name].filter((c5) => NON_ASCII_REGEX.test(c5));
607112
607082
  errorCollector.collect({
607113
607083
  level: APIErrorLevel.ERROR,
607114
607084
  message: `Tag name "${tag2.name}" contains non-ASCII characters: ${nonAsciiChars.join(", ")}. Non-ASCII characters in tag names will be included in URL paths and HTTP headers, which only support ASCII characters. This will cause runtime errors (ERR_INVALID_CHAR).`,
607115
607085
  path: ["tags", tag2.name],
607116
- resolution: `Remove non-ASCII characters from the tag name. For example, rename "${tag2.name}" to "${tag2.name.replace(NON_ASCII_REGEX2, "").trim()}".`
607086
+ resolution: `Remove non-ASCII characters from the tag name. For example, rename "${tag2.name}" to "${tag2.name.replace(NON_ASCII_REGEX, "").trim()}".`
607117
607087
  });
607118
607088
  }
607119
607089
  }
607120
607090
  }
607121
607091
  function validateDescription({ description, path: path106, errorCollector }) {
607122
- if (FRONTMATTER_DELIMITER_REGEX2.test(description)) {
607092
+ if (FRONTMATTER_DELIMITER_REGEX.test(description)) {
607123
607093
  errorCollector.collect({
607124
607094
  level: APIErrorLevel.ERROR,
607125
607095
  message: `Description contains "---" frontmatter delimiters which will cause YAML parsing failures in the generated docs site. The docs renderer interprets content between "---" delimiters as YAML frontmatter, which will fail if the content is not valid YAML.`,
@@ -607156,14 +607126,14 @@ function validateOpenApiSpec({ spec, errorCollector }) {
607156
607126
  }
607157
607127
  if (Array.isArray(op4.tags) && !Array.isArray(spec.tags)) {
607158
607128
  for (const tag2 of op4.tags) {
607159
- if (typeof tag2 === "string" && !seenTags.has(tag2) && NON_ASCII_REGEX2.test(tag2)) {
607129
+ if (typeof tag2 === "string" && !seenTags.has(tag2) && NON_ASCII_REGEX.test(tag2)) {
607160
607130
  seenTags.add(tag2);
607161
- const nonAsciiChars = [...tag2].filter((c5) => NON_ASCII_REGEX2.test(c5));
607131
+ const nonAsciiChars = [...tag2].filter((c5) => NON_ASCII_REGEX.test(c5));
607162
607132
  errorCollector.collect({
607163
607133
  level: APIErrorLevel.ERROR,
607164
607134
  message: `Tag name "${tag2}" contains non-ASCII characters: ${nonAsciiChars.join(", ")}. Non-ASCII characters in tag names will be included in URL paths and HTTP headers, which only support ASCII characters. This will cause runtime errors (ERR_INVALID_CHAR).`,
607165
607135
  path: ["paths", path106, method8, "tags"],
607166
- resolution: `Remove non-ASCII characters from the tag name. For example, rename "${tag2}" to "${tag2.replace(NON_ASCII_REGEX2, "").trim()}".`
607136
+ resolution: `Remove non-ASCII characters from the tag name. For example, rename "${tag2}" to "${tag2.replace(NON_ASCII_REGEX, "").trim()}".`
607167
607137
  });
607168
607138
  }
607169
607139
  }
@@ -614844,7 +614814,7 @@ function audiencesIntersect(a3, b8) {
614844
614814
 
614845
614815
  // ../workspace/oss-validator/lib/rules/no-invalid-tag-names-or-frontmatter/no-invalid-tag-names-or-frontmatter.js
614846
614816
  init_lib6();
614847
- var NON_ASCII_REGEX3 = new RegExp("[^\\x00-\\x7F]");
614817
+ var NON_ASCII_REGEX2 = new RegExp("[^\\x00-\\x7F]");
614848
614818
  var FRONTMATTER_REGEX = /(?:^|\n)\s*---\s*(?:\n|$)/;
614849
614819
  var HTTP_METHODS = ["get", "post", "put", "delete", "patch", "options", "head", "trace"];
614850
614820
  var NoInvalidTagNamesOrFrontmatterRule = {
@@ -614865,8 +614835,8 @@ var NoInvalidTagNamesOrFrontmatterRule = {
614865
614835
  if (Array.isArray(apiDoc.tags)) {
614866
614836
  for (const tag2 of apiDoc.tags) {
614867
614837
  if (typeof tag2 === "object" && tag2 != null && typeof tag2.name === "string") {
614868
- if (NON_ASCII_REGEX3.test(tag2.name)) {
614869
- const nonAsciiChars = [...tag2.name].filter((c5) => NON_ASCII_REGEX3.test(c5));
614838
+ if (NON_ASCII_REGEX2.test(tag2.name)) {
614839
+ const nonAsciiChars = [...tag2.name].filter((c5) => NON_ASCII_REGEX2.test(c5));
614870
614840
  violations.push({
614871
614841
  name: "no-invalid-tag-names-or-frontmatter",
614872
614842
  severity: "error",
@@ -614902,9 +614872,9 @@ var NoInvalidTagNamesOrFrontmatterRule = {
614902
614872
  }
614903
614873
  if (Array.isArray(op4.tags) && !Array.isArray(apiDoc.tags)) {
614904
614874
  for (const tag2 of op4.tags) {
614905
- if (typeof tag2 === "string" && !seenInlineTags.has(tag2) && NON_ASCII_REGEX3.test(tag2)) {
614875
+ if (typeof tag2 === "string" && !seenInlineTags.has(tag2) && NON_ASCII_REGEX2.test(tag2)) {
614906
614876
  seenInlineTags.add(tag2);
614907
- const nonAsciiChars = [...tag2].filter((c5) => NON_ASCII_REGEX3.test(c5));
614877
+ const nonAsciiChars = [...tag2].filter((c5) => NON_ASCII_REGEX2.test(c5));
614908
614878
  violations.push({
614909
614879
  name: "no-invalid-tag-names-or-frontmatter",
614910
614880
  severity: "error",
@@ -622607,7 +622577,7 @@ var AccessTokenPosthogManager = class {
622607
622577
  properties: {
622608
622578
  ...event,
622609
622579
  ...event.properties,
622610
- version: "5.7.6",
622580
+ version: "5.7.7",
622611
622581
  usingAccessToken: true
622612
622582
  }
622613
622583
  });
@@ -622661,7 +622631,7 @@ var UserPosthogManager = class {
622661
622631
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
622662
622632
  event: "CLI",
622663
622633
  properties: {
622664
- version: "5.7.6",
622634
+ version: "5.7.7",
622665
622635
  ...event,
622666
622636
  ...event.properties,
622667
622637
  usingAccessToken: false,
@@ -847021,7 +846991,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
847021
846991
  var LOGS_FOLDER_NAME = "logs";
847022
846992
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
847023
846993
  function getCliSource() {
847024
- const version7 = "5.7.6";
846994
+ const version7 = "5.7.7";
847025
846995
  return `cli@${version7}`;
847026
846996
  }
847027
846997
  var DebugLogger = class {
@@ -859637,7 +859607,7 @@ var LegacyDocsPublisher = class {
859637
859607
  previewId,
859638
859608
  disableTemplates: void 0,
859639
859609
  skipUpload,
859640
- cliVersion: "5.7.6",
859610
+ cliVersion: "5.7.7",
859641
859611
  loginCommand: "fern auth login"
859642
859612
  });
859643
859613
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -904967,6 +904937,11 @@ var Expression2 = class extends AstNode8 {
904967
904937
  case "string-literal":
904968
904938
  writer2.write(this.internalExpression.escape ? `"${escapeSwiftStringLiteralContent(this.internalExpression.value)}"` : `"${this.internalExpression.value}"`);
904969
904939
  break;
904940
+ case "raw-multi-line-string-literal":
904941
+ writer2.write(`#"""
904942
+ ${this.internalExpression.value}
904943
+ """#`);
904944
+ break;
904970
904945
  case "number-literal":
904971
904946
  writer2.write(this.internalExpression.value.toString());
904972
904947
  break;
@@ -905115,6 +905090,18 @@ var Expression2 = class extends AstNode8 {
905115
905090
  static escapedStringLiteral(value2) {
905116
905091
  return new this({ type: "string-literal", value: value2, escape: true });
905117
905092
  }
905093
+ /**
905094
+ * Emits `value` as a Swift raw multi-line string literal (`#"""..."""#`).
905095
+ * Inside a raw string literal, escape sequences such as `\n` are NOT
905096
+ * interpreted by the Swift compiler -- they remain as literal
905097
+ * backslash-n characters at runtime. Use this when `value` already
905098
+ * contains escape sequences that must survive verbatim into the
905099
+ * runtime `String` (e.g. JSON payloads where `\n` must reach the
905100
+ * JSON parser as `\n`, not as a real newline).
905101
+ */
905102
+ static rawMultiLineStringLiteral(value2) {
905103
+ return new this({ type: "raw-multi-line-string-literal", value: value2 });
905104
+ }
905118
905105
  static numberLiteral(value2) {
905119
905106
  return new this({ type: "number-literal", value: value2 });
905120
905107
  }
@@ -934062,7 +934049,7 @@ var CliContext = class _CliContext {
934062
934049
  if (false) {
934063
934050
  this.logger.error("CLI_VERSION is not defined");
934064
934051
  }
934065
- return "5.7.6";
934052
+ return "5.7.7";
934066
934053
  }
934067
934054
  getCliName() {
934068
934055
  if (false) {
@@ -949155,6 +949142,7 @@ async function formatWorkspaces({
949155
949142
  // src/commands/generate/generateDocsWorkspace.ts
949156
949143
  init_lib4();
949157
949144
  init_js();
949145
+ init_lib6();
949158
949146
 
949159
949147
  // src/utils/environment.ts
949160
949148
  function detectCISource() {
@@ -949358,22 +949346,21 @@ ${source_default.yellow("?")} Are you sure you want to continue?`,
949358
949346
  const skippedWorkspacePaths = /* @__PURE__ */ new Set();
949359
949347
  const ossWorkspacesForValidation = await filterOssWorkspaces(project);
949360
949348
  for (const ossWorkspace of ossWorkspacesForValidation) {
949349
+ const apiName = ossWorkspace.workspaceName ?? basename3(ossWorkspace.absoluteFilePath);
949361
949350
  try {
949362
949351
  const violations = await validateOSSWorkspace(ossWorkspace, context3);
949363
949352
  const errors4 = violations.filter((v9) => v9.severity === "fatal" || v9.severity === "error");
949364
949353
  if (errors4.length > 0) {
949365
- for (const error50 of errors4) {
949366
- context3.logger.warn(`${error50.relativeFilepath}: ${error50.message}`);
949367
- }
949368
- context3.logger.warn(
949369
- `Skipping API workspace at ${ossWorkspace.absoluteFilePath} due to ${errors4.length} validation error${errors4.length !== 1 ? "s" : ""}. Run fern check for details.`
949354
+ const reasons = summarizeValidationErrors(errors4);
949355
+ const reasonList = reasons.map((r5) => ` - ${r5}`).join("\n");
949356
+ context3.logger.error(
949357
+ `Skipping API ${apiName} due to ${errors4.length} validation error${errors4.length !== 1 ? "s" : ""}:
949358
+ ${reasonList}`
949370
949359
  );
949371
949360
  skippedWorkspacePaths.add(ossWorkspace.absoluteFilePath);
949372
949361
  }
949373
949362
  } catch (error50) {
949374
- context3.logger.warn(
949375
- `Skipping API workspace at ${ossWorkspace.absoluteFilePath}: ${extractErrorMessage(error50)}`
949376
- );
949363
+ context3.logger.error(`Skipping API ${apiName}: ${extractErrorMessage(error50)}`);
949377
949364
  skippedWorkspacePaths.add(ossWorkspace.absoluteFilePath);
949378
949365
  }
949379
949366
  }
@@ -949413,6 +949400,37 @@ function getExcludeRules(brokenLinks, strictBrokenLinks) {
949413
949400
  }
949414
949401
  return excludeRules;
949415
949402
  }
949403
+ function summarizeValidationErrors(errors4) {
949404
+ const summaries = [];
949405
+ const frontmatterEndpoints = [];
949406
+ const nonAsciiTags = [];
949407
+ const otherErrors = [];
949408
+ for (const error50 of errors4) {
949409
+ if (error50.message.includes("---") && error50.message.includes("frontmatter")) {
949410
+ const methodPathMatch = error50.message.match(/for ((?:GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD|TRACE) \S+)/);
949411
+ frontmatterEndpoints.push(methodPathMatch?.[1] ?? error50.nodePath.join("."));
949412
+ } else if (error50.message.includes("non-ASCII")) {
949413
+ const tagMatch = error50.message.match(/Tag name "([^"]+)"/);
949414
+ nonAsciiTags.push(tagMatch?.[1] ?? "unknown");
949415
+ } else {
949416
+ otherErrors.push(error50);
949417
+ }
949418
+ }
949419
+ if (frontmatterEndpoints.length > 0) {
949420
+ summaries.push(
949421
+ `${frontmatterEndpoints.length} endpoint${frontmatterEndpoints.length !== 1 ? "s" : ""} contain "---" frontmatter delimiters that will cause 500 errors on the docs site`
949422
+ );
949423
+ }
949424
+ if (nonAsciiTags.length > 0) {
949425
+ summaries.push(
949426
+ `${nonAsciiTags.length} tag${nonAsciiTags.length !== 1 ? "s" : ""} contain non-ASCII characters: ${nonAsciiTags.join(", ")}`
949427
+ );
949428
+ }
949429
+ for (const error50 of otherErrors) {
949430
+ summaries.push(`${error50.relativeFilepath}: ${error50.message}`);
949431
+ }
949432
+ return summaries;
949433
+ }
949416
949434
 
949417
949435
  // src/commands/generate-dynamic-ir/generateDynamicIrForWorkspaces.ts
949418
949436
  init_lib6();
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.7.6",
2
+ "version": "5.7.7",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",