@redocly/openapi-core
Version:
See https://github.com/Redocly/redocly-cli
89 lines • 3.08 kB
JavaScript
import { isTruthy } from './utils/is-truthy.js';
import { isPlainObject } from './utils/is-plain-object.js';
export function joinPointer(base, key) {
if (base === '')
base = '#/';
return base[base.length - 1] === '/' ? base + key : base + '/' + key;
}
export function isRef(node) {
return isPlainObject(node) && typeof node.$ref === 'string';
}
export function isExternalValue(node) {
return isPlainObject(node) && typeof node.externalValue === 'string';
}
export class Location {
constructor(source, pointer) {
this.source = source;
this.pointer = pointer;
}
child(components) {
return new Location(this.source, joinPointer(this.pointer, (Array.isArray(components) ? components : [components]).map(escapePointerFragment).join('/')));
}
key() {
return { ...this, reportOnKey: true };
}
get absolutePointer() {
return this.source.absoluteRef + (this.pointer === '#/' ? '' : this.pointer);
}
}
export function unescapePointerFragment(fragment) {
const unescaped = fragment.replace(/~1/g, '/').replace(/~0/g, '~');
try {
return decodeURIComponent(unescaped);
}
catch (e) {
return unescaped;
}
}
export function escapePointerFragment(fragment) {
if (typeof fragment === 'number')
return fragment;
return fragment.replaceAll('~', '~0').replaceAll('/', '~1');
}
export function parseRef(ref) {
const [uri, pointer = ''] = ref.split('#/');
return {
uri: (uri.endsWith('#') ? uri.slice(0, -1) : uri) || null,
pointer: parsePointer(pointer),
};
}
export function parsePointer(pointer) {
return pointer.split('/').map(unescapePointerFragment).filter(isTruthy);
}
export function pointerBaseName(pointer) {
const parts = pointer.split('/');
return parts[parts.length - 1];
}
export function refBaseName(ref) {
// eslint-disable-next-line no-useless-escape
const parts = ref.split(/[\/\\]/); // split by '\' and '/'
return parts[parts.length - 1].replace(/\.[^.]+$/, ''); // replace extension with empty string
}
export function isAbsoluteUrl(ref) {
return ref.startsWith('http://') || ref.startsWith('https://');
}
export function isMappingRef(mapping) {
// TODO: proper detection of mapping refs
return (mapping.startsWith('#') ||
mapping.startsWith('https://') ||
mapping.startsWith('http://') ||
mapping.startsWith('./') ||
mapping.startsWith('../') ||
mapping.indexOf('/') > -1);
}
export function isAnchor(ref) {
return /^#[A-Za-z][A-Za-z0-9\-_:.]*$/.test(ref);
}
export function replaceRef(ref, resolved, ctx) {
if (!isPlainObject(resolved.node)) {
ctx.parent[ctx.key] = resolved.node;
}
else {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
delete ref.$ref;
const obj = Object.assign({}, resolved.node, ref);
Object.assign(ref, obj); // assign ref itself again so ref fields take precedence
}
}
//# sourceMappingURL=ref-utils.js.map