@pothos/plugin-prisma 3.53.0 → 3.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +63 -1
- package/dts/connection-helpers.d.ts +3 -3
- package/dts/connection-helpers.d.ts.map +1 -1
- package/dts/global-types.d.ts +15 -4
- package/dts/global-types.d.ts.map +1 -1
- package/dts/index.d.ts +3 -1
- package/dts/index.d.ts.map +1 -1
- package/dts/interface-ref.d.ts +10 -0
- package/dts/interface-ref.d.ts.map +1 -0
- package/dts/model-loader.d.ts +7 -7
- package/dts/model-loader.d.ts.map +1 -1
- package/dts/prisma-field-builder.d.ts +4 -4
- package/dts/prisma-field-builder.d.ts.map +1 -1
- package/dts/types.d.ts +23 -7
- package/dts/types.d.ts.map +1 -1
- package/dts/util/datamodel.d.ts +3 -3
- package/dts/util/datamodel.d.ts.map +1 -1
- package/dts/util/map-query.d.ts +2 -1
- package/dts/util/map-query.d.ts.map +1 -1
- package/dts/util/usage.d.ts +4 -0
- package/dts/util/usage.d.ts.map +1 -0
- package/esm/connection-helpers.d.ts +3 -3
- package/esm/connection-helpers.d.ts.map +1 -1
- package/esm/connection-helpers.js.map +1 -1
- package/esm/field-builder.js +59 -17
- package/esm/field-builder.js.map +1 -1
- package/esm/global-types.d.ts +21 -10
- package/esm/global-types.d.ts.map +1 -1
- package/esm/global-types.js.map +1 -1
- package/esm/index.d.ts +3 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +48 -3
- package/esm/index.js.map +1 -1
- package/esm/interface-ref.d.ts +10 -0
- package/esm/interface-ref.d.ts.map +1 -0
- package/esm/interface-ref.js +26 -0
- package/esm/interface-ref.js.map +1 -0
- package/esm/model-loader.d.ts +7 -7
- package/esm/model-loader.d.ts.map +1 -1
- package/esm/model-loader.js.map +1 -1
- package/esm/prisma-field-builder.d.ts +4 -4
- package/esm/prisma-field-builder.d.ts.map +1 -1
- package/esm/prisma-field-builder.js +3 -3
- package/esm/prisma-field-builder.js.map +1 -1
- package/esm/schema-builder.js +27 -0
- package/esm/schema-builder.js.map +1 -1
- package/esm/types.d.ts +25 -9
- package/esm/types.d.ts.map +1 -1
- package/esm/util/datamodel.d.ts +3 -3
- package/esm/util/datamodel.d.ts.map +1 -1
- package/esm/util/datamodel.js +3 -2
- package/esm/util/datamodel.js.map +1 -1
- package/esm/util/map-query.d.ts +2 -1
- package/esm/util/map-query.d.ts.map +1 -1
- package/esm/util/map-query.js +21 -14
- package/esm/util/map-query.js.map +1 -1
- package/esm/util/usage.d.ts +4 -0
- package/esm/util/usage.d.ts.map +1 -0
- package/esm/util/usage.js +29 -0
- package/esm/util/usage.js.map +1 -0
- package/lib/connection-helpers.js.map +1 -1
- package/lib/field-builder.js +62 -21
- package/lib/field-builder.js.map +1 -1
- package/lib/index.js +50 -2
- package/lib/index.js.map +1 -1
- package/lib/interface-ref.js +36 -0
- package/lib/interface-ref.js.map +1 -0
- package/lib/model-loader.js.map +1 -1
- package/lib/prisma-field-builder.js +3 -3
- package/lib/prisma-field-builder.js.map +1 -1
- package/lib/schema-builder.js +27 -0
- package/lib/schema-builder.js.map +1 -1
- package/lib/util/datamodel.js +3 -2
- package/lib/util/datamodel.js.map +1 -1
- package/lib/util/map-query.js +20 -13
- package/lib/util/map-query.js.map +1 -1
- package/lib/util/usage.js +51 -0
- package/lib/util/usage.js.map +1 -0
- package/package.json +2 -2
- package/src/connection-helpers.ts +6 -6
- package/src/field-builder.ts +90 -15
- package/src/global-types.ts +39 -11
- package/src/index.ts +56 -2
- package/src/interface-ref.ts +18 -0
- package/src/model-loader.ts +13 -7
- package/src/prisma-field-builder.ts +7 -10
- package/src/schema-builder.ts +44 -1
- package/src/types.ts +66 -9
- package/src/util/datamodel.ts +8 -3
- package/src/util/map-query.ts +38 -14
- package/src/util/usage.ts +33 -0
package/src/types.ts
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
typeBrandKey,
|
|
22
22
|
TypeParam,
|
|
23
23
|
} from '@pothos/core';
|
|
24
|
-
import {
|
|
24
|
+
import { PrismaInterfaceRef, PrismaRef } from './interface-ref';
|
|
25
25
|
import type { PrismaObjectFieldBuilder } from './prisma-field-builder';
|
|
26
26
|
|
|
27
27
|
export interface PrismaDelegate {
|
|
@@ -228,6 +228,60 @@ export type PrismaObjectTypeOptions<
|
|
|
228
228
|
> = PrismaObjectRefOptions<Types, Model, FindUnique, Include, Select, Shape> &
|
|
229
229
|
PrismaObjectImplementationOptions<Types, Model, Interfaces, FindUnique, Select, Shape>;
|
|
230
230
|
|
|
231
|
+
export type PrismaInterfaceRefOptions<
|
|
232
|
+
Types extends SchemaTypes,
|
|
233
|
+
Model extends PrismaModelTypes,
|
|
234
|
+
FindUnique,
|
|
235
|
+
Include,
|
|
236
|
+
Select,
|
|
237
|
+
Shape extends object,
|
|
238
|
+
> = NameOrVariant &
|
|
239
|
+
(
|
|
240
|
+
| {
|
|
241
|
+
include?: Include & Model['Include'];
|
|
242
|
+
select?: never;
|
|
243
|
+
findUnique?: FindUnique &
|
|
244
|
+
(((parent: Shape, context: Types['Context']) => Model['WhereUnique']) | null);
|
|
245
|
+
}
|
|
246
|
+
| {
|
|
247
|
+
select: Model['Select'] & Select;
|
|
248
|
+
include?: never;
|
|
249
|
+
findUnique?: (parent: Shape, context: Types['Context']) => Model['WhereUnique'];
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
export type PrismaInterfaceImplementationOptions<
|
|
254
|
+
Types extends SchemaTypes,
|
|
255
|
+
Model extends PrismaModelTypes,
|
|
256
|
+
Interfaces extends InterfaceParam<Types>[],
|
|
257
|
+
FindUnique,
|
|
258
|
+
Select,
|
|
259
|
+
Shape extends object,
|
|
260
|
+
> = Omit<
|
|
261
|
+
PothosSchemaTypes.InterfaceTypeOptions<Types, Shape, Interfaces>,
|
|
262
|
+
'fields' | 'description'
|
|
263
|
+
> & {
|
|
264
|
+
description?: string | false;
|
|
265
|
+
fields?: PrismaObjectFieldsShape<
|
|
266
|
+
Types,
|
|
267
|
+
Model,
|
|
268
|
+
FindUnique extends null ? true : false,
|
|
269
|
+
Shape & (FindUnique extends null ? {} : { [prismaModelName]?: Model['Name'] }),
|
|
270
|
+
Select
|
|
271
|
+
>;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export type PrismaInterfaceTypeOptions<
|
|
275
|
+
Types extends SchemaTypes,
|
|
276
|
+
Model extends PrismaModelTypes,
|
|
277
|
+
Interfaces extends InterfaceParam<Types>[],
|
|
278
|
+
FindUnique,
|
|
279
|
+
Include,
|
|
280
|
+
Select,
|
|
281
|
+
Shape extends object,
|
|
282
|
+
> = PrismaInterfaceRefOptions<Types, Model, FindUnique, Include, Select, Shape> &
|
|
283
|
+
PrismaInterfaceImplementationOptions<Types, Model, Interfaces, FindUnique, Select, Shape>;
|
|
284
|
+
|
|
231
285
|
type NameOrVariant =
|
|
232
286
|
| {
|
|
233
287
|
name?: never;
|
|
@@ -394,14 +448,14 @@ export type RelatedFieldOptions<
|
|
|
394
448
|
>;
|
|
395
449
|
}) & {
|
|
396
450
|
description?: string | false;
|
|
397
|
-
type?:
|
|
451
|
+
type?: PrismaRef<TypesForRelation<Types, Model, Field>>;
|
|
398
452
|
query?: QueryForField<Types, Args, Model['Include'][Field & keyof Model['Include']]>;
|
|
399
453
|
};
|
|
400
454
|
|
|
401
455
|
export type VariantFieldOptions<
|
|
402
456
|
Types extends SchemaTypes,
|
|
403
457
|
Model extends PrismaModelTypes,
|
|
404
|
-
Variant extends
|
|
458
|
+
Variant extends PrismaRef<Model>,
|
|
405
459
|
Args extends InputFieldMap,
|
|
406
460
|
isNull,
|
|
407
461
|
Shape,
|
|
@@ -458,10 +512,10 @@ export type PrismaFieldOptions<
|
|
|
458
512
|
Types extends SchemaTypes,
|
|
459
513
|
ParentShape,
|
|
460
514
|
Type extends
|
|
461
|
-
|
|
|
515
|
+
| PrismaRef<PrismaModelTypes>
|
|
462
516
|
| keyof Types['PrismaTypes']
|
|
463
517
|
| [keyof Types['PrismaTypes']]
|
|
464
|
-
| [
|
|
518
|
+
| [PrismaRef<PrismaModelTypes>],
|
|
465
519
|
Model extends PrismaModelTypes,
|
|
466
520
|
Param extends TypeParam<Types>,
|
|
467
521
|
Args extends InputFieldMap,
|
|
@@ -494,10 +548,10 @@ export type PrismaFieldWithInputOptions<
|
|
|
494
548
|
Args extends Record<string, InputFieldRef<unknown, 'Arg'>>,
|
|
495
549
|
Fields extends Record<string, InputFieldRef<unknown, 'InputObject'>>,
|
|
496
550
|
Type extends
|
|
497
|
-
|
|
|
551
|
+
| PrismaRef<PrismaModelTypes>
|
|
498
552
|
| keyof Types['PrismaTypes']
|
|
499
553
|
| [keyof Types['PrismaTypes']]
|
|
500
|
-
| [
|
|
554
|
+
| [PrismaRef<PrismaModelTypes>],
|
|
501
555
|
Model extends PrismaModelTypes,
|
|
502
556
|
Param extends TypeParam<Types>,
|
|
503
557
|
Nullable extends FieldNullability<Param>,
|
|
@@ -562,7 +616,10 @@ export type PrismaFieldResolver<
|
|
|
562
616
|
export type PrismaConnectionFieldOptions<
|
|
563
617
|
Types extends SchemaTypes,
|
|
564
618
|
ParentShape,
|
|
565
|
-
Type extends
|
|
619
|
+
Type extends
|
|
620
|
+
| PrismaRef<PrismaModelTypes>
|
|
621
|
+
| PrismaInterfaceRef<PrismaModelTypes>
|
|
622
|
+
| keyof Types['PrismaTypes'],
|
|
566
623
|
Model extends PrismaModelTypes,
|
|
567
624
|
Param extends OutputType<Types>,
|
|
568
625
|
Nullable extends boolean,
|
|
@@ -665,7 +722,7 @@ export type RelatedConnectionOptions<
|
|
|
665
722
|
? {
|
|
666
723
|
description?: string | false;
|
|
667
724
|
query?: QueryForField<Types, Args, Model['Include'][Field & keyof Model['Include']]>;
|
|
668
|
-
type?:
|
|
725
|
+
type?: PrismaRef<TypesForRelation<Types, Model, Field>>;
|
|
669
726
|
cursor: CursorFromRelation<Model, Field>;
|
|
670
727
|
defaultSize?: number | ((args: ConnectionArgs, ctx: Types['Context']) => number);
|
|
671
728
|
maxSize?: number | ((args: ConnectionArgs, ctx: Types['Context']) => number);
|
package/src/util/datamodel.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ObjectRef, PothosSchemaError, SchemaTypes } from '@pothos/core';
|
|
2
|
+
import { PrismaInterfaceRef, PrismaRef } from '../interface-ref';
|
|
2
3
|
import { PrismaObjectRef } from '../object-ref';
|
|
3
4
|
import { PrismaClient, PrismaDelegate, PrismaModelTypes } from '../types';
|
|
4
5
|
import { getDMMF } from './get-client';
|
|
5
6
|
|
|
6
|
-
export const refMap = new WeakMap<object, Map<string,
|
|
7
|
+
export const refMap = new WeakMap<object, Map<string, PrismaRef<PrismaModelTypes>>>();
|
|
7
8
|
export const findUniqueMap = new WeakMap<
|
|
8
9
|
object,
|
|
9
10
|
Map<ObjectRef<unknown>, ((args: unknown, ctx: {}) => unknown) | null>
|
|
@@ -17,14 +18,18 @@ export const includeForRefMap = new WeakMap<
|
|
|
17
18
|
export function getRefFromModel<Types extends SchemaTypes>(
|
|
18
19
|
name: string,
|
|
19
20
|
builder: PothosSchemaTypes.SchemaBuilder<Types>,
|
|
20
|
-
|
|
21
|
+
type: 'object' | 'interface' = 'object',
|
|
22
|
+
): PrismaRef<PrismaModelTypes> {
|
|
21
23
|
if (!refMap.has(builder)) {
|
|
22
24
|
refMap.set(builder, new Map());
|
|
23
25
|
}
|
|
24
26
|
const cache = refMap.get(builder)!;
|
|
25
27
|
|
|
26
28
|
if (!cache.has(name)) {
|
|
27
|
-
cache.set(
|
|
29
|
+
cache.set(
|
|
30
|
+
name,
|
|
31
|
+
type === 'object' ? new PrismaObjectRef(name, name) : new PrismaInterfaceRef(name, name),
|
|
32
|
+
);
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
return cache.get(name)!;
|
package/src/util/map-query.ts
CHANGED
|
@@ -6,10 +6,12 @@ import {
|
|
|
6
6
|
getArgumentValues,
|
|
7
7
|
getNamedType,
|
|
8
8
|
GraphQLField,
|
|
9
|
+
GraphQLInterfaceType,
|
|
9
10
|
GraphQLNamedType,
|
|
10
11
|
GraphQLObjectType,
|
|
11
12
|
GraphQLResolveInfo,
|
|
12
13
|
InlineFragmentNode,
|
|
14
|
+
isInterfaceType,
|
|
13
15
|
isObjectType,
|
|
14
16
|
Kind,
|
|
15
17
|
SelectionSetNode,
|
|
@@ -31,6 +33,7 @@ import {
|
|
|
31
33
|
SelectionState,
|
|
32
34
|
selectionToQuery,
|
|
33
35
|
} from './selections';
|
|
36
|
+
import { wrapWithUsageCheck } from './usage';
|
|
34
37
|
|
|
35
38
|
function addTypeSelectionsForField(
|
|
36
39
|
type: GraphQLNamedType,
|
|
@@ -83,7 +86,7 @@ function addTypeSelectionsForField(
|
|
|
83
86
|
return;
|
|
84
87
|
}
|
|
85
88
|
|
|
86
|
-
if (!isObjectType(type)) {
|
|
89
|
+
if (!(isObjectType(type) || isInterfaceType(type))) {
|
|
87
90
|
return;
|
|
88
91
|
}
|
|
89
92
|
|
|
@@ -142,7 +145,7 @@ function resolveIndirectInclude(
|
|
|
142
145
|
for (const sel of selection.selectionSet.selections) {
|
|
143
146
|
switch (sel.kind) {
|
|
144
147
|
case Kind.FIELD:
|
|
145
|
-
if (sel.name.value === include.name && isObjectType(type)) {
|
|
148
|
+
if (sel.name.value === include.name && (isObjectType(type) || isInterfaceType(type))) {
|
|
146
149
|
const returnType = getNamedType(type.getFields()[sel.name.value].type);
|
|
147
150
|
|
|
148
151
|
resolveIndirectInclude(
|
|
@@ -195,13 +198,14 @@ function resolveIndirectInclude(
|
|
|
195
198
|
}
|
|
196
199
|
|
|
197
200
|
function addNestedSelections(
|
|
198
|
-
type: GraphQLObjectType,
|
|
201
|
+
type: GraphQLObjectType | GraphQLInterfaceType,
|
|
199
202
|
context: object,
|
|
200
203
|
info: GraphQLResolveInfo,
|
|
201
204
|
state: SelectionState,
|
|
202
205
|
selections: SelectionSetNode,
|
|
203
206
|
indirectPath: string[],
|
|
204
207
|
) {
|
|
208
|
+
let parentType = type;
|
|
205
209
|
for (const selection of selections.selections) {
|
|
206
210
|
switch (selection.kind) {
|
|
207
211
|
case Kind.FIELD:
|
|
@@ -209,12 +213,19 @@ function addNestedSelections(
|
|
|
209
213
|
|
|
210
214
|
continue;
|
|
211
215
|
case Kind.FRAGMENT_SPREAD:
|
|
212
|
-
|
|
216
|
+
parentType = info.schema.getType(
|
|
217
|
+
info.fragments[selection.name.value].typeCondition.name.value,
|
|
218
|
+
)! as GraphQLObjectType;
|
|
219
|
+
if (
|
|
220
|
+
isObjectType(type)
|
|
221
|
+
? parentType.name !== type.name
|
|
222
|
+
: parentType.extensions?.pothosPrismaModel !== type.extensions.pothosPrismaModel
|
|
223
|
+
) {
|
|
213
224
|
continue;
|
|
214
225
|
}
|
|
215
226
|
|
|
216
227
|
addNestedSelections(
|
|
217
|
-
|
|
228
|
+
parentType,
|
|
218
229
|
context,
|
|
219
230
|
info,
|
|
220
231
|
state,
|
|
@@ -225,11 +236,18 @@ function addNestedSelections(
|
|
|
225
236
|
continue;
|
|
226
237
|
|
|
227
238
|
case Kind.INLINE_FRAGMENT:
|
|
228
|
-
|
|
239
|
+
parentType = selection.typeCondition
|
|
240
|
+
? (info.schema.getType(selection.typeCondition.name.value) as GraphQLObjectType)
|
|
241
|
+
: type;
|
|
242
|
+
if (
|
|
243
|
+
isObjectType(type)
|
|
244
|
+
? parentType.name !== type.name
|
|
245
|
+
: parentType.extensions?.pothosPrismaModel !== type.extensions.pothosPrismaModel
|
|
246
|
+
) {
|
|
229
247
|
continue;
|
|
230
248
|
}
|
|
231
249
|
|
|
232
|
-
addNestedSelections(
|
|
250
|
+
addNestedSelections(parentType, context, info, state, selection.selectionSet, indirectPath);
|
|
233
251
|
|
|
234
252
|
continue;
|
|
235
253
|
|
|
@@ -242,7 +260,7 @@ function addNestedSelections(
|
|
|
242
260
|
}
|
|
243
261
|
|
|
244
262
|
function addFieldSelection(
|
|
245
|
-
type: GraphQLObjectType,
|
|
263
|
+
type: GraphQLObjectType | GraphQLInterfaceType,
|
|
246
264
|
context: object,
|
|
247
265
|
info: GraphQLResolveInfo,
|
|
248
266
|
state: SelectionState,
|
|
@@ -370,6 +388,7 @@ export function queryFromInfo<T extends SelectionMap['select'] | undefined = und
|
|
|
370
388
|
select,
|
|
371
389
|
path = [],
|
|
372
390
|
paths = [],
|
|
391
|
+
withUsageCheck = false,
|
|
373
392
|
}: {
|
|
374
393
|
context: object;
|
|
375
394
|
info: GraphQLResolveInfo;
|
|
@@ -377,6 +396,7 @@ export function queryFromInfo<T extends SelectionMap['select'] | undefined = und
|
|
|
377
396
|
select?: T;
|
|
378
397
|
path?: string[];
|
|
379
398
|
paths?: string[][];
|
|
399
|
+
withUsageCheck?: boolean;
|
|
380
400
|
}): { select: T } | { include?: {} } {
|
|
381
401
|
const returnType = getNamedType(info.returnType);
|
|
382
402
|
const type = typeName ? info.schema.getTypeMap()[typeName] : returnType;
|
|
@@ -437,7 +457,9 @@ export function queryFromInfo<T extends SelectionMap['select'] | undefined = und
|
|
|
437
457
|
|
|
438
458
|
setLoaderMappings(context, info, state.mappings);
|
|
439
459
|
|
|
440
|
-
|
|
460
|
+
const query = selectionToQuery(state) as { select: T };
|
|
461
|
+
|
|
462
|
+
return withUsageCheck ? wrapWithUsageCheck(query) : query;
|
|
441
463
|
}
|
|
442
464
|
|
|
443
465
|
export function selectionStateFromInfo(
|
|
@@ -449,8 +471,10 @@ export function selectionStateFromInfo(
|
|
|
449
471
|
|
|
450
472
|
const state = createStateForType(type, info);
|
|
451
473
|
|
|
452
|
-
if (!isObjectType(type)) {
|
|
453
|
-
throw new PothosValidationError(
|
|
474
|
+
if (!(isObjectType(type) || isInterfaceType(type))) {
|
|
475
|
+
throw new PothosValidationError(
|
|
476
|
+
'Prisma plugin can only resolve includes for object and interface types',
|
|
477
|
+
);
|
|
454
478
|
}
|
|
455
479
|
|
|
456
480
|
addFieldSelection(type, context, info, state, info.fieldNodes[0], []);
|
|
@@ -498,7 +522,7 @@ function normalizeInclude(path: string[], type: GraphQLNamedType): IndirectInclu
|
|
|
498
522
|
|
|
499
523
|
const normalized: { name: string; type: string }[] = [];
|
|
500
524
|
|
|
501
|
-
if (!isObjectType(currentType)) {
|
|
525
|
+
if (!(isObjectType(currentType) || isInterfaceType(currentType))) {
|
|
502
526
|
throw new PothosValidationError(`Expected ${currentType} to be an Object type`);
|
|
503
527
|
}
|
|
504
528
|
|
|
@@ -511,8 +535,8 @@ function normalizeInclude(path: string[], type: GraphQLNamedType): IndirectInclu
|
|
|
511
535
|
|
|
512
536
|
currentType = getNamedType(field.type);
|
|
513
537
|
|
|
514
|
-
if (!isObjectType(currentType)) {
|
|
515
|
-
throw new PothosValidationError(`Expected ${currentType} to be an Object type`);
|
|
538
|
+
if (!(isObjectType(currentType) || isInterfaceType(currentType))) {
|
|
539
|
+
throw new PothosValidationError(`Expected ${currentType} to be an Object or Interface type`);
|
|
516
540
|
}
|
|
517
541
|
|
|
518
542
|
normalized.push({ name: fieldName, type: currentType.name });
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const usageSymbol = Symbol.for('Pothos.isUsed');
|
|
2
|
+
|
|
3
|
+
export function wrapWithUsageCheck<T extends Object>(obj: T): T {
|
|
4
|
+
const result = {};
|
|
5
|
+
let used = true;
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(result, usageSymbol, {
|
|
8
|
+
get() {
|
|
9
|
+
return used;
|
|
10
|
+
},
|
|
11
|
+
enumerable: false,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
for (const key of Object.keys(obj)) {
|
|
15
|
+
// only set to false if the object has keys
|
|
16
|
+
used = false;
|
|
17
|
+
Object.defineProperty(result, key, {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
21
|
+
get() {
|
|
22
|
+
used = true;
|
|
23
|
+
return obj[key as keyof T];
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return result as T;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function isUsed(obj: object): boolean {
|
|
32
|
+
return !(usageSymbol in obj) || (obj as { [usageSymbol]: boolean })[usageSymbol];
|
|
33
|
+
}
|