@pothos/plugin-prisma 3.12.1 → 3.13.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 +15 -2
- package/README.md +10 -16
- package/dts/field-builder.d.ts.map +1 -1
- package/dts/global-types.d.ts +7 -0
- package/dts/global-types.d.ts.map +1 -1
- package/dts/index.d.ts +4 -2
- package/dts/index.d.ts.map +1 -1
- package/dts/model-loader.d.ts +1 -0
- package/dts/model-loader.d.ts.map +1 -1
- package/dts/prisma-field-builder.d.ts +9 -0
- package/dts/prisma-field-builder.d.ts.map +1 -1
- package/dts/types.d.ts +2 -1
- package/dts/types.d.ts.map +1 -1
- package/dts/util/cursors.d.ts +1 -1
- package/dts/util/cursors.d.ts.map +1 -1
- 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/esm/field-builder.js +5 -1
- package/esm/field-builder.js.map +1 -1
- package/esm/global-types.js.map +1 -1
- package/esm/index.js +2 -1
- package/esm/index.js.map +1 -1
- package/esm/model-loader.js +30 -0
- package/esm/model-loader.js.map +1 -1
- package/esm/prisma-field-builder.js +53 -26
- package/esm/prisma-field-builder.js.map +1 -1
- package/esm/schema-builder.js +7 -2
- package/esm/schema-builder.js.map +1 -1
- package/esm/types.js.map +1 -1
- package/esm/util/cursors.js.map +1 -1
- package/esm/util/datamodel.js +18 -2
- package/esm/util/datamodel.js.map +1 -1
- package/esm/util/map-query.js +4 -1
- package/esm/util/map-query.js.map +1 -1
- package/lib/field-builder.js +25 -59
- package/lib/field-builder.js.map +1 -1
- package/lib/generator.js +10 -7
- package/lib/generator.js.map +1 -1
- package/lib/index.js +32 -26
- package/lib/index.js.map +1 -1
- package/lib/model-loader.js +46 -13
- package/lib/model-loader.js.map +1 -1
- package/lib/node-ref.js +8 -6
- package/lib/node-ref.js.map +1 -1
- package/lib/object-ref.js +11 -4
- package/lib/object-ref.js.map +1 -1
- package/lib/prisma-field-builder.js +71 -41
- package/lib/prisma-field-builder.js.map +1 -1
- package/lib/schema-builder.js +27 -19
- package/lib/schema-builder.js.map +1 -1
- package/lib/types.js +4 -2
- package/lib/types.js.map +1 -1
- package/lib/util/cursors.js +22 -14
- package/lib/util/cursors.js.map +1 -1
- package/lib/util/datamodel.js +38 -16
- package/lib/util/datamodel.js.map +1 -1
- package/lib/util/deep-equal.js +4 -1
- package/lib/util/deep-equal.js.map +1 -1
- package/lib/util/get-client.js +12 -4
- package/lib/util/get-client.js.map +1 -1
- package/lib/util/loader-map.js +13 -5
- package/lib/util/loader-map.js.map +1 -1
- package/lib/util/map-query.js +39 -28
- package/lib/util/map-query.js.map +1 -1
- package/lib/util/relation-map.js +12 -5
- package/lib/util/relation-map.js.map +1 -1
- package/lib/util/selections.js +17 -9
- package/lib/util/selections.js.map +1 -1
- package/package.json +6 -7
- package/src/field-builder.ts +3 -1
- package/src/global-types.ts +16 -0
- package/src/index.ts +17 -1
- package/src/model-loader.ts +36 -0
- package/src/prisma-field-builder.ts +108 -22
- package/src/schema-builder.ts +11 -5
- package/src/types.ts +3 -2
- package/src/util/cursors.ts +1 -1
- package/src/util/datamodel.ts +21 -3
- package/src/util/map-query.ts +10 -1
- package/tsconfig.type.tsbuildinfo +1 -1
|
@@ -14,12 +14,14 @@ import {
|
|
|
14
14
|
SchemaTypes,
|
|
15
15
|
TypeParam,
|
|
16
16
|
} from '@pothos/core';
|
|
17
|
+
import { ModelLoader } from './model-loader';
|
|
17
18
|
import { PrismaObjectRef } from './object-ref';
|
|
18
19
|
import {
|
|
19
20
|
PrismaModelTypes,
|
|
20
21
|
RelatedConnectionOptions,
|
|
21
22
|
RelatedFieldOptions,
|
|
22
23
|
RelationCountOptions,
|
|
24
|
+
SelectionMap,
|
|
23
25
|
ShapeFromConnection,
|
|
24
26
|
VariantFieldOptions,
|
|
25
27
|
} from './types';
|
|
@@ -43,6 +45,25 @@ const RootBuilder: {
|
|
|
43
45
|
): PothosSchemaTypes.RootFieldBuilder<Types, Shape, Kind>;
|
|
44
46
|
} = RootFieldBuilder as never;
|
|
45
47
|
|
|
48
|
+
type ContextForAuth<
|
|
49
|
+
Types extends SchemaTypes,
|
|
50
|
+
Scopes extends {} = {},
|
|
51
|
+
> = PothosSchemaTypes.ScopeAuthContextForAuth<Types, Scopes> extends {
|
|
52
|
+
Context: infer T;
|
|
53
|
+
}
|
|
54
|
+
? T
|
|
55
|
+
: never;
|
|
56
|
+
|
|
57
|
+
type FieldAuthScopes<
|
|
58
|
+
Types extends SchemaTypes,
|
|
59
|
+
Parent,
|
|
60
|
+
Args extends {} = {},
|
|
61
|
+
> = PothosSchemaTypes.ScopeAuthFieldAuthScopes<Types, Parent, Args> extends {
|
|
62
|
+
Scopes: infer T;
|
|
63
|
+
}
|
|
64
|
+
? T
|
|
65
|
+
: never;
|
|
66
|
+
|
|
46
67
|
export class PrismaObjectFieldBuilder<
|
|
47
68
|
Types extends SchemaTypes,
|
|
48
69
|
Model extends PrismaModelTypes,
|
|
@@ -63,6 +84,17 @@ export class PrismaObjectFieldBuilder<
|
|
|
63
84
|
exposeIDList = this.createExpose(['ID']);
|
|
64
85
|
exposeStringList = this.createExpose(['String']);
|
|
65
86
|
|
|
87
|
+
withAuth: 'scopeAuth' extends PluginName
|
|
88
|
+
? <Scopes extends FieldAuthScopes<Types, Shape, Record<string, unknown>>>(
|
|
89
|
+
scopes: Scopes,
|
|
90
|
+
) => PothosSchemaTypes.PrismaObjectFieldBuilder<
|
|
91
|
+
Omit<Types, 'Context'> & { Context: ContextForAuth<Types, Scopes> },
|
|
92
|
+
Model,
|
|
93
|
+
NeedsResolve,
|
|
94
|
+
Shape
|
|
95
|
+
>
|
|
96
|
+
: '@pothos/plugin-scope-auth is required to use this method' = (() => {}) as never;
|
|
97
|
+
|
|
66
98
|
relatedConnection: 'relay' extends PluginName
|
|
67
99
|
? <
|
|
68
100
|
Field extends Model['ListRelations'],
|
|
@@ -133,35 +165,53 @@ export class PrismaObjectFieldBuilder<
|
|
|
133
165
|
args,
|
|
134
166
|
}),
|
|
135
167
|
});
|
|
168
|
+
const cursorSelection = ModelLoader.getCursorSelection(
|
|
169
|
+
ref,
|
|
170
|
+
relationField.type,
|
|
171
|
+
cursor,
|
|
172
|
+
this.builder,
|
|
173
|
+
);
|
|
136
174
|
|
|
137
175
|
const relationSelect = (
|
|
138
176
|
args: object,
|
|
139
177
|
context: object,
|
|
140
178
|
nestedQuery: (query: unknown, path: unknown) => unknown,
|
|
141
|
-
) =>
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
179
|
+
) => {
|
|
180
|
+
const nested = nestedQuery(
|
|
181
|
+
{
|
|
182
|
+
...((typeof query === 'function' ? query(args, context) : query) as {}),
|
|
183
|
+
...prismaCursorConnectionQuery({
|
|
184
|
+
parseCursor,
|
|
185
|
+
maxSize,
|
|
186
|
+
defaultSize,
|
|
187
|
+
args,
|
|
188
|
+
}),
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
getType: () => {
|
|
192
|
+
if (!typeName) {
|
|
193
|
+
typeName = this.builder.configStore.getTypeConfig(ref).name;
|
|
194
|
+
}
|
|
195
|
+
return typeName;
|
|
152
196
|
},
|
|
153
|
-
{
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
197
|
+
path: [{ name: 'edges' }, { name: 'node' }],
|
|
198
|
+
},
|
|
199
|
+
) as SelectionMap;
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
select: {
|
|
203
|
+
[name]: nested?.select
|
|
204
|
+
? {
|
|
205
|
+
...nested,
|
|
206
|
+
select: {
|
|
207
|
+
...cursorSelection,
|
|
208
|
+
...nested.select,
|
|
209
|
+
},
|
|
157
210
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
),
|
|
163
|
-
},
|
|
164
|
-
});
|
|
211
|
+
: nested,
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
};
|
|
165
215
|
|
|
166
216
|
const fieldRef = (
|
|
167
217
|
this as unknown as {
|
|
@@ -448,3 +498,39 @@ export class PrismaObjectFieldBuilder<
|
|
|
448
498
|
};
|
|
449
499
|
}
|
|
450
500
|
}
|
|
501
|
+
|
|
502
|
+
const prismaFieldBuilderProto = PrismaObjectFieldBuilder.prototype as {} as Omit<
|
|
503
|
+
PrismaObjectFieldBuilder<SchemaTypes, PrismaModelTypes, false, {}>,
|
|
504
|
+
'withAuth'
|
|
505
|
+
> & {
|
|
506
|
+
withAuth: (scopes: {}) => unknown;
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
prismaFieldBuilderProto.withAuth = function withAuth(scopes) {
|
|
510
|
+
return addScopes(
|
|
511
|
+
scopes,
|
|
512
|
+
new PrismaObjectFieldBuilder(
|
|
513
|
+
this.typename,
|
|
514
|
+
this.builder,
|
|
515
|
+
this.model,
|
|
516
|
+
this.prismaFieldMap,
|
|
517
|
+
) as never,
|
|
518
|
+
);
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
function addScopes(
|
|
522
|
+
scopes: unknown,
|
|
523
|
+
builder: { createField: (options: Record<string, unknown>) => unknown },
|
|
524
|
+
) {
|
|
525
|
+
const originalCreateField = builder.createField;
|
|
526
|
+
|
|
527
|
+
// eslint-disable-next-line no-param-reassign
|
|
528
|
+
builder.createField = function createField(options) {
|
|
529
|
+
return originalCreateField.call(this, {
|
|
530
|
+
authScopes: scopes,
|
|
531
|
+
...options,
|
|
532
|
+
});
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
return builder as never;
|
|
536
|
+
}
|
package/src/schema-builder.ts
CHANGED
|
@@ -97,11 +97,17 @@ schemaBuilderProto.prismaNode = function prismaNode(
|
|
|
97
97
|
) => {
|
|
98
98
|
const query = queryFromInfo(context, info, typeName);
|
|
99
99
|
const delegate = getDelegateFromModel(getClient(this, context), type);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
100
|
+
|
|
101
|
+
const record = await (delegate.findUniqueOrThrow
|
|
102
|
+
? delegate.findUniqueOrThrow({
|
|
103
|
+
...query,
|
|
104
|
+
where: rawFindUnique ? rawFindUnique(id, context) : { [fieldName]: idParser!(id) },
|
|
105
|
+
} as never)
|
|
106
|
+
: delegate.findUnique({
|
|
107
|
+
...query,
|
|
108
|
+
rejectOnNotFound: true,
|
|
109
|
+
where: rawFindUnique ? rawFindUnique(id, context) : { [fieldName]: idParser!(id) },
|
|
110
|
+
} as never));
|
|
105
111
|
|
|
106
112
|
brandWithType(record, typeName as OutputType<SchemaTypes>);
|
|
107
113
|
|
package/src/types.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { PrismaObjectFieldBuilder } from './field-builder';
|
|
|
24
24
|
import { PrismaObjectRef } from './object-ref';
|
|
25
25
|
|
|
26
26
|
export interface PrismaDelegate {
|
|
27
|
+
findUniqueOrThrow?: (...args: any[]) => Promise<unknown>;
|
|
27
28
|
findUnique: (...args: any[]) => Promise<unknown>;
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -517,10 +518,10 @@ export type RelatedConnectionOptions<
|
|
|
517
518
|
Model['Shape'],
|
|
518
519
|
ObjectRef<unknown>,
|
|
519
520
|
Nullable,
|
|
520
|
-
Args
|
|
521
|
+
Args & InputFieldsFromShape<PothosSchemaTypes.DefaultConnectionArguments>,
|
|
521
522
|
unknown
|
|
522
523
|
>,
|
|
523
|
-
'resolve' | 'type'
|
|
524
|
+
'resolve' | 'type' | 'args'
|
|
524
525
|
> &
|
|
525
526
|
Omit<
|
|
526
527
|
PothosSchemaTypes.ConnectionFieldOptions<
|
package/src/util/cursors.ts
CHANGED
|
@@ -174,7 +174,7 @@ export function serializeID(id: unknown, dataType: string) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
export function parseCompositeCursor(fields: string[]) {
|
|
177
|
-
return (cursor:
|
|
177
|
+
return (cursor: unknown) => {
|
|
178
178
|
const parsed = parseRawCursor(cursor) as unknown[];
|
|
179
179
|
|
|
180
180
|
if (!Array.isArray(parsed)) {
|
package/src/util/datamodel.ts
CHANGED
|
@@ -72,8 +72,15 @@ export function getCursorFormatter<Types extends SchemaTypes>(
|
|
|
72
72
|
) {
|
|
73
73
|
const modelData = getModel(name, builder);
|
|
74
74
|
const primaryKey = modelData.primaryKey?.name ?? modelData.primaryKey?.fields.join('_');
|
|
75
|
+
if (primaryKey === cursor) {
|
|
76
|
+
return formatCursor(modelData.primaryKey!.fields);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const uniqueIndex = modelData.uniqueIndexes.find(
|
|
80
|
+
(idx) => (idx.name ?? idx.fields.join('_')) === cursor,
|
|
81
|
+
);
|
|
75
82
|
|
|
76
|
-
return formatCursor(
|
|
83
|
+
return formatCursor(uniqueIndex?.fields ?? cursor);
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
export function getCursorParser<Types extends SchemaTypes>(
|
|
@@ -84,8 +91,19 @@ export function getCursorParser<Types extends SchemaTypes>(
|
|
|
84
91
|
const modelData = getModel(name, builder);
|
|
85
92
|
const primaryKey = modelData.primaryKey?.name ?? modelData.primaryKey?.fields.join('_');
|
|
86
93
|
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
let parser = parseRawCursor;
|
|
95
|
+
|
|
96
|
+
if (primaryKey === cursor) {
|
|
97
|
+
parser = parseCompositeCursor(modelData.primaryKey!.fields);
|
|
98
|
+
} else {
|
|
99
|
+
const uniqueIndex = modelData.uniqueIndexes.find(
|
|
100
|
+
(idx) => (idx.name ?? idx.fields.join('_')) === cursor,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
if (uniqueIndex) {
|
|
104
|
+
parser = parseCompositeCursor(uniqueIndex.fields);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
89
107
|
|
|
90
108
|
return (rawCursor: string) => ({
|
|
91
109
|
[cursor]: parser(rawCursor),
|
package/src/util/map-query.ts
CHANGED
|
@@ -306,10 +306,19 @@ function addFieldSelection(
|
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
-
export function queryFromInfo(
|
|
309
|
+
export function queryFromInfo(
|
|
310
|
+
context: object,
|
|
311
|
+
info: GraphQLResolveInfo,
|
|
312
|
+
typeName?: string,
|
|
313
|
+
initialSelection?: SelectionMap,
|
|
314
|
+
): {} {
|
|
310
315
|
const type = typeName ? info.schema.getTypeMap()[typeName] : getNamedType(info.returnType);
|
|
311
316
|
const state = createStateForType(type, info);
|
|
312
317
|
|
|
318
|
+
if (initialSelection) {
|
|
319
|
+
mergeSelection(state, initialSelection);
|
|
320
|
+
}
|
|
321
|
+
|
|
313
322
|
addTypeSelectionsForField(type, context, info, state, info.fieldNodes[0], []);
|
|
314
323
|
|
|
315
324
|
setLoaderMappings(context, info, state.mappings);
|