@redocly/openapi-core 1.0.0-beta.65 → 1.0.0-beta.69

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 (90) hide show
  1. package/__tests__/__snapshots__/bundle.test.ts.snap +126 -0
  2. package/__tests__/bundle.test.ts +53 -1
  3. package/__tests__/fixtures/refs/definitions.yaml +3 -0
  4. package/__tests__/fixtures/refs/external-request-body.yaml +13 -0
  5. package/__tests__/fixtures/refs/externalref.yaml +35 -0
  6. package/__tests__/fixtures/refs/hosted.yaml +35 -0
  7. package/__tests__/fixtures/refs/rename.yaml +1 -0
  8. package/__tests__/fixtures/refs/requestBody.yaml +9 -0
  9. package/__tests__/fixtures/refs/simple.yaml +1 -0
  10. package/__tests__/fixtures/refs/vendor.schema.yaml +20 -0
  11. package/lib/bundle.d.ts +4 -0
  12. package/lib/bundle.js +25 -7
  13. package/lib/config/all.js +9 -1
  14. package/lib/config/config.js +1 -1
  15. package/lib/config/minimal.js +1 -0
  16. package/lib/config/recommended.js +1 -0
  17. package/lib/index.d.ts +1 -1
  18. package/lib/index.js +2 -1
  19. package/lib/lint.js +2 -0
  20. package/lib/redocly/index.d.ts +3 -14
  21. package/lib/redocly/index.js +19 -186
  22. package/lib/redocly/registry-api-types.d.ts +28 -0
  23. package/lib/redocly/registry-api-types.js +2 -0
  24. package/lib/redocly/registry-api.d.ts +11 -0
  25. package/lib/redocly/registry-api.js +94 -0
  26. package/lib/ref-utils.js +1 -2
  27. package/lib/rules/common/info-license-url.js +1 -0
  28. package/lib/rules/common/no-http-verbs-in-paths.d.ts +2 -0
  29. package/lib/rules/common/no-http-verbs-in-paths.js +33 -0
  30. package/lib/rules/common/operation-4xx-response.d.ts +2 -0
  31. package/lib/rules/common/operation-4xx-response.js +17 -0
  32. package/lib/rules/common/path-excludes-patterns.d.ts +2 -0
  33. package/lib/rules/common/path-excludes-patterns.js +22 -0
  34. package/lib/rules/common/path-segment-plural.d.ts +2 -0
  35. package/lib/rules/common/path-segment-plural.js +32 -0
  36. package/lib/rules/common/registry-dependencies.js +4 -7
  37. package/lib/rules/oas2/index.d.ts +6 -0
  38. package/lib/rules/oas2/index.js +12 -0
  39. package/lib/rules/oas2/request-mime-type.d.ts +2 -0
  40. package/lib/rules/oas2/request-mime-type.js +17 -0
  41. package/lib/rules/oas2/response-mime-type.d.ts +2 -0
  42. package/lib/rules/oas2/response-mime-type.js +17 -0
  43. package/lib/rules/oas3/index.js +12 -0
  44. package/lib/rules/oas3/no-server-trailing-slash.js +1 -1
  45. package/lib/rules/oas3/request-mime-type.d.ts +2 -0
  46. package/lib/rules/oas3/request-mime-type.js +31 -0
  47. package/lib/rules/oas3/response-mime-type.d.ts +2 -0
  48. package/lib/rules/oas3/response-mime-type.js +31 -0
  49. package/lib/types/oas3_1.js +6 -0
  50. package/lib/utils.d.ts +10 -0
  51. package/lib/utils.js +65 -1
  52. package/lib/walk.d.ts +2 -0
  53. package/lib/walk.js +7 -0
  54. package/package.json +5 -3
  55. package/src/__tests__/utils.test.ts +19 -1
  56. package/src/bundle.ts +51 -9
  57. package/src/config/all.ts +9 -1
  58. package/src/config/config.ts +2 -2
  59. package/src/config/minimal.ts +1 -0
  60. package/src/config/recommended.ts +1 -0
  61. package/src/index.ts +1 -1
  62. package/src/lint.ts +2 -0
  63. package/src/redocly/index.ts +17 -194
  64. package/src/redocly/registry-api-types.ts +31 -0
  65. package/src/redocly/registry-api.ts +106 -0
  66. package/src/ref-utils.ts +1 -3
  67. package/src/rules/common/__tests__/info-license.test.ts +1 -1
  68. package/src/rules/common/__tests__/operation-4xx-response.test.ts +108 -0
  69. package/src/rules/common/info-license-url.ts +1 -0
  70. package/src/rules/common/no-http-verbs-in-paths.ts +36 -0
  71. package/src/rules/common/operation-4xx-response.ts +17 -0
  72. package/src/rules/common/path-excludes-patterns.ts +23 -0
  73. package/src/rules/common/path-segment-plural.ts +31 -0
  74. package/src/rules/common/registry-dependencies.ts +6 -8
  75. package/src/rules/oas2/index.ts +12 -0
  76. package/src/rules/oas2/request-mime-type.ts +17 -0
  77. package/src/rules/oas2/response-mime-type.ts +17 -0
  78. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +19 -0
  79. package/src/rules/oas3/index.ts +12 -0
  80. package/src/rules/oas3/no-server-trailing-slash.ts +1 -1
  81. package/src/rules/oas3/request-mime-type.ts +31 -0
  82. package/src/rules/oas3/response-mime-type.ts +31 -0
  83. package/src/rules/utils.ts +1 -1
  84. package/src/types/oas3_1.ts +7 -0
  85. package/src/utils.ts +75 -0
  86. package/src/walk.ts +10 -0
  87. package/tsconfig.tsbuildinfo +1 -1
  88. package/lib/redocly/query.d.ts +0 -4
  89. package/lib/redocly/query.js +0 -44
  90. package/src/redocly/query.ts +0 -38
@@ -9,16 +9,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.RedoclyClient = void 0;
12
+ exports.isRedoclyRegistryURL = exports.RedoclyClient = void 0;
13
13
  const fs_1 = require("fs");
14
14
  const path_1 = require("path");
15
15
  const os_1 = require("os");
16
16
  const colorette_1 = require("colorette");
17
- const query_1 = require("./query");
17
+ const registry_api_1 = require("./registry-api");
18
18
  const TOKEN_FILENAME = '.redocly-config.json';
19
19
  class RedoclyClient {
20
20
  constructor() {
21
21
  this.loadToken();
22
+ this.registryApi = new registry_api_1.RegistryApi(this.accessToken);
22
23
  }
23
24
  hasToken() {
24
25
  return !!this.accessToken;
@@ -43,10 +44,7 @@ class RedoclyClient {
43
44
  return __awaiter(this, void 0, void 0, function* () {
44
45
  if (!accessToken)
45
46
  return false;
46
- const authDetails = yield RedoclyClient.authorize(accessToken, { verbose });
47
- if (!authDetails)
48
- return false;
49
- return true;
47
+ return this.registryApi.setAccessToken(accessToken).authStatus(verbose);
50
48
  });
51
49
  }
52
50
  getAuthorizationHeader() {
@@ -83,185 +81,20 @@ class RedoclyClient {
83
81
  }
84
82
  process.stdout.write('Logged out from the Redocly account. ✋\n');
85
83
  }
86
- query(queryString, parameters = {}, headers = {}) {
87
- return __awaiter(this, void 0, void 0, function* () {
88
- return query_1.query(queryString, parameters, Object.assign({ Authorization: this.accessToken }, headers));
89
- });
90
- }
91
- static authorize(accessToken, options) {
92
- return __awaiter(this, void 0, void 0, function* () {
93
- const { queryName = '', verbose = false } = options;
94
- try {
95
- const queryStr = `query ${queryName}{ viewer { id } }`;
96
- return yield query_1.query(queryStr, {}, { Authorization: accessToken });
97
- }
98
- catch (e) {
99
- if (verbose)
100
- console.log(e);
101
- return null;
102
- }
103
- });
104
- }
105
- updateDependencies(dependencies) {
106
- return __awaiter(this, void 0, void 0, function* () {
107
- const definitionId = process.env.DEFINITION;
108
- const versionId = process.env.DEFINITION;
109
- const branchId = process.env.BRANCH;
110
- if (!definitionId || !versionId || !branchId)
111
- return;
112
- yield this.query(`
113
- mutation UpdateBranchDependenciesFromURLs(
114
- $urls: [String!]!
115
- $definitionId: Int!
116
- $versionId: Int!
117
- $branchId: Int!
118
- ) {
119
- updateBranchDependenciesFromURLs(
120
- definitionId: $definitionId
121
- versionId: $versionId
122
- branchId: $branchId
123
- urls: $urls
124
- ) {
125
- branchName
126
- }
127
- }
128
- `, {
129
- urls: dependencies || [],
130
- definitionId: parseInt(definitionId, 10),
131
- versionId: parseInt(versionId, 10),
132
- branchId: parseInt(branchId, 10),
133
- });
134
- });
135
- }
136
- updateDefinitionVersion(definitionId, versionId, updatePatch) {
137
- return this.query(`
138
- mutation UpdateDefinitionVersion($definitionId: Int!, $versionId: Int!, $updatePatch: DefinitionVersionPatch!) {
139
- updateDefinitionVersionByDefinitionIdAndId(input: {definitionId: $definitionId, id: $versionId, patch: $updatePatch}) {
140
- definitionVersion {
141
- ...VersionDetails
142
- __typename
143
- }
144
- __typename
145
- }
146
- }
147
-
148
- fragment VersionDetails on DefinitionVersion {
149
- id
150
- nodeId
151
- uuid
152
- definitionId
153
- name
154
- description
155
- sourceType
156
- source
157
- registryAccess
158
- __typename
159
- }
160
- `, {
161
- definitionId,
162
- versionId,
163
- updatePatch,
164
- });
165
- }
166
- getOrganizationId(organizationId) {
167
- return this.query(`
168
- query ($organizationId: String!) {
169
- organizationById(id: $organizationId) {
170
- id
171
- }
172
- }
173
- `, {
174
- organizationId
175
- });
176
- }
177
- getDefinitionByName(name, organizationId) {
178
- return this.query(`
179
- query ($name: String!, $organizationId: String!) {
180
- definition: definitionByOrganizationIdAndName(name: $name, organizationId: $organizationId) {
181
- id
182
- }
183
- }
184
- `, {
185
- name,
186
- organizationId
187
- });
188
- }
189
- createDefinition(organizationId, name) {
190
- return this.query(`
191
- mutation CreateDefinition($organizationId: String!, $name: String!) {
192
- def: createDefinition(input: {organizationId: $organizationId, name: $name }) {
193
- definition {
194
- id
195
- nodeId
196
- name
197
- }
198
- }
199
- }
200
- `, {
201
- organizationId,
202
- name
203
- });
204
- }
205
- createDefinitionVersion(definitionId, name, sourceType, source) {
206
- return this.query(`
207
- mutation CreateVersion($definitionId: Int!, $name: String!, $sourceType: DvSourceType!, $source: JSON) {
208
- createDefinitionVersion(input: {definitionId: $definitionId, name: $name, sourceType: $sourceType, source: $source }) {
209
- definitionVersion {
210
- id
211
- }
212
- }
213
- }
214
- `, {
215
- definitionId,
216
- name,
217
- sourceType,
218
- source
219
- });
220
- }
221
- getSignedUrl(organizationId, filesHash, fileName) {
222
- return this.query(`
223
- query ($organizationId: String!, $filesHash: String!, $fileName: String!) {
224
- signFileUploadCLI(organizationId: $organizationId, filesHash: $filesHash, fileName: $fileName) {
225
- signedFileUrl
226
- uploadedFilePath
227
- }
228
- }
229
- `, {
230
- organizationId,
231
- filesHash,
232
- fileName
233
- });
234
- }
235
- getDefinitionVersion(organizationId, definitionName, versionName) {
236
- return this.query(`
237
- query ($organizationId: String!, $definitionName: String!, $versionName: String!) {
238
- version: definitionVersionByOrganizationDefinitionAndName(organizationId: $organizationId, definitionName: $definitionName, versionName: $versionName) {
239
- id
240
- definitionId
241
- defaultBranch {
242
- name
243
- }
244
- }
245
- }
246
- `, {
247
- organizationId,
248
- definitionName,
249
- versionName
250
- });
251
- }
252
- static isRegistryURL(link) {
253
- const domain = process.env.REDOCLY_DOMAIN || 'redoc.ly';
254
- if (!link.startsWith(`https://api.${domain}/registry/`))
255
- return false;
256
- const registryPath = link.replace(`https://api.${domain}/registry/`, '');
257
- const pathParts = registryPath.split('/');
258
- // we can be sure, that there is job UUID present
259
- // (org, definition, version, bundle, branch, job, "openapi.yaml" 🤦‍♂️)
260
- // so skip this link.
261
- // FIXME
262
- if (pathParts.length === 7)
263
- return false;
264
- return true;
265
- }
266
84
  }
267
85
  exports.RedoclyClient = RedoclyClient;
86
+ function isRedoclyRegistryURL(link) {
87
+ const domain = process.env.REDOCLY_DOMAIN || 'redoc.ly';
88
+ if (!link.startsWith(`https://api.${domain}/registry/`))
89
+ return false;
90
+ const registryPath = link.replace(`https://api.${domain}/registry/`, '');
91
+ const pathParts = registryPath.split('/');
92
+ // we can be sure, that there is job UUID present
93
+ // (org, definition, version, bundle, branch, job, "openapi.yaml" 🤦‍♂️)
94
+ // so skip this link.
95
+ // FIXME
96
+ if (pathParts.length === 7)
97
+ return false;
98
+ return true;
99
+ }
100
+ exports.isRedoclyRegistryURL = isRedoclyRegistryURL;
@@ -0,0 +1,28 @@
1
+ export declare namespace RegistryApiTypes {
2
+ interface VersionParams {
3
+ organizationId: string;
4
+ name: string;
5
+ version: string;
6
+ }
7
+ export interface PrepareFileuploadParams extends VersionParams {
8
+ filesHash: string;
9
+ filename: string;
10
+ isUpsert?: boolean;
11
+ }
12
+ export interface PushApiParams extends VersionParams {
13
+ rootFilePath: string;
14
+ filePaths: string[];
15
+ branch?: string;
16
+ isUpsert?: boolean;
17
+ }
18
+ export interface PrepareFileuploadOKResponse {
19
+ filePath: string;
20
+ signedUploadUrl: string;
21
+ }
22
+ export interface NotFoundProblemResponse {
23
+ status: 404;
24
+ title: 'Not Found';
25
+ code: 'ORGANIZATION_NOT_FOUND' | 'API_VERSION_NOT_FOUND';
26
+ }
27
+ export {};
28
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ import { RegistryApiTypes } from './registry-api-types';
2
+ export declare class RegistryApi {
3
+ private accessToken?;
4
+ private readonly baseUrl;
5
+ constructor(accessToken?: string | undefined);
6
+ private request;
7
+ setAccessToken(accessToken: string): this;
8
+ authStatus(verbose?: boolean): Promise<boolean>;
9
+ prepareFileUpload({ organizationId, name, version, filesHash, filename, isUpsert, }: RegistryApiTypes.PrepareFileuploadParams): Promise<RegistryApiTypes.PrepareFileuploadOKResponse>;
10
+ pushApi({ organizationId, name, version, rootFilePath, filePaths, branch, isUpsert, }: RegistryApiTypes.PushApiParams): Promise<void>;
11
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RegistryApi = void 0;
13
+ const node_fetch_1 = require("node-fetch");
14
+ const version = require('../../package.json').version;
15
+ class RegistryApi {
16
+ constructor(accessToken) {
17
+ this.accessToken = accessToken;
18
+ this.baseUrl = `https://api.${process.env.REDOCLY_DOMAIN || 'redoc.ly'}/registry`;
19
+ }
20
+ request(path = '', options = {}) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ if (!this.accessToken) {
23
+ throw new Error('Unauthorized');
24
+ }
25
+ const headers = Object.assign({}, options.headers || {}, {
26
+ authorization: this.accessToken,
27
+ 'x-redocly-cli-version': version,
28
+ });
29
+ const response = yield node_fetch_1.default(`${this.baseUrl}${path}`, Object.assign({}, options, { headers }));
30
+ if (response.status === 401) {
31
+ throw new Error('Unauthorized');
32
+ }
33
+ if (response.status === 404) {
34
+ const body = yield response.json();
35
+ throw new Error(body.code);
36
+ }
37
+ return response;
38
+ });
39
+ }
40
+ setAccessToken(accessToken) {
41
+ this.accessToken = accessToken;
42
+ return this;
43
+ }
44
+ authStatus(verbose = false) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ try {
47
+ const response = yield this.request();
48
+ return response.ok;
49
+ }
50
+ catch (error) {
51
+ if (verbose) {
52
+ console.log(error);
53
+ }
54
+ return false;
55
+ }
56
+ });
57
+ }
58
+ prepareFileUpload({ organizationId, name, version, filesHash, filename, isUpsert, }) {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ const response = yield this.request(`/${organizationId}/${name}/${version}/prepare-file-upload`, {
61
+ method: 'POST',
62
+ headers: { 'content-type': 'application/json' },
63
+ body: JSON.stringify({
64
+ filesHash,
65
+ filename,
66
+ isUpsert,
67
+ }),
68
+ });
69
+ if (response.ok) {
70
+ return response.json();
71
+ }
72
+ throw new Error('Could not prepare file upload');
73
+ });
74
+ }
75
+ pushApi({ organizationId, name, version, rootFilePath, filePaths, branch, isUpsert, }) {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ const response = yield this.request(`/${organizationId}/${name}/${version}`, {
78
+ method: 'PUT',
79
+ headers: { 'content-type': 'application/json' },
80
+ body: JSON.stringify({
81
+ rootFilePath,
82
+ filePaths,
83
+ branch,
84
+ isUpsert,
85
+ }),
86
+ });
87
+ if (response.ok) {
88
+ return;
89
+ }
90
+ throw new Error('Could not push api');
91
+ });
92
+ }
93
+ }
94
+ exports.RegistryApi = RegistryApi;
package/lib/ref-utils.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isMappingRef = exports.isAbsoluteUrl = exports.refBaseName = exports.pointerBaseName = exports.parsePointer = exports.parseRef = exports.escapePointer = exports.unescapePointer = exports.Location = exports.isRef = exports.joinPointer = void 0;
4
- const path_1 = require("path");
5
4
  function joinPointer(base, key) {
6
5
  if (base === '')
7
6
  base = '#/';
@@ -56,7 +55,7 @@ function pointerBaseName(pointer) {
56
55
  }
57
56
  exports.pointerBaseName = pointerBaseName;
58
57
  function refBaseName(ref) {
59
- const parts = ref.split(path_1.sep);
58
+ const parts = ref.split(/[\/\\]/); // split by '\' and '/'
60
59
  return parts[parts.length - 1].split('.')[0];
61
60
  }
62
61
  exports.refBaseName = refBaseName;
@@ -8,6 +8,7 @@ const InfoLicense = () => {
8
8
  if (!info.license) {
9
9
  report({
10
10
  message: utils_1.missingRequiredField('Info', 'license'),
11
+ location: { reportOnKey: true }
11
12
  });
12
13
  }
13
14
  },
@@ -0,0 +1,2 @@
1
+ import { Oas3Rule, Oas2Rule } from '../../visitors';
2
+ export declare const NoHttpVerbsInPaths: Oas3Rule | Oas2Rule;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoHttpVerbsInPaths = void 0;
4
+ const utils_1 = require("../../utils");
5
+ const httpMethods = ['get', 'head', 'post', 'put', 'patch', 'delete', 'options', 'trace'];
6
+ const NoHttpVerbsInPaths = ({ splitIntoWords }) => {
7
+ return {
8
+ PathItem(_path, { key, report, location }) {
9
+ const pathKey = key.toString();
10
+ if (!pathKey.startsWith('/'))
11
+ return;
12
+ const pathSegments = pathKey.split('/');
13
+ for (const pathSegment of pathSegments) {
14
+ if (!pathSegment || utils_1.isPathParameter(pathSegment))
15
+ continue;
16
+ const isHttpMethodIncluded = (method) => {
17
+ return splitIntoWords
18
+ ? utils_1.splitCamelCaseIntoWords(pathSegment).has(method)
19
+ : pathSegment.toLocaleLowerCase().includes(method);
20
+ };
21
+ for (const method of httpMethods) {
22
+ if (isHttpMethodIncluded(method)) {
23
+ report({
24
+ message: `path \`${pathKey}\` should not contain http verb ${method}`,
25
+ location: location.key(),
26
+ });
27
+ }
28
+ }
29
+ }
30
+ },
31
+ };
32
+ };
33
+ exports.NoHttpVerbsInPaths = NoHttpVerbsInPaths;
@@ -0,0 +1,2 @@
1
+ import { Oas3Rule, Oas2Rule } from '../../visitors';
2
+ export declare const Operation4xxResponse: Oas3Rule | Oas2Rule;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Operation4xxResponse = void 0;
4
+ const Operation4xxResponse = () => {
5
+ return {
6
+ ResponsesMap(responses, { report }) {
7
+ const codes = Object.keys(responses);
8
+ if (!codes.some((code) => /4[Xx0-9]{2}/.test(code))) {
9
+ report({
10
+ message: 'Operation must have at least one `4xx` response.',
11
+ location: { reportOnKey: true },
12
+ });
13
+ }
14
+ },
15
+ };
16
+ };
17
+ exports.Operation4xxResponse = Operation4xxResponse;
@@ -0,0 +1,2 @@
1
+ import { Oas2Rule, Oas3Rule } from '../../visitors';
2
+ export declare const PathExcludesPatterns: Oas3Rule | Oas2Rule;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PathExcludesPatterns = void 0;
4
+ const PathExcludesPatterns = ({ patterns }) => {
5
+ return {
6
+ PathItem(_path, { report, key, location }) {
7
+ if (!patterns)
8
+ throw new Error(`Parameter "patterns" is not provided for "path-excludes-patterns" rule`);
9
+ const pathKey = key.toString();
10
+ if (pathKey.startsWith('/')) {
11
+ const matches = patterns.filter((pattern) => pathKey.match(pattern));
12
+ for (const match of matches) {
13
+ report({
14
+ message: `path \`${pathKey}\` should not match regex pattern: \`${match}\``,
15
+ location: location.key(),
16
+ });
17
+ }
18
+ }
19
+ },
20
+ };
21
+ };
22
+ exports.PathExcludesPatterns = PathExcludesPatterns;
@@ -0,0 +1,2 @@
1
+ import { Oas3Rule, Oas2Rule } from '../../visitors';
2
+ export declare const PathSegmentPlural: Oas3Rule | Oas2Rule;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PathSegmentPlural = void 0;
4
+ const utils_1 = require("../../utils");
5
+ const PathSegmentPlural = (opts) => {
6
+ const { ignoreLastPathSegment, exceptions } = opts;
7
+ return {
8
+ PathItem: {
9
+ leave(_path, { report, key, location }) {
10
+ const pathKey = key.toString();
11
+ if (pathKey.startsWith('/')) {
12
+ const pathSegments = pathKey.split('/');
13
+ pathSegments.shift();
14
+ if (ignoreLastPathSegment && pathSegments.length > 1) {
15
+ pathSegments.pop();
16
+ }
17
+ for (const pathSegment of pathSegments) {
18
+ if (exceptions && exceptions.includes(pathSegment))
19
+ continue;
20
+ if (!utils_1.isPathParameter(pathSegment) && utils_1.isSingular(pathSegment)) {
21
+ report({
22
+ message: `path segment \`${pathSegment}\` should be plural.`,
23
+ location: location.key(),
24
+ });
25
+ }
26
+ }
27
+ }
28
+ },
29
+ },
30
+ };
31
+ };
32
+ exports.PathSegmentPlural = PathSegmentPlural;
@@ -3,21 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RegistryDependencies = void 0;
4
4
  const redocly_1 = require("../../redocly");
5
5
  const RegistryDependencies = () => {
6
- let redoclyClient;
7
6
  let registryDependencies = new Set();
8
7
  return {
9
8
  DefinitionRoot: {
10
- leave() {
11
- redoclyClient = new redocly_1.RedoclyClient();
12
- if (process.env.UPDATE_REGISTRY && redoclyClient.hasToken()) {
13
- redoclyClient.updateDependencies(Array.from(registryDependencies.keys()));
14
- }
9
+ leave(_, ctx) {
10
+ const data = ctx.getVisitorData();
11
+ data.links = Array.from(registryDependencies);
15
12
  },
16
13
  },
17
14
  ref(node) {
18
15
  if (node.$ref) {
19
16
  const link = node.$ref.split('#/')[0];
20
- if (redocly_1.RedoclyClient.isRegistryURL(link)) {
17
+ if (redocly_1.isRedoclyRegistryURL(link)) {
21
18
  registryDependencies.add(link);
22
19
  }
23
20
  }
@@ -12,6 +12,7 @@ export declare const rules: {
12
12
  'boolean-parameter-prefixes': Oas2Rule;
13
13
  'no-path-trailing-slash': Oas2Rule;
14
14
  'operation-2xx-response': Oas2Rule;
15
+ 'operation-4xx-response': Oas2Rule;
15
16
  'operation-operationId-unique': Oas2Rule;
16
17
  'operation-parameters-unique': Oas2Rule;
17
18
  'path-parameters-defined': Oas2Rule;
@@ -30,6 +31,11 @@ export declare const rules: {
30
31
  'no-identical-paths': Oas2Rule;
31
32
  'no-ambiguous-paths': Oas2Rule;
32
33
  'path-http-verbs-order': Oas2Rule;
34
+ 'no-http-verbs-in-paths': Oas2Rule;
35
+ 'path-excludes-patterns': Oas2Rule;
36
+ 'request-mime-type': Oas2Rule;
37
+ 'response-mime-type': Oas2Rule;
38
+ 'path-segment-plural': Oas2Rule;
33
39
  };
34
40
  export declare const preprocessors: {};
35
41
  export declare const decorators: {
@@ -13,6 +13,7 @@ const paths_kebab_case_1 = require("../common/paths-kebab-case");
13
13
  const no_enum_type_mismatch_1 = require("../common/no-enum-type-mismatch");
14
14
  const no_path_trailing_slash_1 = require("../common/no-path-trailing-slash");
15
15
  const operation_2xx_response_1 = require("../common/operation-2xx-response");
16
+ const operation_4xx_response_1 = require("../common/operation-4xx-response");
16
17
  const operation_operationId_unique_1 = require("../common/operation-operationId-unique");
17
18
  const operation_parameters_unique_1 = require("../common/operation-parameters-unique");
18
19
  const path_params_defined_1 = require("../common/path-params-defined");
@@ -31,6 +32,11 @@ const no_identical_paths_1 = require("../common/no-identical-paths");
31
32
  const operation_operationId_1 = require("../common/operation-operationId");
32
33
  const operation_summary_1 = require("../common/operation-summary");
33
34
  const no_ambiguous_paths_1 = require("../common/no-ambiguous-paths");
35
+ const no_http_verbs_in_paths_1 = require("../common/no-http-verbs-in-paths");
36
+ const path_excludes_patterns_1 = require("../common/path-excludes-patterns");
37
+ const request_mime_type_1 = require("./request-mime-type");
38
+ const response_mime_type_1 = require("./response-mime-type");
39
+ const path_segment_plural_1 = require("../common/path-segment-plural");
34
40
  const operation_description_override_1 = require("../common/operation-description-override");
35
41
  const tag_description_override_1 = require("../common/tag-description-override");
36
42
  const info_description_override_1 = require("../common/info-description-override");
@@ -47,6 +53,7 @@ exports.rules = {
47
53
  'boolean-parameter-prefixes': boolean_parameter_prefixes_1.BooleanParameterPrefixes,
48
54
  'no-path-trailing-slash': no_path_trailing_slash_1.NoPathTrailingSlash,
49
55
  'operation-2xx-response': operation_2xx_response_1.Operation2xxResponse,
56
+ 'operation-4xx-response': operation_4xx_response_1.Operation4xxResponse,
50
57
  'operation-operationId-unique': operation_operationId_unique_1.OperationIdUnique,
51
58
  'operation-parameters-unique': operation_parameters_unique_1.OperationParametersUnique,
52
59
  'path-parameters-defined': path_params_defined_1.PathParamsDefined,
@@ -65,6 +72,11 @@ exports.rules = {
65
72
  'no-identical-paths': no_identical_paths_1.NoIdenticalPaths,
66
73
  'no-ambiguous-paths': no_ambiguous_paths_1.NoAmbiguousPaths,
67
74
  'path-http-verbs-order': path_http_verbs_order_1.PathHttpVerbsOrder,
75
+ 'no-http-verbs-in-paths': no_http_verbs_in_paths_1.NoHttpVerbsInPaths,
76
+ 'path-excludes-patterns': path_excludes_patterns_1.PathExcludesPatterns,
77
+ 'request-mime-type': request_mime_type_1.RequestMimeType,
78
+ 'response-mime-type': response_mime_type_1.ResponseMimeType,
79
+ 'path-segment-plural': path_segment_plural_1.PathSegmentPlural,
68
80
  };
69
81
  exports.preprocessors = {};
70
82
  exports.decorators = {
@@ -0,0 +1,2 @@
1
+ import { Oas2Rule } from '../../visitors';
2
+ export declare const RequestMimeType: Oas2Rule;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequestMimeType = void 0;
4
+ const utils_1 = require("../../utils");
5
+ const RequestMimeType = ({ allowedValues }) => {
6
+ return {
7
+ DefinitionRoot(root, ctx) {
8
+ utils_1.validateMimeType({ type: 'consumes', value: root }, ctx, allowedValues);
9
+ },
10
+ Operation: {
11
+ leave(operation, ctx) {
12
+ utils_1.validateMimeType({ type: 'consumes', value: operation }, ctx, allowedValues);
13
+ },
14
+ },
15
+ };
16
+ };
17
+ exports.RequestMimeType = RequestMimeType;
@@ -0,0 +1,2 @@
1
+ import { Oas2Rule } from '../../visitors';
2
+ export declare const ResponseMimeType: Oas2Rule;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResponseMimeType = void 0;
4
+ const utils_1 = require("../../utils");
5
+ const ResponseMimeType = ({ allowedValues }) => {
6
+ return {
7
+ DefinitionRoot(root, ctx) {
8
+ utils_1.validateMimeType({ type: 'produces', value: root }, ctx, allowedValues);
9
+ },
10
+ Operation: {
11
+ leave(operation, ctx) {
12
+ utils_1.validateMimeType({ type: 'produces', value: operation }, ctx, allowedValues);
13
+ },
14
+ },
15
+ };
16
+ };
17
+ exports.ResponseMimeType = ResponseMimeType;