UNPKG

oas-normalize

Version:

Tooling for converting, validating, and parsing OpenAPI, Swagger, and Postman API definitions

250 lines (233 loc) 9.37 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _chunkAKXTCPGMcjs = require('./chunk-AKXTCPGM.cjs'); var _chunkHIUYACR6cjs = require('./chunk-HIUYACR6.cjs'); // src/index.ts var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _openapiparser = require('@readme/openapi-parser'); var _postmantoopenapi = require('@readme/postman-to-openapi'); var _postmantoopenapi2 = _interopRequireDefault(_postmantoopenapi); var _swagger2openapi = require('swagger2openapi'); var _swagger2openapi2 = _interopRequireDefault(_swagger2openapi); var OASNormalize = class _OASNormalize { // biome-ignore lint/suspicious/noExplicitAny: Intentionally loose because this library supports a wide variety of inputs. // biome-ignore lint/suspicious/noExplicitAny: Intentionally loose because this library supports a wide variety of inputs. constructor(file, opts) { this.file = file; this.opts = { colorizeErrors: false, enablePaths: false, parser: {}, ...opts }; if (!this.opts.enablePaths) { if (!this.opts.parser) this.opts.parser = {}; if (!this.opts.parser.resolve) this.opts.parser.resolve = {}; this.opts.parser.resolve = { file: false }; } this.type = _chunkHIUYACR6cjs.getType.call(void 0, this.file); this.cache = { load: false, bundle: false, deref: false }; } /** * Load and return the API definition that `oas-normalize` was initialized with. * */ async load() { if (this.cache.load) return this.cache.load; const resolve = (obj) => { const ret = _chunkHIUYACR6cjs.stringToJSON.call(void 0, obj); this.cache.load = ret; return ret; }; switch (this.type) { case "json": case "string-json": case "string-yaml": return resolve(this.file); case "buffer": return resolve(this.file.toString()); case "url": { const { url, options } = _chunkHIUYACR6cjs.prepareURL.call(void 0, this.file); const resp = await fetch(url, options).then((res) => res.text()); return resolve(resp); } case "path": { if (!this.opts.enablePaths) { throw new Error("Use `opts.enablePaths` to enable accessing local files."); } const contents = _fs2.default.readFileSync(this.file).toString(); if (!contents.trim()) { throw new Error("No file contents found."); } return resolve(contents); } default: throw new Error("Could not load this file."); } } static async convertPostmanToOpenAPI(schema) { return _postmantoopenapi2.default.call(void 0, JSON.stringify(schema), void 0, { outputFormat: "json", replaceVars: true }).then(JSON.parse); } /** * Bundle up the given API definition, resolving any external `$ref` pointers in the process. * */ async bundle() { if (this.cache.bundle) return this.cache.bundle; const parserOptions = this.opts.parser || {}; return this.load().then((schema) => { if (_chunkHIUYACR6cjs.isPostman.call(void 0, schema)) { return _OASNormalize.convertPostmanToOpenAPI(schema); } return schema; }).then((schema) => _openapiparser.bundle.call(void 0, schema, parserOptions)).then((bundled) => { this.cache.bundle = bundled; return bundled; }); } /** * Dereference the given API definition. * */ async dereference() { if (this.cache.deref) return this.cache.deref; const parserOptions = this.opts.parser || {}; return this.load().then((schema) => { if (_chunkHIUYACR6cjs.isPostman.call(void 0, schema)) { return _OASNormalize.convertPostmanToOpenAPI(schema); } return schema; }).then((schema) => _openapiparser.dereference.call(void 0, schema, parserOptions)).then((dereferenced) => { this.cache.deref = dereferenced; return dereferenced; }); } /** * Dereference the given API definition. * * This method is deprecated in favor of `dereference`. It will be removed in a future release. * * @deprecated */ async deref() { return this.dereference(); } /** * Convert a given API definition to OpenAPI if it is not already. * */ async convert() { if (this.cache.convert) return this.cache.convert; return this.load().then(async (schema) => { return _chunkHIUYACR6cjs.isPostman.call(void 0, schema) ? _OASNormalize.convertPostmanToOpenAPI(schema) : schema; }).then(async (schema) => { if (!_chunkHIUYACR6cjs.isSwagger.call(void 0, schema) && !_chunkHIUYACR6cjs.isOpenAPI.call(void 0, schema)) { throw new Error("The supplied API definition is unsupported."); } else if (_chunkHIUYACR6cjs.isOpenAPI.call(void 0, schema)) { return schema; } const baseVersion = parseInt(schema.swagger, 10); if (baseVersion === 1) { throw new Error("Swagger v1.2 is unsupported."); } return _swagger2openapi2.default.convertObj(schema, { anchors: true }).then((options) => options.openapi); }); } /** * Validate a given API definition. * * If supplied a Postman collection it will be converted to OpenAPI first and then run through * standard OpenAPI validation. * */ async validate(opts = {}) { const shouldThrowIfInvalid = _nullishCoalesce(opts.shouldThrowIfInvalid, () => ( true)); const parserOptions = opts.parser || this.opts.parser || {}; if (!parserOptions.validate) parserOptions.validate = {}; if (!parserOptions.validate.errors) parserOptions.validate.errors = {}; parserOptions.validate.errors.colorize = this.opts.colorizeErrors; return this.load().then(async (schema) => { return _chunkHIUYACR6cjs.isPostman.call(void 0, schema) ? _OASNormalize.convertPostmanToOpenAPI(schema) : schema; }).then(async (schema) => { if (!_chunkHIUYACR6cjs.isSwagger.call(void 0, schema) && !_chunkHIUYACR6cjs.isOpenAPI.call(void 0, schema)) { if (shouldThrowIfInvalid) { throw new (0, _chunkAKXTCPGMcjs.ValidationError)("The supplied API definition is unsupported."); } return { valid: false, errors: [{ message: "The supplied API definition is unsupported." }], warnings: [], additionalErrors: 0, specification: null }; } else if (_chunkHIUYACR6cjs.isSwagger.call(void 0, schema)) { const baseVersion = parseInt(schema.swagger, 10); if (baseVersion === 1) { if (shouldThrowIfInvalid) { throw new (0, _chunkAKXTCPGMcjs.ValidationError)("Swagger v1.2 is unsupported."); } return { valid: false, errors: [{ message: "Swagger v1.2 is unsupported." }], warnings: [], additionalErrors: 0, specification: "Swagger" }; } } const clonedSchema = JSON.parse(JSON.stringify(schema)); const result = await _openapiparser.validate.call(void 0, clonedSchema, parserOptions); if (!result.valid && shouldThrowIfInvalid) { throw new (0, _chunkAKXTCPGMcjs.ValidationError)(_openapiparser.compileErrors.call(void 0, result), { errors: result.errors, warnings: result.warnings }); } return result; }); } /** * Retrieve OpenAPI, Swagger, or Postman version information about the supplied API definition. * */ async version() { return this.load().then((schema) => { switch (_chunkHIUYACR6cjs.getAPIDefinitionType.call(void 0, schema)) { case "openapi": return { specification: "openapi", version: schema.openapi }; case "postman": { let version = "unknown"; if (_optionalChain([schema, 'optionalAccess', _ => _.info, 'optionalAccess', _2 => _2.schema])) { const match = (_optionalChain([schema, 'optionalAccess', _3 => _3.info])).schema.match( /http(s?):\/\/schema.getpostman.com\/json\/collection\/v([0-9.]+)\// ); if (match) { version = match[2]; } } return { specification: "postman", version }; } case "swagger": return { specification: "swagger", version: schema.swagger }; default: throw new Error("Unknown file detected."); } }); } }; exports.default = OASNormalize; module.exports = exports.default; //# sourceMappingURL=index.cjs.map