| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- import {joinPath} from './utils/index.js';
- import {InvalidArgumentError} from '@e22m4u/js-format';
- import {OADocumentBuilder} from './oa-document-builder.js';
- import {OAOperationMethod} from './document-specification.js';
- /**
- * Document scope.
- */
- export class OADocumentScope {
- /**
- * @param {object} rootBuilder
- * @param {object} [options]
- */
- constructor(rootBuilder, options = {}) {
- if (!(rootBuilder instanceof OADocumentBuilder)) {
- throw new InvalidArgumentError(
- 'Parameter "rootBuilder" must be an instance of OADocumentBuilder, ' +
- 'but %v was given.',
- rootBuilder,
- );
- }
- if (!options || typeof options !== 'object' || Array.isArray(options)) {
- throw new InvalidArgumentError(
- 'Parameter "options" must be an Object, but %v was given.',
- options,
- );
- }
- if (options.pathPrefix !== undefined) {
- if (!options.pathPrefix || typeof options.pathPrefix !== 'string') {
- throw new InvalidArgumentError(
- 'Parameter "pathPrefix" must be a non-empty String, ' +
- 'but %v was given.',
- options.pathPrefix,
- );
- }
- }
- if (options.tags !== undefined) {
- if (!Array.isArray(options.tags)) {
- throw new InvalidArgumentError(
- 'Parameter "tags" must be an Array, ' + 'but %v was given.',
- options.tags,
- );
- }
- options.tags.forEach((tag, index) => {
- if (!tag || typeof tag !== 'string') {
- throw new InvalidArgumentError(
- 'Element "tags[%d]" must be a non-empty String, ' +
- 'but %v was given.',
- index,
- tag,
- );
- }
- });
- }
- this.rootBuilder = rootBuilder;
- this.pathPrefix = options.pathPrefix || '/';
- this.tags = options.tags || [];
- }
- /**
- * Define operation.
- *
- * @param {object} operationDef
- * @returns {this}
- */
- defineOperation(operationDef) {
- if (
- !operationDef ||
- typeof operationDef !== 'object' ||
- Array.isArray(operationDef)
- ) {
- throw new InvalidArgumentError(
- 'Operation Definition must be an Object, but %v was given.',
- operationDef,
- );
- }
- // path
- if (!operationDef.path || typeof operationDef.path !== 'string') {
- throw new InvalidArgumentError(
- 'Property "path" must be a non-empty String, but %v was given.',
- operationDef.path,
- );
- }
- if (operationDef.path[0] !== '/') {
- throw new InvalidArgumentError(
- 'Property "path" must start with forward slash "/", but %v was given.',
- operationDef.path,
- );
- }
- // method
- if (!operationDef.method || typeof operationDef.method !== 'string') {
- throw new InvalidArgumentError(
- 'Property "method" must be a non-empty String, but %v was given.',
- operationDef.method,
- );
- }
- if (!Object.values(OAOperationMethod).includes(operationDef.method)) {
- throw new InvalidArgumentError(
- 'Property "method" must be one of values: %l, but %v was given.',
- Object.values(OAOperationMethod),
- );
- }
- // operation
- if (
- !operationDef.operation ||
- typeof operationDef.operation !== 'object' ||
- Array.isArray(operationDef.operation)
- ) {
- throw new InvalidArgumentError(
- 'Property "operation" must be an Object, but %v was given.',
- operationDef.operation,
- );
- }
- // склеивание пути
- const fullPath = joinPath(this.pathPrefix, operationDef.path);
- // создание копии схемы операции
- // чтобы избежать мутацию аргумента
- const operation = structuredClone(operationDef.operation);
- // объединение тегов текущей области
- // с тегами текущей операции и удаление
- // дубликатов
- if (this.tags.length > 0) {
- operation.tags = [...this.tags, ...(operation.tags || [])];
- operation.tags = [...new Set(operation.tags)];
- }
- // регистрация операции в родительском
- // экземпляре сборщика документа
- this.rootBuilder.defineOperation({
- ...operationDef,
- path: fullPath,
- operation,
- });
- return this;
- }
- /**
- * Create scope.
- *
- * @param {object} [options]
- * @returns {OADocumentScope}
- */
- createScope(options = {}) {
- if (!options || typeof options !== 'object' || Array.isArray(options)) {
- throw new InvalidArgumentError(
- 'Parameter "options" must be an Object, but %v was given.',
- options,
- );
- }
- if (options.pathPrefix !== undefined) {
- if (!options.pathPrefix || typeof options.pathPrefix !== 'string') {
- throw new InvalidArgumentError(
- 'Parameter "pathPrefix" must be a non-empty String, ' +
- 'but %v was given.',
- options.pathPrefix,
- );
- }
- }
- if (options.tags !== undefined) {
- if (!Array.isArray(options.tags)) {
- throw new InvalidArgumentError(
- 'Parameter "tags" must be an Array, ' + 'but %v was given.',
- options.tags,
- );
- }
- options.tags.forEach((tag, index) => {
- if (!tag || typeof tag !== 'string') {
- throw new InvalidArgumentError(
- 'Element "tags[%d]" must be a non-empty String, ' +
- 'but %v was given.',
- index,
- tag,
- );
- }
- });
- }
- return new OADocumentScope(this.rootBuilder, {
- pathPrefix: joinPath(this.pathPrefix, options.pathPrefix),
- tags: [...this.tags, ...(options.tags || [])],
- });
- }
- /**
- * Build.
- *
- * @returns {object}
- */
- build() {
- return this.rootBuilder.build();
- }
- }
|