UNPKG

@opra/common

Version:
123 lines (122 loc) 4.54 kB
import nodePath from 'node:path'; import { omitUndefined } from '@jsopen/objects'; import { asMutable } from 'ts-gems'; import { cloneObject } from '../../helpers/index.js'; import { OpraSchema } from '../../schema/index.js'; import { DataTypeMap } from '../common/data-type-map.js'; import { DocumentElement } from '../common/document-element.js'; import { CLASS_NAME_PATTERN, DECORATOR, kDataTypeMap } from '../constants.js'; import { HttpOperationDecoratorFactory, } from '../decorators/http-operation.decorator.js'; /** * HttpOperation */ export const HttpOperation = function (...args) { // Decorator if (!this) { const [options] = args; const decoratorChain = []; return HttpOperation[DECORATOR].call(undefined, decoratorChain, options); } // Constructor const [resource, initArgs] = args; DocumentElement.call(this, resource); if (!CLASS_NAME_PATTERN.test(initArgs.name)) throw new TypeError(`Invalid operation name (${initArgs.name})`); const _this = asMutable(this); _this.parameters = []; _this.responses = []; _this.types = _this.node[kDataTypeMap] = new DataTypeMap(); _this.name = initArgs.name; _this.path = initArgs.path; _this.mergePath = initArgs.mergePath; _this.method = initArgs.method || 'GET'; _this.description = initArgs.description; _this.composition = initArgs.composition; _this.compositionOptions = initArgs.compositionOptions ? cloneObject(initArgs.compositionOptions) : undefined; }; /** * @class HttpOperation */ class HttpOperationClass extends DocumentElement { findParameter(paramName, location) { const paramNameLower = paramName.toLowerCase(); let prm; for (prm of this.parameters) { if (location && location !== prm.location) continue; if (typeof prm.name === 'string') { prm._nameLower = prm._nameLower || prm.name.toLowerCase(); if (prm._nameLower === paramNameLower) return prm; } if (prm.name instanceof RegExp && prm.name.test(paramName)) return prm; } } getFullUrl() { const out = this.owner.getFullUrl(); if (out) { if (this.path) { if (this.mergePath) return out + this.path; return nodePath.posix.join(out, this.path); } return out; } return this.path || '/'; } toJSON(options) { const out = omitUndefined({ kind: OpraSchema.HttpOperation.Kind, description: this.description, method: this.method, path: this.path, mergePath: this.mergePath, composition: this.composition, requestBody: this.requestBody?.toJSON(options), }); if (this.types.size) { out.types = {}; for (const v of this.types.values()) { out.types[v.name] = v.toJSON(options); } } if (this.parameters.length) { out.parameters = []; for (const prm of this.parameters) { out.parameters.push(prm.toJSON(options)); } } if (this.responses.length) out.responses = this.responses.map(r => r.toJSON(options)); return out; } } HttpOperation.prototype = HttpOperationClass.prototype; HttpOperation[DECORATOR] = HttpOperationDecoratorFactory; HttpOperation.GET = function (options) { return HttpOperationDecoratorFactory([], { ...options, method: 'GET' }); }; HttpOperation.DELETE = function (options) { return HttpOperationDecoratorFactory([], { ...options, method: 'DELETE' }); }; HttpOperation.HEAD = function (options) { return HttpOperationDecoratorFactory([], { ...options, method: 'HEAD' }); }; HttpOperation.OPTIONS = function (options) { return HttpOperationDecoratorFactory([], { ...options, method: 'OPTIONS' }); }; HttpOperation.PATCH = function (options) { return HttpOperationDecoratorFactory([], { ...options, method: 'PATCH' }); }; HttpOperation.POST = function (options) { return HttpOperationDecoratorFactory([], { ...options, method: 'POST' }); }; HttpOperation.PUT = function (options) { return HttpOperationDecoratorFactory([], { ...options, method: 'PUT' }); }; HttpOperation.SEARCH = function (options) { return HttpOperationDecoratorFactory([], { ...options, method: 'SEARCH' }); };