@opra/common
Version:
Opra common package
118 lines (117 loc) • 4.7 kB
JavaScript
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 {
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;