UNPKG

@opra/common

Version:
123 lines (122 loc) 4.65 kB
import { omitUndefined } from '@jsopen/objects'; import { asMutable } from 'ts-gems'; import { DocumentElement } from '../common/document-element.js'; import { DECORATOR } from '../constants.js'; import { ApiFieldDecoratorFactory } from '../decorators/api-field-decorator.js'; import { testScopeMatch } from '../utils/test-scope-match.js'; import { ComplexTypeBase } from './complex-type-base.js'; /** * @decorator ApiField */ export const ApiField = function (...args) { // Decorator if (!this) { const [options] = args; return ApiField[DECORATOR](options); } // Constructor const [owner, initArgs] = args; DocumentElement.call(this, owner); const _this = asMutable(this); _this.name = initArgs.name; const origin = initArgs.origin || owner; /* istanbul ignore next */ if (!(origin instanceof ComplexTypeBase)) { throw new Error('Field origin should be one of ComplexType, MappedType or MixinType'); } _this.origin = origin; _this.type = initArgs.type || owner.node.getDataType('any'); _this.description = initArgs.description; _this.isArray = initArgs.isArray; _this.isNestedEntity = initArgs.isNestedEntity; _this.default = initArgs.default; _this.fixed = initArgs.fixed; _this.required = initArgs.required; _this.exclusive = initArgs.exclusive; _this.localization = initArgs.localization; _this.keyField = initArgs.keyField; _this.deprecated = initArgs.deprecated; _this.readonly = initArgs.readonly; _this.writeonly = initArgs.writeonly; _this.examples = initArgs.examples; _this.override = initArgs.override; _this.scopePattern = initArgs.scopePattern ? Array.isArray(initArgs.scopePattern) ? initArgs.scopePattern : [initArgs.scopePattern] : undefined; _this.designType = initArgs.designType; _this.override = initArgs.override; }; /** * The ApiFieldClass represents a descriptive metadata structure for API fields, * supporting features like data type definition, scoping, localization, and constraints. * This class extends DocumentElement, inheriting base document structure capabilities. */ class ApiFieldClass extends DocumentElement { origin; inScope(scope) { return testScopeMatch(scope, this.scopePattern); } forScope(scope) { if (!(scope && this.override)) return this; this._overrideCache = this._overrideCache || {}; let field = this._overrideCache[scope]; if (field) return field; if (scope !== '*') { for (const o of this.override) { if (testScopeMatch(scope, o.scopePattern)) { field = omitUndefined({ ...o, id: undefined, owner: undefined, node: undefined, origin: undefined, name: undefined, type: undefined, override: undefined, _overrideCache: undefined, scopePattern: o.scopePattern, }); Object.setPrototypeOf(field, this); break; } } } field = field || this; this._overrideCache[scope] = field; return field; } toJSON(options) { const typeName = this.type ? this.node.getDataTypeNameWithNs(this.type) : undefined; return omitUndefined({ type: typeName ? typeName : this.type?.toJSON(options), description: this.description, isArray: this.isArray || undefined, isNestedEntity: this.isNestedEntity || undefined, default: this.default, fixed: this.fixed, required: this.required || undefined, exclusive: this.exclusive || undefined, localization: this.localization || undefined, keyField: this.keyField || undefined, deprecated: this.deprecated || undefined, readonly: this.readonly || undefined, writeonly: this.writeonly || undefined, examples: this.examples, }); } generateCodec(codec, options, properties) { return this.type.generateCodec(codec, options, { ...properties, designType: this.designType, }); } } ApiField.prototype = ApiFieldClass.prototype; Object.assign(ApiField, ApiFieldDecoratorFactory); ApiField[DECORATOR] = ApiFieldDecoratorFactory;