• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

panates / opra / 29494915195

16 Jul 2026 11:33AM UTC coverage: 83.024% (+0.4%) from 82.653%
29494915195

push

github

erayhanoglu
1.29.1

4118 of 5238 branches covered (78.62%)

Branch coverage included in aggregate %.

34348 of 41093 relevant lines covered (83.59%)

239.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.54
/packages/common/src/document/data-type/complex-type.ts
1
import 'reflect-metadata';
1✔
2
import { omitUndefined } from '@jsopen/objects';
1✔
3
import type { Combine, Type, TypeThunkAsync } from 'ts-gems';
1✔
4
import { asMutable } from 'ts-gems';
1✔
5
import { OpraSchema } from '../../schema/index.js';
1✔
6
import type { ApiDocument } from '../api-document.js';
1✔
7
import type { DocumentElement } from '../common/document-element.js';
1✔
8
import { DocumentInitContext } from '../common/document-init-context.js';
1✔
9
import { DECORATOR } from '../constants.js';
1✔
10
import { ComplexTypeDecorator } from '../decorators/complex-type.decorator.js';
1✔
11
import { ApiField } from './api-field.js';
1✔
12
import { ComplexTypeBase } from './complex-type-base.js';
638✔
13
import { DataType } from './data-type.js';
638✔
14
import type { MappedType } from './mapped-type.js';
546✔
15
import type { MixinType } from './mixin-type.js';
546✔
16

546✔
17
/**
546✔
18
 * @namespace ComplexType
638✔
19
 */
638✔
20
export namespace ComplexType {
638✔
21
  export interface Metadata extends Combine<
638✔
22
    {
638✔
23
      kind: OpraSchema.ComplexType.Kind;
638✔
24
      fields?: Record<string, ApiField.Metadata>;
638✔
25
      additionalFields?:
638✔
26
        boolean | string | TypeThunkAsync | ['error'] | ['error', string];
638✔
27
    },
88✔
28
    DataType.Metadata,
88✔
29
    OpraSchema.ComplexType
88✔
30
  > {}
88✔
31

88✔
32
  export interface Options extends Combine<
88✔
33
    Pick<
88✔
34
      Metadata,
88✔
35
      | 'additionalFields'
88!
36
      | 'keyField'
×
37
      | 'discriminatorField'
×
38
      | 'discriminatorValue'
×
39
    >,
×
40
    DataType.Options,
88✔
41
    Pick<OpraSchema.ComplexType, 'abstract'>
88✔
42
  > {}
88✔
43

88✔
44
  export interface InitArguments extends Combine<
88✔
45
    {
88✔
46
      kind: OpraSchema.ComplexType.Kind;
88✔
47
      base?: ComplexType | MappedType | MixinType;
88✔
48
      fields?: Record<string, ApiField.InitArguments | ApiField>;
88✔
49
      additionalFields?: boolean | DataType | ['error'] | ['error', string];
638✔
50
    },
546✔
51
    DataType.InitArguments,
546✔
52
    ComplexType.Metadata
638✔
53
  > {}
345✔
54

345✔
55
  export interface ParsedFieldPath {
638✔
56
    fieldName: string;
546✔
57
    dataType: DataType;
638✔
58
    field?: ApiField;
638✔
59
    additionalField?: boolean;
638✔
60
    sign?: '+' | '-';
638✔
61
  }
638✔
62
}
638✔
63

638✔
64
/**
638✔
65
 * Type definition for MixinType
638✔
66
 * @class ComplexType
546✔
67
 */
546✔
68
export interface ComplexTypeStatic {
546✔
69
  /**
546✔
70
   * Class constructor of ComplexType
546✔
71
   *
1,549✔
72
   * @param owner
1,549✔
73
   * @param args
1,549✔
74
   * @param context
1,549✔
75
   * @constructor
1,549✔
76
   */
1,549✔
77
  new (
1,549✔
78
    owner: DocumentElement,
1,549✔
79
    args?: ComplexType.InitArguments,
1,549✔
80
    context?: DocumentInitContext,
546✔
81
  ): ComplexType;
1✔
82

1✔
83
  (options?: ComplexType.Options): ClassDecorator;
1✔
84

1✔
85
  prototype: ComplexType;
1✔
86

1✔
87
  extend<T extends Type>(
1✔
88
    typeClass: T,
1!
89
    fields: Record<string, ApiField.Options>,
372✔
90
  ): T;
372✔
91
}
372✔
92

372✔
93
/**
372✔
94
 * Type definition of ComplexType prototype
×
95
 * @interface ComplexType
372✔
96
 */
372✔
97
export interface ComplexType extends ComplexTypeClass {}
372!
98

372✔
99
/**
372✔
100
 * ComplexType constructor
372!
101
 */
372✔
102
export const ComplexType = function (this: ComplexType | void, ...args: any[]) {
1✔
103
  // Decorator
572✔
104
  if (!this) return ComplexType[DECORATOR].apply(undefined, args);
572✔
105
  // Constructor
95✔
106
  const [owner, initArgs] = args as [
572✔
107
    DocumentElement,
572✔
108
    ComplexType.InitArguments,
572✔
109
  ];
572✔
110
  const context: DocumentInitContext =
572✔
111
    args[2] || new DocumentInitContext({ maxErrors: 0 });
572✔
112
  ComplexTypeBase.call(this, owner, initArgs, context);
572✔
113
  const _this = asMutable(this);
572✔
114
  _this.kind = OpraSchema.ComplexType.Kind;
572✔
115
  _this.discriminatorField = initArgs.discriminatorField;
572✔
116
  _this.discriminatorValue = initArgs.discriminatorValue;
350✔
117
  if (initArgs.base) {
1✔
118
    context.enter('.base', () => {
1✔
119
      // noinspection SuspiciousTypeOfGuard
1✔
120
      if (!(initArgs.base instanceof ComplexTypeBase)) {
1!
121
        throw new TypeError(
350✔
122
          `"${(initArgs.base! as DataType).kind}" can't be set as base for a "${this.kind}"`,
572✔
123
        );
413✔
124
      }
413✔
125
      _this.base = initArgs.base;
413✔
126
      _this.additionalFields = _this.base.additionalFields;
413✔
127
      _this.keyField = _this.base.keyField;
2,263✔
128

1,695✔
129
      /* Copy fields from base */
2,263✔
130
      for (const v of _this.base.fields('*')) {
1,684✔
131
        (_this as any)._fields.set(v.name, new ApiField(this, v));
413✔
132
      }
413✔
133
    });
413✔
134
  }
405✔
135
  if (initArgs.additionalFields !== undefined)
572✔
136
    _this.additionalFields = initArgs.additionalFields;
1✔
137
  if (initArgs.keyField !== undefined) _this.keyField = initArgs.keyField;
2,518!
138
  _this.ctor = initArgs.ctor || _this.base?.ctor;
558✔
139

558✔
140
  /* Add own fields */
2,518✔
141
  if (initArgs.fields) {
1✔
142
    context.enter('.fields', () => {
1✔
143
      for (const [k, v] of Object.entries(initArgs.fields!)) {
1✔
144
        const field = new ApiField(this, {
1✔
145
          ...v,
1✔
146
          name: k,
1✔
147
        });
1✔
148
        (this as any)._fields.set(field.name, field);
1✔
149
      }
1✔
150
    });
1✔
151
  }
1✔
152
} as Function as ComplexTypeStatic;
1✔
153

1✔
154
/**
1✔
155
 *
1✔
156
 * @class ComplexType
1✔
157
 */
1✔
158
abstract class ComplexTypeClass extends ComplexTypeBase {
1✔
159
  declare readonly kind: OpraSchema.ComplexType.Kind;
1✔
160
  readonly base?: ComplexType | MappedType | MixinType;
1✔
161
  declare readonly ctor?: Type;
1✔
162
  declare discriminatorField?: string;
1✔
163
  declare discriminatorValue?: string;
1✔
164

1✔
165
  extendsFrom(baseType: DataType | string | Type | object): boolean {
1✔
166
    if (!(baseType instanceof DataType))
1✔
167
      baseType = this.node.getDataType(baseType);
1✔
168
    if (!(baseType instanceof ComplexTypeBase)) return false;
1✔
169
    if (baseType === this) return true;
1✔
170
    return !!this.base?.extendsFrom(baseType);
1✔
171
  }
1✔
172

1✔
173
  toJSON(options?: ApiDocument.ExportOptions): OpraSchema.ComplexType {
1✔
174
    const superJson = super.toJSON(options);
1✔
175
    const baseName = this.base
1✔
176
      ? this.node.getDataTypeNameWithNs(this.base)
1✔
177
      : undefined;
1✔
178
    const out: OpraSchema.ComplexType = {
1✔
179
      ...superJson,
1✔
180
      kind: this.kind,
1✔
181
      base: this.base
1✔
182
        ? baseName
1✔
183
          ? baseName
1✔
184
          : this.base.toJSON(options)
1✔
185
        : undefined,
1✔
186
      discriminatorField: this.discriminatorField,
1✔
187
      discriminatorValue: this.discriminatorValue,
1✔
188
    };
1✔
189
    if (this.additionalFields) {
1✔
190
      if (this.additionalFields instanceof DataType) {
1✔
191
        const typeName = this.node.getDataTypeNameWithNs(this.additionalFields);
1✔
192
        out.additionalFields = typeName
1✔
193
          ? typeName
1✔
194
          : (this.additionalFields.toJSON(options) as OpraSchema.DataType);
1✔
195
      } else out.additionalFields = this.additionalFields;
1✔
196
    }
1✔
197
    if (this._fields.size) {
1✔
198
      const fields = {};
1✔
199
      let i = 0;
1✔
200
      for (const field of this._fields.values()) {
1✔
201
        if (field.origin === this && field.inScope(options?.scope)) {
1✔
202
          fields[field.name] = field.toJSON(options);
1✔
203
          i++;
1✔
204
        }
1✔
205
      }
1✔
206
      if (i) out.fields = fields;
1✔
207
    }
1✔
208
    return omitUndefined(out);
1✔
209
  }
1✔
210

1✔
211
  protected _locateBase(
1✔
212
    callback: (base: ComplexTypeBase) => boolean,
1✔
213
  ): ComplexTypeBase | undefined {
1✔
214
    if (!this.base) return;
1✔
215
    if (callback(this.base)) return this.base;
1✔
216
    if ((this.base as any)._locateBase)
1✔
217
      return (this.base as any)._locateBase(callback);
1✔
218
  }
1✔
219
}
1✔
220

1✔
221
ComplexType.prototype = ComplexTypeClass.prototype;
1✔
222
Object.assign(ComplexType, ComplexTypeDecorator);
1✔
223
ComplexType[DECORATOR] = ComplexTypeDecorator;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc