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

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 (189) hide show
  1. package/README.md +4 -4
  2. package/__tests__/utils.ts +5 -5
  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 +5 -5
  15. package/lib/config/config.js +4 -4
  16. package/lib/config/load.js +4 -4
  17. package/lib/config/minimal.d.ts +2 -2
  18. package/lib/config/minimal.js +1 -1
  19. package/lib/config/recommended.d.ts +2 -2
  20. package/lib/config/recommended.js +1 -1
  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 +1 -1
  29. package/lib/index.js +2 -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/common/info-license-url.d.ts +1 -1
  36. package/lib/rules/common/info-license-url.js +5 -10
  37. package/lib/rules/common/info-license.d.ts +2 -0
  38. package/lib/rules/common/info-license.js +17 -0
  39. package/lib/rules/common/no-enum-type-mismatch.js +1 -3
  40. package/lib/rules/common/operation-operationId.js +1 -1
  41. package/lib/rules/common/path-not-include-query.js +1 -1
  42. package/lib/rules/common/paths-kebab-case.js +4 -1
  43. package/lib/rules/common/spec.js +1 -1
  44. package/lib/rules/oas2/index.js +4 -4
  45. package/lib/rules/oas2/remove-unused-components.js +3 -3
  46. package/lib/rules/oas3/index.js +4 -4
  47. package/lib/rules/oas3/no-empty-servers.js +1 -1
  48. package/lib/rules/oas3/remove-unused-components.js +2 -2
  49. package/lib/rules/other/stats.js +43 -14
  50. package/lib/rules/utils.d.ts +1 -1
  51. package/lib/rules/utils.js +4 -1
  52. package/lib/types/index.d.ts +2 -2
  53. package/lib/types/redocly-yaml.js +8 -7
  54. package/package.json +1 -1
  55. package/src/__tests__/__snapshots__/bundle.test.ts.snap +141 -0
  56. package/src/__tests__/bundle.test.ts +68 -34
  57. package/src/__tests__/codeframes.test.ts +13 -14
  58. package/src/__tests__/js-yaml.test.ts +6 -4
  59. package/src/__tests__/lint.test.ts +74 -6
  60. package/src/__tests__/login.test.ts +2 -2
  61. package/src/__tests__/normalizeVisitors.test.ts +4 -4
  62. package/src/__tests__/ref-utils.test.ts +13 -13
  63. package/src/__tests__/resolve-http.test.ts +1 -1
  64. package/src/__tests__/resolve.test.ts +14 -11
  65. package/src/__tests__/walk.test.ts +48 -56
  66. package/src/benchmark/benches/lint-with-many-rules.bench.ts +1 -1
  67. package/src/benchmark/benches/lint-with-nested-rule.bench.ts +1 -1
  68. package/src/benchmark/benches/lint-with-no-rules.bench.ts +1 -1
  69. package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +1 -1
  70. package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +1 -1
  71. package/src/benchmark/benches/recommended-oas3.bench.ts +3 -3
  72. package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
  73. package/src/benchmark/benchmark.js +9 -5
  74. package/src/benchmark/utils.ts +5 -5
  75. package/src/bundle.ts +18 -17
  76. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +1 -1
  77. package/src/config/__tests__/config-resolvers.test.ts +123 -121
  78. package/src/config/__tests__/config.test.ts +76 -76
  79. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +4 -2
  80. package/src/config/__tests__/fixtures/resolve-config/plugin.js +4 -1
  81. package/src/config/__tests__/resolve-plugins.test.ts +3 -3
  82. package/src/config/__tests__/utils.test.ts +83 -0
  83. package/src/config/all.ts +3 -4
  84. package/src/config/builtIn.ts +5 -5
  85. package/src/config/config-resolvers.ts +122 -83
  86. package/src/config/config.ts +5 -5
  87. package/src/config/load.ts +6 -6
  88. package/src/config/minimal.ts +3 -3
  89. package/src/config/recommended.ts +3 -3
  90. package/src/config/rules.ts +6 -6
  91. package/src/config/types.ts +28 -19
  92. package/src/config/utils.ts +70 -50
  93. package/src/decorators/__tests__/filter-out.test.ts +8 -4
  94. package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
  95. package/src/decorators/common/filters/filter-helper.ts +1 -1
  96. package/src/decorators/common/info-description-override.ts +1 -1
  97. package/src/decorators/common/operation-description-override.ts +1 -1
  98. package/src/decorators/common/remove-x-internal.ts +4 -4
  99. package/src/decorators/common/tag-description-override.ts +1 -1
  100. package/src/format/codeframes.ts +4 -4
  101. package/src/format/format.ts +10 -10
  102. package/src/index.ts +2 -3
  103. package/src/js-yaml/index.ts +3 -8
  104. package/src/lint.ts +22 -18
  105. package/src/oas-types.ts +1 -6
  106. package/src/redocly/__tests__/redocly-client.test.ts +25 -19
  107. package/src/redocly/index.ts +6 -4
  108. package/src/redocly/registry-api.ts +6 -6
  109. package/src/ref-utils.ts +2 -2
  110. package/src/resolve.ts +7 -4
  111. package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
  112. package/src/rules/__tests__/utils.test.ts +122 -0
  113. package/src/rules/ajv.ts +3 -4
  114. package/src/rules/common/__tests__/info-description.test.ts +3 -3
  115. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  116. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  117. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  118. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +8 -8
  119. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  120. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
  121. package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
  122. package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
  123. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  124. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  125. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  126. package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
  127. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  128. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  129. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  130. package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
  131. package/src/rules/common/__tests__/paths-kebab-case.test.ts +15 -15
  132. package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +8 -8
  133. package/src/rules/common/__tests__/spec.test.ts +2 -2
  134. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  135. package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
  136. package/src/rules/common/assertions/__tests__/asserts.test.ts +513 -130
  137. package/src/rules/common/assertions/index.ts +6 -6
  138. package/src/rules/common/info-license-url.ts +4 -9
  139. package/src/rules/common/info-license.ts +15 -0
  140. package/src/rules/common/no-ambiguous-paths.ts +1 -1
  141. package/src/rules/common/no-enum-type-mismatch.ts +12 -9
  142. package/src/rules/common/no-invalid-parameter-examples.ts +2 -2
  143. package/src/rules/common/no-invalid-schema-examples.ts +1 -1
  144. package/src/rules/common/operation-operationId.ts +1 -1
  145. package/src/rules/common/operation-parameters-unique.ts +2 -2
  146. package/src/rules/common/path-not-include-query.ts +1 -1
  147. package/src/rules/common/path-params-defined.ts +1 -1
  148. package/src/rules/common/paths-kebab-case.ts +4 -1
  149. package/src/rules/common/scalar-property-missing-example.ts +1 -1
  150. package/src/rules/common/spec.ts +10 -7
  151. package/src/rules/no-unresolved-refs.ts +1 -1
  152. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  153. package/src/rules/oas2/__tests__/spec/info.test.ts +12 -12
  154. package/src/rules/oas2/__tests__/spec/operation.test.ts +4 -4
  155. package/src/rules/oas2/__tests__/spec/paths.test.ts +10 -10
  156. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +6 -2
  157. package/src/rules/oas2/__tests__/spec/utils.ts +6 -6
  158. package/src/rules/oas2/index.ts +3 -3
  159. package/src/rules/oas2/remove-unused-components.ts +13 -8
  160. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  161. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  162. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +8 -8
  163. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
  164. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  165. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  166. package/src/rules/oas3/__tests__/spec/callbacks.test.ts +1 -1
  167. package/src/rules/oas3/__tests__/spec/info.test.ts +12 -12
  168. package/src/rules/oas3/__tests__/spec/operation.test.ts +8 -8
  169. package/src/rules/oas3/__tests__/spec/paths.test.ts +10 -10
  170. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +12 -12
  171. package/src/rules/oas3/__tests__/spec/servers.test.ts +15 -15
  172. package/src/rules/oas3/__tests__/spec/spec.test.ts +6 -6
  173. package/src/rules/oas3/__tests__/spec/utils.ts +6 -6
  174. package/src/rules/oas3/index.ts +3 -3
  175. package/src/rules/oas3/no-empty-servers.ts +1 -1
  176. package/src/rules/oas3/no-invalid-media-type-examples.ts +12 -4
  177. package/src/rules/oas3/no-servers-empty-enum.ts +9 -10
  178. package/src/rules/oas3/remove-unused-components.ts +18 -7
  179. package/src/rules/other/stats.ts +46 -17
  180. package/src/rules/utils.ts +5 -3
  181. package/src/types/index.ts +5 -5
  182. package/src/types/redocly-yaml.ts +8 -7
  183. package/src/typings/common.ts +9 -1
  184. package/src/typings/openapi.ts +1 -1
  185. package/src/visitors.ts +4 -4
  186. package/tsconfig.tsbuildinfo +1 -1
  187. package/lib/rules/common/license-url.d.ts +0 -2
  188. package/lib/rules/common/license-url.js +0 -12
  189. package/src/rules/common/license-url.ts +0 -10
@@ -25,14 +25,26 @@ function parsePresetName(presetName) {
25
25
  }
26
26
  }
27
27
  exports.parsePresetName = parsePresetName;
28
- function transformApiDefinitionsToApis(apiDefinitions = {}) {
29
- let apis = {};
28
+ function transformApiDefinitionsToApis(apiDefinitions) {
29
+ if (!apiDefinitions)
30
+ return undefined;
31
+ const apis = {};
30
32
  for (const [apiName, apiPath] of Object.entries(apiDefinitions)) {
31
33
  apis[apiName] = { root: apiPath };
32
34
  }
33
35
  return apis;
34
36
  }
35
37
  exports.transformApiDefinitionsToApis = transformApiDefinitionsToApis;
38
+ function transformApis(legacyApis) {
39
+ if (!legacyApis)
40
+ return undefined;
41
+ const apis = {};
42
+ for (let _a of Object.entries(legacyApis)) {
43
+ const [apiName, _b] = _a, { lint } = _b, apiContent = __rest(_b, ["lint"]);
44
+ apis[apiName] = Object.assign({ styleguide: lint }, apiContent);
45
+ }
46
+ return apis;
47
+ }
36
48
  function prefixRules(rules, prefix) {
37
49
  if (!prefix)
38
50
  return rules;
@@ -63,7 +75,7 @@ function mergeExtends(rulesConfList) {
63
75
  };
64
76
  for (let rulesConf of rulesConfList) {
65
77
  if (rulesConf.extends) {
66
- throw new Error(`\`extends\` is not supported in shared configs yet: ${JSON.stringify(rulesConf, null, 2)}.`);
78
+ throw new Error(`'extends' is not supported in shared configs yet: ${JSON.stringify(rulesConf, null, 2)}.`);
67
79
  }
68
80
  Object.assign(result.rules, rulesConf.rules);
69
81
  Object.assign(result.oas2Rules, rulesConf.oas2Rules);
@@ -93,44 +105,49 @@ function mergeExtends(rulesConfList) {
93
105
  return result;
94
106
  }
95
107
  exports.mergeExtends = mergeExtends;
96
- function getMergedConfig(config, entrypointAlias) {
108
+ function getMergedConfig(config, apiName) {
97
109
  var _a, _b, _c, _d, _e, _f;
98
110
  const extendPaths = [
99
- ...Object.values(config.apis).map((api) => { var _a; return (_a = api === null || api === void 0 ? void 0 : api.lint) === null || _a === void 0 ? void 0 : _a.extendPaths; }),
100
- (_b = (_a = config.rawConfig) === null || _a === void 0 ? void 0 : _a.lint) === null || _b === void 0 ? void 0 : _b.extendPaths,
111
+ ...Object.values(config.apis).map((api) => { var _a; return (_a = api === null || api === void 0 ? void 0 : api.styleguide) === null || _a === void 0 ? void 0 : _a.extendPaths; }),
112
+ (_b = (_a = config.rawConfig) === null || _a === void 0 ? void 0 : _a.styleguide) === null || _b === void 0 ? void 0 : _b.extendPaths,
101
113
  ]
102
114
  .flat()
103
115
  .filter(Boolean);
104
116
  const pluginPaths = [
105
- ...Object.values(config.apis).map((api) => { var _a; return (_a = api === null || api === void 0 ? void 0 : api.lint) === null || _a === void 0 ? void 0 : _a.pluginPaths; }),
106
- (_d = (_c = config.rawConfig) === null || _c === void 0 ? void 0 : _c.lint) === null || _d === void 0 ? void 0 : _d.pluginPaths,
117
+ ...Object.values(config.apis).map((api) => { var _a; return (_a = api === null || api === void 0 ? void 0 : api.styleguide) === null || _a === void 0 ? void 0 : _a.pluginPaths; }),
118
+ (_d = (_c = config.rawConfig) === null || _c === void 0 ? void 0 : _c.styleguide) === null || _d === void 0 ? void 0 : _d.pluginPaths,
107
119
  ]
108
120
  .flat()
109
121
  .filter(Boolean);
110
- return entrypointAlias
111
- ? new config_1.Config(Object.assign(Object.assign({}, config.rawConfig), { lint: Object.assign(Object.assign({}, (config.apis[entrypointAlias]
112
- ? config.apis[entrypointAlias].lint
113
- : config.rawConfig.lint)), { extendPaths,
114
- pluginPaths }), 'features.openapi': Object.assign(Object.assign({}, config['features.openapi']), (_e = config.apis[entrypointAlias]) === null || _e === void 0 ? void 0 : _e['features.openapi']), 'features.mockServer': Object.assign(Object.assign({}, config['features.mockServer']), (_f = config.apis[entrypointAlias]) === null || _f === void 0 ? void 0 : _f['features.mockServer']) }), config.configFile)
122
+ return apiName
123
+ ? new config_1.Config(Object.assign(Object.assign({}, config.rawConfig), { styleguide: Object.assign(Object.assign({}, (config.apis[apiName]
124
+ ? config.apis[apiName].styleguide
125
+ : config.rawConfig.styleguide)), { extendPaths,
126
+ pluginPaths }), 'features.openapi': Object.assign(Object.assign({}, config['features.openapi']), (_e = config.apis[apiName]) === null || _e === void 0 ? void 0 : _e['features.openapi']), 'features.mockServer': Object.assign(Object.assign({}, config['features.mockServer']), (_f = config.apis[apiName]) === null || _f === void 0 ? void 0 : _f['features.mockServer']) }), config.configFile)
115
127
  : config;
116
128
  }
117
129
  exports.getMergedConfig = getMergedConfig;
118
- function transformConfig(rawConfig) {
119
- if (rawConfig.apis && rawConfig.apiDefinitions) {
120
- throw new Error("Do not use 'apiDefinitions' field. Use 'apis' instead.\n");
130
+ function checkForDeprecatedFields(deprecatedField, updatedField, rawConfig) {
131
+ const isDeprecatedFieldInApis = rawConfig.apis &&
132
+ Object.values(rawConfig.apis).some((api) => api[deprecatedField]);
133
+ if (rawConfig[deprecatedField] && rawConfig[updatedField]) {
134
+ throw new Error(`Do not use '${deprecatedField}' field. Use '${updatedField}' instead.\n`);
121
135
  }
122
- if (rawConfig['features.openapi'] &&
123
- rawConfig.referenceDocs) {
124
- throw new Error("Do not use 'referenceDocs' field. Use 'features.openapi' instead.\n");
136
+ if (rawConfig[deprecatedField] || isDeprecatedFieldInApis) {
137
+ process.stderr.write(`The ${colorette_1.yellow(deprecatedField)} field is deprecated. Use ${colorette_1.green(updatedField)} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`);
125
138
  }
126
- const _a = rawConfig, { apiDefinitions, referenceDocs } = _a, rest = __rest(_a, ["apiDefinitions", "referenceDocs"]);
127
- if (apiDefinitions) {
128
- process.stderr.write(`The ${colorette_1.yellow('apiDefinitions')} field is deprecated. Use ${colorette_1.green('apis')} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`);
129
- }
130
- if (referenceDocs) {
131
- process.stderr.write(`The ${colorette_1.yellow('referenceDocs')} field is deprecated. Use ${colorette_1.green('features.openapi')} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`);
139
+ }
140
+ function transformConfig(rawConfig) {
141
+ const migratedFields = [
142
+ ['apiDefinitions', 'apis'],
143
+ ['referenceDocs', 'features.openapi'],
144
+ ['lint', 'styleguide'], // TODO: update docs
145
+ ];
146
+ for (const [deprecatedField, updatedField] of migratedFields) {
147
+ checkForDeprecatedFields(deprecatedField, updatedField, rawConfig);
132
148
  }
133
- return Object.assign({ 'features.openapi': referenceDocs, apis: transformApiDefinitionsToApis(apiDefinitions) }, rest);
149
+ const { apis, apiDefinitions, referenceDocs, lint } = rawConfig, rest = __rest(rawConfig, ["apis", "apiDefinitions", "referenceDocs", "lint"]);
150
+ return Object.assign({ 'features.openapi': referenceDocs, apis: transformApis(apis) || transformApiDefinitionsToApis(apiDefinitions), styleguide: lint }, rest);
134
151
  }
135
152
  exports.transformConfig = transformConfig;
136
153
  function getResolveConfig(resolve) {
@@ -51,8 +51,8 @@ const RemoveXInternal = ({ internalFlagProperty }) => {
51
51
  any: {
52
52
  enter: (node, ctx) => {
53
53
  removeInternal(node, ctx);
54
- }
55
- }
54
+ },
55
+ },
56
56
  };
57
57
  };
58
58
  exports.RemoveXInternal = RemoveXInternal;
@@ -167,7 +167,7 @@ function formatProblems(problems, opts) {
167
167
  function formatStylish(problem, locationPad, ruleIdPad) {
168
168
  const color = COLORS[problem.severity];
169
169
  if (!SEVERITY_NAMES[problem.severity]) {
170
- return 'Error not found severity. Please check your config file. Allowed values: \`warn,error,off\`';
170
+ return 'Error not found severity. Please check your config file. Allowed values: `warn,error,off`';
171
171
  }
172
172
  const severityName = color(SEVERITY_NAMES[problem.severity].toLowerCase().padEnd(7));
173
173
  const { start } = problem.location[0];
package/lib/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export { Oas2Definition } from './typings/swagger';
8
8
  export { StatsAccumulator, StatsName } from './typings/common';
9
9
  export { normalizeTypes } from './types';
10
10
  export { Stats } from './rules/other/stats';
11
- export { Config, LintConfig, RawConfig, IGNORE_FILE, Region, getMergedConfig, transformConfig, loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES, RuleSeverity } from './config';
11
+ export { Config, StyleguideConfig, RawConfig, IGNORE_FILE, Region, getMergedConfig, transformConfig, loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES, RuleSeverity, } from './config';
12
12
  export { RedoclyClient, isRedoclyRegistryURL } from './redocly';
13
13
  export { Source, BaseResolver, Document, resolveDocument, ResolveError, YamlParseError, makeDocumentFromString, } from './resolve';
14
14
  export { parseYaml, stringifyYaml } from './js-yaml';
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapTypeToComponent = exports.bundleDocument = exports.bundle = exports.lintConfig = exports.lintFromString = exports.lintDocument = exports.validate = exports.lint = exports.getTotals = exports.formatProblems = exports.getLineColLocation = exports.getAstNodeByPointer = exports.walkDocument = exports.normalizeVisitors = exports.OasVersion = exports.openAPIMajor = exports.OasMajorVersion = exports.detectOpenAPI = exports.isRef = exports.unescapePointer = exports.stringifyYaml = exports.parseYaml = exports.makeDocumentFromString = exports.YamlParseError = exports.ResolveError = exports.resolveDocument = exports.BaseResolver = exports.Source = exports.isRedoclyRegistryURL = exports.RedoclyClient = exports.CONFIG_FILE_NAMES = exports.findConfig = exports.getConfig = exports.loadConfig = exports.transformConfig = exports.getMergedConfig = exports.IGNORE_FILE = exports.LintConfig = exports.Config = exports.Stats = exports.normalizeTypes = exports.ConfigTypes = exports.Oas2Types = exports.Oas3Types = exports.Oas3_1Types = exports.doesYamlFileExist = exports.slash = exports.readFileFromUrl = void 0;
3
+ exports.mapTypeToComponent = exports.bundleDocument = exports.bundle = exports.lintConfig = exports.lintFromString = exports.lintDocument = exports.validate = exports.lint = exports.getTotals = exports.formatProblems = exports.getLineColLocation = exports.getAstNodeByPointer = exports.walkDocument = exports.normalizeVisitors = exports.OasVersion = exports.openAPIMajor = exports.OasMajorVersion = exports.detectOpenAPI = exports.isRef = exports.unescapePointer = exports.stringifyYaml = exports.parseYaml = exports.makeDocumentFromString = exports.YamlParseError = exports.ResolveError = exports.resolveDocument = exports.BaseResolver = exports.Source = exports.isRedoclyRegistryURL = exports.RedoclyClient = exports.CONFIG_FILE_NAMES = exports.findConfig = exports.getConfig = exports.loadConfig = exports.transformConfig = exports.getMergedConfig = exports.IGNORE_FILE = exports.StyleguideConfig = exports.Config = exports.Stats = exports.normalizeTypes = exports.ConfigTypes = exports.Oas2Types = exports.Oas3Types = exports.Oas3_1Types = exports.doesYamlFileExist = exports.slash = exports.readFileFromUrl = void 0;
4
4
  var utils_1 = require("./utils");
5
5
  Object.defineProperty(exports, "readFileFromUrl", { enumerable: true, get: function () { return utils_1.readFileFromUrl; } });
6
6
  Object.defineProperty(exports, "slash", { enumerable: true, get: function () { return utils_1.slash; } });
@@ -19,7 +19,7 @@ var stats_1 = require("./rules/other/stats");
19
19
  Object.defineProperty(exports, "Stats", { enumerable: true, get: function () { return stats_1.Stats; } });
20
20
  var config_1 = require("./config");
21
21
  Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
22
- Object.defineProperty(exports, "LintConfig", { enumerable: true, get: function () { return config_1.LintConfig; } });
22
+ Object.defineProperty(exports, "StyleguideConfig", { enumerable: true, get: function () { return config_1.StyleguideConfig; } });
23
23
  Object.defineProperty(exports, "IGNORE_FILE", { enumerable: true, get: function () { return config_1.IGNORE_FILE; } });
24
24
  Object.defineProperty(exports, "getMergedConfig", { enumerable: true, get: function () { return config_1.getMergedConfig; } });
25
25
  Object.defineProperty(exports, "transformConfig", { enumerable: true, get: function () { return config_1.transformConfig; } });
@@ -6,12 +6,7 @@ exports.stringifyYaml = exports.parseYaml = void 0;
6
6
  const js_yaml_1 = require("js-yaml");
7
7
  const DEFAULT_SCHEMA_WITHOUT_TIMESTAMP = js_yaml_1.JSON_SCHEMA.extend({
8
8
  implicit: [js_yaml_1.types.merge],
9
- explicit: [
10
- js_yaml_1.types.binary,
11
- js_yaml_1.types.omap,
12
- js_yaml_1.types.pairs,
13
- js_yaml_1.types.set,
14
- ],
9
+ explicit: [js_yaml_1.types.binary, js_yaml_1.types.omap, js_yaml_1.types.pairs, js_yaml_1.types.set],
15
10
  });
16
11
  const parseYaml = (str, opts) => js_yaml_1.load(str, Object.assign({ schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP }, opts));
17
12
  exports.parseYaml = parseYaml;
package/lib/lint.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BaseResolver, Document } from './resolve';
2
2
  import { NodeType } from './types';
3
3
  import { ProblemSeverity } from './walk';
4
- import { LintConfig, Config } from './config';
4
+ import { StyleguideConfig, Config } from './config';
5
5
  export declare function lint(opts: {
6
6
  ref: string;
7
7
  config: Config;
@@ -15,7 +15,7 @@ export declare function lintFromString(opts: {
15
15
  }): Promise<import("./walk").NormalizedProblem[]>;
16
16
  export declare function lintDocument(opts: {
17
17
  document: Document;
18
- config: LintConfig;
18
+ config: StyleguideConfig;
19
19
  customTypes?: Record<string, NodeType>;
20
20
  externalRefResolver: BaseResolver;
21
21
  }): Promise<import("./walk").NormalizedProblem[]>;
package/lib/lint.js CHANGED
@@ -26,7 +26,7 @@ function lint(opts) {
26
26
  return __awaiter(this, void 0, void 0, function* () {
27
27
  const { ref, externalRefResolver = new resolve_1.BaseResolver(opts.config.resolve) } = opts;
28
28
  const document = (yield externalRefResolver.resolveDocument(null, ref, true));
29
- return lintDocument(Object.assign(Object.assign({ document }, opts), { externalRefResolver, config: opts.config.lint }));
29
+ return lintDocument(Object.assign(Object.assign({ document }, opts), { externalRefResolver, config: opts.config.styleguide }));
30
30
  });
31
31
  }
32
32
  exports.lint = lint;
@@ -34,7 +34,7 @@ function lintFromString(opts) {
34
34
  return __awaiter(this, void 0, void 0, function* () {
35
35
  const { source, absoluteRef, externalRefResolver = new resolve_1.BaseResolver(opts.config.resolve) } = opts;
36
36
  const document = resolve_1.makeDocumentFromString(source, absoluteRef || '/');
37
- return lintDocument(Object.assign(Object.assign({ document }, opts), { externalRefResolver, config: opts.config.lint }));
37
+ return lintDocument(Object.assign(Object.assign({ document }, opts), { externalRefResolver, config: opts.config.styleguide }));
38
38
  });
39
39
  }
40
40
  exports.lintFromString = lintFromString;
@@ -45,7 +45,11 @@ function lintDocument(opts) {
45
45
  const oasVersion = oas_types_1.detectOpenAPI(document.parsed);
46
46
  const oasMajorVersion = oas_types_1.openAPIMajor(oasVersion);
47
47
  const rules = config.getRulesForOasVersion(oasMajorVersion);
48
- const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === oas_types_1.OasMajorVersion.Version3) ? (oasVersion === oas_types_1.OasVersion.Version3_1 ? oas3_1_1.Oas3_1Types : oas3_1.Oas3Types) : oas2_1.Oas2Types, oasVersion), config);
48
+ const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === oas_types_1.OasMajorVersion.Version3)
49
+ ? oasVersion === oas_types_1.OasVersion.Version3_1
50
+ ? oas3_1_1.Oas3_1Types
51
+ : oas3_1.Oas3Types
52
+ : oas2_1.Oas2Types, oasVersion), config);
49
53
  const ctx = {
50
54
  problems: [],
51
55
  oasVersion: oasVersion,
@@ -57,7 +61,7 @@ function lintDocument(opts) {
57
61
  const resolvedRefMap = yield resolve_1.resolveDocument({
58
62
  rootDocument: document,
59
63
  rootType: types.DefinitionRoot,
60
- externalRefResolver
64
+ externalRefResolver,
61
65
  });
62
66
  walk_1.walkDocument({
63
67
  document,
@@ -79,12 +83,18 @@ function lintConfig(opts) {
79
83
  visitorsData: {},
80
84
  };
81
85
  const plugins = config_1.resolvePlugins([config_1.defaultPlugin]);
82
- const config = new config_1.LintConfig({
86
+ const config = new config_1.StyleguideConfig({
83
87
  plugins,
84
88
  rules: { spec: 'error' },
85
89
  });
86
90
  const types = types_1.normalizeTypes(redocly_yaml_1.ConfigTypes, config);
87
- const rules = [{ severity: severity || 'error', ruleId: 'configuration spec', visitor: spec_1.OasSpec({ severity: 'error' }) }];
91
+ const rules = [
92
+ {
93
+ severity: severity || 'error',
94
+ ruleId: 'configuration spec',
95
+ visitor: spec_1.OasSpec({ severity: 'error' }),
96
+ },
97
+ ];
88
98
  const normalizedVisitors = visitors_1.normalizeVisitors(rules, types);
89
99
  walk_1.walkDocument({
90
100
  document,
@@ -13,5 +13,5 @@ export declare class RegistryApi {
13
13
  organizations: string[];
14
14
  }>;
15
15
  prepareFileUpload({ organizationId, name, version, filesHash, filename, isUpsert, }: RegistryApiTypes.PrepareFileuploadParams): Promise<RegistryApiTypes.PrepareFileuploadOKResponse>;
16
- pushApi({ organizationId, name, version, rootFilePath, filePaths, branch, isUpsert, isPublic, batchId, batchSize }: RegistryApiTypes.PushApiParams): Promise<void>;
16
+ pushApi({ organizationId, name, version, rootFilePath, filePaths, branch, isUpsert, isPublic, batchId, batchSize, }: RegistryApiTypes.PushApiParams): Promise<void>;
17
17
  }
@@ -80,7 +80,7 @@ class RegistryApi {
80
80
  throw new Error('Could not prepare file upload');
81
81
  });
82
82
  }
83
- pushApi({ organizationId, name, version, rootFilePath, filePaths, branch, isUpsert, isPublic, batchId, batchSize }) {
83
+ pushApi({ organizationId, name, version, rootFilePath, filePaths, branch, isUpsert, isPublic, batchId, batchSize, }) {
84
84
  return __awaiter(this, void 0, void 0, function* () {
85
85
  const response = yield this.request(`/${organizationId}/${name}/${version}`, {
86
86
  method: 'PUT',
@@ -95,7 +95,7 @@ class RegistryApi {
95
95
  isUpsert,
96
96
  isPublic,
97
97
  batchId,
98
- batchSize
98
+ batchSize,
99
99
  }),
100
100
  }, this.region);
101
101
  if (response.ok) {
@@ -1,2 +1,2 @@
1
1
  import { Oas3Rule, Oas2Rule } from '../../visitors';
2
- export declare const InfoLicense: Oas3Rule | Oas2Rule;
2
+ export declare const InfoLicenseUrl: Oas3Rule | Oas2Rule;
@@ -1,17 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InfoLicense = void 0;
3
+ exports.InfoLicenseUrl = void 0;
4
4
  const utils_1 = require("../utils");
5
- const InfoLicense = () => {
5
+ const InfoLicenseUrl = () => {
6
6
  return {
7
- Info(info, { report }) {
8
- if (!info.license) {
9
- report({
10
- message: utils_1.missingRequiredField('Info', 'license'),
11
- location: { reportOnKey: true }
12
- });
13
- }
7
+ License(license, ctx) {
8
+ utils_1.validateDefinedAndNonEmpty('url', license, ctx);
14
9
  },
15
10
  };
16
11
  };
17
- exports.InfoLicense = InfoLicense;
12
+ exports.InfoLicenseUrl = InfoLicenseUrl;
@@ -0,0 +1,2 @@
1
+ import { Oas3Rule, Oas2Rule } from '../../visitors';
2
+ export declare const InfoLicense: Oas3Rule | Oas2Rule;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InfoLicense = void 0;
4
+ const utils_1 = require("../utils");
5
+ const InfoLicense = () => {
6
+ return {
7
+ Info(info, { report }) {
8
+ if (!info.license) {
9
+ report({
10
+ message: utils_1.missingRequiredField('Info', 'license'),
11
+ location: { reportOnKey: true },
12
+ });
13
+ }
14
+ },
15
+ };
16
+ };
17
+ exports.InfoLicense = InfoLicense;
@@ -28,14 +28,12 @@ const NoEnumTypeMismatch = () => {
28
28
  if (mismatchedResults[enumValue].length !== schema.type.length)
29
29
  delete mismatchedResults[enumValue];
30
30
  }
31
- ;
32
31
  for (const mismatchedKey of Object.keys(mismatchedResults)) {
33
32
  report({
34
- message: `Enum value \`${mismatchedKey}\` must be of one type. Allowed types: \`${schema.type}\`.`,
33
+ message: `Enum value \`${mismatchedKey}\` must be of allowed types: \`${schema.type}\`.`,
35
34
  location: location.child(['enum', schema.enum.indexOf(mismatchedKey)]),
36
35
  });
37
36
  }
38
- ;
39
37
  }
40
38
  },
41
39
  };
@@ -10,7 +10,7 @@ const OperationOperationId = () => {
10
10
  utils_1.validateDefinedAndNonEmpty('operationId', operation, ctx);
11
11
  },
12
12
  },
13
- }
13
+ },
14
14
  };
15
15
  };
16
16
  exports.OperationOperationId = OperationOperationId;
@@ -12,7 +12,7 @@ const PathNotIncludeQuery = () => {
12
12
  });
13
13
  }
14
14
  },
15
- }
15
+ },
16
16
  };
17
17
  };
18
18
  exports.PathNotIncludeQuery = PathNotIncludeQuery;
@@ -4,7 +4,10 @@ exports.PathsKebabCase = void 0;
4
4
  const PathsKebabCase = () => {
5
5
  return {
6
6
  PathItem(_path, { report, key }) {
7
- const segments = key.substr(1).split('/').filter(s => s !== ''); // filter out empty segments
7
+ const segments = key
8
+ .substr(1)
9
+ .split('/')
10
+ .filter((s) => s !== ''); // filter out empty segments
8
11
  if (!segments.every((segment) => /^{.+}$/.test(segment) || /^[a-z0-9-.]+$/.test(segment))) {
9
12
  report({
10
13
  message: `\`${key}\` does not use kebab-case.`,
@@ -45,7 +45,7 @@ const OasSpec = () => {
45
45
  }
46
46
  report({
47
47
  message: `The field \`${propName}\` is not allowed here.`,
48
- location: location.child([propName]).key()
48
+ location: location.child([propName]).key(),
49
49
  });
50
50
  }
51
51
  }
@@ -6,8 +6,8 @@ const no_invalid_schema_examples_1 = require("../common/no-invalid-schema-exampl
6
6
  const no_invalid_parameter_examples_1 = require("../common/no-invalid-parameter-examples");
7
7
  const info_description_1 = require("../common/info-description");
8
8
  const info_contact_1 = require("../common/info-contact");
9
+ const info_license_1 = require("../common/info-license");
9
10
  const info_license_url_1 = require("../common/info-license-url");
10
- const license_url_1 = require("../common/license-url");
11
11
  const boolean_parameter_prefixes_1 = require("./boolean-parameter-prefixes");
12
12
  const tag_description_1 = require("../common/tag-description");
13
13
  const tags_alphabetical_1 = require("../common/tags-alphabetical");
@@ -48,8 +48,8 @@ exports.rules = {
48
48
  'no-invalid-parameter-examples': no_invalid_parameter_examples_1.NoInvalidParameterExamples,
49
49
  'info-description': info_description_1.InfoDescription,
50
50
  'info-contact': info_contact_1.InfoContact,
51
- 'info-license': info_license_url_1.InfoLicense,
52
- 'info-license-url': license_url_1.InfoLicenseUrl,
51
+ 'info-license': info_license_1.InfoLicense,
52
+ 'info-license-url': info_license_url_1.InfoLicenseUrl,
53
53
  'tag-description': tag_description_1.TagDescription,
54
54
  'tags-alphabetical': tags_alphabetical_1.TagsAlphabetical,
55
55
  'paths-kebab-case': paths_kebab_case_1.PathsKebabCase,
@@ -58,7 +58,7 @@ exports.rules = {
58
58
  'no-path-trailing-slash': no_path_trailing_slash_1.NoPathTrailingSlash,
59
59
  'operation-2xx-response': operation_2xx_response_1.Operation2xxResponse,
60
60
  'operation-4xx-response': operation_4xx_response_1.Operation4xxResponse,
61
- 'assertions': assertions_1.Assertions,
61
+ assertions: assertions_1.Assertions,
62
62
  'operation-operationId-unique': operation_operationId_unique_1.OperationIdUnique,
63
63
  'operation-parameters-unique': operation_parameters_unique_1.OperationParametersUnique,
64
64
  'path-parameters-defined': path_params_defined_1.PathParamsDefined,
@@ -24,14 +24,14 @@ const RemoveUnusedComponents = () => {
24
24
  name: key.toString(),
25
25
  });
26
26
  }
27
- }
27
+ },
28
28
  },
29
29
  DefinitionRoot: {
30
30
  leave(root, ctx) {
31
31
  const data = ctx.getVisitorData();
32
32
  data.removedCount = 0;
33
33
  let rootComponents = new Set();
34
- components.forEach(usageInfo => {
34
+ components.forEach((usageInfo) => {
35
35
  const { used, name, componentType } = usageInfo;
36
36
  if (!used && componentType) {
37
37
  rootComponents.add(componentType);
@@ -67,7 +67,7 @@ const RemoveUnusedComponents = () => {
67
67
  SecurityScheme(_securityScheme, { location, key }) {
68
68
  registerComponent(location, 'securityDefinitions', key.toString());
69
69
  },
70
- }
70
+ },
71
71
  };
72
72
  };
73
73
  exports.RemoveUnusedComponents = RemoveUnusedComponents;
@@ -20,13 +20,13 @@ const no_server_trailing_slash_1 = require("./no-server-trailing-slash");
20
20
  const info_description_1 = require("../common/info-description");
21
21
  const tag_description_1 = require("../common/tag-description");
22
22
  const info_contact_1 = require("../common/info-contact");
23
+ const info_license_1 = require("../common/info-license");
23
24
  const info_license_url_1 = require("../common/info-license-url");
24
25
  const operation_description_1 = require("../common/operation-description");
25
26
  const no_unused_components_1 = require("./no-unused-components");
26
27
  const path_not_include_query_1 = require("../common/path-not-include-query");
27
28
  const parameter_description_1 = require("../common/parameter-description");
28
29
  const operation_singular_tag_1 = require("../common/operation-singular-tag");
29
- const license_url_1 = require("../common/license-url");
30
30
  const operation_security_defined_1 = require("../common/operation-security-defined");
31
31
  const no_unresolved_refs_1 = require("../no-unresolved-refs");
32
32
  const boolean_parameter_prefixes_1 = require("./boolean-parameter-prefixes");
@@ -54,11 +54,11 @@ exports.rules = {
54
54
  spec: spec_1.OasSpec,
55
55
  'info-description': info_description_1.InfoDescription,
56
56
  'info-contact': info_contact_1.InfoContact,
57
- 'info-license': info_license_url_1.InfoLicense,
58
- 'info-license-url': license_url_1.InfoLicenseUrl,
57
+ 'info-license': info_license_1.InfoLicense,
58
+ 'info-license-url': info_license_url_1.InfoLicenseUrl,
59
59
  'operation-2xx-response': operation_2xx_response_1.Operation2xxResponse,
60
60
  'operation-4xx-response': operation_4xx_response_1.Operation4xxResponse,
61
- 'assertions': assertions_1.Assertions,
61
+ assertions: assertions_1.Assertions,
62
62
  'operation-operationId-unique': operation_operationId_unique_1.OperationIdUnique,
63
63
  'operation-parameters-unique': operation_parameters_unique_1.OperationParametersUnique,
64
64
  'path-parameters-defined': path_params_defined_1.PathParamsDefined,
@@ -7,7 +7,7 @@ const NoEmptyServers = () => {
7
7
  if (!root.hasOwnProperty('servers')) {
8
8
  report({
9
9
  message: 'Servers must be present.',
10
- location: location.child(['openapi']).key()
10
+ location: location.child(['openapi']).key(),
11
11
  });
12
12
  return;
13
13
  }
@@ -24,13 +24,13 @@ const RemoveUnusedComponents = () => {
24
24
  name: key.toString(),
25
25
  });
26
26
  }
27
- }
27
+ },
28
28
  },
29
29
  DefinitionRoot: {
30
30
  leave(root, ctx) {
31
31
  const data = ctx.getVisitorData();
32
32
  data.removedCount = 0;
33
- components.forEach(usageInfo => {
33
+ components.forEach((usageInfo) => {
34
34
  const { used, componentType, name } = usageInfo;
35
35
  if (!used && componentType) {
36
36
  let componentChild = root.components[componentType];
@@ -3,10 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Stats = void 0;
4
4
  const Stats = (statsAccumulator) => {
5
5
  return {
6
- ExternalDocs: { leave() { statsAccumulator.externalDocs.total++; } },
7
- ref: { enter(ref) { statsAccumulator.refs.items.add(ref['$ref']); } },
8
- Tag: { leave(tag) { statsAccumulator.tags.items.add(tag.name); } },
9
- Link: { leave(link) { statsAccumulator.links.items.add(link.operationId); } },
6
+ ExternalDocs: {
7
+ leave() {
8
+ statsAccumulator.externalDocs.total++;
9
+ },
10
+ },
11
+ ref: {
12
+ enter(ref) {
13
+ statsAccumulator.refs.items.add(ref['$ref']);
14
+ },
15
+ },
16
+ Tag: {
17
+ leave(tag) {
18
+ statsAccumulator.tags.items.add(tag.name);
19
+ },
20
+ },
21
+ Link: {
22
+ leave(link) {
23
+ statsAccumulator.links.items.add(link.operationId);
24
+ },
25
+ },
10
26
  DefinitionRoot: {
11
27
  leave() {
12
28
  statsAccumulator.parameters.total = statsAccumulator.parameters.items.size;
@@ -18,27 +34,40 @@ const Stats = (statsAccumulator) => {
18
34
  WebhooksMap: {
19
35
  Operation: {
20
36
  leave(operation) {
21
- operation.tags.forEach((tag) => { statsAccumulator.tags.items.add(tag); });
22
- }
23
- }
37
+ operation.tags.forEach((tag) => {
38
+ statsAccumulator.tags.items.add(tag);
39
+ });
40
+ },
41
+ },
24
42
  },
25
43
  PathMap: {
26
44
  PathItem: {
27
- leave() { statsAccumulator.pathItems.total++; },
45
+ leave() {
46
+ statsAccumulator.pathItems.total++;
47
+ },
28
48
  Operation: {
29
49
  leave(operation) {
30
50
  statsAccumulator.operations.total++;
31
- operation.tags && operation.tags.forEach((tag) => { statsAccumulator.tags.items.add(tag); });
32
- }
51
+ operation.tags &&
52
+ operation.tags.forEach((tag) => {
53
+ statsAccumulator.tags.items.add(tag);
54
+ });
55
+ },
33
56
  },
34
- Parameter: { leave(parameter) {
57
+ Parameter: {
58
+ leave(parameter) {
35
59
  statsAccumulator.parameters.items.add(parameter.name);
36
- } },
60
+ },
61
+ },
37
62
  },
38
63
  },
39
64
  NamedSchemas: {
40
- Schema: { leave() { statsAccumulator.schemas.total++; } }
41
- }
65
+ Schema: {
66
+ leave() {
67
+ statsAccumulator.schemas.total++;
68
+ },
69
+ },
70
+ },
42
71
  };
43
72
  };
44
73
  exports.Stats = Stats;
@@ -1,7 +1,7 @@
1
1
  import { UserContext } from '../walk';
2
2
  import { Location } from '../ref-utils';
3
3
  import { Oas3Schema, Referenced } from '../typings/openapi';
4
- export declare function oasTypeOf(value: unknown): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "array" | "null";
4
+ export declare function oasTypeOf(value: unknown): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "integer" | "array" | "null";
5
5
  /**
6
6
  * Checks if value matches specified JSON schema type
7
7
  *
@@ -11,6 +11,9 @@ function oasTypeOf(value) {
11
11
  else if (value === null) {
12
12
  return 'null';
13
13
  }
14
+ else if (Number.isInteger(value)) {
15
+ return 'integer';
16
+ }
14
17
  else {
15
18
  return typeof value;
16
19
  }
@@ -25,7 +28,7 @@ exports.oasTypeOf = oasTypeOf;
25
28
  */
26
29
  function matchesJsonSchemaType(value, type, nullable) {
27
30
  if (nullable && value === null) {
28
- return value === null;
31
+ return true;
29
32
  }
30
33
  switch (type) {
31
34
  case 'array':