orchid-graphql 1.4.4 → 1.5.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/README.md +18 -20
- package/dist/index.cjs +290 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +179 -0
- package/dist/index.d.ts +14 -1
- package/dist/index.js +284 -2
- package/dist/index.js.map +1 -1
- package/package.json +10 -14
- package/src/orm/orm.ts +2 -2
- package/src/resolvers/graph.ts +1 -1
- package/src/resolvers/table.ts +1 -1
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { GraphQLResolveInfo } from 'graphql';
|
|
2
|
+
import { DbTable } from 'orchid-orm';
|
|
3
|
+
import { Query } from 'pqb';
|
|
4
|
+
|
|
5
|
+
interface FieldResolverOptions<Orm extends OrmAdapter, Context> {
|
|
6
|
+
/** Table field (if different from GraphQL field) */
|
|
7
|
+
tableField?: string;
|
|
8
|
+
/** Legacy alias for `tableField`. */
|
|
9
|
+
modelField?: string;
|
|
10
|
+
/** Custom query modifier (if different than simply selecting a field). */
|
|
11
|
+
modify?: FieldResolveModifier<Orm, Context>;
|
|
12
|
+
/** Post-process selected value. Return a new value or a promise. */
|
|
13
|
+
transform?(value: any, instance: any, context: FieldResolveContext<Orm, Context>): any;
|
|
14
|
+
}
|
|
15
|
+
type FieldResolveModifier<Orm extends OrmAdapter, Context> = (query: Orm["Query"], context: FieldResolveContext<Orm, Context>) => Orm["Query"];
|
|
16
|
+
interface FieldResolveContext<Orm extends OrmAdapter, Context> extends TableResolveContext<Orm, Context> {
|
|
17
|
+
/** GraphQL field */
|
|
18
|
+
field: string;
|
|
19
|
+
}
|
|
20
|
+
type FieldResolver<Orm extends OrmAdapter, Context> = FieldResolveModifier<Orm, Context>;
|
|
21
|
+
declare function defineFieldResolver<Orm extends OrmAdapter, Context>(options?: FieldResolverOptions<Orm, Context>): FieldResolver<Orm, Context>;
|
|
22
|
+
|
|
23
|
+
interface TableResolverOptions<Orm extends OrmAdapter, Context> {
|
|
24
|
+
/** allow to resolve all table fields without explicitly listing them */
|
|
25
|
+
allowAllFields?: boolean;
|
|
26
|
+
/** allow to filter all table fields without explicitly listing them */
|
|
27
|
+
allowAllFilters?: boolean;
|
|
28
|
+
fields?: Record<string, SimpleFieldResolver<Orm, Context>>;
|
|
29
|
+
modifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>;
|
|
30
|
+
modify?: TableResolveModifier<Orm, Context>;
|
|
31
|
+
transform?(instance: any, context: any): void | PromiseLike<void>;
|
|
32
|
+
}
|
|
33
|
+
type SimpleFieldResolver<Orm extends OrmAdapter, Context> = true | string | FieldResolver<Orm, Context>;
|
|
34
|
+
type TableResolveModifier<Orm extends OrmAdapter, Context> = (query: Orm["Query"], context: TableResolveContext<Orm, Context>) => Orm["Query"];
|
|
35
|
+
interface TableResolveContext<Orm extends OrmAdapter, Context> extends GraphResolveContext<Context> {
|
|
36
|
+
graph: GraphResolver<Orm, Context>;
|
|
37
|
+
/** GraphQL type */
|
|
38
|
+
type: string;
|
|
39
|
+
}
|
|
40
|
+
declare class TableResolver<Orm extends OrmAdapter, Context> {
|
|
41
|
+
readonly orm: Orm;
|
|
42
|
+
readonly table: Orm["Table"];
|
|
43
|
+
readonly options: TableResolverOptions<Orm, Context>;
|
|
44
|
+
readonly relations: Set<string>;
|
|
45
|
+
readonly virtual_fields: Set<string>;
|
|
46
|
+
readonly modifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>;
|
|
47
|
+
readonly table_field_resolvers?: Record<string, FieldResolver<Orm, Context>>;
|
|
48
|
+
constructor(orm: Orm, table: Orm["Table"], options?: TableResolverOptions<Orm, Context>);
|
|
49
|
+
/** Modify query to select fields/relations and filter the result set. */
|
|
50
|
+
resolve(query: Orm["Query"], context: TableResolveContext<Orm, Context>): Orm["Query"];
|
|
51
|
+
/**
|
|
52
|
+
* Create field resolver which will modify query to resolve GraphQL field.
|
|
53
|
+
*/
|
|
54
|
+
_get_default_field_resolver(field: string, tableField?: string): FieldResolver<Orm, Context>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type FiltersDef = boolean;
|
|
58
|
+
type ApplyFiltersModifier<Orm extends OrmAdapter, Context> = (query: Orm["Query"], value: any, context: TableResolveContext<Orm, Context>) => Orm["Query"];
|
|
59
|
+
|
|
60
|
+
interface FieldsByTypeName {
|
|
61
|
+
[str: string]: {
|
|
62
|
+
[str: string]: ResolveTree;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
interface ResolveTree {
|
|
66
|
+
name: string;
|
|
67
|
+
alias: string;
|
|
68
|
+
args: {
|
|
69
|
+
[str: string]: unknown;
|
|
70
|
+
};
|
|
71
|
+
fieldsByTypeName: FieldsByTypeName;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type GraphResolverOptions<Orm extends OrmAdapter, Context> = Pick<TableResolverOptions<Orm, Context>, "allowAllFields" | "allowAllFilters">;
|
|
75
|
+
interface GraphResolveOptions<Context> {
|
|
76
|
+
info: GraphQLResolveInfo;
|
|
77
|
+
context: Context;
|
|
78
|
+
filters?: FiltersDef;
|
|
79
|
+
/** Subfield path if not resolving root query, e.g.: ['user'] */
|
|
80
|
+
path?: string[];
|
|
81
|
+
}
|
|
82
|
+
type GraphResolveContext<Context> = Omit<GraphResolveOptions<Context>, "info"> & {
|
|
83
|
+
tree: ResolveTree;
|
|
84
|
+
};
|
|
85
|
+
declare class GraphResolver<Orm extends OrmAdapter, Context> {
|
|
86
|
+
readonly orm: Orm;
|
|
87
|
+
readonly type_resolvers: Record<string, TableResolver<Orm, Context>>;
|
|
88
|
+
readonly options: GraphResolverOptions<Orm, Context>;
|
|
89
|
+
constructor(orm: Orm, type_resolvers: Record<string, TableResolver<Orm, Context>>, options?: GraphResolverOptions<Orm, Context>);
|
|
90
|
+
resolve(query: Orm["Query"], { info, ...context }: GraphResolveOptions<Context>): Orm["Query"] | undefined;
|
|
91
|
+
resolvePage(query: Orm["Query"], paginator: Paginator<Orm, Context>, { info, ...context }: GraphResolveOptions<Context>): Orm["QueryTransform"];
|
|
92
|
+
_get_resolve_tree(info: GraphQLResolveInfo): ResolveTree;
|
|
93
|
+
_resolve_type(query: Orm["Query"], context: GraphResolveContext<Context>): Orm["Query"] | undefined;
|
|
94
|
+
_resolve_page(query: Orm["Query"], paginator: Paginator<Orm, Context>, context: GraphResolveContext<Context>): Orm["QueryTransform"];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface Paginator<Orm extends OrmAdapter, Context> {
|
|
98
|
+
/** GraphQL path, for example: `["nodes"]` */
|
|
99
|
+
readonly path: string[];
|
|
100
|
+
paginate(query: Orm["Query"], context: PaginateContext<Orm, Context>): Orm["QueryTransform"];
|
|
101
|
+
}
|
|
102
|
+
interface PaginateContext<Orm extends OrmAdapter, Context> extends GraphResolveContext<Context> {
|
|
103
|
+
graph: GraphResolver<Orm, Context>;
|
|
104
|
+
}
|
|
105
|
+
type GetPageFn = (nodes: any[]) => any;
|
|
106
|
+
|
|
107
|
+
type OrmModifier<Orm extends OrmAdapter> = (query: Orm["Query"], ...args: any[]) => Orm["Query"];
|
|
108
|
+
interface OrmAdapter<Table = any, Query = any, QueryTransform = any> {
|
|
109
|
+
Table: Table;
|
|
110
|
+
Query: Query;
|
|
111
|
+
QueryTransform: QueryTransform;
|
|
112
|
+
/** ORM table -> db table */
|
|
113
|
+
get_table_table(table: Table): string;
|
|
114
|
+
/** ORM table -> relation names */
|
|
115
|
+
get_table_relations(table: Table): string[];
|
|
116
|
+
/** ORM table -> virtual fields */
|
|
117
|
+
get_table_virtual_fields(table: Table): string[];
|
|
118
|
+
get_table_modifiers(table: Table): Record<string, OrmModifier<this>> | undefined;
|
|
119
|
+
/** ORM query -> db table */
|
|
120
|
+
get_query_table(query: Query): string;
|
|
121
|
+
select_field(query: Query, opts: {
|
|
122
|
+
field: string;
|
|
123
|
+
as: string;
|
|
124
|
+
}): Query;
|
|
125
|
+
select_relation(query: Query, opts: {
|
|
126
|
+
relation: string;
|
|
127
|
+
as: string;
|
|
128
|
+
modify: (subquery: Query) => Query;
|
|
129
|
+
}): Query;
|
|
130
|
+
where(query: Query, field: string, op: string | undefined, value: any): Query;
|
|
131
|
+
where_raw(query: Query, expression: string, bindings: Record<string, any>): Query;
|
|
132
|
+
reset_query_order(query: Query): Query;
|
|
133
|
+
add_query_order(query: Query, field: string, desc: boolean): Query;
|
|
134
|
+
set_query_limit(query: Query, limit: number): Query;
|
|
135
|
+
set_query_page_result(query: Query, get_page: GetPageFn): QueryTransform;
|
|
136
|
+
modify_subquery_pagination(subquery: Query, context: Record<string, any>): Query;
|
|
137
|
+
finish_query_pagination(query: Query, field: string, context: Record<string, any>): Query;
|
|
138
|
+
/** Set ORM query to run callback afterwards */
|
|
139
|
+
run_after_query(query: Query, fn: (result: any) => any): Query;
|
|
140
|
+
/** Prevent `SELECT *` by explicitly selecting ID */
|
|
141
|
+
prevent_select_all(query: Query): Query;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
declare function defineCursorPaginator(options?: Partial<CursorPaginatorOptions>): CursorPaginator<OrmAdapter<any, any, any>, unknown>;
|
|
145
|
+
interface CursorPaginatorOptions {
|
|
146
|
+
fields: string[];
|
|
147
|
+
take: number;
|
|
148
|
+
}
|
|
149
|
+
declare class CursorPaginator<Orm extends OrmAdapter, Context> implements Paginator<Orm, Context> {
|
|
150
|
+
readonly path: string[];
|
|
151
|
+
readonly options: CursorPaginatorOptions;
|
|
152
|
+
readonly fields: Array<{
|
|
153
|
+
name: string;
|
|
154
|
+
desc: boolean;
|
|
155
|
+
}>;
|
|
156
|
+
constructor(options?: Partial<CursorPaginatorOptions>);
|
|
157
|
+
paginate(query: Orm["Query"], context: PaginateContext<Orm, Context>): any;
|
|
158
|
+
_create_cursor(instance: any): string;
|
|
159
|
+
_parse_cursor(cursor: string): {
|
|
160
|
+
expression: string;
|
|
161
|
+
bindings: Record<string, any>;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
interface RelationResolverOptions<Orm extends OrmAdapter, Context> extends Omit<FieldResolverOptions<Orm, Context>, "modify"> {
|
|
166
|
+
filters?: FiltersDef;
|
|
167
|
+
modify?: TableResolveModifier<Orm, Context>;
|
|
168
|
+
}
|
|
169
|
+
declare function defineRelationResolver<Orm extends OrmAdapter, Context>(options?: RelationResolverOptions<Orm, Context>): FieldResolver<Orm, Context>;
|
|
170
|
+
|
|
171
|
+
declare function definePageResolver<Orm extends OrmAdapter, Context>(paginator: Paginator<Orm, Context>, options?: RelationResolverOptions<Orm, Context>): FieldResolver<Orm, Context>;
|
|
172
|
+
|
|
173
|
+
type OrchidOrm = OrmAdapter<DbTable<any>, Query, Pick<Promise<any>, "then" | "catch">>;
|
|
174
|
+
|
|
175
|
+
declare function createGraphResolver<Context = unknown>(types: Record<string, TableResolver<OrchidOrm, Context>>, options?: GraphResolverOptions<OrchidOrm, Context>): GraphResolver<OrchidOrm, Context>;
|
|
176
|
+
|
|
177
|
+
declare function defineTableResolver<Context = unknown>(table: DbTable<any>, options?: TableResolverOptions<OrchidOrm, Context>): TableResolver<OrchidOrm, Context>;
|
|
178
|
+
|
|
179
|
+
export { createGraphResolver, defineCursorPaginator as cursor, defineCursorPaginator, defineFieldResolver, definePageResolver, defineRelationResolver, defineTableResolver, defineFieldResolver as field, createGraphResolver as graph, definePageResolver as page, defineRelationResolver as relation, defineTableResolver as table };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { GraphQLResolveInfo } from 'graphql';
|
|
2
|
-
import { ResolveTree } from 'graphql-parse-resolve-info';
|
|
3
2
|
import { DbTable } from 'orchid-orm';
|
|
4
3
|
import { Query } from 'pqb';
|
|
5
4
|
|
|
@@ -58,6 +57,20 @@ declare class TableResolver<Orm extends OrmAdapter, Context> {
|
|
|
58
57
|
type FiltersDef = boolean;
|
|
59
58
|
type ApplyFiltersModifier<Orm extends OrmAdapter, Context> = (query: Orm["Query"], value: any, context: TableResolveContext<Orm, Context>) => Orm["Query"];
|
|
60
59
|
|
|
60
|
+
interface FieldsByTypeName {
|
|
61
|
+
[str: string]: {
|
|
62
|
+
[str: string]: ResolveTree;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
interface ResolveTree {
|
|
66
|
+
name: string;
|
|
67
|
+
alias: string;
|
|
68
|
+
args: {
|
|
69
|
+
[str: string]: unknown;
|
|
70
|
+
};
|
|
71
|
+
fieldsByTypeName: FieldsByTypeName;
|
|
72
|
+
}
|
|
73
|
+
|
|
61
74
|
type GraphResolverOptions<Orm extends OrmAdapter, Context> = Pick<TableResolverOptions<Orm, Context>, "allowAllFields" | "allowAllFilters">;
|
|
62
75
|
interface GraphResolveOptions<Context> {
|
|
63
76
|
info: GraphQLResolveInfo;
|
package/dist/index.js
CHANGED
|
@@ -123,8 +123,289 @@ function defineFieldResolver(options = {}) {
|
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
// ../graphql-orm/src/utils/graphql-parse-resolve-info.ts
|
|
127
|
+
import assert from "node:assert";
|
|
128
|
+
import {
|
|
129
|
+
getNamedType,
|
|
130
|
+
GraphQLObjectType,
|
|
131
|
+
GraphQLUnionType,
|
|
132
|
+
isCompositeType
|
|
133
|
+
} from "graphql";
|
|
134
|
+
import { getArgumentValues } from "graphql";
|
|
135
|
+
|
|
136
|
+
// ../graphql-orm/src/utils/graphql-parse-resolve-info-debug.ts
|
|
137
|
+
function debugFactory(name) {
|
|
138
|
+
function debug2() {
|
|
139
|
+
}
|
|
140
|
+
debug2.enabled = false;
|
|
141
|
+
return debug2;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ../graphql-orm/src/utils/graphql-parse-resolve-info.ts
|
|
145
|
+
var debug = debugFactory("graphql-parse-resolve-info");
|
|
146
|
+
var DEBUG_ENABLED = debug.enabled;
|
|
147
|
+
function getArgVal(resolveInfo, argument) {
|
|
148
|
+
if (argument.kind === "Variable") {
|
|
149
|
+
return resolveInfo.variableValues[argument.name.value];
|
|
150
|
+
} else if (argument.kind === "BooleanValue") {
|
|
151
|
+
return argument.value;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function argNameIsIf(arg) {
|
|
155
|
+
return arg && arg.name ? arg.name.value === "if" : false;
|
|
156
|
+
}
|
|
157
|
+
function skipField(resolveInfo, { directives = [] }) {
|
|
158
|
+
let skip = false;
|
|
159
|
+
directives.forEach((directive) => {
|
|
160
|
+
const directiveName = directive.name.value;
|
|
161
|
+
if (Array.isArray(directive.arguments)) {
|
|
162
|
+
const ifArgumentAst = directive.arguments.find(argNameIsIf);
|
|
163
|
+
if (ifArgumentAst) {
|
|
164
|
+
const argumentValueAst = ifArgumentAst.value;
|
|
165
|
+
if (directiveName === "skip") {
|
|
166
|
+
skip = skip || getArgVal(resolveInfo, argumentValueAst);
|
|
167
|
+
} else if (directiveName === "include") {
|
|
168
|
+
skip = skip || !getArgVal(resolveInfo, argumentValueAst);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return skip;
|
|
174
|
+
}
|
|
175
|
+
function parseResolveInfo(resolveInfo, inOptions = {}) {
|
|
176
|
+
const fieldNodes = (
|
|
177
|
+
// @ts-ignore Property 'fieldASTs' does not exist on type 'GraphQLResolveInfo'.
|
|
178
|
+
resolveInfo.fieldNodes || resolveInfo.fieldASTs
|
|
179
|
+
);
|
|
180
|
+
const options = inOptions === true ? {} : inOptions;
|
|
181
|
+
const forceParse = inOptions === true || inOptions.forceParse;
|
|
182
|
+
const { parentType } = resolveInfo;
|
|
183
|
+
if (!fieldNodes) {
|
|
184
|
+
throw new Error("No fieldNodes provided!");
|
|
185
|
+
}
|
|
186
|
+
if (options.keepRoot == null) {
|
|
187
|
+
options.keepRoot = false;
|
|
188
|
+
}
|
|
189
|
+
if (options.deep == null) {
|
|
190
|
+
options.deep = true;
|
|
191
|
+
}
|
|
192
|
+
const tree = fieldTreeFromAST(
|
|
193
|
+
fieldNodes,
|
|
194
|
+
resolveInfo,
|
|
195
|
+
void 0,
|
|
196
|
+
options,
|
|
197
|
+
parentType
|
|
198
|
+
);
|
|
199
|
+
if (!options.keepRoot) {
|
|
200
|
+
const typeKey = firstKey(tree);
|
|
201
|
+
if (!typeKey) {
|
|
202
|
+
if (forceParse) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
`GraphQL schema issue: simplified parseResolveInfo failed (tree had no keys); perhaps you need to use the keepRoot option?`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
const fields = tree[typeKey];
|
|
210
|
+
const fieldKey = firstKey(fields);
|
|
211
|
+
if (!fieldKey) {
|
|
212
|
+
if (forceParse) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
`GraphQL schema issue: simplified parseResolveInfo failed (could not get key from fields); perhaps you need to use the keepRoot option?`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
return fields[fieldKey];
|
|
220
|
+
}
|
|
221
|
+
return tree;
|
|
222
|
+
}
|
|
223
|
+
function getFieldFromAST(ast, parentType) {
|
|
224
|
+
if (ast.kind === "Field") {
|
|
225
|
+
const fieldNode = ast;
|
|
226
|
+
const fieldName = fieldNode.name.value;
|
|
227
|
+
if (!(parentType instanceof GraphQLUnionType)) {
|
|
228
|
+
const type = parentType;
|
|
229
|
+
return type.getFields()[fieldName];
|
|
230
|
+
} else {
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return void 0;
|
|
234
|
+
}
|
|
235
|
+
var iNum = 1;
|
|
236
|
+
function fieldTreeFromAST(inASTs, resolveInfo, initTree = {}, options = {}, parentType, depth = "") {
|
|
237
|
+
const instance = iNum++;
|
|
238
|
+
if (DEBUG_ENABLED)
|
|
239
|
+
debug(
|
|
240
|
+
"%s[%d] Entering fieldTreeFromAST with parent type '%s'",
|
|
241
|
+
depth,
|
|
242
|
+
instance,
|
|
243
|
+
parentType
|
|
244
|
+
);
|
|
245
|
+
const { variableValues } = resolveInfo;
|
|
246
|
+
const fragments = resolveInfo.fragments || {};
|
|
247
|
+
const asts = Array.isArray(inASTs) ? inASTs : [inASTs];
|
|
248
|
+
if (!initTree[parentType.name]) {
|
|
249
|
+
initTree[parentType.name] = {};
|
|
250
|
+
}
|
|
251
|
+
const outerDepth = depth;
|
|
252
|
+
return asts.reduce((tree, selectionVal, idx) => {
|
|
253
|
+
const depth2 = DEBUG_ENABLED ? `${outerDepth} ` : null;
|
|
254
|
+
if (DEBUG_ENABLED)
|
|
255
|
+
debug(
|
|
256
|
+
"%s[%d] Processing AST %d of %d; kind = %s",
|
|
257
|
+
depth2,
|
|
258
|
+
instance,
|
|
259
|
+
idx + 1,
|
|
260
|
+
asts.length,
|
|
261
|
+
selectionVal.kind
|
|
262
|
+
);
|
|
263
|
+
if (skipField(resolveInfo, selectionVal)) {
|
|
264
|
+
if (DEBUG_ENABLED)
|
|
265
|
+
debug("%s[%d] IGNORING due to directive", depth2, instance);
|
|
266
|
+
} else if (selectionVal.kind === "Field") {
|
|
267
|
+
const val = selectionVal;
|
|
268
|
+
const name = val.name.value;
|
|
269
|
+
const isReserved = name[0] === "_" && name[1] === "_" && name !== "__id";
|
|
270
|
+
if (isReserved) {
|
|
271
|
+
if (DEBUG_ENABLED)
|
|
272
|
+
debug(
|
|
273
|
+
"%s[%d] IGNORING because field '%s' is reserved",
|
|
274
|
+
depth2,
|
|
275
|
+
instance,
|
|
276
|
+
name
|
|
277
|
+
);
|
|
278
|
+
} else {
|
|
279
|
+
const alias = val.alias && val.alias.value ? val.alias.value : name;
|
|
280
|
+
if (DEBUG_ENABLED)
|
|
281
|
+
debug(
|
|
282
|
+
"%s[%d] Field '%s' (alias = '%s')",
|
|
283
|
+
depth2,
|
|
284
|
+
instance,
|
|
285
|
+
name,
|
|
286
|
+
alias
|
|
287
|
+
);
|
|
288
|
+
const field = getFieldFromAST(val, parentType);
|
|
289
|
+
if (field == null) {
|
|
290
|
+
return tree;
|
|
291
|
+
}
|
|
292
|
+
const fieldGqlTypeOrUndefined = getNamedType(field.type);
|
|
293
|
+
if (!fieldGqlTypeOrUndefined) {
|
|
294
|
+
return tree;
|
|
295
|
+
}
|
|
296
|
+
const fieldGqlType = fieldGqlTypeOrUndefined;
|
|
297
|
+
const args = getArgumentValues(
|
|
298
|
+
field,
|
|
299
|
+
val,
|
|
300
|
+
variableValues
|
|
301
|
+
) || {};
|
|
302
|
+
if (parentType.name && !tree[parentType.name][alias]) {
|
|
303
|
+
const newTreeRoot = {
|
|
304
|
+
name,
|
|
305
|
+
alias,
|
|
306
|
+
args,
|
|
307
|
+
fieldsByTypeName: isCompositeType(fieldGqlType) ? {
|
|
308
|
+
[fieldGqlType.name]: {}
|
|
309
|
+
} : {}
|
|
310
|
+
};
|
|
311
|
+
tree[parentType.name][alias] = newTreeRoot;
|
|
312
|
+
}
|
|
313
|
+
const selectionSet = val.selectionSet;
|
|
314
|
+
if (selectionSet != null && options.deep && isCompositeType(fieldGqlType)) {
|
|
315
|
+
const newParentType = fieldGqlType;
|
|
316
|
+
if (DEBUG_ENABLED)
|
|
317
|
+
debug("%s[%d] Recursing into subfields", depth2, instance);
|
|
318
|
+
fieldTreeFromAST(
|
|
319
|
+
selectionSet.selections,
|
|
320
|
+
resolveInfo,
|
|
321
|
+
tree[parentType.name][alias].fieldsByTypeName,
|
|
322
|
+
options,
|
|
323
|
+
newParentType,
|
|
324
|
+
`${depth2} `
|
|
325
|
+
);
|
|
326
|
+
} else {
|
|
327
|
+
if (DEBUG_ENABLED)
|
|
328
|
+
debug("%s[%d] Exiting (no fields to add)", depth2, instance);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
} else if (selectionVal.kind === "FragmentSpread" && options.deep) {
|
|
332
|
+
const val = selectionVal;
|
|
333
|
+
const name = val.name && val.name.value;
|
|
334
|
+
if (DEBUG_ENABLED)
|
|
335
|
+
debug("%s[%d] Fragment spread '%s'", depth2, instance, name);
|
|
336
|
+
const fragment = fragments[name];
|
|
337
|
+
assert(fragment, 'unknown fragment "' + name + '"');
|
|
338
|
+
let fragmentType = parentType;
|
|
339
|
+
if (fragment.typeCondition) {
|
|
340
|
+
fragmentType = getType(resolveInfo, fragment.typeCondition);
|
|
341
|
+
}
|
|
342
|
+
if (fragmentType && isCompositeType(fragmentType)) {
|
|
343
|
+
const newParentType = fragmentType;
|
|
344
|
+
fieldTreeFromAST(
|
|
345
|
+
fragment.selectionSet.selections,
|
|
346
|
+
resolveInfo,
|
|
347
|
+
tree,
|
|
348
|
+
options,
|
|
349
|
+
newParentType,
|
|
350
|
+
`${depth2} `
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
} else if (selectionVal.kind === "InlineFragment" && options.deep) {
|
|
354
|
+
const val = selectionVal;
|
|
355
|
+
const fragment = val;
|
|
356
|
+
let fragmentType = parentType;
|
|
357
|
+
if (fragment.typeCondition) {
|
|
358
|
+
fragmentType = getType(resolveInfo, fragment.typeCondition);
|
|
359
|
+
}
|
|
360
|
+
if (DEBUG_ENABLED)
|
|
361
|
+
debug(
|
|
362
|
+
"%s[%d] Inline fragment (parent = '%s', type = '%s')",
|
|
363
|
+
depth2,
|
|
364
|
+
instance,
|
|
365
|
+
parentType,
|
|
366
|
+
fragmentType
|
|
367
|
+
);
|
|
368
|
+
if (fragmentType && isCompositeType(fragmentType)) {
|
|
369
|
+
const newParentType = fragmentType;
|
|
370
|
+
fieldTreeFromAST(
|
|
371
|
+
fragment.selectionSet.selections,
|
|
372
|
+
resolveInfo,
|
|
373
|
+
tree,
|
|
374
|
+
options,
|
|
375
|
+
newParentType,
|
|
376
|
+
`${depth2} `
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
} else {
|
|
380
|
+
if (DEBUG_ENABLED)
|
|
381
|
+
debug(
|
|
382
|
+
"%s[%d] IGNORING because kind '%s' not understood",
|
|
383
|
+
depth2,
|
|
384
|
+
instance,
|
|
385
|
+
selectionVal.kind
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
return tree;
|
|
389
|
+
}, initTree);
|
|
390
|
+
}
|
|
391
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
392
|
+
function firstKey(obj) {
|
|
393
|
+
for (const key in obj) {
|
|
394
|
+
if (hasOwnProperty.call(obj, key)) {
|
|
395
|
+
return key;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function getType(resolveInfo, typeCondition) {
|
|
400
|
+
const { schema } = resolveInfo;
|
|
401
|
+
const { kind, name } = typeCondition;
|
|
402
|
+
if (kind === "NamedType") {
|
|
403
|
+
const typeName = name.value;
|
|
404
|
+
return schema.getType(typeName);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
126
408
|
// ../graphql-orm/src/resolvers/graph.ts
|
|
127
|
-
import { parseResolveInfo } from "graphql-parse-resolve-info";
|
|
128
409
|
var GraphResolver = class {
|
|
129
410
|
constructor(orm2, type_resolvers, options = {}) {
|
|
130
411
|
this.orm = orm2;
|
|
@@ -341,6 +622,7 @@ var TableResolver = class {
|
|
|
341
622
|
};
|
|
342
623
|
|
|
343
624
|
// src/orm/orm.ts
|
|
625
|
+
import { raw } from "orchid-orm";
|
|
344
626
|
var orm = {
|
|
345
627
|
Table: void 0,
|
|
346
628
|
Query: void 0,
|
|
@@ -378,7 +660,7 @@ var orm = {
|
|
|
378
660
|
return query.where({ [field]: op ? { [op]: value } : value });
|
|
379
661
|
},
|
|
380
662
|
where_raw(query, expression, bindings) {
|
|
381
|
-
return query.where(
|
|
663
|
+
return query.where(raw({ raw: expression, values: bindings }));
|
|
382
664
|
},
|
|
383
665
|
// Order & Limit
|
|
384
666
|
reset_query_order(query) {
|