@scalar/openapi-parser 0.25.7 → 0.25.8

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @scalar/openapi-parser
2
2
 
3
+ ## 0.25.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [#8579](https://github.com/scalar/scalar/pull/8579): feat(openapi-parser): improve format validation error messages for $ref with non-ASCII characters
8
+
3
9
  ## 0.25.7
4
10
 
5
11
  ## 0.25.6
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/betterAjvErrors/helpers.ts"],"names":[],"mappings":"AAcA,OAAO,EAGL,mBAAmB,EAIpB,MAAM,qBAAqB,CAAA;AA8J5B,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,SAAS,KAAA,EAAE,OAAO,KAAA,yBAKlD"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/betterAjvErrors/helpers.ts"],"names":[],"mappings":"AAcA,OAAO,EAGL,mBAAmB,EAKpB,MAAM,qBAAqB,CAAA;AAgK5B,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,SAAS,KAAA,EAAE,OAAO,KAAA,yBAKlD"}
@@ -1,6 +1,6 @@
1
1
  import { concatAll, getChildren, getErrors, getSiblings, isAdditionalPropertiesError, isAnyOfError, isEnumError, isIfError, isOneOfError, isRequiredError, isUnevaluatedPropertiesError, notUndefined, } from './utils.js';
2
- import { AdditionalPropValidationError, DefaultValidationError, EnumValidationError, PatternValidationError, RequiredValidationError, UnevaluatedPropValidationError, } from './validation-errors/index.js';
3
- const JSON_POINTERS_REGEX = /\/[\w_-]+(\/\d+)?/g;
2
+ import { AdditionalPropValidationError, DefaultValidationError, EnumValidationError, FormatValidationError, PatternValidationError, RequiredValidationError, UnevaluatedPropValidationError, } from './validation-errors/index.js';
3
+ const JSON_POINTERS_REGEX = /\/[\w$_-]+(\/\d+)?/g;
4
4
  // Make a tree of errors from ajv errors array
5
5
  function makeTree(ajvErrors = []) {
6
6
  const root = { children: {} };
@@ -134,6 +134,8 @@ function createErrorInstances(root, options) {
134
134
  return ret.concat(new AdditionalPropValidationError(error, options));
135
135
  case 'pattern':
136
136
  return ret.concat(new PatternValidationError(error, options));
137
+ case 'format':
138
+ return ret.concat(new FormatValidationError(error, options));
137
139
  case 'required':
138
140
  return ret.concat(new RequiredValidationError(error, options));
139
141
  case 'unevaluatedProperties':
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Enhanced error messages for `format` keyword validation failures.
3
+ *
4
+ * Currently provides context for:
5
+ * - `uri-reference` format on `$ref` paths (non-ASCII characters, etc.)
6
+ *
7
+ * To add a new format enhancer, add a case to the switch in `getError()`.
8
+ */
9
+ export default class FormatValidationError extends BaseValidationError {
10
+ constructor(...args: any[]);
11
+ name: string;
12
+ getError(): {
13
+ message: string;
14
+ path: string;
15
+ };
16
+ /**
17
+ * Builds a contextual error message for uri-reference format failures on $ref values.
18
+ */
19
+ _getUriReferenceMessage(): string;
20
+ /**
21
+ * Attempts to extract the actual $ref value from the specification
22
+ * by walking the instancePath through the spec object.
23
+ */
24
+ _extractRefValue(): string;
25
+ }
26
+ import BaseValidationError from './base.js';
27
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../../src/utils/betterAjvErrors/validation-errors/format.js"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH;IACE,4BAIC;IAFC,aAAmC;IAIrC;;;MAkBC;IAED;;OAEG;IACH,kCAYC;IAED;;;OAGG;IACH,2BA0BC;CACF;gCArF+B,QAAQ"}
@@ -0,0 +1,73 @@
1
+ import BaseValidationError from './base.js';
2
+ /**
3
+ * Enhanced error messages for `format` keyword validation failures.
4
+ *
5
+ * Currently provides context for:
6
+ * - `uri-reference` format on `$ref` paths (non-ASCII characters, etc.)
7
+ *
8
+ * To add a new format enhancer, add a case to the switch in `getError()`.
9
+ */
10
+ export default class FormatValidationError extends BaseValidationError {
11
+ constructor(...args) {
12
+ super(...args);
13
+ this.name = 'FormatValidationError';
14
+ this.options.isSkipEndLocation = true;
15
+ }
16
+ getError() {
17
+ const { keyword, message, params, instancePath: errorPath } = this.options;
18
+ const path = this.instancePath;
19
+ const format = params?.format;
20
+ // uri-reference format on $ref paths
21
+ if (format === 'uri-reference' && path?.endsWith('/$ref')) {
22
+ return {
23
+ message: this._getUriReferenceMessage(),
24
+ path,
25
+ };
26
+ }
27
+ // Default: fall back to the same format as DefaultValidationError
28
+ return {
29
+ message: `${keyword} ${message}`,
30
+ path,
31
+ };
32
+ }
33
+ /**
34
+ * Builds a contextual error message for uri-reference format failures on $ref values.
35
+ */
36
+ _getUriReferenceMessage() {
37
+ const refValue = this._extractRefValue();
38
+ if (refValue && /[^\x00-\x7F]/.test(refValue)) {
39
+ return `$ref "${refValue}" contains non-ASCII characters`;
40
+ }
41
+ if (refValue) {
42
+ return `$ref "${refValue}" is not a valid URI reference`;
43
+ }
44
+ return '$ref is not a valid URI reference';
45
+ }
46
+ /**
47
+ * Attempts to extract the actual $ref value from the specification
48
+ * by walking the instancePath through the spec object.
49
+ */
50
+ _extractRefValue() {
51
+ const spec = this.schema;
52
+ if (!spec || typeof spec !== 'object') {
53
+ return null;
54
+ }
55
+ const path = this.instancePath;
56
+ if (!path) {
57
+ return null;
58
+ }
59
+ // Parse JSON Pointer segments, decoding ~1 (/) and ~0 (~)
60
+ const segments = path
61
+ .split('/')
62
+ .filter(Boolean)
63
+ .map((s) => s.replace(/~1/g, '/').replace(/~0/g, '~'));
64
+ let current = spec;
65
+ for (const segment of segments) {
66
+ if (current === null || current === undefined || typeof current !== 'object') {
67
+ return null;
68
+ }
69
+ current = current[segment];
70
+ }
71
+ return typeof current === 'string' ? current : null;
72
+ }
73
+ }
@@ -1,6 +1,7 @@
1
1
  export { default as AdditionalPropValidationError } from "./additional-prop.js";
2
2
  export { default as DefaultValidationError } from "./default.js";
3
3
  export { default as EnumValidationError } from "./enum.js";
4
+ export { default as FormatValidationError } from "./format.js";
4
5
  export { default as PatternValidationError } from "./pattern.js";
5
6
  export { default as RequiredValidationError } from "./required.js";
6
7
  export { default as UnevaluatedPropValidationError } from "./unevaluated-prop.js";
@@ -1,6 +1,7 @@
1
1
  export { default as AdditionalPropValidationError } from './additional-prop.js';
2
2
  export { default as DefaultValidationError } from './default.js';
3
3
  export { default as EnumValidationError } from './enum.js';
4
+ export { default as FormatValidationError } from './format.js';
4
5
  export { default as PatternValidationError } from './pattern.js';
5
6
  export { default as RequiredValidationError } from './required.js';
6
7
  export { default as UnevaluatedPropValidationError } from './unevaluated-prop.js';
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "parser",
18
18
  "typescript"
19
19
  ],
20
- "version": "0.25.7",
20
+ "version": "0.25.8",
21
21
  "engines": {
22
22
  "node": ">=22"
23
23
  },
@@ -54,17 +54,17 @@
54
54
  "jsonpointer": "^5.0.1",
55
55
  "leven": "^4.0.0",
56
56
  "yaml": "^2.8.0",
57
- "@scalar/helpers": "0.4.2",
58
- "@scalar/json-magic": "0.12.4",
59
- "@scalar/openapi-upgrader": "0.2.3",
60
- "@scalar/openapi-types": "0.6.1"
57
+ "@scalar/helpers": "0.4.3",
58
+ "@scalar/openapi-types": "0.7.0",
59
+ "@scalar/openapi-upgrader": "0.2.4",
60
+ "@scalar/json-magic": "0.12.5"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@apidevtools/swagger-parser": "10.1.0",
64
64
  "@types/node": "^24.1.0",
65
65
  "just-diff": "^6.0.2",
66
66
  "vite": "8.0.0",
67
- "@scalar/types": "0.7.5"
67
+ "@scalar/types": "0.7.6"
68
68
  },
69
69
  "scripts": {
70
70
  "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",