@redocly/openapi-core 1.0.0-beta.104 → 1.0.0-beta.107

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 (203) hide show
  1. package/README.md +4 -4
  2. package/__tests__/utils.ts +8 -6
  3. package/lib/benchmark/benches/recommended-oas3.bench.js +1 -1
  4. package/lib/benchmark/utils.d.ts +2 -2
  5. package/lib/benchmark/utils.js +2 -2
  6. package/lib/bundle.d.ts +2 -2
  7. package/lib/bundle.js +2 -2
  8. package/lib/config/all.d.ts +2 -2
  9. package/lib/config/all.js +1 -1
  10. package/lib/config/builtIn.d.ts +2 -2
  11. package/lib/config/builtIn.js +2 -2
  12. package/lib/config/config-resolvers.d.ts +5 -5
  13. package/lib/config/config-resolvers.js +39 -36
  14. package/lib/config/config.d.ts +6 -5
  15. package/lib/config/config.js +27 -20
  16. package/lib/config/load.js +6 -7
  17. package/lib/config/minimal.d.ts +2 -2
  18. package/lib/config/minimal.js +3 -2
  19. package/lib/config/recommended.d.ts +2 -2
  20. package/lib/config/recommended.js +3 -2
  21. package/lib/config/rules.d.ts +2 -2
  22. package/lib/config/rules.js +1 -1
  23. package/lib/config/types.d.ts +23 -19
  24. package/lib/config/utils.d.ts +5 -5
  25. package/lib/config/utils.js +43 -26
  26. package/lib/decorators/common/remove-x-internal.js +2 -2
  27. package/lib/format/format.js +1 -1
  28. package/lib/index.d.ts +2 -2
  29. package/lib/index.js +3 -2
  30. package/lib/js-yaml/index.js +1 -6
  31. package/lib/lint.d.ts +2 -2
  32. package/lib/lint.js +16 -6
  33. package/lib/redocly/registry-api.d.ts +1 -1
  34. package/lib/redocly/registry-api.js +2 -2
  35. package/lib/rules/ajv.d.ts +1 -1
  36. package/lib/rules/ajv.js +6 -6
  37. package/lib/rules/common/info-license-url.d.ts +1 -1
  38. package/lib/rules/common/info-license-url.js +5 -10
  39. package/lib/rules/common/info-license.d.ts +2 -0
  40. package/lib/rules/common/info-license.js +17 -0
  41. package/lib/rules/common/no-enum-type-mismatch.js +1 -3
  42. package/lib/rules/common/no-invalid-parameter-examples.js +3 -3
  43. package/lib/rules/common/no-invalid-schema-examples.js +3 -3
  44. package/lib/rules/common/operation-operationId.js +1 -1
  45. package/lib/rules/common/path-not-include-query.js +1 -1
  46. package/lib/rules/common/paths-kebab-case.js +4 -1
  47. package/lib/rules/common/spec.js +1 -1
  48. package/lib/rules/oas2/index.js +4 -4
  49. package/lib/rules/oas2/remove-unused-components.js +3 -3
  50. package/lib/rules/oas3/index.js +4 -4
  51. package/lib/rules/oas3/no-empty-servers.js +1 -1
  52. package/lib/rules/oas3/no-invalid-media-type-examples.js +2 -2
  53. package/lib/rules/oas3/remove-unused-components.js +2 -2
  54. package/lib/rules/other/stats.js +43 -14
  55. package/lib/rules/utils.d.ts +3 -2
  56. package/lib/rules/utils.js +19 -4
  57. package/lib/types/index.d.ts +2 -2
  58. package/lib/types/redocly-yaml.js +8 -7
  59. package/lib/utils.d.ts +5 -2
  60. package/lib/utils.js +20 -2
  61. package/lib/walk.d.ts +2 -1
  62. package/lib/walk.js +6 -3
  63. package/package.json +2 -2
  64. package/src/__tests__/__snapshots__/bundle.test.ts.snap +141 -0
  65. package/src/__tests__/bundle.test.ts +68 -34
  66. package/src/__tests__/codeframes.test.ts +13 -14
  67. package/src/__tests__/fixtures/.redocly.lint-ignore.yaml +5 -0
  68. package/src/__tests__/js-yaml.test.ts +6 -4
  69. package/src/__tests__/lint.test.ts +127 -12
  70. package/src/__tests__/login.test.ts +2 -2
  71. package/src/__tests__/normalizeVisitors.test.ts +4 -4
  72. package/src/__tests__/ref-utils.test.ts +13 -13
  73. package/src/__tests__/resolve-http.test.ts +1 -1
  74. package/src/__tests__/resolve.test.ts +14 -11
  75. package/src/__tests__/utils.test.ts +42 -1
  76. package/src/__tests__/walk.test.ts +48 -56
  77. package/src/benchmark/benches/lint-with-many-rules.bench.ts +1 -1
  78. package/src/benchmark/benches/lint-with-nested-rule.bench.ts +1 -1
  79. package/src/benchmark/benches/lint-with-no-rules.bench.ts +1 -1
  80. package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +1 -1
  81. package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +1 -1
  82. package/src/benchmark/benches/recommended-oas3.bench.ts +3 -3
  83. package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
  84. package/src/benchmark/benchmark.js +9 -5
  85. package/src/benchmark/utils.ts +5 -5
  86. package/src/bundle.ts +18 -17
  87. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +3 -1
  88. package/src/config/__tests__/config-resolvers.test.ts +123 -121
  89. package/src/config/__tests__/config.test.ts +76 -76
  90. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +4 -2
  91. package/src/config/__tests__/fixtures/resolve-config/plugin.js +4 -1
  92. package/src/config/__tests__/load.test.ts +2 -2
  93. package/src/config/__tests__/resolve-plugins.test.ts +3 -3
  94. package/src/config/__tests__/utils.test.ts +83 -0
  95. package/src/config/all.ts +3 -4
  96. package/src/config/builtIn.ts +5 -5
  97. package/src/config/config-resolvers.ts +122 -83
  98. package/src/config/config.ts +36 -32
  99. package/src/config/load.ts +13 -16
  100. package/src/config/minimal.ts +5 -4
  101. package/src/config/recommended.ts +5 -4
  102. package/src/config/rules.ts +6 -6
  103. package/src/config/types.ts +28 -19
  104. package/src/config/utils.ts +74 -54
  105. package/src/decorators/__tests__/filter-out.test.ts +8 -4
  106. package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
  107. package/src/decorators/common/filters/filter-helper.ts +1 -1
  108. package/src/decorators/common/info-description-override.ts +1 -1
  109. package/src/decorators/common/operation-description-override.ts +1 -1
  110. package/src/decorators/common/remove-x-internal.ts +4 -4
  111. package/src/decorators/common/tag-description-override.ts +1 -1
  112. package/src/format/codeframes.ts +4 -4
  113. package/src/format/format.ts +10 -10
  114. package/src/index.ts +3 -4
  115. package/src/js-yaml/index.ts +3 -8
  116. package/src/lint.ts +22 -18
  117. package/src/oas-types.ts +1 -6
  118. package/src/redocly/__tests__/redocly-client.test.ts +25 -19
  119. package/src/redocly/index.ts +6 -4
  120. package/src/redocly/registry-api.ts +6 -6
  121. package/src/ref-utils.ts +2 -2
  122. package/src/resolve.ts +7 -4
  123. package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
  124. package/src/rules/__tests__/utils.test.ts +160 -0
  125. package/src/rules/ajv.ts +7 -8
  126. package/src/rules/common/__tests__/info-description.test.ts +3 -3
  127. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  128. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  129. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  130. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +8 -8
  131. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  132. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
  133. package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
  134. package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
  135. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  136. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  137. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  138. package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
  139. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  140. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  141. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  142. package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
  143. package/src/rules/common/__tests__/paths-kebab-case.test.ts +15 -15
  144. package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +8 -8
  145. package/src/rules/common/__tests__/spec.test.ts +2 -2
  146. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  147. package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
  148. package/src/rules/common/assertions/__tests__/asserts.test.ts +513 -130
  149. package/src/rules/common/assertions/index.ts +6 -6
  150. package/src/rules/common/info-license-url.ts +4 -9
  151. package/src/rules/common/info-license.ts +15 -0
  152. package/src/rules/common/no-ambiguous-paths.ts +1 -1
  153. package/src/rules/common/no-enum-type-mismatch.ts +12 -9
  154. package/src/rules/common/no-invalid-parameter-examples.ts +4 -4
  155. package/src/rules/common/no-invalid-schema-examples.ts +4 -4
  156. package/src/rules/common/operation-operationId.ts +1 -1
  157. package/src/rules/common/operation-parameters-unique.ts +2 -2
  158. package/src/rules/common/path-not-include-query.ts +1 -1
  159. package/src/rules/common/path-params-defined.ts +1 -1
  160. package/src/rules/common/paths-kebab-case.ts +4 -1
  161. package/src/rules/common/scalar-property-missing-example.ts +1 -1
  162. package/src/rules/common/spec.ts +10 -7
  163. package/src/rules/no-unresolved-refs.ts +1 -1
  164. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  165. package/src/rules/oas2/__tests__/spec/info.test.ts +12 -12
  166. package/src/rules/oas2/__tests__/spec/operation.test.ts +4 -4
  167. package/src/rules/oas2/__tests__/spec/paths.test.ts +10 -10
  168. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +6 -2
  169. package/src/rules/oas2/__tests__/spec/utils.ts +6 -6
  170. package/src/rules/oas2/index.ts +3 -3
  171. package/src/rules/oas2/remove-unused-components.ts +13 -8
  172. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  173. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  174. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +13 -13
  175. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
  176. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  177. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  178. package/src/rules/oas3/__tests__/spec/callbacks.test.ts +1 -1
  179. package/src/rules/oas3/__tests__/spec/info.test.ts +12 -12
  180. package/src/rules/oas3/__tests__/spec/operation.test.ts +8 -8
  181. package/src/rules/oas3/__tests__/spec/paths.test.ts +10 -10
  182. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +12 -12
  183. package/src/rules/oas3/__tests__/spec/servers.test.ts +15 -15
  184. package/src/rules/oas3/__tests__/spec/spec.test.ts +6 -6
  185. package/src/rules/oas3/__tests__/spec/utils.ts +6 -6
  186. package/src/rules/oas3/index.ts +3 -3
  187. package/src/rules/oas3/no-empty-servers.ts +1 -1
  188. package/src/rules/oas3/no-invalid-media-type-examples.ts +14 -6
  189. package/src/rules/oas3/no-servers-empty-enum.ts +9 -10
  190. package/src/rules/oas3/remove-unused-components.ts +18 -7
  191. package/src/rules/other/stats.ts +46 -17
  192. package/src/rules/utils.ts +19 -3
  193. package/src/types/index.ts +5 -5
  194. package/src/types/redocly-yaml.ts +8 -7
  195. package/src/typings/common.ts +9 -1
  196. package/src/typings/openapi.ts +1 -1
  197. package/src/utils.ts +31 -8
  198. package/src/visitors.ts +4 -4
  199. package/src/walk.ts +15 -11
  200. package/tsconfig.tsbuildinfo +1 -1
  201. package/lib/rules/common/license-url.d.ts +0 -2
  202. package/lib/rules/common/license-url.js +0 -12
  203. package/src/rules/common/license-url.ts +0 -10
package/src/lint.ts CHANGED
@@ -1,20 +1,17 @@
1
1
  import { BaseResolver, resolveDocument, Document, makeDocumentFromString } from './resolve';
2
- import {
3
- normalizeVisitors,
4
- } from './visitors';
2
+ import { normalizeVisitors } from './visitors';
5
3
  import { Oas3_1Types } from './types/oas3_1';
6
4
  import { Oas3Types } from './types/oas3';
7
5
  import { Oas2Types } from './types/oas2';
8
6
  import { NodeType } from './types';
9
7
  import { ProblemSeverity, WalkContext, walkDocument } from './walk';
10
- import { LintConfig, Config, initRules, defaultPlugin, resolvePlugins } from './config';
8
+ import { StyleguideConfig, Config, initRules, defaultPlugin, resolvePlugins } from './config';
11
9
  import { normalizeTypes } from './types';
12
10
  import { releaseAjvInstance } from './rules/ajv';
13
11
  import { detectOpenAPI, Oas3RuleSet, OasMajorVersion, OasVersion, openAPIMajor } from './oas-types';
14
12
  import { ConfigTypes } from './types/redocly-yaml';
15
13
  import { OasSpec } from './rules/common/spec';
16
14
 
17
-
18
15
  export async function lint(opts: {
19
16
  ref: string;
20
17
  config: Config;
@@ -27,7 +24,7 @@ export async function lint(opts: {
27
24
  document,
28
25
  ...opts,
29
26
  externalRefResolver,
30
- config: opts.config.lint,
27
+ config: opts.config.styleguide,
31
28
  });
32
29
  }
33
30
 
@@ -44,13 +41,13 @@ export async function lintFromString(opts: {
44
41
  document,
45
42
  ...opts,
46
43
  externalRefResolver,
47
- config: opts.config.lint,
44
+ config: opts.config.styleguide,
48
45
  });
49
46
  }
50
47
 
51
48
  export async function lintDocument(opts: {
52
49
  document: Document;
53
- config: LintConfig;
50
+ config: StyleguideConfig;
54
51
  customTypes?: Record<string, NodeType>;
55
52
  externalRefResolver: BaseResolver;
56
53
  }) {
@@ -62,10 +59,14 @@ export async function lintDocument(opts: {
62
59
  const rules = config.getRulesForOasVersion(oasMajorVersion);
63
60
  const types = normalizeTypes(
64
61
  config.extendTypes(
65
- customTypes ?? oasMajorVersion === OasMajorVersion.Version3 ? (oasVersion === OasVersion.Version3_1 ? Oas3_1Types : Oas3Types) : Oas2Types,
66
- oasVersion,
62
+ customTypes ?? oasMajorVersion === OasMajorVersion.Version3
63
+ ? oasVersion === OasVersion.Version3_1
64
+ ? Oas3_1Types
65
+ : Oas3Types
66
+ : Oas2Types,
67
+ oasVersion
67
68
  ),
68
- config,
69
+ config
69
70
  );
70
71
 
71
72
  const ctx: WalkContext = {
@@ -80,7 +81,7 @@ export async function lintDocument(opts: {
80
81
  const resolvedRefMap = await resolveDocument({
81
82
  rootDocument: document,
82
83
  rootType: types.DefinitionRoot,
83
- externalRefResolver
84
+ externalRefResolver,
84
85
  });
85
86
 
86
87
  walkDocument({
@@ -93,10 +94,7 @@ export async function lintDocument(opts: {
93
94
  return ctx.problems.map((problem) => config.addProblemToIgnore(problem));
94
95
  }
95
96
 
96
- export async function lintConfig(opts: {
97
- document: Document
98
- severity?: ProblemSeverity
99
- }) {
97
+ export async function lintConfig(opts: { document: Document; severity?: ProblemSeverity }) {
100
98
  const { document, severity } = opts;
101
99
 
102
100
  const ctx: WalkContext = {
@@ -105,13 +103,19 @@ export async function lintConfig(opts: {
105
103
  visitorsData: {},
106
104
  };
107
105
  const plugins = resolvePlugins([defaultPlugin]);
108
- const config = new LintConfig({
106
+ const config = new StyleguideConfig({
109
107
  plugins,
110
108
  rules: { spec: 'error' },
111
109
  });
112
110
 
113
111
  const types = normalizeTypes(ConfigTypes, config);
114
- const rules = [{ severity: severity || 'error', ruleId: 'configuration spec', visitor: OasSpec({ severity: 'error' }) }];
112
+ const rules = [
113
+ {
114
+ severity: severity || 'error',
115
+ ruleId: 'configuration spec',
116
+ visitor: OasSpec({ severity: 'error' }),
117
+ },
118
+ ];
115
119
  const normalizedVisitors = normalizeVisitors(rules, types);
116
120
 
117
121
  walkDocument({
package/src/oas-types.ts CHANGED
@@ -1,9 +1,4 @@
1
- import {
2
- Oas3Rule,
3
- Oas3Preprocessor,
4
- Oas2Rule,
5
- Oas2Preprocessor,
6
- } from './visitors';
1
+ import { Oas3Rule, Oas3Preprocessor, Oas2Rule, Oas2Preprocessor } from './visitors';
7
2
 
8
3
  export type RuleSet<T> = Record<string, T>;
9
4
 
@@ -59,55 +59,57 @@ describe('RedoclyClient', () => {
59
59
 
60
60
  it('should resolve all tokens', async () => {
61
61
  let spy = jest.spyOn(RedoclyClient.prototype, 'readCredentialsFile').mockImplementation(() => {
62
- return { token: "accessToken", us: "accessToken", eu: "eu-accessToken" };
62
+ return { token: 'accessToken', us: 'accessToken', eu: 'eu-accessToken' };
63
63
  });
64
64
  const client = new RedoclyClient();
65
65
  const tokens = client.getAllTokens();
66
66
  expect(tokens).toStrictEqual([
67
67
  { region: 'us', token: 'accessToken' },
68
- { region: 'eu', token: 'eu-accessToken' }
68
+ { region: 'eu', token: 'eu-accessToken' },
69
69
  ]);
70
70
  spy.mockRestore();
71
71
  });
72
72
 
73
73
  it('should resolve valid tokens data', async () => {
74
74
  let spy = jest.spyOn(RedoclyClient.prototype, 'readCredentialsFile').mockImplementation(() => {
75
- return { us: "accessToken", eu: "eu-accessToken" }
75
+ return { us: 'accessToken', eu: 'eu-accessToken' };
76
76
  });
77
77
  const client = new RedoclyClient();
78
78
  const tokens = await client.getValidTokens();
79
79
  expect(tokens).toStrictEqual([
80
80
  { region: 'us', token: 'accessToken', valid: true },
81
- { region: 'eu', token: 'eu-accessToken', valid: true }
81
+ { region: 'eu', token: 'eu-accessToken', valid: true },
82
82
  ]);
83
83
  spy.mockRestore();
84
84
  });
85
85
 
86
86
  it('should not call setAccessTokens by default', () => {
87
- let spy = jest.spyOn(RedoclyClient.prototype, 'readCredentialsFile').mockImplementation(() => ({}));
87
+ let spy = jest
88
+ .spyOn(RedoclyClient.prototype, 'readCredentialsFile')
89
+ .mockImplementation(() => ({}));
88
90
  jest.spyOn(RedoclyClient.prototype, 'setAccessTokens').mockImplementation();
89
91
  const client = new RedoclyClient();
90
- expect(client.setAccessTokens).not.toHaveBeenCalled()
92
+ expect(client.setAccessTokens).not.toHaveBeenCalled();
91
93
  spy.mockRestore();
92
94
  });
93
95
 
94
96
  it('should set correct accessTokens - backward compatibility: default US region', () => {
95
- let spy = jest.spyOn(RedoclyClient.prototype, 'readCredentialsFile').mockImplementation(() => ({ token: testToken }));
97
+ let spy = jest
98
+ .spyOn(RedoclyClient.prototype, 'readCredentialsFile')
99
+ .mockImplementation(() => ({ token: testToken }));
96
100
  jest.spyOn(RedoclyClient.prototype, 'setAccessTokens').mockImplementation();
97
101
  const client = new RedoclyClient();
98
- expect(client.setAccessTokens).toBeCalledWith(
99
- expect.objectContaining({ us: testToken })
100
- );
102
+ expect(client.setAccessTokens).toBeCalledWith(expect.objectContaining({ us: testToken }));
101
103
  spy.mockRestore();
102
104
  });
103
105
 
104
106
  it('should set correct accessTokens - backward compatibility: EU region', () => {
105
- let spy = jest.spyOn(RedoclyClient.prototype, 'readCredentialsFile').mockImplementation(() => ({ token: testToken }));
107
+ let spy = jest
108
+ .spyOn(RedoclyClient.prototype, 'readCredentialsFile')
109
+ .mockImplementation(() => ({ token: testToken }));
106
110
  jest.spyOn(RedoclyClient.prototype, 'setAccessTokens').mockImplementation();
107
111
  const client = new RedoclyClient('eu');
108
- expect(client.setAccessTokens).toBeCalledWith(
109
- expect.objectContaining({ eu: testToken })
110
- );
112
+ expect(client.setAccessTokens).toBeCalledWith(expect.objectContaining({ eu: testToken }));
111
113
  spy.mockRestore();
112
114
  });
113
115
 
@@ -116,25 +118,29 @@ describe('RedoclyClient', () => {
116
118
  let spy = jest.spyOn(RedoclyClient.prototype, 'readCredentialsFile').mockImplementation();
117
119
  jest.spyOn(RedoclyClient.prototype, 'setAccessTokens').mockImplementation();
118
120
  const client = new RedoclyClient();
119
- expect(client.setAccessTokens).toHaveBeenNthCalledWith(1, { "us": REDOCLY_AUTHORIZATION_TOKEN });
121
+ expect(client.setAccessTokens).toHaveBeenNthCalledWith(1, { us: REDOCLY_AUTHORIZATION_TOKEN });
120
122
  spy.mockRestore();
121
123
  });
122
124
 
123
125
  it('should set correct accessTokens prioritizing REDOCLY_AUTHORIZATION env over token in file', () => {
124
126
  process.env.REDOCLY_AUTHORIZATION = REDOCLY_AUTHORIZATION_TOKEN;
125
- let spy = jest.spyOn(RedoclyClient.prototype, 'readCredentialsFile').mockImplementation(() => ({ token: testToken }));
127
+ let spy = jest
128
+ .spyOn(RedoclyClient.prototype, 'readCredentialsFile')
129
+ .mockImplementation(() => ({ token: testToken }));
126
130
  jest.spyOn(RedoclyClient.prototype, 'setAccessTokens').mockImplementation();
127
131
  const client = new RedoclyClient();
128
- expect(client.setAccessTokens).toHaveBeenNthCalledWith(2, { "us": REDOCLY_AUTHORIZATION_TOKEN });
132
+ expect(client.setAccessTokens).toHaveBeenNthCalledWith(2, { us: REDOCLY_AUTHORIZATION_TOKEN });
129
133
  spy.mockRestore();
130
134
  });
131
135
 
132
136
  it('should set correct accessTokens prioritizing REDOCLY_AUTHORIZATION env over EU token', () => {
133
137
  process.env.REDOCLY_AUTHORIZATION = REDOCLY_AUTHORIZATION_TOKEN;
134
- let spy = jest.spyOn(RedoclyClient.prototype, 'readCredentialsFile').mockImplementation(() => ({ us: testToken }));
138
+ let spy = jest
139
+ .spyOn(RedoclyClient.prototype, 'readCredentialsFile')
140
+ .mockImplementation(() => ({ us: testToken }));
135
141
  jest.spyOn(RedoclyClient.prototype, 'setAccessTokens').mockImplementation();
136
142
  const client = new RedoclyClient('eu');
137
- expect(client.setAccessTokens).toHaveBeenNthCalledWith(2, { "eu": REDOCLY_AUTHORIZATION_TOKEN });
143
+ expect(client.setAccessTokens).toHaveBeenNthCalledWith(2, { eu: REDOCLY_AUTHORIZATION_TOKEN });
138
144
  spy.mockRestore();
139
145
  });
140
146
  });
@@ -28,12 +28,14 @@ export class RedoclyClient {
28
28
 
29
29
  loadRegion(region?: Region) {
30
30
  if (region && !DOMAINS[region]) {
31
- throw new Error(`Invalid argument: region in config file.\nGiven: ${green(region)}, choices: "us", "eu".`);
31
+ throw new Error(
32
+ `Invalid argument: region in config file.\nGiven: ${green(region)}, choices: "us", "eu".`
33
+ );
32
34
  }
33
35
 
34
36
  if (env.REDOCLY_DOMAIN) {
35
37
  return (AVAILABLE_REGIONS.find(
36
- (region) => DOMAINS[region as Region] === env.REDOCLY_DOMAIN,
38
+ (region) => DOMAINS[region as Region] === env.REDOCLY_DOMAIN
37
39
  ) || DEFAULT_REGION) as Region;
38
40
  }
39
41
  return region || DEFAULT_REGION;
@@ -91,7 +93,7 @@ export class RedoclyClient {
91
93
  const allTokens = this.getAllTokens();
92
94
 
93
95
  const verifiedTokens = await Promise.allSettled(
94
- allTokens.map(({ token, region }) => this.verifyToken(token, region)),
96
+ allTokens.map(({ token, region }) => this.verifyToken(token, region))
95
97
  );
96
98
 
97
99
  return allTokens
@@ -134,7 +136,7 @@ export class RedoclyClient {
134
136
  async verifyToken(
135
137
  accessToken: string,
136
138
  region: Region,
137
- verbose: boolean = false,
139
+ verbose: boolean = false
138
140
  ): Promise<{ viewerId: string; organizations: string[] }> {
139
141
  return this.registryApi.authStatus(accessToken, region, verbose);
140
142
  }
@@ -31,7 +31,7 @@ export class RegistryApi {
31
31
 
32
32
  const response = await fetch(
33
33
  `${this.getBaseUrl(region)}${path}`,
34
- Object.assign({}, options, { headers }),
34
+ Object.assign({}, options, { headers })
35
35
  );
36
36
 
37
37
  if (response.status === 401) {
@@ -49,7 +49,7 @@ export class RegistryApi {
49
49
  async authStatus(
50
50
  accessToken: string,
51
51
  region: Region,
52
- verbose = false,
52
+ verbose = false
53
53
  ): Promise<{ viewerId: string; organizations: string[] }> {
54
54
  try {
55
55
  const response = await this.request('', { headers: { authorization: accessToken } }, region);
@@ -86,7 +86,7 @@ export class RegistryApi {
86
86
  isUpsert,
87
87
  }),
88
88
  },
89
- this.region,
89
+ this.region
90
90
  );
91
91
 
92
92
  if (response.ok) {
@@ -106,7 +106,7 @@ export class RegistryApi {
106
106
  isUpsert,
107
107
  isPublic,
108
108
  batchId,
109
- batchSize
109
+ batchSize,
110
110
  }: RegistryApiTypes.PushApiParams) {
111
111
  const response = await this.request(
112
112
  `/${organizationId}/${name}/${version}`,
@@ -123,10 +123,10 @@ export class RegistryApi {
123
123
  isUpsert,
124
124
  isPublic,
125
125
  batchId,
126
- batchSize
126
+ batchSize,
127
127
  }),
128
128
  },
129
- this.region,
129
+ this.region
130
130
  );
131
131
 
132
132
  if (response.ok) {
package/src/ref-utils.ts CHANGED
@@ -18,8 +18,8 @@ export class Location {
18
18
  this.source,
19
19
  joinPointer(
20
20
  this.pointer,
21
- (Array.isArray(components) ? components : [components]).map(escapePointer).join('/'),
22
- ),
21
+ (Array.isArray(components) ? components : [components]).map(escapePointer).join('/')
22
+ )
23
23
  );
24
24
  }
25
25
 
package/src/resolve.ts CHANGED
@@ -232,7 +232,7 @@ export async function resolveDocument(opts: {
232
232
  rootNode: any,
233
233
  rootNodeDocument: Document,
234
234
  rootNodePointer: string,
235
- type: any,
235
+ type: any
236
236
  ) {
237
237
  const rootNodeDocAbsoluteRef = rootNodeDocument.source.absoluteRef;
238
238
 
@@ -295,7 +295,7 @@ export async function resolveDocument(opts: {
295
295
  resolvedRef.node,
296
296
  resolvedRef.document,
297
297
  resolvedRef.nodePointer!,
298
- type,
298
+ type
299
299
  );
300
300
  }
301
301
  });
@@ -306,7 +306,7 @@ export async function resolveDocument(opts: {
306
306
  async function followRef(
307
307
  document: Document,
308
308
  ref: OasRef,
309
- refStack: RefFrame,
309
+ refStack: RefFrame
310
310
  ): Promise<ResolvedRef> {
311
311
  if (hasRef(refStack.prev, ref)) {
312
312
  throw new Error('Self-referencing circular pointer');
@@ -316,7 +316,10 @@ export async function resolveDocument(opts: {
316
316
  let targetDoc: Document;
317
317
  try {
318
318
  targetDoc = isRemote
319
- ? ((await externalRefResolver.resolveDocument(document.source.absoluteRef, uri!)) as Document)
319
+ ? ((await externalRefResolver.resolveDocument(
320
+ document.source.absoluteRef,
321
+ uri!
322
+ )) as Document)
320
323
  : document;
321
324
  } catch (error) {
322
325
  const resolvedRef = {
@@ -15,7 +15,7 @@ describe('oas3 boolean-parameter-prefixes', () => {
15
15
  requestBody:
16
16
  $ref: 'invalid.yaml'
17
17
  `,
18
- path.join(__dirname, 'foobar.yaml'),
18
+ path.join(__dirname, 'foobar.yaml')
19
19
  );
20
20
 
21
21
  const results = await lintDocument({
@@ -55,7 +55,7 @@ describe('oas3 boolean-parameter-prefixes', () => {
55
55
  requestBody:
56
56
  $ref: 'fixtures/invalid-yaml.yaml'
57
57
  `,
58
- path.join(__dirname, 'foobar.yaml'),
58
+ path.join(__dirname, 'foobar.yaml')
59
59
  );
60
60
 
61
61
  const results = await lintDocument({
@@ -112,7 +112,7 @@ describe('oas3 boolean-parameter-prefixes', () => {
112
112
  requestBody:
113
113
  $ref: 'fixtures/ref.yaml'
114
114
  `,
115
- path.join(__dirname, 'foobar.yaml'),
115
+ path.join(__dirname, 'foobar.yaml')
116
116
  );
117
117
 
118
118
  const results = await lintDocument({
@@ -136,7 +136,7 @@ describe('oas3 boolean-parameter-prefixes', () => {
136
136
  requestBody:
137
137
  $ref: '#/components/requestBodies/a'
138
138
  `,
139
- path.join(__dirname, 'foobar.yaml'),
139
+ path.join(__dirname, 'foobar.yaml')
140
140
  );
141
141
 
142
142
  const results = await lintDocument({
@@ -0,0 +1,160 @@
1
+ import {
2
+ fieldNonEmpty,
3
+ matchesJsonSchemaType,
4
+ missingRequiredField,
5
+ oasTypeOf,
6
+ getAdditionalPropertiesOption,
7
+ } from '../utils';
8
+
9
+ describe('field-non-empty', () => {
10
+ it('should match expected message', () => {
11
+ const message = fieldNonEmpty('Car', 'color');
12
+ expect(message).toBe('Car object `color` must be non-empty string.');
13
+ });
14
+ });
15
+
16
+ describe('matches-json-schema-type', () => {
17
+ it('should report true on a null value with nullable type', () => {
18
+ const results = matchesJsonSchemaType(null, 'string', true);
19
+ expect(results).toBe(true);
20
+ });
21
+
22
+ it('should report true on a value and type integer', () => {
23
+ const results = matchesJsonSchemaType(123, 'integer', false);
24
+ expect(results).toBe(true);
25
+ });
26
+
27
+ it('should report false when the value is not integer and type is integer', () => {
28
+ const results = matchesJsonSchemaType(3.14, 'integer', false);
29
+ expect(results).toBe(false);
30
+ });
31
+
32
+ it('should report true when the value is a number and type is number', () => {
33
+ const results = matchesJsonSchemaType(3.14, 'number', false);
34
+ expect(results).toBe(true);
35
+ });
36
+
37
+ it('should report true when the value is an integer and type is number', () => {
38
+ const results = matchesJsonSchemaType(3, 'number', false);
39
+ expect(results).toBe(true);
40
+ });
41
+
42
+ it('should report true when the value is true and type is boolean', () => {
43
+ const results = matchesJsonSchemaType(true, 'boolean', false);
44
+ expect(results).toBe(true);
45
+ });
46
+
47
+ it('should report true when the value is false and type is boolean', () => {
48
+ const results = matchesJsonSchemaType(false, 'boolean', false);
49
+ expect(results).toBe(true);
50
+ });
51
+
52
+ it('should report true when the value is a string and type is boolean', () => {
53
+ const results = matchesJsonSchemaType('test', 'boolean', false);
54
+ expect(results).toBe(false);
55
+ });
56
+
57
+ it('should report true on an array value with array type', () => {
58
+ const results = matchesJsonSchemaType(['foo', 'bar'], 'array', false);
59
+ expect(results).toBe(true);
60
+ });
61
+
62
+ it('should report false on an array value with object type', () => {
63
+ const results = matchesJsonSchemaType(['foo', 'bar'], 'object', false);
64
+ expect(results).toBe(false);
65
+ });
66
+
67
+ it('should report true on an object value with object type', () => {
68
+ const car = { type: 'Fiat', model: '500', color: 'white' };
69
+ const results = matchesJsonSchemaType(car, 'object', true);
70
+ expect(results).toBe(true);
71
+ });
72
+
73
+ it('should report false on an object value with array type', () => {
74
+ const car = { type: 'Fiat', model: '500', color: 'white' };
75
+ const results = matchesJsonSchemaType(car, 'array', true);
76
+ expect(results).toBe(false);
77
+ });
78
+ });
79
+
80
+ describe('missing-required-field', () => {
81
+ it('should match expected message for missing required field', () => {
82
+ const message = missingRequiredField('Car', 'color');
83
+ expect(message).toBe('Car object should contain `color` field.');
84
+ });
85
+ });
86
+
87
+ describe('oas-type-of', () => {
88
+ it('should report the correct oas type for a string', () => {
89
+ const results = oasTypeOf('word');
90
+ expect(results).toBe('string');
91
+ });
92
+
93
+ it('should report the correct oas type for an integer', () => {
94
+ const results = oasTypeOf(123);
95
+ expect(results).toBe('integer');
96
+ });
97
+
98
+ it('should report the correct oas type for a number', () => {
99
+ const results = oasTypeOf(3.14);
100
+ expect(results).toBe('number');
101
+ });
102
+
103
+ it('should report the correct oas type for a null value', () => {
104
+ const results = oasTypeOf(null);
105
+ expect(results).toBe('null');
106
+ });
107
+
108
+ it('should report the correct oas type for a true boolean', () => {
109
+ const results = oasTypeOf(true);
110
+ expect(results).toBe('boolean');
111
+ });
112
+
113
+ it('should report the correct oas type for a false boolean', () => {
114
+ const results = oasTypeOf(false);
115
+ expect(results).toBe('boolean');
116
+ });
117
+
118
+ it('should report the correct oas type for an array', () => {
119
+ const results = oasTypeOf(['foo', 'bar']);
120
+ expect(results).toBe('array');
121
+ });
122
+
123
+ it('should report the correct oas type for an object', () => {
124
+ const car = { type: 'Fiat', model: '500', color: 'white' };
125
+ const results = oasTypeOf(car);
126
+ expect(results).toBe('object');
127
+ });
128
+ });
129
+
130
+ describe('get-additional-properties-option', () => {
131
+ it('should return actual option', () => {
132
+ const options = {
133
+ allowAdditionalProperties: true,
134
+ };
135
+ expect(getAdditionalPropertiesOption(options)).toBeTruthy();
136
+ });
137
+
138
+ it('should reverse option', () => {
139
+ const options = {
140
+ disallowAdditionalProperties: true,
141
+ };
142
+ expect(getAdditionalPropertiesOption(options)).toBeFalsy();
143
+ });
144
+
145
+ it('should throw error with message', () => {
146
+ const options = {
147
+ allowAdditionalProperties: true,
148
+ disallowAdditionalProperties: false,
149
+ };
150
+
151
+ try {
152
+ getAdditionalPropertiesOption(options);
153
+ } catch (error) {
154
+ expect(error).toBeInstanceOf(Error);
155
+ expect(error.message).toEqual(
156
+ "Do not use 'disallowAdditionalProperties' field. Use 'allowAdditionalProperties' instead.\n"
157
+ );
158
+ }
159
+ });
160
+ });
package/src/rules/ajv.ts CHANGED
@@ -8,7 +8,7 @@ export function releaseAjvInstance() {
8
8
  ajvInstance = null;
9
9
  }
10
10
 
11
- function getAjv(resolve: ResolveFn, disallowAdditionalProperties: boolean) {
11
+ function getAjv(resolve: ResolveFn, allowAdditionalProperties: boolean) {
12
12
  if (!ajvInstance) {
13
13
  ajvInstance = new Ajv({
14
14
  schemaId: '$id',
@@ -20,7 +20,7 @@ function getAjv(resolve: ResolveFn, disallowAdditionalProperties: boolean) {
20
20
  discriminator: true,
21
21
  allowUnionTypes: true,
22
22
  validateFormats: false, // TODO: fix it
23
- defaultAdditionalProperties: !disallowAdditionalProperties,
23
+ defaultAdditionalProperties: allowAdditionalProperties,
24
24
  loadSchemaSync(base: string, $ref: string) {
25
25
  const resolvedRef = resolve({ $ref }, base.split('#')[0]);
26
26
  if (!resolvedRef || !resolvedRef.location) return false;
@@ -36,9 +36,9 @@ function getAjvValidator(
36
36
  schema: any,
37
37
  loc: Location,
38
38
  resolve: ResolveFn,
39
- disallowAdditionalProperties: boolean,
39
+ allowAdditionalProperties: boolean
40
40
  ): ValidateFunction | undefined {
41
- const ajv = getAjv(resolve, disallowAdditionalProperties);
41
+ const ajv = getAjv(resolve, allowAdditionalProperties);
42
42
 
43
43
  if (!ajv.getSchema(loc.absolutePointer)) {
44
44
  ajv.addSchema({ $id: loc.absolutePointer, ...schema }, loc.absolutePointer);
@@ -53,9 +53,9 @@ export function validateJsonSchema(
53
53
  schemaLoc: Location,
54
54
  instancePath: string,
55
55
  resolve: ResolveFn,
56
- disallowAdditionalProperties: boolean,
56
+ allowAdditionalProperties: boolean
57
57
  ): { valid: boolean; errors: (ErrorObject & { suggest?: string[] })[] } {
58
- const validate = getAjvValidator(schema, schemaLoc, resolve, disallowAdditionalProperties);
58
+ const validate = getAjvValidator(schema, schemaLoc, resolve, allowAdditionalProperties);
59
59
  if (!validate) return { valid: true, errors: [] }; // unresolved refs are reported
60
60
 
61
61
  const valid = validate(data, {
@@ -73,8 +73,7 @@ export function validateJsonSchema(
73
73
 
74
74
  function beatifyErrorMessage(error: ErrorObject) {
75
75
  let message = error.message;
76
- let suggest =
77
- error.keyword === 'enum' ? error.params.allowedValues : undefined;
76
+ let suggest = error.keyword === 'enum' ? error.params.allowedValues : undefined;
78
77
  if (suggest) {
79
78
  message += ` ${suggest.map((e: any) => `"${e}"`).join(', ')}`;
80
79
  }
@@ -11,7 +11,7 @@ describe('Oas3 info-description', () => {
11
11
  info:
12
12
  version: '1.0'
13
13
  `,
14
- 'foobar.yaml',
14
+ 'foobar.yaml'
15
15
  );
16
16
 
17
17
  const results = await lintDocument({
@@ -49,7 +49,7 @@ describe('Oas3 info-description', () => {
49
49
  version: '1.0'
50
50
  description: ''
51
51
  `,
52
- 'foobar.yaml',
52
+ 'foobar.yaml'
53
53
  );
54
54
 
55
55
  const results = await lintDocument({
@@ -86,7 +86,7 @@ describe('Oas3 info-description', () => {
86
86
  info:
87
87
  description: test description
88
88
  `,
89
- 'foobar.yaml',
89
+ 'foobar.yaml'
90
90
  );
91
91
 
92
92
  const results = await lintDocument({
@@ -11,7 +11,7 @@ describe('Oas3 info-license', () => {
11
11
  info:
12
12
  version: '1.0'
13
13
  `,
14
- 'foobar.yaml',
14
+ 'foobar.yaml'
15
15
  );
16
16
 
17
17
  const results = await lintDocument({
@@ -48,7 +48,7 @@ describe('Oas3 info-license', () => {
48
48
  name: MIT
49
49
  url: google.com
50
50
  `,
51
- 'foobar.yaml',
51
+ 'foobar.yaml'
52
52
  );
53
53
 
54
54
  const results = await lintDocument({
@@ -12,7 +12,7 @@ describe('Oas3 license-url', () => {
12
12
  license:
13
13
  name: MIT
14
14
  `,
15
- 'foobar.yaml',
15
+ 'foobar.yaml'
16
16
  );
17
17
 
18
18
  const results = await lintDocument({
@@ -49,7 +49,7 @@ describe('Oas3 license-url', () => {
49
49
  name: MIT
50
50
  url: google.com
51
51
  `,
52
- 'foobar.yaml',
52
+ 'foobar.yaml'
53
53
  );
54
54
 
55
55
  const results = await lintDocument({
@@ -40,7 +40,7 @@ describe('no-ambiguous-paths', () => {
40
40
  get:
41
41
  summary: List all pets
42
42
  `,
43
- 'foobar.yaml',
43
+ 'foobar.yaml'
44
44
  );
45
45
 
46
46
  const results = await lintDocument({