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

satisfactory-dev / ajv-utilities / 25141049688

30 Apr 2026 12:29AM UTC coverage: 99.378% (+0.3%) from 99.03%
25141049688

push

github

SignpostMarv
remove toString from interface

491 of 495 branches covered (99.19%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

16 existing lines in 1 file now uncovered.

3979 of 4003 relevant lines covered (99.4%)

23224.49 hits per line

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

95.82
/src/TypeScriptify/TypeReferences.ts
1
import type {
3✔
2
        ArrayTypeNode,
3✔
3
        ImportSpecifier,
3✔
4
        IndexedAccessTypeNode,
3✔
5
        TupleTypeNode,
3✔
6
        TypeReferenceNode,
3✔
7
} from 'typescript';
3✔
8
import {
3✔
9
        createPrinter,
3✔
10
        createSourceFile,
3✔
11
        EmitHint,
3✔
12
        factory,
3✔
13
        ScriptTarget,
3✔
14
} from 'typescript';
3✔
15

3✔
16
import type {
3✔
17
        as_array_config,
3✔
18
        specify_types_config,
3✔
19
} from './types.ts';
3✔
20

3✔
21
export type prepend_with_imports = {
3✔
22
        [key: string]: Types,
3✔
23
        ajv: Types,
3✔
24
        '@satisfactory-dev/ajv-utilities': Types,
3✔
25
};
3✔
26

3✔
27
interface HasOutput<
3✔
28
        TypeResult extends (
3✔
29
                | TypeReferenceNode
3✔
30
                | IndexedAccessTypeNode
3✔
31
                | TupleTypeNode
3✔
32
                | ArrayTypeNode
3✔
33
        ) = (
3✔
34
                | TypeReferenceNode
3✔
35
                | IndexedAccessTypeNode
3✔
36
                | TupleTypeNode
3✔
37
                | ArrayTypeNode
3✔
38
        ),
3✔
39
> {
3✔
40
        toTypeResult(): TypeResult;
3✔
41
}
3✔
42

3✔
43
export function to_string(instance: HasOutput) {
3✔
44
        const printer = createPrinter({
16✔
45
                omitTrailingSemicolon: true,
16✔
46
        });
16✔
47

16✔
48
        return printer.printNode(
16✔
49
                EmitHint.Unspecified,
16✔
50
                instance.toTypeResult(),
16✔
51
                createSourceFile('foo.ts', '', ScriptTarget.ESNext),
16✔
52
        );
16✔
53
}
16✔
54

3✔
55
abstract class Type<
3✔
56
        TypeResult extends (
3✔
57
                | TypeReferenceNode
3✔
58
                | IndexedAccessTypeNode
3✔
59
                | TupleTypeNode
3✔
60
                | ArrayTypeNode
3✔
61
        ),
3✔
62
> implements HasOutput<TypeResult> {
3✔
63
        readonly name: Exclude<string, ''>;
3✔
64

3,955✔
65
        #id: Exclude<string, ''> | undefined;
3✔
66

3✔
67
        get id(): Exclude<string, ''> {
3✔
68
                if (!this.#id) {
15,150✔
69
                        this.#id = this.toId();
3,913✔
70
                }
3,913✔
71

15,150✔
72
                return this.#id;
15,150✔
73
        }
15,150✔
74

3✔
75
        constructor(name: Exclude<string, ''>) {
3✔
76
                this.name = name;
3,955✔
77
        }
3,955✔
78

3✔
79
        protected toId(): string {
3✔
80
                return this.name;
3,921✔
81
        }
3,921✔
82

3✔
83
        toImportSpecifier(): ImportSpecifier {
3✔
84
                return factory.createImportSpecifier(
122✔
85
                        false,
122✔
86
                        undefined,
122✔
87
                        factory.createIdentifier(this.name),
122✔
88
                );
122✔
89
        }
122✔
90

3✔
91
        abstract withArgs(args: [string, ...string[]]): WithArgs;
3✔
92

3✔
93
        abstract toTypeResult(): TypeResult;
3✔
94

3✔
95
        withSubTypeChain(
3✔
96
                sub_type_chain: [string, ...string[]],
13✔
97
        ): WithSubTypeChain {
13✔
98
                return new WithSubTypeChain(
13✔
99
                        this,
13✔
100
                        sub_type_chain,
13✔
101
                );
13✔
102
        }
13✔
103

3✔
104
        withArray(
3✔
105
                config: as_array_config,
4✔
106
        ): WithArray {
4✔
107
                return new WithArray(
4✔
108
                        this,
4✔
109
                        config,
4✔
110
                );
4✔
111
        }
4✔
112
}
3✔
113

3✔
114
export class NameOnly extends Type<TypeReferenceNode> {
3✔
115
        toTypeResult(): TypeReferenceNode {
3✔
116
                return factory.createTypeReferenceNode(this.name);
68✔
117
        }
68✔
118

3✔
119
        withArgs(args: [string, ...string[]]): WithArgs {
3✔
120
                return new WithArgs(this.name, args);
9✔
121
        }
9✔
122
}
3✔
123

3✔
124
export class Aliased extends Type<TypeReferenceNode> {
3✔
125
        readonly as: Exclude<string, ''>;
3✔
126

3✔
127
        constructor(name: Aliased['name'], as: Aliased['as']) {
3✔
128
                super(name);
10✔
129

10✔
130
                this.as = as;
10✔
131
        }
10✔
132

3✔
133
        protected toId(): string {
3✔
134
                return `${this.name} as ${this.as}`;
8✔
135
        }
8✔
136

3✔
137
        toImportSpecifier(): ImportSpecifier {
3✔
138
                return factory.createImportSpecifier(
4✔
139
                        false,
4✔
140
                        factory.createIdentifier(this.name),
4✔
141
                        factory.createIdentifier(this.as),
4✔
142
                );
4✔
143
        }
4✔
144

3✔
145
        toTypeResult(): TypeReferenceNode {
3✔
146
                return factory.createTypeReferenceNode(this.as);
6✔
147
        }
6✔
148

3✔
149
        withArgs(args: [string, ...string[]]): WithArgs {
3✔
150
                return new WithArgs(this.name, args, this.as);
4✔
151
        }
4✔
152
}
3✔
153

3✔
154
class WithArgs extends Type<TypeReferenceNode> {
3✔
155
        readonly as: Exclude<string, ''> | undefined;
3✔
156

13✔
157
        readonly args: [string, ...string[]];
3✔
158

3✔
159
        constructor(
3✔
160
                name: WithArgs['name'],
13✔
161
                args: WithArgs['args'],
13✔
162
                as?: Exclude<WithArgs['as'], undefined>,
13✔
163
        ) {
13✔
164
                super(name);
13✔
165

13✔
166
                this.args = args;
13✔
167
                this.as = as;
13✔
168
        }
13✔
169

3✔
170
        toTypeResult() {
3✔
171
                return factory.createTypeReferenceNode(
13✔
172
                        this.as || this.name,
13✔
173
                        this.args.map((value) => factory.createLiteralTypeNode(
13✔
174
                                factory.createStringLiteral(value),
30✔
175
                        )),
13✔
176
                );
13✔
177
        }
13✔
178

3✔
179
        withSubTypeChain(
3✔
UNCOV
180
                sub_type_chain: [string, ...string[]],
×
UNCOV
181
        ): WithSubTypeChain {
×
UNCOV
182
                return new WithSubTypeChain(
×
UNCOV
183
                        this,
×
UNCOV
184
                        sub_type_chain,
×
UNCOV
185
                );
×
UNCOV
186
        }
×
187

3✔
188
        withArray(
3✔
UNCOV
189
                config: as_array_config,
×
UNCOV
190
        ): WithArray {
×
UNCOV
191
                return new WithArray(
×
UNCOV
192
                        this,
×
UNCOV
193
                        config,
×
UNCOV
194
                );
×
UNCOV
195
        }
×
196

3✔
197
        withArgs(args: WithArgs['args']) {
3✔
UNCOV
198
                return new WithArgs(this.name, args, this.as);
×
UNCOV
199
        }
×
200
}
3✔
201

3✔
202
class WithSubTypeChain implements HasOutput<IndexedAccessTypeNode> {
3✔
203
        #parent: HasOutput;
3✔
204

13✔
205
        readonly sub_type_chain: [string, ...string[]];
3✔
206

3✔
207
        constructor(
3✔
208
                parent: HasOutput,
13✔
209
                sub_type_chain: [string, ...string[]],
13✔
210
        ) {
13✔
211
                this.#parent = parent;
13✔
212
                this.sub_type_chain = sub_type_chain;
13✔
213
        }
13✔
214

3✔
215
        withArray(config: as_array_config): WithArray {
3✔
216
                return new WithArray(this.#parent, config);
×
217
        }
×
218

3✔
219
        toTypeResult() {
3✔
220
                const [
13✔
221
                        first,
13✔
222
                        ...remaining
13✔
223
                ] = this.sub_type_chain;
13✔
224

13✔
225
                let access = factory.createIndexedAccessTypeNode(
13✔
226
                        this.#parent.toTypeResult(),
13✔
227
                        factory.createLiteralTypeNode(factory.createStringLiteral(
13✔
228
                                first,
13✔
229
                        )),
13✔
230
                );
13✔
231

13✔
232
                for (const sub_type of remaining) {
13✔
233
                        access = factory.createIndexedAccessTypeNode(
1✔
234
                                access,
1✔
235
                                factory.createLiteralTypeNode(factory.createStringLiteral(
1✔
236
                                        sub_type,
1✔
237
                                )),
1✔
238
                        );
1✔
239
                }
1✔
240

13✔
241
                return access;
13✔
242
        }
13✔
243
}
3✔
244

3✔
245
class WithArray implements HasOutput<TupleTypeNode | ArrayTypeNode> {
3✔
246
        #parent: HasOutput;
3✔
247

4✔
248
        readonly as_array: as_array_config;
3✔
249

3✔
250
        constructor(
3✔
251
                parent: HasOutput,
4✔
252
                as_array: as_array_config,
4✔
253
        ) {
4✔
254
                this.#parent = parent;
4✔
255
                this.as_array = as_array;
4✔
256
        }
4✔
257

3✔
258
        toTypeResult() {
3✔
259
                if (true === this.as_array || this.as_array.minimum < 1) {
4✔
260
                        return factory.createArrayTypeNode(this.#parent.toTypeResult());
2✔
261
                }
2✔
262

2✔
263
                const args: ReturnType<HasOutput['toTypeResult']>[] = [];
2✔
264

2✔
265
                const minimum = Math.max(1, this.as_array.minimum);
2✔
266

2✔
267
                for (let i = 0; i < minimum; ++i) {
2✔
268
                        args.push(this.#parent.toTypeResult());
2✔
269
                }
2✔
270

2✔
271
                return factory.createTupleTypeNode(
2✔
272
                        [
2✔
273
                                ...args,
2✔
274
                                factory.createRestTypeNode(
2✔
275
                                        factory.createArrayTypeNode(this.#parent.toTypeResult()),
2✔
276
                                ),
2✔
277
                        ],
2✔
278
                );
2✔
279
        }
4✔
280
}
3✔
281

3✔
282
export class Types {
3✔
283
        list_of_types: [
3✔
284
                (
92✔
285
                        | NameOnly
92✔
286
                        | Aliased
92✔
287
                ),
92✔
288
                ...(
92✔
289
                        | NameOnly
92✔
290
                        | Aliased
92✔
291
                )[],
92✔
292
        ] | undefined = undefined;
3✔
293

3✔
294
        get size() {
3✔
295
                return this.list_of_types ? this.list_of_types.length : 0;
77✔
296
        }
77✔
297

3✔
298
        #is_object_type(
3✔
299
                type: specify_types_config,
3,942✔
300
        ): type is Exclude<specify_types_config, string> {
3,942✔
301
                return 'string' !== typeof type;
3,942✔
302
        }
3,942✔
303

3✔
304
        add<T extends specify_types_config>(type: T) {
3✔
305
                const is_object = this.#is_object_type(type);
3,942✔
306

3,942✔
307
                let as_object = (
3,942✔
308
                        !is_object
3,942✔
309
                                ? new NameOnly(type)
3,942✔
310
                                : (
3,942✔
311
                                        'as' in type && type.as
36✔
312
                                                ? new Aliased(type.name, type.as)
36✔
313
                                                : new NameOnly(type.name)
36✔
314
                                )
36✔
315
                );
3,942✔
316

3,942✔
317
                if (undefined === this.list_of_types) {
3,942✔
318
                        this.list_of_types = [as_object];
69✔
319
                } else {
8✔
320
                        const maybe = this.list_of_types.find((
3,857✔
321
                                maybe,
7,474✔
322
                        ) => maybe.id === as_object.id);
3,857✔
323

3,857✔
324
                        if (!maybe) {
3,857✔
325
                                this.list_of_types.push(as_object);
3,857✔
326
                        } else {
3,857✔
327
                                as_object = maybe;
3,857✔
328
                        }
3,857✔
329
                }
3,857✔
330

3,942✔
331
                if (is_object) {
3,942✔
332
                        let result: (
36✔
333
                                | Aliased
36✔
334
                                | NameOnly
36✔
335
                                | WithArgs
36✔
336
                                | WithSubTypeChain
36✔
337
                                | WithArray
36✔
338
                        ) = as_object;
36✔
339

36✔
340
                        if ('args' in type) {
36✔
341
                                result = result.withArgs(type.args);
13✔
342
                        }
13✔
343

36✔
344
                        if ('sub_type_chain' in type && !!type.sub_type_chain) {
36✔
345
                                result = result.withSubTypeChain(type.sub_type_chain);
13✔
346
                        }
13✔
347

36✔
348
                        if ('as_array' in type && !!type.as_array) {
36✔
349
                                result = result.withArray(type.as_array);
4✔
350
                        }
4✔
351

36✔
352
                        return result;
36✔
353
                }
36✔
354

3,906✔
355
                return as_object;
3,906✔
356
        }
3,942✔
357

3✔
358
        * [Symbol.iterator]() {
3✔
359
                if (!this.list_of_types) {
70✔
360
                        return;
70✔
361
                }
70✔
362

70✔
363
                for (const type of this.list_of_types) {
70✔
364
                        yield type;
126✔
365
                }
126✔
366
        }
70✔
367
}
3✔
368

3✔
369
export type {
3✔
370
        WithArgs,
3✔
371
        WithSubTypeChain,
3✔
372
        WithArray,
3✔
373
};
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc