UNPKG

@opra/common

Version:
122 lines (121 loc) 4.75 kB
import 'reflect-metadata'; import { omitUndefined } from '@jsopen/objects'; import { asMutable } from 'ts-gems'; import { OpraSchema } from '../../schema/index.js'; import { ApiField } from './api-field.js'; import { ComplexTypeBase } from './complex-type-base.js'; import { DataType } from './data-type.js'; import { getIsInheritedPredicateFn } from './utils/get-is-inherited-predicate-fn.js'; /** * MappedType constructor */ export const MappedType = function (...args) { if (!this) throw new TypeError('"this" should be passed to call class constructor'); // Constructor const [owner, initArgs, context] = args; ComplexTypeBase.call(this, owner, initArgs, context); const _this = asMutable(this); _this.kind = OpraSchema.MappedType.Kind; if (initArgs.base) { // noinspection SuspiciousTypeOfGuard if (!(initArgs.base instanceof ComplexTypeBase)) { throw new TypeError(`"${initArgs.base.kind}" can't be set as base for a "${this.kind}"`); } _this.base = initArgs.base; _this.ctor = initArgs.ctor || _this.base.ctor; if (initArgs.pick) _this.pick = initArgs.pick.map(f => _this.base.normalizeFieldPath(f)); else if (initArgs.omit) _this.omit = initArgs.omit.map(f => _this.base.normalizeFieldPath(f)); else if (initArgs.partial) { _this.partial = Array.isArray(initArgs.partial) ? initArgs.partial.map(f => _this.base.normalizeFieldPath(f)) : initArgs.partial; } else if (initArgs.required) { _this.required = Array.isArray(initArgs.required) ? initArgs.required.map(f => _this.base.normalizeFieldPath(f)) : initArgs.required; } /** Copy fields from base */ const isInheritedPredicate = getIsInheritedPredicateFn(_this.pick, _this.omit); const partial = Array.isArray(_this.partial) ? _this.partial.map(x => x.toLowerCase()) : _this.partial; const required = Array.isArray(_this.required) ? _this.required.map(x => x.toLowerCase()) : _this.required; for (const [k, v] of _this.base.fieldEntries('*')) { if (!isInheritedPredicate(k)) continue; const meta = { ...v }; if (partial === true || (Array.isArray(partial) && partial.includes(v.name.toLowerCase()))) { meta.required = false; } else if (required === true || (Array.isArray(required) && required.includes(v.name.toLowerCase()))) { meta.required = true; } const field = new ApiField(this, meta); _this._fields.set(field.name, field); } if (!_this.pick || _this.base.additionalFields === false || (Array.isArray(_this.base.additionalFields) && _this.base.additionalFields?.[0] === 'error')) { _this.additionalFields = _this.base.additionalFields; } if (initArgs.base.keyField && isInheritedPredicate(initArgs.base.keyField)) _this.keyField = initArgs.base.keyField; _this.discriminatorField = initArgs.base.discriminatorField; _this.discriminatorValue = initArgs.base.discriminatorValue; } }; /** * * @class MappedType */ class MappedTypeClass extends ComplexTypeBase { omit; pick; partial; required; extendsFrom(baseType) { if (!(baseType instanceof DataType)) baseType = this.node.getDataType(baseType); if (!(baseType instanceof ComplexTypeBase)) return false; if (baseType === this) return true; return !!this.base?.extendsFrom(baseType); } toJSON(options) { const superJson = super.toJSON(options); const baseName = this.base ? this.node.getDataTypeNameWithNs(this.base) : undefined; return omitUndefined({ ...superJson, base: baseName ? baseName : this.base.toJSON(options), kind: this.kind, pick: this.pick, omit: this.omit, partial: this.partial, required: this.required, discriminatorField: this.discriminatorField, discriminatorValue: this.discriminatorValue, }); } _locateBase(callback) { if (!this.base) return; if (callback(this.base)) return this.base; if (this.base._locateBase) return this.base._locateBase(callback); } } MappedType.prototype = MappedTypeClass.prototype; MappedType._applyMixin = () => undefined;