@redocly/openapi-core 1.0.0-beta.105 → 1.0.0-beta.108

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 (240) hide show
  1. package/README.md +4 -4
  2. package/__tests__/utils.ts +5 -5
  3. package/lib/benchmark/benches/lint-with-top-level-rule-report.bench.js +0 -1
  4. package/lib/benchmark/benches/recommended-oas3.bench.js +1 -1
  5. package/lib/benchmark/utils.d.ts +2 -2
  6. package/lib/benchmark/utils.js +2 -2
  7. package/lib/bundle.d.ts +2 -2
  8. package/lib/bundle.js +7 -4
  9. package/lib/config/all.d.ts +2 -2
  10. package/lib/config/all.js +3 -3
  11. package/lib/config/builtIn.d.ts +2 -2
  12. package/lib/config/builtIn.js +2 -2
  13. package/lib/config/config-resolvers.d.ts +5 -5
  14. package/lib/config/config-resolvers.js +70 -49
  15. package/lib/config/config.d.ts +8 -10
  16. package/lib/config/config.js +10 -7
  17. package/lib/config/load.d.ts +7 -0
  18. package/lib/config/load.js +18 -10
  19. package/lib/config/minimal.d.ts +2 -2
  20. package/lib/config/minimal.js +5 -4
  21. package/lib/config/recommended.d.ts +2 -2
  22. package/lib/config/recommended.js +5 -4
  23. package/lib/config/rules.d.ts +3 -3
  24. package/lib/config/rules.js +1 -1
  25. package/lib/config/types.d.ts +23 -19
  26. package/lib/config/utils.d.ts +5 -5
  27. package/lib/config/utils.js +48 -31
  28. package/lib/decorators/common/registry-dependencies.js +1 -1
  29. package/lib/decorators/common/remove-x-internal.js +2 -2
  30. package/lib/env.d.ts +3 -0
  31. package/lib/env.js +8 -0
  32. package/lib/format/codeframes.js +16 -10
  33. package/lib/format/format.js +29 -27
  34. package/lib/index.d.ts +5 -5
  35. package/lib/index.js +4 -2
  36. package/lib/js-yaml/index.js +2 -6
  37. package/lib/lint.d.ts +2 -2
  38. package/lib/lint.js +16 -6
  39. package/lib/logger.d.ts +10 -0
  40. package/lib/logger.js +31 -0
  41. package/lib/output.d.ts +3 -0
  42. package/lib/output.js +9 -0
  43. package/lib/redocly/index.js +10 -9
  44. package/lib/redocly/registry-api-types.d.ts +28 -30
  45. package/lib/redocly/registry-api.d.ts +4 -3
  46. package/lib/redocly/registry-api.js +9 -4
  47. package/lib/ref-utils.js +2 -1
  48. package/lib/resolve.d.ts +1 -1
  49. package/lib/resolve.js +1 -1
  50. package/lib/rules/ajv.d.ts +1 -1
  51. package/lib/rules/ajv.js +7 -7
  52. package/lib/rules/common/assertions/asserts.js +4 -4
  53. package/lib/rules/common/assertions/index.js +1 -1
  54. package/lib/rules/common/info-license-url.d.ts +1 -1
  55. package/lib/rules/common/info-license-url.js +5 -10
  56. package/lib/rules/common/info-license.d.ts +2 -0
  57. package/lib/rules/common/info-license.js +17 -0
  58. package/lib/rules/common/no-enum-type-mismatch.js +1 -3
  59. package/lib/rules/common/no-invalid-parameter-examples.js +3 -3
  60. package/lib/rules/common/no-invalid-schema-examples.js +3 -3
  61. package/lib/rules/common/operation-operationId.js +1 -1
  62. package/lib/rules/common/operation-security-defined.js +1 -1
  63. package/lib/rules/common/path-not-include-query.js +1 -1
  64. package/lib/rules/common/paths-kebab-case.js +4 -1
  65. package/lib/rules/common/spec.js +3 -3
  66. package/lib/rules/oas2/index.js +4 -4
  67. package/lib/rules/oas2/remove-unused-components.js +5 -5
  68. package/lib/rules/oas3/index.js +6 -6
  69. package/lib/rules/oas3/no-empty-servers.js +1 -1
  70. package/lib/rules/oas3/no-invalid-media-type-examples.js +2 -2
  71. package/lib/rules/oas3/no-server-variables-empty-enum.d.ts +2 -0
  72. package/lib/rules/oas3/{no-servers-empty-enum.js → no-server-variables-empty-enum.js} +4 -4
  73. package/lib/rules/oas3/no-unused-components.js +1 -1
  74. package/lib/rules/oas3/remove-unused-components.js +5 -5
  75. package/lib/rules/other/stats.js +43 -14
  76. package/lib/rules/utils.d.ts +3 -2
  77. package/lib/rules/utils.js +20 -5
  78. package/lib/types/index.d.ts +2 -2
  79. package/lib/types/redocly-yaml.js +9 -8
  80. package/lib/utils.d.ts +5 -0
  81. package/lib/utils.js +22 -5
  82. package/lib/visitors.d.ts +1 -1
  83. package/lib/visitors.js +2 -2
  84. package/lib/walk.d.ts +2 -1
  85. package/lib/walk.js +6 -3
  86. package/package.json +2 -2
  87. package/src/__tests__/__snapshots__/bundle.test.ts.snap +141 -0
  88. package/src/__tests__/bundle.test.ts +68 -34
  89. package/src/__tests__/codeframes.test.ts +13 -14
  90. package/src/__tests__/js-yaml.test.ts +6 -4
  91. package/src/__tests__/lint.test.ts +74 -6
  92. package/src/__tests__/logger-browser.test.ts +53 -0
  93. package/src/__tests__/logger.test.ts +47 -0
  94. package/src/__tests__/login.test.ts +2 -2
  95. package/src/__tests__/normalizeVisitors.test.ts +4 -4
  96. package/src/__tests__/output-browser.test.ts +18 -0
  97. package/src/__tests__/output.test.ts +15 -0
  98. package/src/__tests__/ref-utils.test.ts +13 -13
  99. package/src/__tests__/resolve-http.test.ts +1 -1
  100. package/src/__tests__/resolve.test.ts +14 -11
  101. package/src/__tests__/utils-browser.test.ts +11 -0
  102. package/src/__tests__/utils.test.ts +7 -0
  103. package/src/__tests__/walk.test.ts +48 -56
  104. package/src/benchmark/benches/lint-with-many-rules.bench.ts +1 -1
  105. package/src/benchmark/benches/lint-with-nested-rule.bench.ts +1 -1
  106. package/src/benchmark/benches/lint-with-no-rules.bench.ts +1 -1
  107. package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +1 -2
  108. package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +1 -1
  109. package/src/benchmark/benches/recommended-oas3.bench.ts +3 -3
  110. package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
  111. package/src/benchmark/benchmark.js +9 -5
  112. package/src/benchmark/utils.ts +5 -5
  113. package/src/bundle.ts +24 -20
  114. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +7 -5
  115. package/src/config/__tests__/config-resolvers.test.ts +123 -121
  116. package/src/config/__tests__/config.test.ts +111 -76
  117. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +4 -2
  118. package/src/config/__tests__/fixtures/resolve-config/plugin.js +4 -1
  119. package/src/config/__tests__/load.test.ts +79 -1
  120. package/src/config/__tests__/resolve-plugins.test.ts +3 -3
  121. package/src/config/__tests__/utils.test.ts +83 -0
  122. package/src/config/all.ts +5 -6
  123. package/src/config/builtIn.ts +5 -5
  124. package/src/config/config-resolvers.ts +161 -96
  125. package/src/config/config.ts +15 -13
  126. package/src/config/load.ts +34 -11
  127. package/src/config/minimal.ts +7 -6
  128. package/src/config/recommended.ts +7 -6
  129. package/src/config/rules.ts +6 -6
  130. package/src/config/types.ts +28 -19
  131. package/src/config/utils.ts +78 -57
  132. package/src/decorators/__tests__/filter-out.test.ts +8 -4
  133. package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
  134. package/src/decorators/common/filters/filter-helper.ts +1 -1
  135. package/src/decorators/common/info-description-override.ts +1 -1
  136. package/src/decorators/common/operation-description-override.ts +1 -1
  137. package/src/decorators/common/registry-dependencies.ts +1 -1
  138. package/src/decorators/common/remove-x-internal.ts +4 -4
  139. package/src/decorators/common/tag-description-override.ts +1 -1
  140. package/src/env.ts +5 -0
  141. package/src/format/codeframes.ts +18 -12
  142. package/src/format/format.ts +37 -42
  143. package/src/index.ts +8 -7
  144. package/src/js-yaml/index.ts +4 -8
  145. package/src/lint.ts +22 -18
  146. package/src/logger.ts +34 -0
  147. package/src/oas-types.ts +1 -6
  148. package/src/output.ts +7 -0
  149. package/src/redocly/__tests__/redocly-client.test.ts +25 -19
  150. package/src/redocly/index.ts +12 -7
  151. package/src/redocly/registry-api-types.ts +27 -29
  152. package/src/redocly/registry-api.ts +22 -12
  153. package/src/ref-utils.ts +4 -3
  154. package/src/resolve.ts +11 -8
  155. package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
  156. package/src/rules/__tests__/utils.test.ts +160 -0
  157. package/src/rules/ajv.ts +7 -8
  158. package/src/rules/common/__tests__/info-description.test.ts +3 -3
  159. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  160. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  161. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  162. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +8 -8
  163. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  164. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
  165. package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
  166. package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
  167. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  168. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  169. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  170. package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
  171. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  172. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  173. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  174. package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
  175. package/src/rules/common/__tests__/paths-kebab-case.test.ts +15 -15
  176. package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +8 -8
  177. package/src/rules/common/__tests__/spec.test.ts +2 -2
  178. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  179. package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
  180. package/src/rules/common/assertions/__tests__/asserts.test.ts +513 -130
  181. package/src/rules/common/assertions/asserts.ts +4 -4
  182. package/src/rules/common/assertions/index.ts +7 -7
  183. package/src/rules/common/info-license-url.ts +4 -9
  184. package/src/rules/common/info-license.ts +15 -0
  185. package/src/rules/common/no-ambiguous-paths.ts +1 -1
  186. package/src/rules/common/no-enum-type-mismatch.ts +12 -9
  187. package/src/rules/common/no-invalid-parameter-examples.ts +4 -4
  188. package/src/rules/common/no-invalid-schema-examples.ts +4 -4
  189. package/src/rules/common/operation-operationId.ts +1 -1
  190. package/src/rules/common/operation-parameters-unique.ts +2 -2
  191. package/src/rules/common/operation-security-defined.ts +1 -1
  192. package/src/rules/common/path-not-include-query.ts +1 -1
  193. package/src/rules/common/path-params-defined.ts +1 -1
  194. package/src/rules/common/paths-kebab-case.ts +4 -1
  195. package/src/rules/common/scalar-property-missing-example.ts +1 -1
  196. package/src/rules/common/spec.ts +12 -9
  197. package/src/rules/no-unresolved-refs.ts +1 -1
  198. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  199. package/src/rules/oas2/__tests__/spec/info.test.ts +12 -12
  200. package/src/rules/oas2/__tests__/spec/operation.test.ts +4 -4
  201. package/src/rules/oas2/__tests__/spec/paths.test.ts +10 -10
  202. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +6 -2
  203. package/src/rules/oas2/__tests__/spec/utils.ts +6 -6
  204. package/src/rules/oas2/index.ts +3 -3
  205. package/src/rules/oas2/remove-unused-components.ts +14 -9
  206. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  207. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +16 -16
  208. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  209. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +13 -13
  210. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
  211. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  212. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  213. package/src/rules/oas3/__tests__/spec/callbacks.test.ts +1 -1
  214. package/src/rules/oas3/__tests__/spec/info.test.ts +12 -12
  215. package/src/rules/oas3/__tests__/spec/operation.test.ts +8 -8
  216. package/src/rules/oas3/__tests__/spec/paths.test.ts +10 -10
  217. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +12 -12
  218. package/src/rules/oas3/__tests__/spec/servers.test.ts +15 -15
  219. package/src/rules/oas3/__tests__/spec/spec.test.ts +6 -6
  220. package/src/rules/oas3/__tests__/spec/utils.ts +6 -6
  221. package/src/rules/oas3/index.ts +5 -5
  222. package/src/rules/oas3/no-empty-servers.ts +1 -1
  223. package/src/rules/oas3/no-invalid-media-type-examples.ts +14 -6
  224. package/src/rules/oas3/{no-servers-empty-enum.ts → no-server-variables-empty-enum.ts} +10 -11
  225. package/src/rules/oas3/no-unused-components.ts +1 -1
  226. package/src/rules/oas3/remove-unused-components.ts +21 -10
  227. package/src/rules/other/stats.ts +46 -17
  228. package/src/rules/utils.ts +20 -4
  229. package/src/types/index.ts +5 -5
  230. package/src/types/redocly-yaml.ts +9 -8
  231. package/src/typings/common.ts +9 -1
  232. package/src/typings/openapi.ts +1 -1
  233. package/src/utils.ts +26 -3
  234. package/src/visitors.ts +9 -9
  235. package/src/walk.ts +15 -11
  236. package/tsconfig.tsbuildinfo +1 -1
  237. package/lib/rules/common/license-url.d.ts +0 -2
  238. package/lib/rules/common/license-url.js +0 -12
  239. package/lib/rules/oas3/no-servers-empty-enum.d.ts +0 -2
  240. package/src/rules/common/license-url.ts +0 -10
@@ -1,11 +1,12 @@
1
1
  import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
2
2
  import { resolve } from 'path';
3
3
  import { homedir } from 'os';
4
- import { green } from 'colorette';
5
4
  import { RegistryApi } from './registry-api';
6
- import { DEFAULT_REGION, DOMAINS, AVAILABLE_REGIONS, env } from '../config/config';
5
+ import { DEFAULT_REGION, DOMAINS, AVAILABLE_REGIONS } from '../config/config';
6
+ import { env } from '../env';
7
7
  import { RegionalToken, RegionalTokenWithValidity } from './redocly-client-types';
8
8
  import { isNotEmptyObject } from '../utils';
9
+ import { colorize } from '../logger';
9
10
 
10
11
  import type { AccessTokens, Region } from '../config/types';
11
12
 
@@ -28,12 +29,16 @@ export class RedoclyClient {
28
29
 
29
30
  loadRegion(region?: Region) {
30
31
  if (region && !DOMAINS[region]) {
31
- throw new Error(`Invalid argument: region in config file.\nGiven: ${green(region)}, choices: "us", "eu".`);
32
+ throw new Error(
33
+ `Invalid argument: region in config file.\nGiven: ${colorize.green(
34
+ region
35
+ )}, choices: "us", "eu".`
36
+ );
32
37
  }
33
38
 
34
39
  if (env.REDOCLY_DOMAIN) {
35
40
  return (AVAILABLE_REGIONS.find(
36
- (region) => DOMAINS[region as Region] === env.REDOCLY_DOMAIN,
41
+ (region) => DOMAINS[region as Region] === env.REDOCLY_DOMAIN
37
42
  ) || DEFAULT_REGION) as Region;
38
43
  }
39
44
  return region || DEFAULT_REGION;
@@ -91,7 +96,7 @@ export class RedoclyClient {
91
96
  const allTokens = this.getAllTokens();
92
97
 
93
98
  const verifiedTokens = await Promise.allSettled(
94
- allTokens.map(({ token, region }) => this.verifyToken(token, region)),
99
+ allTokens.map(({ token, region }) => this.verifyToken(token, region))
95
100
  );
96
101
 
97
102
  return allTokens
@@ -134,7 +139,7 @@ export class RedoclyClient {
134
139
  async verifyToken(
135
140
  accessToken: string,
136
141
  region: Region,
137
- verbose: boolean = false,
142
+ verbose: boolean = false
138
143
  ): Promise<{ viewerId: string; organizations: string[] }> {
139
144
  return this.registryApi.authStatus(accessToken, region, verbose);
140
145
  }
@@ -150,7 +155,7 @@ export class RedoclyClient {
150
155
 
151
156
  const credentials = {
152
157
  ...this.readCredentialsFile(credentialsPath),
153
- [this.region!]: accessToken,
158
+ [this.region]: accessToken,
154
159
  token: accessToken, // FIXME: backward compatibility, remove on 1.0.0
155
160
  };
156
161
  this.accessTokens = credentials;
@@ -1,34 +1,32 @@
1
- export namespace RegistryApiTypes {
2
- interface VersionParams {
3
- organizationId: string;
4
- name: string;
5
- version: string;
6
- }
1
+ interface VersionParams {
2
+ organizationId: string;
3
+ name: string;
4
+ version: string;
5
+ }
7
6
 
8
- export interface PrepareFileuploadParams extends VersionParams {
9
- filesHash: string;
10
- filename: string;
11
- isUpsert?: boolean;
12
- }
7
+ export interface PrepareFileuploadParams extends VersionParams {
8
+ filesHash: string;
9
+ filename: string;
10
+ isUpsert?: boolean;
11
+ }
13
12
 
14
- export interface PushApiParams extends VersionParams {
15
- rootFilePath: string;
16
- filePaths: string[];
17
- branch?: string;
18
- isUpsert?: boolean;
19
- isPublic?: boolean;
20
- batchId?: string;
21
- batchSize?: number;
22
- }
13
+ export interface PushApiParams extends VersionParams {
14
+ rootFilePath: string;
15
+ filePaths: string[];
16
+ branch?: string;
17
+ isUpsert?: boolean;
18
+ isPublic?: boolean;
19
+ batchId?: string;
20
+ batchSize?: number;
21
+ }
23
22
 
24
- export interface PrepareFileuploadOKResponse {
25
- filePath: string;
26
- signedUploadUrl: string;
27
- }
23
+ export interface PrepareFileuploadOKResponse {
24
+ filePath: string;
25
+ signedUploadUrl: string;
26
+ }
28
27
 
29
- export interface NotFoundProblemResponse {
30
- status: 404;
31
- title: 'Not Found';
32
- code: 'ORGANIZATION_NOT_FOUND' | 'API_VERSION_NOT_FOUND';
33
- }
28
+ export interface NotFoundProblemResponse {
29
+ status: 404;
30
+ title: 'Not Found';
31
+ code: 'ORGANIZATION_NOT_FOUND' | 'API_VERSION_NOT_FOUND';
34
32
  }
@@ -1,10 +1,17 @@
1
1
  import fetch, { RequestInit, HeadersInit } from 'node-fetch';
2
- import { RegistryApiTypes } from './registry-api-types';
2
+ import type {
3
+ NotFoundProblemResponse,
4
+ PrepareFileuploadOKResponse,
5
+ PrepareFileuploadParams,
6
+ PushApiParams,
7
+ } from './registry-api-types';
8
+ import type { AccessTokens, Region } from '../config/types';
3
9
  import { DEFAULT_REGION, DOMAINS } from '../config/config';
4
10
  import { isNotEmptyObject } from '../utils';
5
11
  const version = require('../../package.json').version;
6
12
 
7
- import type { AccessTokens, Region } from '../config/types';
13
+ export const currentCommand =
14
+ typeof process !== 'undefined' ? process.env?.REDOCLY_CLI_COMMAND || '' : '';
8
15
 
9
16
  export class RegistryApi {
10
17
  constructor(private accessTokens: AccessTokens, private region: Region) {}
@@ -23,7 +30,10 @@ export class RegistryApi {
23
30
  }
24
31
 
25
32
  private async request(path = '', options: RequestInit = {}, region?: Region) {
26
- const headers = Object.assign({}, options.headers || {}, { 'x-redocly-cli-version': version });
33
+ const headers = Object.assign({}, options.headers || {}, {
34
+ 'x-redocly-cli-version': version,
35
+ 'user-agent': `redocly-cli / ${version} ${currentCommand}`,
36
+ });
27
37
 
28
38
  if (!headers.hasOwnProperty('authorization')) {
29
39
  throw new Error('Unauthorized');
@@ -31,7 +41,7 @@ export class RegistryApi {
31
41
 
32
42
  const response = await fetch(
33
43
  `${this.getBaseUrl(region)}${path}`,
34
- Object.assign({}, options, { headers }),
44
+ Object.assign({}, options, { headers })
35
45
  );
36
46
 
37
47
  if (response.status === 401) {
@@ -39,7 +49,7 @@ export class RegistryApi {
39
49
  }
40
50
 
41
51
  if (response.status === 404) {
42
- const body: RegistryApiTypes.NotFoundProblemResponse = await response.json();
52
+ const body: NotFoundProblemResponse = await response.json();
43
53
  throw new Error(body.code);
44
54
  }
45
55
 
@@ -49,7 +59,7 @@ export class RegistryApi {
49
59
  async authStatus(
50
60
  accessToken: string,
51
61
  region: Region,
52
- verbose = false,
62
+ verbose = false
53
63
  ): Promise<{ viewerId: string; organizations: string[] }> {
54
64
  try {
55
65
  const response = await this.request('', { headers: { authorization: accessToken } }, region);
@@ -71,7 +81,7 @@ export class RegistryApi {
71
81
  filesHash,
72
82
  filename,
73
83
  isUpsert,
74
- }: RegistryApiTypes.PrepareFileuploadParams): Promise<RegistryApiTypes.PrepareFileuploadOKResponse> {
84
+ }: PrepareFileuploadParams): Promise<PrepareFileuploadOKResponse> {
75
85
  const response = await this.request(
76
86
  `/${organizationId}/${name}/${version}/prepare-file-upload`,
77
87
  {
@@ -86,7 +96,7 @@ export class RegistryApi {
86
96
  isUpsert,
87
97
  }),
88
98
  },
89
- this.region,
99
+ this.region
90
100
  );
91
101
 
92
102
  if (response.ok) {
@@ -106,8 +116,8 @@ export class RegistryApi {
106
116
  isUpsert,
107
117
  isPublic,
108
118
  batchId,
109
- batchSize
110
- }: RegistryApiTypes.PushApiParams) {
119
+ batchSize,
120
+ }: PushApiParams) {
111
121
  const response = await this.request(
112
122
  `/${organizationId}/${name}/${version}`,
113
123
  {
@@ -123,10 +133,10 @@ export class RegistryApi {
123
133
  isUpsert,
124
134
  isPublic,
125
135
  batchId,
126
- batchSize
136
+ batchSize,
127
137
  }),
128
138
  },
129
- this.region,
139
+ this.region
130
140
  );
131
141
 
132
142
  if (response.ok) {
package/src/ref-utils.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Source } from './resolve';
2
2
  import { OasRef } from './typings/openapi';
3
+ import { isTruthy } from './utils';
3
4
 
4
5
  export function joinPointer(base: string, key: string | number) {
5
6
  if (base === '') base = '#/';
@@ -18,8 +19,8 @@ export class Location {
18
19
  this.source,
19
20
  joinPointer(
20
21
  this.pointer,
21
- (Array.isArray(components) ? components : [components]).map(escapePointer).join('/'),
22
- ),
22
+ (Array.isArray(components) ? components : [components]).map(escapePointer).join('/')
23
+ )
23
24
  );
24
25
  }
25
26
 
@@ -45,7 +46,7 @@ export function parseRef(ref: string): { uri: string | null; pointer: string[] }
45
46
  const [uri, pointer] = ref.split('#/');
46
47
  return {
47
48
  uri: uri || null,
48
- pointer: pointer ? pointer.split('/').map(unescapePointer).filter(Boolean) : [],
49
+ pointer: pointer ? pointer.split('/').map(unescapePointer).filter(isTruthy) : [],
49
50
  };
50
51
  }
51
52
 
package/src/resolve.ts CHANGED
@@ -91,7 +91,7 @@ export function makeDocumentFromString(sourceString: string, absoluteRef: string
91
91
  export class BaseResolver {
92
92
  cache: Map<string, Promise<Document | ResolveError>> = new Map();
93
93
 
94
- constructor(private config: ResolveConfig = { http: { headers: [] } }) {}
94
+ constructor(protected config: ResolveConfig = { http: { headers: [] } }) {}
95
95
 
96
96
  getFiles() {
97
97
  return new Set(Array.from(this.cache.keys()));
@@ -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,11 +316,14 @@ 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 = {
323
- resolved: false as false,
326
+ resolved: false as const,
324
327
  isRemote,
325
328
  document: undefined,
326
329
  error: error,
@@ -331,7 +334,7 @@ export async function resolveDocument(opts: {
331
334
  }
332
335
 
333
336
  let resolvedRef: ResolvedRef = {
334
- resolved: true as true,
337
+ resolved: true as const,
335
338
  document: targetDoc,
336
339
  isRemote,
337
340
  node: document.parsed,
@@ -341,7 +344,7 @@ export async function resolveDocument(opts: {
341
344
  let target = targetDoc.parsed as any;
342
345
 
343
346
  const segments = pointer;
344
- for (let segment of segments) {
347
+ for (const segment of segments) {
345
348
  if (typeof target !== 'object') {
346
349
  target = undefined;
347
350
  break;
@@ -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
+ const 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({