• 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

96.45
/packages/common/src/document/data-type/api-field.ts
1
import { omitUndefined } from '@jsopen/objects';
1✔
2
import type { Combine, StrictOmit, Type, TypeThunkAsync } from 'ts-gems';
1✔
3
import { asMutable } from 'ts-gems';
1✔
4
import { type Validator, vg } from 'valgen';
1✔
5
import { OpraSchema } from '../../schema/index.js';
1✔
6
import type { ApiDocument } from '../api-document.js';
1✔
7
import { DocumentElement } from '../common/document-element.js';
1✔
8
import { DECORATOR } from '../constants.js';
1✔
9
import { ApiFieldDecoratorFactory } from '../decorators/api-field-decorator.js';
1✔
10
import { testScopeMatch } from '../utils/test-scope-match.js';
1✔
11
import type { ComplexType } from './complex-type.js';
3,012✔
12
import { ComplexTypeBase } from './complex-type-base.js';
225✔
13
import type { DataType } from './data-type.js';
3,012✔
14
import type { EnumType } from './enum-type.js';
2,787✔
15
import type { MappedType } from './mapped-type.js';
2,787✔
16
import type { MixinType } from './mixin-type.js';
2,787✔
17

2,787✔
18
/**
2,787✔
19
 * Type definition of ComplexType constructor type
3,012✔
20
 * @type ApiFieldConstructor
3,012✔
21
 */
3,012✔
22
export interface ApiFieldConstructor extends ApiFieldDecoratorFactory {
3,012!
23
  prototype: ApiField;
×
24

×
25
  new (
×
26
    owner: ComplexType | MappedType | MixinType,
3,012✔
27
    args: ApiField.InitArguments,
3,012!
28
  ): ApiField;
3,012✔
29
}
3,012✔
30

3,012✔
31
/**
3,012✔
32
 * The ApiField represents a descriptive metadata structure for API fields,
3,012✔
33
 * supporting features like data type definition, scoping, localization, and constraints.
3,012✔
34
 * This class extends DocumentElement, inheriting base document structure capabilities.
3,012✔
35
 *
3,012✔
36
 * @class ApiField
3,012✔
37
 */
3,012✔
38
export interface ApiField extends ApiFieldClass {}
3,012✔
39

3,012✔
40
/**
3,012✔
41
 * @decorator ApiField
3,012✔
42
 */
3,012✔
43
export const ApiField = function (this: ApiField | void, ...args: any[]) {
3,012✔
44
  // Decorator
3,012✔
45
  if (!(this instanceof ApiField)) {
3,012✔
46
    const [options] = args;
3,012✔
47
    return ApiField[DECORATOR](options);
3,012✔
48
  }
3,012✔
49
  // Constructor
3,012✔
50
  const [owner, initArgs] = args as [ComplexType, ApiField.InitArguments];
3,012✔
51
  DocumentElement.call(this, owner);
15✔
52
  const _this = asMutable(this);
8✔
53
  _this.name = initArgs.name;
3,012✔
54
  const origin = initArgs.origin || owner;
3,012✔
55
  /* istanbul ignore next */
1✔
56
  if (!(origin instanceof ComplexTypeBase)) {
1✔
57
    throw new Error(
1✔
58
      'Field origin should be one of ComplexType, MappedType or MixinType',
1✔
59
    );
1✔
60
  }
1✔
61
  _this.origin = origin;
1✔
62
  _this.type = initArgs.type || owner.node.getDataType('any');
1✔
63
  _this.description = initArgs.description;
1✔
64
  _this.isArray = initArgs.isArray;
1✔
65
  _this.isNestedEntity = initArgs.isNestedEntity;
1!
66
  _this.default = initArgs.default;
11,006✔
67
  _this.fixed = initArgs.fixed;
1✔
68
  _this.required = initArgs.required;
4,303✔
69
  _this.exclusive = initArgs.exclusive;
4,303✔
70
  _this.localization = initArgs.localization;
4,303✔
71
  _this.keyField = initArgs.keyField;
4,303✔
72
  _this.deprecated = initArgs.deprecated;
4,303✔
73
  _this.readonly = initArgs.readonly;
4,303✔
74
  _this.writeonly = initArgs.writeonly;
3✔
75
  _this.examples = initArgs.examples;
3✔
76
  _this.override = initArgs.override;
3✔
77
  _this.scopePattern = initArgs.scopePattern
1✔
78
    ? Array.isArray(initArgs.scopePattern)
1✔
79
      ? initArgs.scopePattern
1✔
80
      : [initArgs.scopePattern]
1✔
81
    : undefined;
1✔
82
  _this.designType = initArgs.designType;
1✔
83
  _this.override = initArgs.override;
1✔
84
} as ApiFieldConstructor;
1✔
85

1✔
86
/**
1✔
87
 * The ApiFieldClass represents a descriptive metadata structure for API fields,
1✔
88
 * supporting features like data type definition, scoping, localization, and constraints.
1✔
89
 * This class extends DocumentElement, inheriting base document structure capabilities.
1✔
90
 */
1✔
91
class ApiFieldClass extends DocumentElement {
3✔
92
  declare protected _overrideCache?: Record<string, this>;
4,303✔
93
  declare readonly owner: ComplexType | MappedType | MixinType;
1✔
94
  readonly origin?: ComplexType | MappedType | MixinType;
1,684✔
95
  declare readonly scopePattern?: (string | RegExp)[];
1,684!
96
  declare readonly designType?: Type;
1,684✔
97
  declare readonly name: string;
1,684✔
98
  declare readonly type: DataType;
1,684✔
99
  declare readonly description?: string;
1,684✔
100
  /* @deprecated */
1,684✔
101
  declare readonly isArray?: boolean;
1,684✔
102
  declare readonly isNestedEntity?: boolean;
1,684✔
103
  declare readonly default?: any;
1,684✔
104
  declare readonly fixed?: any;
1,684✔
105
  declare readonly required?: boolean;
1,684✔
106
  declare readonly exclusive?: boolean;
1,684✔
107
  declare readonly localization?: boolean;
1,684✔
108
  declare readonly keyField?: string;
1,684✔
109
  declare readonly deprecated?: boolean | string;
1,684✔
110
  declare readonly readonly?: boolean;
1,684✔
111
  declare readonly writeonly?: boolean;
1,684✔
112
  declare readonly examples?: any[] | Record<string, any>;
1,684✔
113
  declare readonly override: ApiField.InitArguments['override'];
1,684✔
114

1✔
115
  inScope(scope?: string | '*'): boolean {
1✔
116
    return testScopeMatch(scope, this.scopePattern);
4,315!
117
  }
×
118

4,315✔
119
  forScope(scope?: string): this {
4,315✔
120
    if (!(scope && this.override)) return this;
4,315✔
121
    this._overrideCache = this._overrideCache || {};
4,315✔
122
    let field = this._overrideCache[scope];
4,315!
123
    if (field) return field;
4,315✔
124
    if (scope !== '*') {
56✔
125
      for (const o of this.override) {
56✔
126
        if (testScopeMatch(scope, o.scopePattern)) {
4,315✔
127
          field = omitUndefined({
190✔
128
            ...o,
4,315✔
129
            id: undefined,
4,315✔
130
            owner: undefined,
1✔
131
            node: undefined,
1✔
132
            origin: undefined,
1✔
133
            name: undefined,
1✔
134
            type: undefined,
1✔
135
            override: undefined,
1✔
136
            _overrideCache: undefined,
1✔
137
            scopePattern: o.scopePattern,
1✔
138
          }) as this;
1✔
139
          Object.setPrototypeOf(field, this);
1✔
140
          break;
1✔
141
        }
1✔
142
      }
1✔
143
    }
1✔
144
    field = field || this;
1✔
145
    this._overrideCache[scope] = field;
1✔
146
    return field;
1✔
147
  }
1✔
148

1✔
149
  toJSON(options?: ApiDocument.ExportOptions): OpraSchema.Field {
1✔
150
    const typeName = this.type
1✔
151
      ? this.node.getDataTypeNameWithNs(this.type)
1✔
152
      : undefined;
1✔
153
    return omitUndefined<OpraSchema.Field>({
1✔
154
      type: typeName ? typeName : (this.type?.toJSON(options) as any),
1✔
155
      description: this.description,
1✔
156
      isArray: this.isArray || undefined,
1✔
157
      isNestedEntity: this.isNestedEntity || undefined,
1✔
158
      default: this.default,
1✔
159
      fixed: this.fixed,
1✔
160
      required: this.required || undefined,
1✔
161
      exclusive: this.exclusive || undefined,
1✔
162
      localization: this.localization || undefined,
1✔
163
      keyField: this.keyField || undefined,
1✔
164
      deprecated: this.deprecated || undefined,
1✔
165
      readonly: this.readonly || undefined,
1✔
166
      writeonly: this.writeonly || undefined,
1✔
167
      examples: this.examples,
1✔
168
    }) as OpraSchema.Field;
1✔
169
  }
1✔
170

1✔
171
  generateCodec(
1✔
172
    codec: 'encode' | 'decode',
1✔
173
    options?: DataType.GenerateCodecOptions,
1✔
174
    properties?: any,
1✔
175
  ): Validator {
1✔
176
    if (this.fixed) return vg.fixed(this.fixed);
1✔
177
    let fn =
1✔
178
      this.type?.generateCodec(codec, options, {
1✔
179
        ...properties,
1✔
180
        designType: this.designType,
1✔
181
      }) || vg.isAny();
1✔
182
    if (this.default !== undefined) {
1✔
183
      fn = vg.required(fn, {
1✔
184
        default: this.default,
1✔
185
      });
1✔
186
    }
1✔
187
    if (this.isArray && !(this.type.kind === OpraSchema.ArrayType.Kind))
1✔
188
      fn = vg.isArray(fn);
1✔
189
    return fn;
1✔
190
  }
1✔
191
}
1✔
192

1✔
193
ApiField.prototype = ApiFieldClass.prototype;
1✔
194
Object.assign(ApiField, ApiFieldDecoratorFactory);
1✔
195
ApiField[DECORATOR] = ApiFieldDecoratorFactory;
1✔
196

1✔
197
/**
1✔
198
 * @namespace ApiField
1✔
199
 */
1✔
200
export namespace ApiField {
1✔
201
  export interface Metadata extends Combine<
1✔
202
    {
1✔
203
      type?:
1✔
204
        | string
1✔
205
        | OpraSchema.DataType
1✔
206
        | TypeThunkAsync
1✔
207
        | EnumType.EnumObject
1✔
208
        | EnumType.EnumArray
1✔
209
        | object;
1✔
210
    },
1✔
211
    OpraSchema.Field
1✔
212
  > {
1✔
213
    scopePattern?: (string | RegExp) | (string | RegExp)[];
1✔
214
    override?: StrictOmit<
1✔
215
      Metadata,
1✔
216
      'override' | 'type' | 'isArray' | 'isNestedEntity'
1✔
217
    >[];
1✔
218
    designType?: Type;
1✔
219
  }
1✔
220

1✔
221
  export interface Options extends Partial<
1✔
222
    StrictOmit<Metadata, 'override' | 'scopePattern'>
1✔
223
  > {
1✔
224
    /**
1✔
225
     * A variable that defines the pattern or patterns used to determine scope.
1✔
226
     * This can either be a single string or regular expression, or an array containing multiple strings or regular expressions.
1✔
227
     *
1✔
228
     * - If a single string or RegExp is provided, it is directly used as the scope pattern.
1✔
229
     * - If an array is provided, each element within the array is used as a valid scope pattern.
1✔
230
     */
1✔
231
    scopePattern?: (string | RegExp) | (string | RegExp)[];
1✔
232
  }
1✔
233

1✔
234
  export interface InitArguments extends Combine<
1✔
235
    {
1✔
236
      name: string;
1✔
237
      origin?: ComplexType | MappedType | MixinType;
1✔
238
      type?: DataType;
1✔
239
    },
1✔
240
    Metadata
1✔
241
  > {}
1✔
242
}
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