orchid-graphql 1.7.0 → 1.8.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/dist/index.cjs +82 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +82 -52
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/orm/orm.ts +25 -4
package/dist/index.cjs
CHANGED
|
@@ -36,20 +36,17 @@ __export(src_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(src_exports);
|
|
37
37
|
|
|
38
38
|
// ../base/src/paginators/cursor.ts
|
|
39
|
+
var import_node_buffer = require("buffer");
|
|
39
40
|
function defineCursorPaginator(options = {}) {
|
|
40
41
|
return new CursorPaginator(options);
|
|
41
42
|
}
|
|
42
43
|
var CursorPaginator = class {
|
|
43
44
|
path = ["nodes"];
|
|
44
|
-
|
|
45
|
+
pageSize;
|
|
45
46
|
fields;
|
|
46
47
|
constructor(options = {}) {
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
take: 10,
|
|
50
|
-
...options
|
|
51
|
-
};
|
|
52
|
-
this.fields = this.options.fields.map((field) => {
|
|
48
|
+
this.pageSize = options.take ?? 10;
|
|
49
|
+
this.fields = options.fields?.map((field) => {
|
|
53
50
|
if (field.startsWith("-")) {
|
|
54
51
|
return { name: field.slice(1), desc: true };
|
|
55
52
|
} else {
|
|
@@ -60,59 +57,73 @@ var CursorPaginator = class {
|
|
|
60
57
|
paginate(query, context) {
|
|
61
58
|
const { orm: orm2 } = context.graph;
|
|
62
59
|
const { args } = context.tree;
|
|
63
|
-
const
|
|
60
|
+
const pageSize = args.take ?? this.pageSize;
|
|
64
61
|
const cursor = args.cursor;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
const table = orm2.get_query_table(query);
|
|
63
|
+
const orderFields = (this.fields ? this.fields.map((f) => ({
|
|
64
|
+
field: f.name,
|
|
65
|
+
dir: f.desc ? "DESC" : "ASC"
|
|
66
|
+
})) : orm2.get_query_order(query)).map((o) => ({ ...o, alias: "_order_" + o.field }));
|
|
67
|
+
if (this.fields) {
|
|
68
|
+
query = orm2.reset_query_order(query);
|
|
69
|
+
for (const { alias, dir } of orderFields) {
|
|
70
|
+
query = orm2.add_query_order(query, { field: alias, dir });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!orderFields.length) {
|
|
74
|
+
throw new Error("Query must be ordered.");
|
|
75
|
+
}
|
|
76
|
+
for (const { field, alias } of orderFields) {
|
|
77
|
+
query = orm2.select_field(query, { field, as: alias });
|
|
69
78
|
}
|
|
70
79
|
if (cursor) {
|
|
71
|
-
const
|
|
72
|
-
|
|
80
|
+
const parsedCursor = parseCursor(cursor);
|
|
81
|
+
const left = [];
|
|
82
|
+
const right = [];
|
|
83
|
+
for (let i = 0; i < orderFields.length; ++i) {
|
|
84
|
+
const { field, alias, dir } = orderFields[i];
|
|
85
|
+
const [expressions, placeholders] = dir === "ASC" ? [left, right] : [right, left];
|
|
86
|
+
expressions.push(`"${table}"."${field}"`);
|
|
87
|
+
placeholders.push("$" + alias);
|
|
88
|
+
}
|
|
89
|
+
const sqlExpr = `(${left.join(",")}) > (${right.join(",")})`;
|
|
90
|
+
const bindings = Object.fromEntries(
|
|
91
|
+
orderFields.map(({ alias }, i) => [alias, parsedCursor[i]])
|
|
92
|
+
);
|
|
93
|
+
query = orm2.where_raw(query, sqlExpr, bindings);
|
|
94
|
+
}
|
|
95
|
+
query = orm2.set_query_limit(query, pageSize + 1);
|
|
96
|
+
function createNodeCursor(node) {
|
|
97
|
+
return createCursor(
|
|
98
|
+
orderFields.map(({ field, alias }) => {
|
|
99
|
+
const value = node[alias];
|
|
100
|
+
if (value === void 0) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Unable to create cursor: undefined field ${field} (${alias})`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return String(value);
|
|
106
|
+
})
|
|
107
|
+
);
|
|
73
108
|
}
|
|
74
|
-
query = orm2.set_query_limit(query, take + 1);
|
|
75
109
|
return orm2.set_query_page_result(query, (nodes) => {
|
|
76
110
|
let cursor2;
|
|
77
|
-
if (nodes.length >
|
|
78
|
-
cursor2 =
|
|
79
|
-
nodes = nodes.slice(0,
|
|
111
|
+
if (nodes.length > pageSize) {
|
|
112
|
+
cursor2 = createNodeCursor(nodes[pageSize - 1]);
|
|
113
|
+
nodes = nodes.slice(0, pageSize);
|
|
80
114
|
}
|
|
81
115
|
return { nodes, cursor: cursor2 };
|
|
82
116
|
});
|
|
83
117
|
}
|
|
84
|
-
_create_cursor(instance) {
|
|
85
|
-
return JSON.stringify(
|
|
86
|
-
this.fields.map((field) => {
|
|
87
|
-
const value = instance[field.name];
|
|
88
|
-
if (value === void 0) {
|
|
89
|
-
throw new Error(
|
|
90
|
-
`Unable to create cursor: undefined field ${field.name}`
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
return String(value);
|
|
94
|
-
})
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
_parse_cursor(cursor) {
|
|
98
|
-
const values = JSON.parse(cursor);
|
|
99
|
-
const left = [];
|
|
100
|
-
const right = [];
|
|
101
|
-
const bindings = {};
|
|
102
|
-
for (let i = 0; i < this.fields.length; ++i) {
|
|
103
|
-
const field = this.fields[i];
|
|
104
|
-
const expressions = field.desc ? right : left;
|
|
105
|
-
const placeholders = field.desc ? left : right;
|
|
106
|
-
expressions.push(`"${field.name}"`);
|
|
107
|
-
placeholders.push("$" + field.name);
|
|
108
|
-
bindings[field.name] = values[i];
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
expression: `(${left.join(",")}) > (${right.join(",")})`,
|
|
112
|
-
bindings
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
118
|
};
|
|
119
|
+
function createCursor(parts) {
|
|
120
|
+
return import_node_buffer.Buffer.from(parts.map(String).join(String.fromCharCode(0))).toString(
|
|
121
|
+
"base64url"
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
function parseCursor(cursor) {
|
|
125
|
+
return import_node_buffer.Buffer.from(cursor, "base64url").toString().split(String.fromCharCode(0));
|
|
126
|
+
}
|
|
116
127
|
|
|
117
128
|
// ../base/src/utils/run-after.ts
|
|
118
129
|
function run_after_query(orm2, query, transform) {
|
|
@@ -225,12 +236,13 @@ function definePageResolver(paginator, options = {}) {
|
|
|
225
236
|
relation: tableField || field,
|
|
226
237
|
as: field,
|
|
227
238
|
modify(subquery) {
|
|
239
|
+
subquery = modify ? modify(subquery, context) : subquery;
|
|
228
240
|
subquery = graph._resolve_page(subquery, paginator, context);
|
|
229
241
|
subquery = graph.orm.modify_subquery_pagination(
|
|
230
242
|
subquery,
|
|
231
243
|
pagination_context
|
|
232
244
|
);
|
|
233
|
-
return
|
|
245
|
+
return subquery;
|
|
234
246
|
}
|
|
235
247
|
});
|
|
236
248
|
query = graph.orm.finish_query_pagination(query, field, pagination_context);
|
|
@@ -422,8 +434,26 @@ var orm = {
|
|
|
422
434
|
reset_query_order(query) {
|
|
423
435
|
return query.clear("order");
|
|
424
436
|
},
|
|
425
|
-
add_query_order(query, field,
|
|
426
|
-
return query.order({ [field]:
|
|
437
|
+
add_query_order(query, { field, dir }) {
|
|
438
|
+
return query.order({ [field]: dir });
|
|
439
|
+
},
|
|
440
|
+
get_query_order(query) {
|
|
441
|
+
return query.q.order?.flatMap((orderItem) => {
|
|
442
|
+
if (typeof orderItem === "string") {
|
|
443
|
+
return { field: "orderItem", dir: "ASC" };
|
|
444
|
+
} else if (typeof orderItem === "object") {
|
|
445
|
+
return Object.entries(orderItem).map(([field, order]) => {
|
|
446
|
+
const [dir] = order.split(" ", 1);
|
|
447
|
+
if (dir === "ASC" || dir === "DESC") {
|
|
448
|
+
return { field, dir };
|
|
449
|
+
} else {
|
|
450
|
+
throw new Error("Unsupported order: " + order);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
} else {
|
|
454
|
+
throw new TypeError("Unsupported order type: " + orderItem);
|
|
455
|
+
}
|
|
456
|
+
}) || [];
|
|
427
457
|
},
|
|
428
458
|
set_query_limit(query, limit) {
|
|
429
459
|
return query.limit(limit);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../../base/src/paginators/cursor.ts","../../base/src/utils/run-after.ts","../../base/src/resolvers/field.ts","../../base/src/resolvers/graph.ts","../../base/src/resolvers/page.ts","../../base/src/resolvers/relation.ts","../../base/src/utils/is-plain-object.ts","../../base/src/filters/filters.ts","../../base/src/resolvers/table.ts","../src/orm/orm.ts","../src/resolvers/graph.ts","../src/resolvers/table.ts"],"sourcesContent":["export {\n\tcreateGraphResolver,\n\tcreateGraphResolver as graph,\n} from \"./resolvers/graph\"\nexport {\n\tdefineTableResolver,\n\tdefineTableResolver as table,\n} from \"./resolvers/table\"\nexport {\n\tdefineCursorPaginator as cursor,\n\tdefineCursorPaginator,\n} from \"graphql-orm\"\nexport { defineFieldResolver, defineFieldResolver as field } from \"graphql-orm\"\nexport { definePageResolver, definePageResolver as page } from \"graphql-orm\"\nexport {\n\tdefineRelationResolver,\n\tdefineRelationResolver as relation,\n} from \"graphql-orm\"\n","import { OrmAdapter } from \"../orm/orm\"\nimport { PaginateContext, Paginator } from \"./base\"\n\nexport function defineCursorPaginator(\n\toptions: Partial<CursorPaginatorOptions> = {},\n) {\n\treturn new CursorPaginator(options)\n}\n\nexport interface CursorPaginatorOptions {\n\tfields: string[]\n\ttake: number\n}\n\nexport interface CursorPaginatorArgs {\n\tcursor?: string\n\ttake?: number\n}\n\nexport interface CursorPaginatorPage<M> {\n\tnodes: M[]\n\tcursor?: string\n}\n\nclass CursorPaginator<Orm extends OrmAdapter, Context>\n\timplements Paginator<Orm, Context>\n{\n\treadonly path = [\"nodes\"]\n\treadonly options: CursorPaginatorOptions\n\n\treadonly fields: Array<{\n\t\tname: string\n\t\tdesc: boolean\n\t}>\n\n\tconstructor(options: Partial<CursorPaginatorOptions> = {}) {\n\t\tthis.options = {\n\t\t\tfields: [\"id\"],\n\t\t\ttake: 10,\n\t\t\t...options,\n\t\t}\n\t\tthis.fields = this.options.fields.map((field) => {\n\t\t\tif (field.startsWith(\"-\")) {\n\t\t\t\treturn { name: field.slice(1), desc: true }\n\t\t\t} else {\n\t\t\t\treturn { name: field, desc: false }\n\t\t\t}\n\t\t})\n\t}\n\n\tpaginate(query: Orm[\"Query\"], context: PaginateContext<Orm, Context>) {\n\t\tconst { orm } = context.graph\n\t\tconst { args } = context.tree\n\n\t\tconst take = (args.take as number | undefined) ?? this.options.take\n\t\tconst cursor = args.cursor as string | undefined\n\n\t\t// Set query order\n\t\tquery = orm.reset_query_order(query)\n\t\tfor (const field of this.fields) {\n\t\t\t// TODO: prevent potential name clash with aliases like .as(`_${table_ref}_order_key_0`)\n\t\t\tquery = orm.select_field(query, { field: field.name, as: field.name })\n\t\t\tquery = orm.add_query_order(query, field.name, field.desc)\n\t\t}\n\n\t\tif (cursor) {\n\t\t\tconst { expression, bindings } = this._parse_cursor(cursor)\n\t\t\tquery = orm.where_raw(query, expression, bindings)\n\t\t}\n\t\tquery = orm.set_query_limit(query, take + 1)\n\n\t\treturn orm.set_query_page_result(query, (nodes) => {\n\t\t\tlet cursor: string | undefined\n\t\t\tif (nodes.length > take) {\n\t\t\t\tcursor = this._create_cursor(nodes[take - 1])\n\t\t\t\tnodes = nodes.slice(0, take)\n\t\t\t}\n\t\t\treturn { nodes, cursor }\n\t\t})\n\t}\n\n\t_create_cursor(instance: any) {\n\t\treturn JSON.stringify(\n\t\t\tthis.fields.map((field) => {\n\t\t\t\tconst value = instance[field.name]\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Unable to create cursor: undefined field ${field.name}`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn String(value)\n\t\t\t}),\n\t\t)\n\t}\n\n\t_parse_cursor(cursor: string) {\n\t\tconst values = JSON.parse(cursor)\n\t\tconst left: string[] = []\n\t\tconst right: string[] = []\n\t\tconst bindings: Record<string, any> = {}\n\t\tfor (let i = 0; i < this.fields.length; ++i) {\n\t\t\tconst field = this.fields[i]\n\t\t\tconst expressions = field.desc ? right : left\n\t\t\tconst placeholders = field.desc ? left : right\n\t\t\texpressions.push(`\"${field.name}\"`)\n\t\t\tplaceholders.push(\"$\" + field.name)\n\t\t\tbindings[field.name] = values[i]\n\t\t}\n\t\treturn {\n\t\t\texpression: `(${left.join(\",\")}) > (${right.join(\",\")})`,\n\t\t\tbindings,\n\t\t}\n\t}\n}\n","import { OrmAdapter } from \"../orm/orm\"\n\nexport function run_after_query<Orm extends OrmAdapter>(\n\torm: Orm,\n\tquery: Orm[\"Query\"],\n\ttransform: (instance: any) => any,\n): Orm[\"Query\"] {\n\treturn orm.run_after_query(query, async (result) => {\n\t\t// FIXME: returning result is ignored in orchid (unlike objection). Add some hacks instead.\n\t\tif (Array.isArray(result)) {\n\t\t\tconst result1 = await Promise.all(result.map(transform))\n\t\t\treturn result1.filter(Boolean) // Skip empty objects\n\t\t} else if (result) {\n\t\t\treturn transform(result)\n\t\t} else {\n\t\t\t// Supposedly, single query returning NULL\n\t\t\treturn result\n\t\t}\n\t})\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { run_after_query } from \"../utils/run-after\"\nimport { TableResolveContext } from \"./table\"\n\nexport interface FieldResolverOptions<Orm extends OrmAdapter, Context> {\n\t/** Table field (if different from GraphQL field) */\n\ttableField?: string\n\t/** Legacy alias for `tableField`. */\n\tmodelField?: string\n\t/** Custom query modifier (if different than simply selecting a field). */\n\tmodify?: FieldResolveModifier<Orm, Context>\n\t/** Post-process selected value. Return a new value or a promise. */\n\ttransform?(\n\t\tvalue: any,\n\t\tinstance: any,\n\t\tcontext: FieldResolveContext<Orm, Context>,\n\t): any\n}\n\nexport type FieldResolveModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tcontext: FieldResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport interface FieldResolveContext<Orm extends OrmAdapter, Context>\n\textends TableResolveContext<Orm, Context> {\n\t/** GraphQL field */\n\tfield: string\n}\n\n// That is a coincidence for now.\nexport type FieldResolver<\n\tOrm extends OrmAdapter,\n\tContext,\n> = FieldResolveModifier<Orm, Context>\n\nexport function parse_field_options<\n\tO extends Pick<FieldResolverOptions<any, any>, \"modelField\" | \"tableField\">,\n>(options: O): Omit<O, \"modelField\"> {\n\tconst { tableField, modelField } = options\n\tif (tableField && modelField) {\n\t\tthrow new Error(\n\t\t\t`Both tableField and modelField are defined. Use only one of them.`,\n\t\t)\n\t}\n\treturn { ...options, tableField: tableField || modelField }\n}\n\nexport function defineFieldResolver<Orm extends OrmAdapter, Context>(\n\toptions: FieldResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, modify, transform } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { field } = context\n\t\tif (modify) {\n\t\t\tquery = modify(query, context)\n\t\t} else {\n\t\t\tquery = context.graph.orm.select_field(query, {\n\t\t\t\tfield: tableField || field,\n\t\t\t\tas: field,\n\t\t\t})\n\t\t}\n\t\tif (transform) {\n\t\t\tquery = run_after_query(context.graph.orm, query, async (instance) => {\n\t\t\t\tinstance[field] = await transform(instance[field], instance, context)\n\t\t\t\treturn instance\n\t\t\t})\n\t\t}\n\t\treturn query\n\t}\n}\n","import type { GraphQLResolveInfo } from \"graphql\"\nimport { parseResolveInfo, ResolveTree } from \"graphql-parse-resolve-info\"\n\nimport { FiltersDef } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport { Paginator } from \"../paginators/base\"\nimport type { TableResolver, TableResolverOptions } from \"./table\"\n\nexport type GraphResolverOptions<Orm extends OrmAdapter, Context> = Pick<\n\tTableResolverOptions<Orm, Context>,\n\t\"allowAllFields\" | \"allowAllFilters\"\n>\n\nexport interface GraphResolveOptions<Context> {\n\tinfo: GraphQLResolveInfo\n\tcontext: Context\n\tfilters?: FiltersDef\n\t/** Subfield path if not resolving root query, e.g.: ['user'] */\n\tpath?: string[]\n}\n\nexport type GraphResolveContext<Context> = Omit<\n\tGraphResolveOptions<Context>,\n\t\"info\"\n> & {\n\ttree: ResolveTree\n}\n\nexport class GraphResolver<Orm extends OrmAdapter, Context> {\n\tconstructor(\n\t\treadonly orm: Orm,\n\t\treadonly type_resolvers: Record<string, TableResolver<Orm, Context>>,\n\t\treadonly options: GraphResolverOptions<Orm, Context> = {},\n\t) {}\n\n\tresolve<T>(\n\t\tquery: Orm[\"Query\"],\n\t\t{ info, ...context }: GraphResolveOptions<Context>,\n\t): Promise<T> {\n\t\tconst tree = this._get_resolve_tree(info)\n\t\treturn this._resolve_type(query, { ...context, tree })\n\t}\n\n\tresolvePage(\n\t\tquery: Orm[\"Query\"],\n\t\tpaginator: Paginator<Orm, Context>,\n\t\t{ info, ...context }: GraphResolveOptions<Context>,\n\t) {\n\t\tconst tree = this._get_resolve_tree(info)\n\t\treturn this._resolve_page(query, paginator, { ...context, tree })\n\t}\n\n\t_get_resolve_tree(info: GraphQLResolveInfo) {\n\t\treturn parseResolveInfo(info) as ResolveTree\n\t}\n\n\t_resolve_type(\n\t\tquery: Orm[\"Query\"],\n\t\tcontext: GraphResolveContext<Context>,\n\t): Orm[\"Query\"] {\n\t\tlet { tree } = context\n\t\t// Dive into subtree if requested.\n\t\tif (context.path) {\n\t\t\tfor (const field of context.path) {\n\t\t\t\tconst type = Object.keys(tree.fieldsByTypeName)[0]\n\t\t\t\ttree = tree.fieldsByTypeName[type][field]\n\t\t\t\tif (!tree) {\n\t\t\t\t\t// This graphql field was never requested, ignore.\n\t\t\t\t\t// This happens when a user resolves a graph for a root subfield which was not requested by the client (and is thus not present in the tree).\n\t\t\t\t\t//\n\t\t\t\t\t// FIXME: this break typings contract. We are supposed to return a query.\n\t\t\t\t\treturn Promise.resolve()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst type = Object.keys(tree.fieldsByTypeName)[0]\n\t\tconst type_resolver = this.type_resolvers[type]\n\t\tif (!type_resolver) {\n\t\t\tthrow new Error(`Resolver not found for type ${type}.`)\n\t\t}\n\t\treturn type_resolver.resolve(query, {\n\t\t\t...context,\n\t\t\tgraph: this,\n\t\t\ttree,\n\t\t\ttype,\n\t\t\tpath: undefined,\n\t\t})\n\t}\n\n\t_resolve_page(\n\t\tquery: Orm[\"Query\"],\n\t\tpaginator: Paginator<Orm, Context>,\n\t\tcontext: GraphResolveContext<Context>,\n\t) {\n\t\tif (context.path) {\n\t\t\t// TODO: handle non-empty context.path\n\t\t\tthrow new Error(\"Paginating under non-root path not yet supported.\")\n\t\t}\n\t\tquery = this._resolve_type(query, { ...context, path: paginator.path })\n\t\treturn paginator.paginate(query, {\n\t\t\t...context,\n\t\t\tgraph: this,\n\t\t})\n\t}\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { Paginator } from \"../paginators/base\"\nimport { FieldResolver, parse_field_options } from \"./field\"\nimport { RelationResolverOptions } from \"./relation\"\n\nexport function definePageResolver<Orm extends OrmAdapter, Context>(\n\tpaginator: Paginator<Orm, Context>,\n\toptions: RelationResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, modify } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { graph, field } = context\n\t\t// Objection.js requires a workaround to handle paginated content,\n\t\t// it must be saved into context and re-injected later.\n\t\t// The modify + finish is a no-op in Orchid.\n\t\tconst pagination_context = {}\n\t\tquery = graph.orm.select_relation(query, {\n\t\t\trelation: tableField || field,\n\t\t\tas: field,\n\t\t\tmodify(subquery) {\n\t\t\t\tsubquery = graph._resolve_page(subquery, paginator, context)\n\t\t\t\tsubquery = graph.orm.modify_subquery_pagination(\n\t\t\t\t\tsubquery,\n\t\t\t\t\tpagination_context,\n\t\t\t\t)\n\t\t\t\treturn modify ? modify(subquery, context) : subquery\n\t\t\t},\n\t\t})\n\t\tquery = graph.orm.finish_query_pagination(query, field, pagination_context)\n\t\treturn query\n\t}\n}\n","import { FiltersDef } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport {\n\tFieldResolver,\n\tFieldResolverOptions,\n\tparse_field_options,\n} from \"./field\"\nimport { TableResolveModifier } from \"./table\"\n\nexport interface RelationResolverOptions<Orm extends OrmAdapter, Context>\n\textends Omit<FieldResolverOptions<Orm, Context>, \"modify\"> {\n\tfilters?: FiltersDef\n\tmodify?: TableResolveModifier<Orm, Context>\n}\n\nexport function defineRelationResolver<Orm extends OrmAdapter, Context>(\n\toptions: RelationResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, filters, modify } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { graph, field } = context\n\t\treturn graph.orm.select_relation(query, {\n\t\t\trelation: tableField || field,\n\t\t\tas: field,\n\t\t\tmodify(subquery) {\n\t\t\t\tsubquery = graph._resolve_type(subquery, { ...context, filters })\n\t\t\t\treturn modify ? modify(subquery, context) : subquery\n\t\t\t},\n\t\t})\n\t}\n}\n","export function is_plain_object(obj: any): obj is Record<string, any> {\n\treturn typeof obj === \"object\" && !Array.isArray(obj)\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { TableResolveContext } from \"../resolvers/table\"\nimport { is_plain_object } from \"../utils/is-plain-object\"\n\n// TODO: per-field definitions\nexport type FiltersDef = boolean\n\nexport type FilterScalarValue = null | string | number | boolean\nexport type FilterValue = FilterScalarValue | Exclude<FilterScalarValue, null>[]\nexport type Filter = { [property: string]: FilterValue }\n\ninterface ApplyFiltersOptions<Orm extends OrmAdapter, Context> {\n\tfilters: FiltersDef\n\tmodifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\tcontext: TableResolveContext<Orm, Context>\n}\n\nexport type ApplyFiltersModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tvalue: any,\n\tcontext: TableResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport function apply_filters<Orm extends OrmAdapter, Context>(\n\tquery: Orm[\"Query\"],\n\t{ filters, modifiers, context }: ApplyFiltersOptions<Orm, Context>,\n): Orm[\"Query\"] {\n\tif (!filters) {\n\t\treturn query\n\t}\n\tconst filter_obj = context.tree.args?.filter\n\tif (!filter_obj) {\n\t\treturn query\n\t}\n\tif (!is_plain_object(filter_obj)) {\n\t\tthrow new Error(`Invalid filter: ${filter_obj}, must be object.`)\n\t}\n\tfor (const [field, value] of Object.entries(filter_obj)) {\n\t\tif (value === undefined) {\n\t\t\t// Support optional GraphQL arguments in filter\n\t\t\tcontinue\n\t\t}\n\t\tif (modifiers?.[field]) {\n\t\t\tquery = modifiers[field](query, value, context)\n\t\t} else {\n\t\t\tconst [table_field, op0] = field.split(\"__\")\n\t\t\tconst op = op0?.toLowerCase()\n\t\t\t// TODO: validate op\n\t\t\tquery = context.graph.orm.where(query, table_field, op, value)\n\t\t}\n\t}\n\treturn query\n}\n","import { apply_filters, ApplyFiltersModifier } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport { run_after_query } from \"../utils/run-after\"\nimport { defineFieldResolver, FieldResolver } from \"./field\"\nimport type { GraphResolveContext, GraphResolver } from \"./graph\"\nimport { defineRelationResolver } from \"./relation\"\n\nexport interface TableResolverOptions<Orm extends OrmAdapter, Context> {\n\t/** allow to resolve all table fields without explicitly listing them */\n\tallowAllFields?: boolean\n\t/** allow to filter all table fields without explicitly listing them */\n\tallowAllFilters?: boolean\n\tfields?: Record<string, SimpleFieldResolver<Orm, Context>>\n\tmodifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\tmodify?: TableResolveModifier<Orm, Context>\n\ttransform?(instance: any, context: any): void | PromiseLike<void>\n}\n\nexport type SimpleFieldResolver<Orm extends OrmAdapter, Context> =\n\t| true\n\t| string\n\t| FieldResolver<Orm, Context>\n\nexport type TableResolveModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tcontext: TableResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport interface TableResolveContext<Orm extends OrmAdapter, Context>\n\textends GraphResolveContext<Context> {\n\tgraph: GraphResolver<Orm, Context>\n\t/** GraphQL type */\n\ttype: string\n}\n\nexport class TableResolver<Orm extends OrmAdapter, Context> {\n\t// Introspection results\n\treadonly relations: Set<string>\n\treadonly virtual_fields: Set<string>\n\treadonly modifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\n\treadonly table_field_resolvers?: Record<string, FieldResolver<Orm, Context>>\n\n\tconstructor(\n\t\treadonly orm: Orm,\n\t\treadonly table: Orm[\"Table\"],\n\t\treadonly options: TableResolverOptions<Orm, Context> = {},\n\t) {\n\t\tthis.relations = new Set(orm.get_table_relations(table))\n\t\tthis.virtual_fields = new Set(orm.get_table_virtual_fields(table))\n\t\tthis.modifiers = { ...orm.get_table_modifiers(table), ...options.modifiers }\n\n\t\t// Pre-create field resolvers\n\t\tconst { fields } = options\n\t\tif (fields) {\n\t\t\tthis.table_field_resolvers = Object.keys(fields).reduce<\n\t\t\t\tRecord<string, FieldResolver<Orm, Context>>\n\t\t\t>((resolvers, field) => {\n\t\t\t\tconst r0 = fields[field]\n\t\t\t\tconst r: FieldResolver<Orm, Context> | undefined =\n\t\t\t\t\ttypeof r0 === \"function\"\n\t\t\t\t\t\t? r0\n\t\t\t\t\t\t: r0 === true\n\t\t\t\t\t\t\t? this._get_default_field_resolver(field)\n\t\t\t\t\t\t\t: typeof r0 === \"string\"\n\t\t\t\t\t\t\t\t? this._get_default_field_resolver(field, r0)\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\tif (r === undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Field resolver must be a function, string, or true; found ${typeof r0}.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tresolvers[field] = r\n\t\t\t\treturn resolvers\n\t\t\t}, {})\n\t\t}\n\t}\n\n\t/** Modify query to select fields/relations and filter the result set. */\n\tresolve(query: Orm[\"Query\"], context: TableResolveContext<Orm, Context>) {\n\t\tconst { modify, transform } = this.options\n\t\tconst { graph, tree, type, filters } = context\n\n\t\tconst query_table = this.orm.get_query_table(query)\n\t\tconst table_table = this.orm.get_table_table(this.table)\n\n\t\tif (query_table !== table_table) {\n\t\t\tthrow new Error(\n\t\t\t\t`Mismatching query table for type ${type}: expected ${table_table}, received ${query_table}.`,\n\t\t\t)\n\t\t}\n\n\t\tconst allow_all_fields =\n\t\t\tthis.options.allowAllFields ??\n\t\t\tgraph.options.allowAllFields ??\n\t\t\t!this.options.fields\n\n\t\tif (!allow_all_fields && !this.table_field_resolvers) {\n\t\t\tthrow new Error(\n\t\t\t\t`Resolver for type ${type} must either allow all fields or specify options.fields.`,\n\t\t\t)\n\t\t}\n\n\t\tif (modify) {\n\t\t\tquery = modify(query, context)\n\t\t}\n\n\t\tfor (const subtree of Object.values(tree.fieldsByTypeName[type])) {\n\t\t\tconst field = subtree.name\n\t\t\tconst r: FieldResolver<Orm, Context> | undefined =\n\t\t\t\tthis.table_field_resolvers?.[field] ||\n\t\t\t\t(allow_all_fields ? this._get_default_field_resolver(field) : undefined)\n\t\t\tif (!r) {\n\t\t\t\tthrow new Error(`No field resolver defined for field ${type}.${field}.`)\n\t\t\t}\n\t\t\tif (r) {\n\t\t\t\tquery = r(query, { ...context, tree: subtree, field })\n\t\t\t}\n\t\t}\n\n\t\tconst allow_all_filters =\n\t\t\tthis.options.allowAllFilters ?? graph.options.allowAllFilters\n\n\t\tconst effective_filters = allow_all_filters ? true : filters\n\n\t\tif (effective_filters) {\n\t\t\tquery = apply_filters<Orm, Context>(query, {\n\t\t\t\tfilters: effective_filters,\n\t\t\t\tmodifiers: this.modifiers,\n\t\t\t\tcontext,\n\t\t\t})\n\t\t}\n\n\t\tif (transform) {\n\t\t\tquery = run_after_query(this.orm, query, (instance) => {\n\t\t\t\treturn transform(instance, context)\n\t\t\t})\n\t\t}\n\n\t\tquery = this.orm.prevent_select_all(query)\n\n\t\treturn query\n\t}\n\n\t/**\n\t * Create field resolver which will modify query to resolve GraphQL field.\n\t */\n\t_get_default_field_resolver(\n\t\tfield: string,\n\t\ttableField?: string,\n\t): FieldResolver<Orm, Context> {\n\t\tconst table_field_lookup = tableField || field\n\t\tif (\n\t\t\tthis.options.modifiers?.[table_field_lookup] ||\n\t\t\tthis.virtual_fields.has(table_field_lookup)\n\t\t) {\n\t\t\t// Keep query as is.\n\t\t\treturn (query) => query\n\t\t} else if (this.relations.has(table_field_lookup)) {\n\t\t\t// TODO: pre-create and cache\n\t\t\treturn defineRelationResolver({ tableField })\n\t\t} else {\n\t\t\t// TODO: create simplified resolver?\n\t\t\treturn defineFieldResolver({ tableField })\n\t\t}\n\t}\n}\n","import { OrmAdapter } from \"graphql-orm\"\nimport type { Query, Table } from \"orchid-orm\"\nimport { raw } from \"orchid-orm\"\n\nexport type OrchidOrm = OrmAdapter<\n\tTable,\n\tQuery,\n\t// TODO: Type as QueryTransform once it's published.\n\tPick<Promise<any>, \"then\" | \"catch\">\n>\n\nexport const orm: OrchidOrm = {\n\tTable: undefined as unknown as OrchidOrm[\"Table\"],\n\tQuery: undefined as unknown as OrchidOrm[\"Query\"],\n\tQueryTransform: undefined as unknown as OrchidOrm[\"QueryTransform\"],\n\n\t// Reflection\n\n\tget_table_table(table) {\n\t\treturn table.table!\n\t},\n\n\tget_table_relations(table) {\n\t\treturn Object.keys(table.relations)\n\t},\n\n\tget_table_virtual_fields() {\n\t\t// Not supported by Orchid.\n\t\treturn []\n\t},\n\n\tget_table_modifiers() {\n\t\treturn undefined\n\t},\n\n\tget_query_table(query) {\n\t\tif (!query.table) {\n\t\t\tthrow new Error(\"Query must have table.\")\n\t\t}\n\t\treturn query.table\n\t},\n\n\t// Select\n\n\tselect_field(query, { field, as }) {\n\t\treturn query.select({ [as]: field })\n\t},\n\n\tselect_relation(query, { relation, as, modify }) {\n\t\t// as any casts needed in orchid-orm 1.31+\n\t\treturn query.select({\n\t\t\t[as]: (q: any) => modify(q[relation]),\n\t\t} as any)\n\t},\n\n\t// Find\n\n\twhere(query, field, op, value) {\n\t\treturn query.where({ [field]: op ? { [op]: value } : value })\n\t},\n\n\twhere_raw(query, expression, bindings) {\n\t\treturn query.where(raw({ raw: expression, values: bindings }))\n\t},\n\n\t// Order & Limit\n\n\treset_query_order(query) {\n\t\treturn query.clear(\"order\")\n\t},\n\n\tadd_query_order(query, field, desc) {\n\t\treturn query.order({ [field]: desc ? \"DESC\" : \"ASC\" })\n\t},\n\n\tset_query_limit(query, limit) {\n\t\treturn query.limit(limit)\n\t},\n\n\t// Pagination helpers\n\n\tset_query_page_result(query, get_page) {\n\t\treturn query.transform((nodes) => get_page(nodes as any))\n\t},\n\n\tmodify_subquery_pagination(subquery) {\n\t\treturn subquery\n\t},\n\n\tfinish_query_pagination(query) {\n\t\treturn query\n\t},\n\n\t// Misc\n\n\trun_after_query(query, fn) {\n\t\treturn query.afterQuery((data) => fn(data))\n\t},\n\n\tprevent_select_all(query) {\n\t\t// Not needed in Orchid\n\t\treturn query\n\t},\n}\n","import {\n\tGraphResolveOptions,\n\tGraphResolver,\n\tGraphResolverOptions,\n\tTableResolver,\n} from \"graphql-orm\"\nimport { Query } from \"orchid-orm\"\n\nimport { OrchidOrm, orm } from \"../orm/orm\"\n\nexport function createGraphResolver<Context = unknown>(\n\ttypes: Record<string, TableResolver<OrchidOrm, Context>>,\n\toptions?: GraphResolverOptions<OrchidOrm, Context>,\n) {\n\treturn new OrchidGraphResolver<Context>(types, options)\n}\n\nclass OrchidGraphResolver<Context> extends GraphResolver<OrchidOrm, Context> {\n\tconstructor(\n\t\tpublic readonly types: Record<string, TableResolver<OrchidOrm, Context>>,\n\t\tpublic readonly options: GraphResolverOptions<OrchidOrm, Context> = {},\n\t) {\n\t\tsuper(orm, types, options)\n\t}\n\n\tresolve<T>(\n\t\tquery: Query & {\n\t\t\treturnType: unknown extends T\n\t\t\t\t? any\n\t\t\t\t: T extends unknown[]\n\t\t\t\t\t? undefined | \"all\"\n\t\t\t\t\t: T extends undefined\n\t\t\t\t\t\t? \"one\"\n\t\t\t\t\t\t: \"oneOrThrow\"\n\t\t},\n\t\toptions: GraphResolveOptions<Context>,\n\t): Promise<T> {\n\t\treturn super.resolve(query, options)\n\t}\n}\n","import { TableResolver, TableResolverOptions } from \"graphql-orm\"\nimport { Table } from \"orchid-orm\"\n\nimport { OrchidOrm, orm } from \"../orm/orm\"\n\nexport function defineTableResolver<Context = unknown>(\n\ttable: Table,\n\toptions: TableResolverOptions<OrchidOrm, Context> = {},\n) {\n\treturn new TableResolver(orm, table as any, options)\n}\n"],"mappings":"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","names":["orm","cursor","orm","orm","type","orm"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../base/src/paginators/cursor.ts","../../base/src/utils/run-after.ts","../../base/src/resolvers/field.ts","../../base/src/resolvers/graph.ts","../../base/src/resolvers/page.ts","../../base/src/resolvers/relation.ts","../../base/src/utils/is-plain-object.ts","../../base/src/filters/filters.ts","../../base/src/resolvers/table.ts","../src/orm/orm.ts","../src/resolvers/graph.ts","../src/resolvers/table.ts"],"sourcesContent":["export {\n\tcreateGraphResolver,\n\tcreateGraphResolver as graph,\n} from \"./resolvers/graph\"\nexport {\n\tdefineTableResolver,\n\tdefineTableResolver as table,\n} from \"./resolvers/table\"\nexport {\n\tdefineCursorPaginator as cursor,\n\tdefineCursorPaginator,\n} from \"graphql-orm\"\nexport { defineFieldResolver, defineFieldResolver as field } from \"graphql-orm\"\nexport { definePageResolver, definePageResolver as page } from \"graphql-orm\"\nexport {\n\tdefineRelationResolver,\n\tdefineRelationResolver as relation,\n} from \"graphql-orm\"\n","import { Buffer } from \"node:buffer\"\n\nimport { OrmAdapter, SortOrder } from \"../orm/orm\"\nimport { PaginateContext, Paginator } from \"./base\"\n\nexport function defineCursorPaginator(\n\toptions: Partial<CursorPaginatorOptions> = {},\n) {\n\treturn new CursorPaginator(options)\n}\n\nexport interface CursorPaginatorOptions {\n\tfields?: string[]\n\ttake?: number\n}\n\nexport interface CursorPaginatorArgs {\n\tcursor?: string\n\ttake?: number\n}\n\nexport interface CursorPaginatorPage<M> {\n\tnodes: M[]\n\tcursor?: string\n}\n\nclass CursorPaginator<Orm extends OrmAdapter, Context>\n\timplements Paginator<Orm, Context>\n{\n\treadonly path = [\"nodes\"]\n\n\treadonly pageSize: number\n\n\treadonly fields?: Array<{\n\t\tname: string\n\t\tdesc: boolean\n\t}>\n\n\tconstructor(options: CursorPaginatorOptions = {}) {\n\t\tthis.pageSize = options.take ?? 10\n\t\tthis.fields = options.fields?.map((field) => {\n\t\t\tif (field.startsWith(\"-\")) {\n\t\t\t\treturn { name: field.slice(1), desc: true }\n\t\t\t} else {\n\t\t\t\treturn { name: field, desc: false }\n\t\t\t}\n\t\t})\n\t}\n\n\tpaginate(query: Orm[\"Query\"], context: PaginateContext<Orm, Context>) {\n\t\tconst { orm } = context.graph\n\t\tconst { args } = context.tree\n\n\t\tconst pageSize = (args.take as number | undefined) ?? this.pageSize\n\t\tconst cursor = args.cursor as string | undefined\n\n\t\tconst table = orm.get_query_table(query)\n\n\t\tconst orderFields = (\n\t\t\tthis.fields\n\t\t\t\t? this.fields.map<SortOrder>((f) => ({\n\t\t\t\t\t\tfield: f.name,\n\t\t\t\t\t\tdir: f.desc ? \"DESC\" : \"ASC\",\n\t\t\t\t\t}))\n\t\t\t\t: orm.get_query_order(query)\n\t\t).map((o) => ({ ...o, alias: \"_order_\" + o.field }))\n\n\t\tif (this.fields) {\n\t\t\tquery = orm.reset_query_order(query)\n\t\t\tfor (const { alias, dir } of orderFields) {\n\t\t\t\tquery = orm.add_query_order(query, { field: alias, dir })\n\t\t\t}\n\t\t}\n\n\t\tif (!orderFields.length) {\n\t\t\tthrow new Error(\"Query must be ordered.\")\n\t\t}\n\n\t\tfor (const { field, alias } of orderFields) {\n\t\t\tquery = orm.select_field(query, { field, as: alias })\n\t\t}\n\n\t\tif (cursor) {\n\t\t\tconst parsedCursor = parseCursor(cursor)\n\t\t\t// Prepare raw SQL.\n\t\t\t// For example, for (amount asc, id asc) order, that would be:\n\t\t\t// (amount, $id) >= ($amount, id)\n\t\t\tconst left: string[] = []\n\t\t\tconst right: string[] = []\n\t\t\tfor (let i = 0; i < orderFields.length; ++i) {\n\t\t\t\tconst { field, alias, dir } = orderFields[i]\n\t\t\t\tconst [expressions, placeholders] =\n\t\t\t\t\tdir === \"ASC\" ? [left, right] : [right, left]\n\t\t\t\texpressions.push(`\"${table}\".\"${field}\"`)\n\t\t\t\tplaceholders.push(\"$\" + alias)\n\t\t\t}\n\t\t\tconst sqlExpr = `(${left.join(\",\")}) > (${right.join(\",\")})`\n\t\t\tconst bindings = Object.fromEntries(\n\t\t\t\torderFields.map(({ alias }, i) => [alias, parsedCursor[i]]),\n\t\t\t)\n\t\t\tquery = orm.where_raw(query, sqlExpr, bindings)\n\t\t}\n\t\tquery = orm.set_query_limit(query, pageSize + 1)\n\n\t\t// TODO add support for reverse cursor, borrow implementation from orchid-pagination.\n\t\tfunction createNodeCursor(node: any) {\n\t\t\treturn createCursor(\n\t\t\t\torderFields.map(({ field, alias }) => {\n\t\t\t\t\tconst value = node[alias]\n\t\t\t\t\t// TODO add support for custom serializer(s).\n\t\t\t\t\tif (value === undefined) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Unable to create cursor: undefined field ${field} (${alias})`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\treturn String(value)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\treturn orm.set_query_page_result(query, (nodes) => {\n\t\t\tlet cursor: string | undefined\n\t\t\tif (nodes.length > pageSize) {\n\t\t\t\tcursor = createNodeCursor(nodes[pageSize - 1])\n\t\t\t\tnodes = nodes.slice(0, pageSize)\n\t\t\t}\n\t\t\treturn { nodes, cursor }\n\t\t})\n\t}\n}\n\nfunction createCursor(parts: string[]) {\n\treturn Buffer.from(parts.map(String).join(String.fromCharCode(0))).toString(\n\t\t\"base64url\",\n\t)\n}\n\nfunction parseCursor(cursor: string): string[] {\n\treturn Buffer.from(cursor, \"base64url\")\n\t\t.toString()\n\t\t.split(String.fromCharCode(0))\n}\n","import { OrmAdapter } from \"../orm/orm\"\n\nexport function run_after_query<Orm extends OrmAdapter>(\n\torm: Orm,\n\tquery: Orm[\"Query\"],\n\ttransform: (instance: any) => any,\n): Orm[\"Query\"] {\n\treturn orm.run_after_query(query, async (result) => {\n\t\t// FIXME: returning result is ignored in orchid (unlike objection). Add some hacks instead.\n\t\tif (Array.isArray(result)) {\n\t\t\tconst result1 = await Promise.all(result.map(transform))\n\t\t\treturn result1.filter(Boolean) // Skip empty objects\n\t\t} else if (result) {\n\t\t\treturn transform(result)\n\t\t} else {\n\t\t\t// Supposedly, single query returning NULL\n\t\t\treturn result\n\t\t}\n\t})\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { run_after_query } from \"../utils/run-after\"\nimport { TableResolveContext } from \"./table\"\n\nexport interface FieldResolverOptions<Orm extends OrmAdapter, Context> {\n\t/** Table field (if different from GraphQL field) */\n\ttableField?: string\n\t/** Legacy alias for `tableField`. */\n\tmodelField?: string\n\t/** Custom query modifier (if different than simply selecting a field). */\n\tmodify?: FieldResolveModifier<Orm, Context>\n\t/** Post-process selected value. Return a new value or a promise. */\n\ttransform?(\n\t\tvalue: any,\n\t\tinstance: any,\n\t\tcontext: FieldResolveContext<Orm, Context>,\n\t): any\n}\n\nexport type FieldResolveModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tcontext: FieldResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport interface FieldResolveContext<Orm extends OrmAdapter, Context>\n\textends TableResolveContext<Orm, Context> {\n\t/** GraphQL field */\n\tfield: string\n}\n\n// That is a coincidence for now.\nexport type FieldResolver<\n\tOrm extends OrmAdapter,\n\tContext,\n> = FieldResolveModifier<Orm, Context>\n\nexport function parse_field_options<\n\tO extends Pick<FieldResolverOptions<any, any>, \"modelField\" | \"tableField\">,\n>(options: O): Omit<O, \"modelField\"> {\n\tconst { tableField, modelField } = options\n\tif (tableField && modelField) {\n\t\tthrow new Error(\n\t\t\t`Both tableField and modelField are defined. Use only one of them.`,\n\t\t)\n\t}\n\treturn { ...options, tableField: tableField || modelField }\n}\n\nexport function defineFieldResolver<Orm extends OrmAdapter, Context>(\n\toptions: FieldResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, modify, transform } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { field } = context\n\t\tif (modify) {\n\t\t\tquery = modify(query, context)\n\t\t} else {\n\t\t\tquery = context.graph.orm.select_field(query, {\n\t\t\t\tfield: tableField || field,\n\t\t\t\tas: field,\n\t\t\t})\n\t\t}\n\t\tif (transform) {\n\t\t\tquery = run_after_query(context.graph.orm, query, async (instance) => {\n\t\t\t\tinstance[field] = await transform(instance[field], instance, context)\n\t\t\t\treturn instance\n\t\t\t})\n\t\t}\n\t\treturn query\n\t}\n}\n","import type { GraphQLResolveInfo } from \"graphql\"\nimport { parseResolveInfo, ResolveTree } from \"graphql-parse-resolve-info\"\n\nimport { FiltersDef } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport { Paginator } from \"../paginators/base\"\nimport type { TableResolver, TableResolverOptions } from \"./table\"\n\nexport type GraphResolverOptions<Orm extends OrmAdapter, Context> = Pick<\n\tTableResolverOptions<Orm, Context>,\n\t\"allowAllFields\" | \"allowAllFilters\"\n>\n\nexport interface GraphResolveOptions<Context> {\n\tinfo: GraphQLResolveInfo\n\tcontext: Context\n\tfilters?: FiltersDef\n\t/** Subfield path if not resolving root query, e.g.: ['user'] */\n\tpath?: string[]\n}\n\nexport type GraphResolveContext<Context> = Omit<\n\tGraphResolveOptions<Context>,\n\t\"info\"\n> & {\n\ttree: ResolveTree\n}\n\nexport class GraphResolver<Orm extends OrmAdapter, Context> {\n\tconstructor(\n\t\treadonly orm: Orm,\n\t\treadonly type_resolvers: Record<string, TableResolver<Orm, Context>>,\n\t\treadonly options: GraphResolverOptions<Orm, Context> = {},\n\t) {}\n\n\tresolve<T>(\n\t\tquery: Orm[\"Query\"],\n\t\t{ info, ...context }: GraphResolveOptions<Context>,\n\t): Promise<T> {\n\t\tconst tree = this._get_resolve_tree(info)\n\t\treturn this._resolve_type(query, { ...context, tree })\n\t}\n\n\tresolvePage(\n\t\tquery: Orm[\"Query\"],\n\t\tpaginator: Paginator<Orm, Context>,\n\t\t{ info, ...context }: GraphResolveOptions<Context>,\n\t) {\n\t\tconst tree = this._get_resolve_tree(info)\n\t\treturn this._resolve_page(query, paginator, { ...context, tree })\n\t}\n\n\t_get_resolve_tree(info: GraphQLResolveInfo) {\n\t\treturn parseResolveInfo(info) as ResolveTree\n\t}\n\n\t_resolve_type(\n\t\tquery: Orm[\"Query\"],\n\t\tcontext: GraphResolveContext<Context>,\n\t): Orm[\"Query\"] {\n\t\tlet { tree } = context\n\t\t// Dive into subtree if requested.\n\t\tif (context.path) {\n\t\t\tfor (const field of context.path) {\n\t\t\t\tconst type = Object.keys(tree.fieldsByTypeName)[0]\n\t\t\t\ttree = tree.fieldsByTypeName[type][field]\n\t\t\t\tif (!tree) {\n\t\t\t\t\t// This graphql field was never requested, ignore.\n\t\t\t\t\t// This happens when a user resolves a graph for a root subfield which was not requested by the client (and is thus not present in the tree).\n\t\t\t\t\t//\n\t\t\t\t\t// FIXME: this break typings contract. We are supposed to return a query.\n\t\t\t\t\treturn Promise.resolve()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst type = Object.keys(tree.fieldsByTypeName)[0]\n\t\tconst type_resolver = this.type_resolvers[type]\n\t\tif (!type_resolver) {\n\t\t\tthrow new Error(`Resolver not found for type ${type}.`)\n\t\t}\n\t\treturn type_resolver.resolve(query, {\n\t\t\t...context,\n\t\t\tgraph: this,\n\t\t\ttree,\n\t\t\ttype,\n\t\t\tpath: undefined,\n\t\t})\n\t}\n\n\t_resolve_page(\n\t\tquery: Orm[\"Query\"],\n\t\tpaginator: Paginator<Orm, Context>,\n\t\tcontext: GraphResolveContext<Context>,\n\t) {\n\t\tif (context.path) {\n\t\t\t// TODO: handle non-empty context.path\n\t\t\tthrow new Error(\"Paginating under non-root path not yet supported.\")\n\t\t}\n\t\tquery = this._resolve_type(query, { ...context, path: paginator.path })\n\t\treturn paginator.paginate(query, {\n\t\t\t...context,\n\t\t\tgraph: this,\n\t\t})\n\t}\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { Paginator } from \"../paginators/base\"\nimport { FieldResolver, parse_field_options } from \"./field\"\nimport { RelationResolverOptions } from \"./relation\"\n\nexport function definePageResolver<Orm extends OrmAdapter, Context>(\n\tpaginator: Paginator<Orm, Context>,\n\toptions: RelationResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, modify } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { graph, field } = context\n\t\t// Objection.js requires a workaround to handle paginated content,\n\t\t// it must be saved into context and re-injected later.\n\t\t// The modify + finish is a no-op in Orchid.\n\t\tconst pagination_context = {}\n\t\tquery = graph.orm.select_relation(query, {\n\t\t\trelation: tableField || field,\n\t\t\tas: field,\n\t\t\tmodify(subquery) {\n\t\t\t\tsubquery = modify ? modify(subquery, context) : subquery\n\t\t\t\tsubquery = graph._resolve_page(subquery, paginator, context)\n\t\t\t\tsubquery = graph.orm.modify_subquery_pagination(\n\t\t\t\t\tsubquery,\n\t\t\t\t\tpagination_context,\n\t\t\t\t)\n\t\t\t\treturn subquery\n\t\t\t},\n\t\t})\n\t\tquery = graph.orm.finish_query_pagination(query, field, pagination_context)\n\t\treturn query\n\t}\n}\n","import { FiltersDef } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport {\n\tFieldResolver,\n\tFieldResolverOptions,\n\tparse_field_options,\n} from \"./field\"\nimport { TableResolveModifier } from \"./table\"\n\nexport interface RelationResolverOptions<Orm extends OrmAdapter, Context>\n\textends Omit<FieldResolverOptions<Orm, Context>, \"modify\"> {\n\tfilters?: FiltersDef\n\tmodify?: TableResolveModifier<Orm, Context>\n}\n\nexport function defineRelationResolver<Orm extends OrmAdapter, Context>(\n\toptions: RelationResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, filters, modify } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { graph, field } = context\n\t\treturn graph.orm.select_relation(query, {\n\t\t\trelation: tableField || field,\n\t\t\tas: field,\n\t\t\tmodify(subquery) {\n\t\t\t\tsubquery = graph._resolve_type(subquery, { ...context, filters })\n\t\t\t\treturn modify ? modify(subquery, context) : subquery\n\t\t\t},\n\t\t})\n\t}\n}\n","export function is_plain_object(obj: any): obj is Record<string, any> {\n\treturn typeof obj === \"object\" && !Array.isArray(obj)\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { TableResolveContext } from \"../resolvers/table\"\nimport { is_plain_object } from \"../utils/is-plain-object\"\n\n// TODO: per-field definitions\nexport type FiltersDef = boolean\n\nexport type FilterScalarValue = null | string | number | boolean\nexport type FilterValue = FilterScalarValue | Exclude<FilterScalarValue, null>[]\nexport type Filter = { [property: string]: FilterValue }\n\ninterface ApplyFiltersOptions<Orm extends OrmAdapter, Context> {\n\tfilters: FiltersDef\n\tmodifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\tcontext: TableResolveContext<Orm, Context>\n}\n\nexport type ApplyFiltersModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tvalue: any,\n\tcontext: TableResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport function apply_filters<Orm extends OrmAdapter, Context>(\n\tquery: Orm[\"Query\"],\n\t{ filters, modifiers, context }: ApplyFiltersOptions<Orm, Context>,\n): Orm[\"Query\"] {\n\tif (!filters) {\n\t\treturn query\n\t}\n\tconst filter_obj = context.tree.args?.filter\n\tif (!filter_obj) {\n\t\treturn query\n\t}\n\tif (!is_plain_object(filter_obj)) {\n\t\tthrow new Error(`Invalid filter: ${filter_obj}, must be object.`)\n\t}\n\tfor (const [field, value] of Object.entries(filter_obj)) {\n\t\tif (value === undefined) {\n\t\t\t// Support optional GraphQL arguments in filter\n\t\t\tcontinue\n\t\t}\n\t\tif (modifiers?.[field]) {\n\t\t\tquery = modifiers[field](query, value, context)\n\t\t} else {\n\t\t\tconst [table_field, op0] = field.split(\"__\")\n\t\t\tconst op = op0?.toLowerCase()\n\t\t\t// TODO: validate op\n\t\t\tquery = context.graph.orm.where(query, table_field, op, value)\n\t\t}\n\t}\n\treturn query\n}\n","import { apply_filters, ApplyFiltersModifier } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport { run_after_query } from \"../utils/run-after\"\nimport { defineFieldResolver, FieldResolver } from \"./field\"\nimport type { GraphResolveContext, GraphResolver } from \"./graph\"\nimport { defineRelationResolver } from \"./relation\"\n\nexport interface TableResolverOptions<Orm extends OrmAdapter, Context> {\n\t/** allow to resolve all table fields without explicitly listing them */\n\tallowAllFields?: boolean\n\t/** allow to filter all table fields without explicitly listing them */\n\tallowAllFilters?: boolean\n\tfields?: Record<string, SimpleFieldResolver<Orm, Context>>\n\tmodifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\tmodify?: TableResolveModifier<Orm, Context>\n\ttransform?(instance: any, context: any): void | PromiseLike<void>\n}\n\nexport type SimpleFieldResolver<Orm extends OrmAdapter, Context> =\n\t| true\n\t| string\n\t| FieldResolver<Orm, Context>\n\nexport type TableResolveModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tcontext: TableResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport interface TableResolveContext<Orm extends OrmAdapter, Context>\n\textends GraphResolveContext<Context> {\n\tgraph: GraphResolver<Orm, Context>\n\t/** GraphQL type */\n\ttype: string\n}\n\nexport class TableResolver<Orm extends OrmAdapter, Context> {\n\t// Introspection results\n\treadonly relations: Set<string>\n\treadonly virtual_fields: Set<string>\n\treadonly modifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\n\treadonly table_field_resolvers?: Record<string, FieldResolver<Orm, Context>>\n\n\tconstructor(\n\t\treadonly orm: Orm,\n\t\treadonly table: Orm[\"Table\"],\n\t\treadonly options: TableResolverOptions<Orm, Context> = {},\n\t) {\n\t\tthis.relations = new Set(orm.get_table_relations(table))\n\t\tthis.virtual_fields = new Set(orm.get_table_virtual_fields(table))\n\t\tthis.modifiers = { ...orm.get_table_modifiers(table), ...options.modifiers }\n\n\t\t// Pre-create field resolvers\n\t\tconst { fields } = options\n\t\tif (fields) {\n\t\t\tthis.table_field_resolvers = Object.keys(fields).reduce<\n\t\t\t\tRecord<string, FieldResolver<Orm, Context>>\n\t\t\t>((resolvers, field) => {\n\t\t\t\tconst r0 = fields[field]\n\t\t\t\tconst r: FieldResolver<Orm, Context> | undefined =\n\t\t\t\t\ttypeof r0 === \"function\"\n\t\t\t\t\t\t? r0\n\t\t\t\t\t\t: r0 === true\n\t\t\t\t\t\t\t? this._get_default_field_resolver(field)\n\t\t\t\t\t\t\t: typeof r0 === \"string\"\n\t\t\t\t\t\t\t\t? this._get_default_field_resolver(field, r0)\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\tif (r === undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Field resolver must be a function, string, or true; found ${typeof r0}.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tresolvers[field] = r\n\t\t\t\treturn resolvers\n\t\t\t}, {})\n\t\t}\n\t}\n\n\t/** Modify query to select fields/relations and filter the result set. */\n\tresolve(query: Orm[\"Query\"], context: TableResolveContext<Orm, Context>) {\n\t\tconst { modify, transform } = this.options\n\t\tconst { graph, tree, type, filters } = context\n\n\t\tconst query_table = this.orm.get_query_table(query)\n\t\tconst table_table = this.orm.get_table_table(this.table)\n\n\t\tif (query_table !== table_table) {\n\t\t\tthrow new Error(\n\t\t\t\t`Mismatching query table for type ${type}: expected ${table_table}, received ${query_table}.`,\n\t\t\t)\n\t\t}\n\n\t\tconst allow_all_fields =\n\t\t\tthis.options.allowAllFields ??\n\t\t\tgraph.options.allowAllFields ??\n\t\t\t!this.options.fields\n\n\t\tif (!allow_all_fields && !this.table_field_resolvers) {\n\t\t\tthrow new Error(\n\t\t\t\t`Resolver for type ${type} must either allow all fields or specify options.fields.`,\n\t\t\t)\n\t\t}\n\n\t\tif (modify) {\n\t\t\tquery = modify(query, context)\n\t\t}\n\n\t\tfor (const subtree of Object.values(tree.fieldsByTypeName[type])) {\n\t\t\tconst field = subtree.name\n\t\t\tconst r: FieldResolver<Orm, Context> | undefined =\n\t\t\t\tthis.table_field_resolvers?.[field] ||\n\t\t\t\t(allow_all_fields ? this._get_default_field_resolver(field) : undefined)\n\t\t\tif (!r) {\n\t\t\t\tthrow new Error(`No field resolver defined for field ${type}.${field}.`)\n\t\t\t}\n\t\t\tif (r) {\n\t\t\t\tquery = r(query, { ...context, tree: subtree, field })\n\t\t\t}\n\t\t}\n\n\t\tconst allow_all_filters =\n\t\t\tthis.options.allowAllFilters ?? graph.options.allowAllFilters\n\n\t\tconst effective_filters = allow_all_filters ? true : filters\n\n\t\tif (effective_filters) {\n\t\t\tquery = apply_filters<Orm, Context>(query, {\n\t\t\t\tfilters: effective_filters,\n\t\t\t\tmodifiers: this.modifiers,\n\t\t\t\tcontext,\n\t\t\t})\n\t\t}\n\n\t\tif (transform) {\n\t\t\tquery = run_after_query(this.orm, query, (instance) => {\n\t\t\t\treturn transform(instance, context)\n\t\t\t})\n\t\t}\n\n\t\tquery = this.orm.prevent_select_all(query)\n\n\t\treturn query\n\t}\n\n\t/**\n\t * Create field resolver which will modify query to resolve GraphQL field.\n\t */\n\t_get_default_field_resolver(\n\t\tfield: string,\n\t\ttableField?: string,\n\t): FieldResolver<Orm, Context> {\n\t\tconst table_field_lookup = tableField || field\n\t\tif (\n\t\t\tthis.options.modifiers?.[table_field_lookup] ||\n\t\t\tthis.virtual_fields.has(table_field_lookup)\n\t\t) {\n\t\t\t// Keep query as is.\n\t\t\treturn (query) => query\n\t\t} else if (this.relations.has(table_field_lookup)) {\n\t\t\t// TODO: pre-create and cache\n\t\t\treturn defineRelationResolver({ tableField })\n\t\t} else {\n\t\t\t// TODO: create simplified resolver?\n\t\t\treturn defineFieldResolver({ tableField })\n\t\t}\n\t}\n}\n","import { OrmAdapter, SortOrder } from \"graphql-orm\"\nimport type { Query, SelectQueryData, Table } from \"orchid-orm\"\nimport { raw } from \"orchid-orm\"\n\nexport type OrchidOrm = OrmAdapter<\n\tTable,\n\tQuery,\n\t// TODO: Type as QueryTransform once it's published.\n\tPick<Promise<any>, \"then\" | \"catch\">\n>\n\nexport const orm: OrchidOrm = {\n\tTable: undefined as unknown as OrchidOrm[\"Table\"],\n\tQuery: undefined as unknown as OrchidOrm[\"Query\"],\n\tQueryTransform: undefined as unknown as OrchidOrm[\"QueryTransform\"],\n\n\t// Reflection\n\n\tget_table_table(table) {\n\t\treturn table.table!\n\t},\n\n\tget_table_relations(table) {\n\t\treturn Object.keys(table.relations)\n\t},\n\n\tget_table_virtual_fields() {\n\t\t// Not supported by Orchid.\n\t\treturn []\n\t},\n\n\tget_table_modifiers() {\n\t\treturn undefined\n\t},\n\n\tget_query_table(query) {\n\t\tif (!query.table) {\n\t\t\tthrow new Error(\"Query must have table.\")\n\t\t}\n\t\treturn query.table\n\t},\n\n\t// Select\n\n\tselect_field(query, { field, as }) {\n\t\treturn query.select({ [as]: field })\n\t},\n\n\tselect_relation(query, { relation, as, modify }) {\n\t\t// as any casts needed in orchid-orm 1.31+\n\t\treturn query.select({\n\t\t\t[as]: (q: any) => modify(q[relation]),\n\t\t} as any)\n\t},\n\n\t// Find\n\n\twhere(query, field, op, value) {\n\t\treturn query.where({ [field]: op ? { [op]: value } : value })\n\t},\n\n\twhere_raw(query, expression, bindings) {\n\t\treturn query.where(raw({ raw: expression, values: bindings }))\n\t},\n\n\t// Order & Limit\n\n\treset_query_order(query) {\n\t\treturn query.clear(\"order\")\n\t},\n\n\tadd_query_order(query, { field, dir }) {\n\t\treturn query.order({ [field]: dir })\n\t},\n\n\tget_query_order(query) {\n\t\treturn (\n\t\t\t(query.q as SelectQueryData).order?.flatMap<SortOrder>((orderItem) => {\n\t\t\t\tif (typeof orderItem === \"string\") {\n\t\t\t\t\treturn { field: \"orderItem\", dir: \"ASC\" }\n\t\t\t\t} else if (typeof orderItem === \"object\") {\n\t\t\t\t\treturn Object.entries(orderItem).map<SortOrder>(([field, order]) => {\n\t\t\t\t\t\tconst [dir] = order.split(\" \", 1)\n\t\t\t\t\t\tif (dir === \"ASC\" || dir === \"DESC\") {\n\t\t\t\t\t\t\treturn { field, dir }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new Error(\"Unsupported order: \" + order)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthrow new TypeError(\"Unsupported order type: \" + orderItem)\n\t\t\t\t}\n\t\t\t}) || []\n\t\t)\n\t},\n\n\tset_query_limit(query, limit) {\n\t\treturn query.limit(limit)\n\t},\n\n\t// Pagination helpers\n\n\tset_query_page_result(query, get_page) {\n\t\treturn query.transform((nodes) => get_page(nodes as any))\n\t},\n\n\tmodify_subquery_pagination(subquery) {\n\t\treturn subquery\n\t},\n\n\tfinish_query_pagination(query) {\n\t\treturn query\n\t},\n\n\t// Misc\n\n\trun_after_query(query, fn) {\n\t\treturn query.afterQuery((data) => fn(data))\n\t},\n\n\tprevent_select_all(query) {\n\t\t// Not needed in Orchid\n\t\treturn query\n\t},\n}\n","import {\n\tGraphResolveOptions,\n\tGraphResolver,\n\tGraphResolverOptions,\n\tTableResolver,\n} from \"graphql-orm\"\nimport { Query } from \"orchid-orm\"\n\nimport { OrchidOrm, orm } from \"../orm/orm\"\n\nexport function createGraphResolver<Context = unknown>(\n\ttypes: Record<string, TableResolver<OrchidOrm, Context>>,\n\toptions?: GraphResolverOptions<OrchidOrm, Context>,\n) {\n\treturn new OrchidGraphResolver<Context>(types, options)\n}\n\nclass OrchidGraphResolver<Context> extends GraphResolver<OrchidOrm, Context> {\n\tconstructor(\n\t\tpublic readonly types: Record<string, TableResolver<OrchidOrm, Context>>,\n\t\tpublic readonly options: GraphResolverOptions<OrchidOrm, Context> = {},\n\t) {\n\t\tsuper(orm, types, options)\n\t}\n\n\tresolve<T>(\n\t\tquery: Query & {\n\t\t\treturnType: unknown extends T\n\t\t\t\t? any\n\t\t\t\t: T extends unknown[]\n\t\t\t\t\t? undefined | \"all\"\n\t\t\t\t\t: T extends undefined\n\t\t\t\t\t\t? \"one\"\n\t\t\t\t\t\t: \"oneOrThrow\"\n\t\t},\n\t\toptions: GraphResolveOptions<Context>,\n\t): Promise<T> {\n\t\treturn super.resolve(query, options)\n\t}\n}\n","import { TableResolver, TableResolverOptions } from \"graphql-orm\"\nimport { Table } from \"orchid-orm\"\n\nimport { OrchidOrm, orm } from \"../orm/orm\"\n\nexport function defineTableResolver<Context = unknown>(\n\ttable: Table,\n\toptions: TableResolverOptions<OrchidOrm, Context> = {},\n) {\n\treturn new TableResolver(orm, table as any, options)\n}\n"],"mappings":"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","names":["orm","cursor","orm","orm","type","orm"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -91,6 +91,10 @@ interface PaginateContext<Orm extends OrmAdapter, Context> extends GraphResolveC
|
|
|
91
91
|
type GetPageFn = (nodes: any[]) => any;
|
|
92
92
|
|
|
93
93
|
type OrmModifier<Orm extends OrmAdapter> = (query: Orm["Query"], ...args: any[]) => Orm["Query"];
|
|
94
|
+
interface SortOrder {
|
|
95
|
+
field: string;
|
|
96
|
+
dir: "ASC" | "DESC";
|
|
97
|
+
}
|
|
94
98
|
interface OrmAdapter<Table = any, Query = any, QueryTransform = any> {
|
|
95
99
|
Table: Table;
|
|
96
100
|
Query: Query;
|
|
@@ -116,7 +120,8 @@ interface OrmAdapter<Table = any, Query = any, QueryTransform = any> {
|
|
|
116
120
|
where(query: Query, field: string, op: string | undefined, value: any): Query;
|
|
117
121
|
where_raw(query: Query, expression: string, bindings: Record<string, any>): Query;
|
|
118
122
|
reset_query_order(query: Query): Query;
|
|
119
|
-
add_query_order(query: Query,
|
|
123
|
+
add_query_order(query: Query, order: SortOrder): Query;
|
|
124
|
+
get_query_order(query: Query): SortOrder[];
|
|
120
125
|
set_query_limit(query: Query, limit: number): Query;
|
|
121
126
|
set_query_page_result(query: Query, get_page: GetPageFn): QueryTransform;
|
|
122
127
|
modify_subquery_pagination(subquery: Query, context: Record<string, any>): Query;
|
|
@@ -129,23 +134,18 @@ interface OrmAdapter<Table = any, Query = any, QueryTransform = any> {
|
|
|
129
134
|
|
|
130
135
|
declare function defineCursorPaginator(options?: Partial<CursorPaginatorOptions>): CursorPaginator<OrmAdapter<any, any, any>, unknown>;
|
|
131
136
|
interface CursorPaginatorOptions {
|
|
132
|
-
fields
|
|
133
|
-
take
|
|
137
|
+
fields?: string[];
|
|
138
|
+
take?: number;
|
|
134
139
|
}
|
|
135
140
|
declare class CursorPaginator<Orm extends OrmAdapter, Context> implements Paginator<Orm, Context> {
|
|
136
141
|
readonly path: string[];
|
|
137
|
-
readonly
|
|
138
|
-
readonly fields
|
|
142
|
+
readonly pageSize: number;
|
|
143
|
+
readonly fields?: Array<{
|
|
139
144
|
name: string;
|
|
140
145
|
desc: boolean;
|
|
141
146
|
}>;
|
|
142
|
-
constructor(options?:
|
|
147
|
+
constructor(options?: CursorPaginatorOptions);
|
|
143
148
|
paginate(query: Orm["Query"], context: PaginateContext<Orm, Context>): any;
|
|
144
|
-
_create_cursor(instance: any): string;
|
|
145
|
-
_parse_cursor(cursor: string): {
|
|
146
|
-
expression: string;
|
|
147
|
-
bindings: Record<string, any>;
|
|
148
|
-
};
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
interface RelationResolverOptions<Orm extends OrmAdapter, Context> extends Omit<FieldResolverOptions<Orm, Context>, "modify"> {
|
package/dist/index.d.ts
CHANGED
|
@@ -91,6 +91,10 @@ interface PaginateContext<Orm extends OrmAdapter, Context> extends GraphResolveC
|
|
|
91
91
|
type GetPageFn = (nodes: any[]) => any;
|
|
92
92
|
|
|
93
93
|
type OrmModifier<Orm extends OrmAdapter> = (query: Orm["Query"], ...args: any[]) => Orm["Query"];
|
|
94
|
+
interface SortOrder {
|
|
95
|
+
field: string;
|
|
96
|
+
dir: "ASC" | "DESC";
|
|
97
|
+
}
|
|
94
98
|
interface OrmAdapter<Table = any, Query = any, QueryTransform = any> {
|
|
95
99
|
Table: Table;
|
|
96
100
|
Query: Query;
|
|
@@ -116,7 +120,8 @@ interface OrmAdapter<Table = any, Query = any, QueryTransform = any> {
|
|
|
116
120
|
where(query: Query, field: string, op: string | undefined, value: any): Query;
|
|
117
121
|
where_raw(query: Query, expression: string, bindings: Record<string, any>): Query;
|
|
118
122
|
reset_query_order(query: Query): Query;
|
|
119
|
-
add_query_order(query: Query,
|
|
123
|
+
add_query_order(query: Query, order: SortOrder): Query;
|
|
124
|
+
get_query_order(query: Query): SortOrder[];
|
|
120
125
|
set_query_limit(query: Query, limit: number): Query;
|
|
121
126
|
set_query_page_result(query: Query, get_page: GetPageFn): QueryTransform;
|
|
122
127
|
modify_subquery_pagination(subquery: Query, context: Record<string, any>): Query;
|
|
@@ -129,23 +134,18 @@ interface OrmAdapter<Table = any, Query = any, QueryTransform = any> {
|
|
|
129
134
|
|
|
130
135
|
declare function defineCursorPaginator(options?: Partial<CursorPaginatorOptions>): CursorPaginator<OrmAdapter<any, any, any>, unknown>;
|
|
131
136
|
interface CursorPaginatorOptions {
|
|
132
|
-
fields
|
|
133
|
-
take
|
|
137
|
+
fields?: string[];
|
|
138
|
+
take?: number;
|
|
134
139
|
}
|
|
135
140
|
declare class CursorPaginator<Orm extends OrmAdapter, Context> implements Paginator<Orm, Context> {
|
|
136
141
|
readonly path: string[];
|
|
137
|
-
readonly
|
|
138
|
-
readonly fields
|
|
142
|
+
readonly pageSize: number;
|
|
143
|
+
readonly fields?: Array<{
|
|
139
144
|
name: string;
|
|
140
145
|
desc: boolean;
|
|
141
146
|
}>;
|
|
142
|
-
constructor(options?:
|
|
147
|
+
constructor(options?: CursorPaginatorOptions);
|
|
143
148
|
paginate(query: Orm["Query"], context: PaginateContext<Orm, Context>): any;
|
|
144
|
-
_create_cursor(instance: any): string;
|
|
145
|
-
_parse_cursor(cursor: string): {
|
|
146
|
-
expression: string;
|
|
147
|
-
bindings: Record<string, any>;
|
|
148
|
-
};
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
interface RelationResolverOptions<Orm extends OrmAdapter, Context> extends Omit<FieldResolverOptions<Orm, Context>, "modify"> {
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
// ../base/src/paginators/cursor.ts
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
2
3
|
function defineCursorPaginator(options = {}) {
|
|
3
4
|
return new CursorPaginator(options);
|
|
4
5
|
}
|
|
5
6
|
var CursorPaginator = class {
|
|
6
7
|
path = ["nodes"];
|
|
7
|
-
|
|
8
|
+
pageSize;
|
|
8
9
|
fields;
|
|
9
10
|
constructor(options = {}) {
|
|
10
|
-
this.
|
|
11
|
-
|
|
12
|
-
take: 10,
|
|
13
|
-
...options
|
|
14
|
-
};
|
|
15
|
-
this.fields = this.options.fields.map((field) => {
|
|
11
|
+
this.pageSize = options.take ?? 10;
|
|
12
|
+
this.fields = options.fields?.map((field) => {
|
|
16
13
|
if (field.startsWith("-")) {
|
|
17
14
|
return { name: field.slice(1), desc: true };
|
|
18
15
|
} else {
|
|
@@ -23,59 +20,73 @@ var CursorPaginator = class {
|
|
|
23
20
|
paginate(query, context) {
|
|
24
21
|
const { orm: orm2 } = context.graph;
|
|
25
22
|
const { args } = context.tree;
|
|
26
|
-
const
|
|
23
|
+
const pageSize = args.take ?? this.pageSize;
|
|
27
24
|
const cursor = args.cursor;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
const table = orm2.get_query_table(query);
|
|
26
|
+
const orderFields = (this.fields ? this.fields.map((f) => ({
|
|
27
|
+
field: f.name,
|
|
28
|
+
dir: f.desc ? "DESC" : "ASC"
|
|
29
|
+
})) : orm2.get_query_order(query)).map((o) => ({ ...o, alias: "_order_" + o.field }));
|
|
30
|
+
if (this.fields) {
|
|
31
|
+
query = orm2.reset_query_order(query);
|
|
32
|
+
for (const { alias, dir } of orderFields) {
|
|
33
|
+
query = orm2.add_query_order(query, { field: alias, dir });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!orderFields.length) {
|
|
37
|
+
throw new Error("Query must be ordered.");
|
|
38
|
+
}
|
|
39
|
+
for (const { field, alias } of orderFields) {
|
|
40
|
+
query = orm2.select_field(query, { field, as: alias });
|
|
32
41
|
}
|
|
33
42
|
if (cursor) {
|
|
34
|
-
const
|
|
35
|
-
|
|
43
|
+
const parsedCursor = parseCursor(cursor);
|
|
44
|
+
const left = [];
|
|
45
|
+
const right = [];
|
|
46
|
+
for (let i = 0; i < orderFields.length; ++i) {
|
|
47
|
+
const { field, alias, dir } = orderFields[i];
|
|
48
|
+
const [expressions, placeholders] = dir === "ASC" ? [left, right] : [right, left];
|
|
49
|
+
expressions.push(`"${table}"."${field}"`);
|
|
50
|
+
placeholders.push("$" + alias);
|
|
51
|
+
}
|
|
52
|
+
const sqlExpr = `(${left.join(",")}) > (${right.join(",")})`;
|
|
53
|
+
const bindings = Object.fromEntries(
|
|
54
|
+
orderFields.map(({ alias }, i) => [alias, parsedCursor[i]])
|
|
55
|
+
);
|
|
56
|
+
query = orm2.where_raw(query, sqlExpr, bindings);
|
|
57
|
+
}
|
|
58
|
+
query = orm2.set_query_limit(query, pageSize + 1);
|
|
59
|
+
function createNodeCursor(node) {
|
|
60
|
+
return createCursor(
|
|
61
|
+
orderFields.map(({ field, alias }) => {
|
|
62
|
+
const value = node[alias];
|
|
63
|
+
if (value === void 0) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Unable to create cursor: undefined field ${field} (${alias})`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return String(value);
|
|
69
|
+
})
|
|
70
|
+
);
|
|
36
71
|
}
|
|
37
|
-
query = orm2.set_query_limit(query, take + 1);
|
|
38
72
|
return orm2.set_query_page_result(query, (nodes) => {
|
|
39
73
|
let cursor2;
|
|
40
|
-
if (nodes.length >
|
|
41
|
-
cursor2 =
|
|
42
|
-
nodes = nodes.slice(0,
|
|
74
|
+
if (nodes.length > pageSize) {
|
|
75
|
+
cursor2 = createNodeCursor(nodes[pageSize - 1]);
|
|
76
|
+
nodes = nodes.slice(0, pageSize);
|
|
43
77
|
}
|
|
44
78
|
return { nodes, cursor: cursor2 };
|
|
45
79
|
});
|
|
46
80
|
}
|
|
47
|
-
_create_cursor(instance) {
|
|
48
|
-
return JSON.stringify(
|
|
49
|
-
this.fields.map((field) => {
|
|
50
|
-
const value = instance[field.name];
|
|
51
|
-
if (value === void 0) {
|
|
52
|
-
throw new Error(
|
|
53
|
-
`Unable to create cursor: undefined field ${field.name}`
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
return String(value);
|
|
57
|
-
})
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
_parse_cursor(cursor) {
|
|
61
|
-
const values = JSON.parse(cursor);
|
|
62
|
-
const left = [];
|
|
63
|
-
const right = [];
|
|
64
|
-
const bindings = {};
|
|
65
|
-
for (let i = 0; i < this.fields.length; ++i) {
|
|
66
|
-
const field = this.fields[i];
|
|
67
|
-
const expressions = field.desc ? right : left;
|
|
68
|
-
const placeholders = field.desc ? left : right;
|
|
69
|
-
expressions.push(`"${field.name}"`);
|
|
70
|
-
placeholders.push("$" + field.name);
|
|
71
|
-
bindings[field.name] = values[i];
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
expression: `(${left.join(",")}) > (${right.join(",")})`,
|
|
75
|
-
bindings
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
81
|
};
|
|
82
|
+
function createCursor(parts) {
|
|
83
|
+
return Buffer.from(parts.map(String).join(String.fromCharCode(0))).toString(
|
|
84
|
+
"base64url"
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
function parseCursor(cursor) {
|
|
88
|
+
return Buffer.from(cursor, "base64url").toString().split(String.fromCharCode(0));
|
|
89
|
+
}
|
|
79
90
|
|
|
80
91
|
// ../base/src/utils/run-after.ts
|
|
81
92
|
function run_after_query(orm2, query, transform) {
|
|
@@ -188,12 +199,13 @@ function definePageResolver(paginator, options = {}) {
|
|
|
188
199
|
relation: tableField || field,
|
|
189
200
|
as: field,
|
|
190
201
|
modify(subquery) {
|
|
202
|
+
subquery = modify ? modify(subquery, context) : subquery;
|
|
191
203
|
subquery = graph._resolve_page(subquery, paginator, context);
|
|
192
204
|
subquery = graph.orm.modify_subquery_pagination(
|
|
193
205
|
subquery,
|
|
194
206
|
pagination_context
|
|
195
207
|
);
|
|
196
|
-
return
|
|
208
|
+
return subquery;
|
|
197
209
|
}
|
|
198
210
|
});
|
|
199
211
|
query = graph.orm.finish_query_pagination(query, field, pagination_context);
|
|
@@ -385,8 +397,26 @@ var orm = {
|
|
|
385
397
|
reset_query_order(query) {
|
|
386
398
|
return query.clear("order");
|
|
387
399
|
},
|
|
388
|
-
add_query_order(query, field,
|
|
389
|
-
return query.order({ [field]:
|
|
400
|
+
add_query_order(query, { field, dir }) {
|
|
401
|
+
return query.order({ [field]: dir });
|
|
402
|
+
},
|
|
403
|
+
get_query_order(query) {
|
|
404
|
+
return query.q.order?.flatMap((orderItem) => {
|
|
405
|
+
if (typeof orderItem === "string") {
|
|
406
|
+
return { field: "orderItem", dir: "ASC" };
|
|
407
|
+
} else if (typeof orderItem === "object") {
|
|
408
|
+
return Object.entries(orderItem).map(([field, order]) => {
|
|
409
|
+
const [dir] = order.split(" ", 1);
|
|
410
|
+
if (dir === "ASC" || dir === "DESC") {
|
|
411
|
+
return { field, dir };
|
|
412
|
+
} else {
|
|
413
|
+
throw new Error("Unsupported order: " + order);
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
} else {
|
|
417
|
+
throw new TypeError("Unsupported order type: " + orderItem);
|
|
418
|
+
}
|
|
419
|
+
}) || [];
|
|
390
420
|
},
|
|
391
421
|
set_query_limit(query, limit) {
|
|
392
422
|
return query.limit(limit);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../base/src/paginators/cursor.ts","../../base/src/utils/run-after.ts","../../base/src/resolvers/field.ts","../../base/src/resolvers/graph.ts","../../base/src/resolvers/page.ts","../../base/src/resolvers/relation.ts","../../base/src/utils/is-plain-object.ts","../../base/src/filters/filters.ts","../../base/src/resolvers/table.ts","../src/orm/orm.ts","../src/resolvers/graph.ts","../src/resolvers/table.ts"],"sourcesContent":["import { OrmAdapter } from \"../orm/orm\"\nimport { PaginateContext, Paginator } from \"./base\"\n\nexport function defineCursorPaginator(\n\toptions: Partial<CursorPaginatorOptions> = {},\n) {\n\treturn new CursorPaginator(options)\n}\n\nexport interface CursorPaginatorOptions {\n\tfields: string[]\n\ttake: number\n}\n\nexport interface CursorPaginatorArgs {\n\tcursor?: string\n\ttake?: number\n}\n\nexport interface CursorPaginatorPage<M> {\n\tnodes: M[]\n\tcursor?: string\n}\n\nclass CursorPaginator<Orm extends OrmAdapter, Context>\n\timplements Paginator<Orm, Context>\n{\n\treadonly path = [\"nodes\"]\n\treadonly options: CursorPaginatorOptions\n\n\treadonly fields: Array<{\n\t\tname: string\n\t\tdesc: boolean\n\t}>\n\n\tconstructor(options: Partial<CursorPaginatorOptions> = {}) {\n\t\tthis.options = {\n\t\t\tfields: [\"id\"],\n\t\t\ttake: 10,\n\t\t\t...options,\n\t\t}\n\t\tthis.fields = this.options.fields.map((field) => {\n\t\t\tif (field.startsWith(\"-\")) {\n\t\t\t\treturn { name: field.slice(1), desc: true }\n\t\t\t} else {\n\t\t\t\treturn { name: field, desc: false }\n\t\t\t}\n\t\t})\n\t}\n\n\tpaginate(query: Orm[\"Query\"], context: PaginateContext<Orm, Context>) {\n\t\tconst { orm } = context.graph\n\t\tconst { args } = context.tree\n\n\t\tconst take = (args.take as number | undefined) ?? this.options.take\n\t\tconst cursor = args.cursor as string | undefined\n\n\t\t// Set query order\n\t\tquery = orm.reset_query_order(query)\n\t\tfor (const field of this.fields) {\n\t\t\t// TODO: prevent potential name clash with aliases like .as(`_${table_ref}_order_key_0`)\n\t\t\tquery = orm.select_field(query, { field: field.name, as: field.name })\n\t\t\tquery = orm.add_query_order(query, field.name, field.desc)\n\t\t}\n\n\t\tif (cursor) {\n\t\t\tconst { expression, bindings } = this._parse_cursor(cursor)\n\t\t\tquery = orm.where_raw(query, expression, bindings)\n\t\t}\n\t\tquery = orm.set_query_limit(query, take + 1)\n\n\t\treturn orm.set_query_page_result(query, (nodes) => {\n\t\t\tlet cursor: string | undefined\n\t\t\tif (nodes.length > take) {\n\t\t\t\tcursor = this._create_cursor(nodes[take - 1])\n\t\t\t\tnodes = nodes.slice(0, take)\n\t\t\t}\n\t\t\treturn { nodes, cursor }\n\t\t})\n\t}\n\n\t_create_cursor(instance: any) {\n\t\treturn JSON.stringify(\n\t\t\tthis.fields.map((field) => {\n\t\t\t\tconst value = instance[field.name]\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Unable to create cursor: undefined field ${field.name}`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn String(value)\n\t\t\t}),\n\t\t)\n\t}\n\n\t_parse_cursor(cursor: string) {\n\t\tconst values = JSON.parse(cursor)\n\t\tconst left: string[] = []\n\t\tconst right: string[] = []\n\t\tconst bindings: Record<string, any> = {}\n\t\tfor (let i = 0; i < this.fields.length; ++i) {\n\t\t\tconst field = this.fields[i]\n\t\t\tconst expressions = field.desc ? right : left\n\t\t\tconst placeholders = field.desc ? left : right\n\t\t\texpressions.push(`\"${field.name}\"`)\n\t\t\tplaceholders.push(\"$\" + field.name)\n\t\t\tbindings[field.name] = values[i]\n\t\t}\n\t\treturn {\n\t\t\texpression: `(${left.join(\",\")}) > (${right.join(\",\")})`,\n\t\t\tbindings,\n\t\t}\n\t}\n}\n","import { OrmAdapter } from \"../orm/orm\"\n\nexport function run_after_query<Orm extends OrmAdapter>(\n\torm: Orm,\n\tquery: Orm[\"Query\"],\n\ttransform: (instance: any) => any,\n): Orm[\"Query\"] {\n\treturn orm.run_after_query(query, async (result) => {\n\t\t// FIXME: returning result is ignored in orchid (unlike objection). Add some hacks instead.\n\t\tif (Array.isArray(result)) {\n\t\t\tconst result1 = await Promise.all(result.map(transform))\n\t\t\treturn result1.filter(Boolean) // Skip empty objects\n\t\t} else if (result) {\n\t\t\treturn transform(result)\n\t\t} else {\n\t\t\t// Supposedly, single query returning NULL\n\t\t\treturn result\n\t\t}\n\t})\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { run_after_query } from \"../utils/run-after\"\nimport { TableResolveContext } from \"./table\"\n\nexport interface FieldResolverOptions<Orm extends OrmAdapter, Context> {\n\t/** Table field (if different from GraphQL field) */\n\ttableField?: string\n\t/** Legacy alias for `tableField`. */\n\tmodelField?: string\n\t/** Custom query modifier (if different than simply selecting a field). */\n\tmodify?: FieldResolveModifier<Orm, Context>\n\t/** Post-process selected value. Return a new value or a promise. */\n\ttransform?(\n\t\tvalue: any,\n\t\tinstance: any,\n\t\tcontext: FieldResolveContext<Orm, Context>,\n\t): any\n}\n\nexport type FieldResolveModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tcontext: FieldResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport interface FieldResolveContext<Orm extends OrmAdapter, Context>\n\textends TableResolveContext<Orm, Context> {\n\t/** GraphQL field */\n\tfield: string\n}\n\n// That is a coincidence for now.\nexport type FieldResolver<\n\tOrm extends OrmAdapter,\n\tContext,\n> = FieldResolveModifier<Orm, Context>\n\nexport function parse_field_options<\n\tO extends Pick<FieldResolverOptions<any, any>, \"modelField\" | \"tableField\">,\n>(options: O): Omit<O, \"modelField\"> {\n\tconst { tableField, modelField } = options\n\tif (tableField && modelField) {\n\t\tthrow new Error(\n\t\t\t`Both tableField and modelField are defined. Use only one of them.`,\n\t\t)\n\t}\n\treturn { ...options, tableField: tableField || modelField }\n}\n\nexport function defineFieldResolver<Orm extends OrmAdapter, Context>(\n\toptions: FieldResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, modify, transform } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { field } = context\n\t\tif (modify) {\n\t\t\tquery = modify(query, context)\n\t\t} else {\n\t\t\tquery = context.graph.orm.select_field(query, {\n\t\t\t\tfield: tableField || field,\n\t\t\t\tas: field,\n\t\t\t})\n\t\t}\n\t\tif (transform) {\n\t\t\tquery = run_after_query(context.graph.orm, query, async (instance) => {\n\t\t\t\tinstance[field] = await transform(instance[field], instance, context)\n\t\t\t\treturn instance\n\t\t\t})\n\t\t}\n\t\treturn query\n\t}\n}\n","import type { GraphQLResolveInfo } from \"graphql\"\nimport { parseResolveInfo, ResolveTree } from \"graphql-parse-resolve-info\"\n\nimport { FiltersDef } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport { Paginator } from \"../paginators/base\"\nimport type { TableResolver, TableResolverOptions } from \"./table\"\n\nexport type GraphResolverOptions<Orm extends OrmAdapter, Context> = Pick<\n\tTableResolverOptions<Orm, Context>,\n\t\"allowAllFields\" | \"allowAllFilters\"\n>\n\nexport interface GraphResolveOptions<Context> {\n\tinfo: GraphQLResolveInfo\n\tcontext: Context\n\tfilters?: FiltersDef\n\t/** Subfield path if not resolving root query, e.g.: ['user'] */\n\tpath?: string[]\n}\n\nexport type GraphResolveContext<Context> = Omit<\n\tGraphResolveOptions<Context>,\n\t\"info\"\n> & {\n\ttree: ResolveTree\n}\n\nexport class GraphResolver<Orm extends OrmAdapter, Context> {\n\tconstructor(\n\t\treadonly orm: Orm,\n\t\treadonly type_resolvers: Record<string, TableResolver<Orm, Context>>,\n\t\treadonly options: GraphResolverOptions<Orm, Context> = {},\n\t) {}\n\n\tresolve<T>(\n\t\tquery: Orm[\"Query\"],\n\t\t{ info, ...context }: GraphResolveOptions<Context>,\n\t): Promise<T> {\n\t\tconst tree = this._get_resolve_tree(info)\n\t\treturn this._resolve_type(query, { ...context, tree })\n\t}\n\n\tresolvePage(\n\t\tquery: Orm[\"Query\"],\n\t\tpaginator: Paginator<Orm, Context>,\n\t\t{ info, ...context }: GraphResolveOptions<Context>,\n\t) {\n\t\tconst tree = this._get_resolve_tree(info)\n\t\treturn this._resolve_page(query, paginator, { ...context, tree })\n\t}\n\n\t_get_resolve_tree(info: GraphQLResolveInfo) {\n\t\treturn parseResolveInfo(info) as ResolveTree\n\t}\n\n\t_resolve_type(\n\t\tquery: Orm[\"Query\"],\n\t\tcontext: GraphResolveContext<Context>,\n\t): Orm[\"Query\"] {\n\t\tlet { tree } = context\n\t\t// Dive into subtree if requested.\n\t\tif (context.path) {\n\t\t\tfor (const field of context.path) {\n\t\t\t\tconst type = Object.keys(tree.fieldsByTypeName)[0]\n\t\t\t\ttree = tree.fieldsByTypeName[type][field]\n\t\t\t\tif (!tree) {\n\t\t\t\t\t// This graphql field was never requested, ignore.\n\t\t\t\t\t// This happens when a user resolves a graph for a root subfield which was not requested by the client (and is thus not present in the tree).\n\t\t\t\t\t//\n\t\t\t\t\t// FIXME: this break typings contract. We are supposed to return a query.\n\t\t\t\t\treturn Promise.resolve()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst type = Object.keys(tree.fieldsByTypeName)[0]\n\t\tconst type_resolver = this.type_resolvers[type]\n\t\tif (!type_resolver) {\n\t\t\tthrow new Error(`Resolver not found for type ${type}.`)\n\t\t}\n\t\treturn type_resolver.resolve(query, {\n\t\t\t...context,\n\t\t\tgraph: this,\n\t\t\ttree,\n\t\t\ttype,\n\t\t\tpath: undefined,\n\t\t})\n\t}\n\n\t_resolve_page(\n\t\tquery: Orm[\"Query\"],\n\t\tpaginator: Paginator<Orm, Context>,\n\t\tcontext: GraphResolveContext<Context>,\n\t) {\n\t\tif (context.path) {\n\t\t\t// TODO: handle non-empty context.path\n\t\t\tthrow new Error(\"Paginating under non-root path not yet supported.\")\n\t\t}\n\t\tquery = this._resolve_type(query, { ...context, path: paginator.path })\n\t\treturn paginator.paginate(query, {\n\t\t\t...context,\n\t\t\tgraph: this,\n\t\t})\n\t}\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { Paginator } from \"../paginators/base\"\nimport { FieldResolver, parse_field_options } from \"./field\"\nimport { RelationResolverOptions } from \"./relation\"\n\nexport function definePageResolver<Orm extends OrmAdapter, Context>(\n\tpaginator: Paginator<Orm, Context>,\n\toptions: RelationResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, modify } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { graph, field } = context\n\t\t// Objection.js requires a workaround to handle paginated content,\n\t\t// it must be saved into context and re-injected later.\n\t\t// The modify + finish is a no-op in Orchid.\n\t\tconst pagination_context = {}\n\t\tquery = graph.orm.select_relation(query, {\n\t\t\trelation: tableField || field,\n\t\t\tas: field,\n\t\t\tmodify(subquery) {\n\t\t\t\tsubquery = graph._resolve_page(subquery, paginator, context)\n\t\t\t\tsubquery = graph.orm.modify_subquery_pagination(\n\t\t\t\t\tsubquery,\n\t\t\t\t\tpagination_context,\n\t\t\t\t)\n\t\t\t\treturn modify ? modify(subquery, context) : subquery\n\t\t\t},\n\t\t})\n\t\tquery = graph.orm.finish_query_pagination(query, field, pagination_context)\n\t\treturn query\n\t}\n}\n","import { FiltersDef } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport {\n\tFieldResolver,\n\tFieldResolverOptions,\n\tparse_field_options,\n} from \"./field\"\nimport { TableResolveModifier } from \"./table\"\n\nexport interface RelationResolverOptions<Orm extends OrmAdapter, Context>\n\textends Omit<FieldResolverOptions<Orm, Context>, \"modify\"> {\n\tfilters?: FiltersDef\n\tmodify?: TableResolveModifier<Orm, Context>\n}\n\nexport function defineRelationResolver<Orm extends OrmAdapter, Context>(\n\toptions: RelationResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, filters, modify } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { graph, field } = context\n\t\treturn graph.orm.select_relation(query, {\n\t\t\trelation: tableField || field,\n\t\t\tas: field,\n\t\t\tmodify(subquery) {\n\t\t\t\tsubquery = graph._resolve_type(subquery, { ...context, filters })\n\t\t\t\treturn modify ? modify(subquery, context) : subquery\n\t\t\t},\n\t\t})\n\t}\n}\n","export function is_plain_object(obj: any): obj is Record<string, any> {\n\treturn typeof obj === \"object\" && !Array.isArray(obj)\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { TableResolveContext } from \"../resolvers/table\"\nimport { is_plain_object } from \"../utils/is-plain-object\"\n\n// TODO: per-field definitions\nexport type FiltersDef = boolean\n\nexport type FilterScalarValue = null | string | number | boolean\nexport type FilterValue = FilterScalarValue | Exclude<FilterScalarValue, null>[]\nexport type Filter = { [property: string]: FilterValue }\n\ninterface ApplyFiltersOptions<Orm extends OrmAdapter, Context> {\n\tfilters: FiltersDef\n\tmodifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\tcontext: TableResolveContext<Orm, Context>\n}\n\nexport type ApplyFiltersModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tvalue: any,\n\tcontext: TableResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport function apply_filters<Orm extends OrmAdapter, Context>(\n\tquery: Orm[\"Query\"],\n\t{ filters, modifiers, context }: ApplyFiltersOptions<Orm, Context>,\n): Orm[\"Query\"] {\n\tif (!filters) {\n\t\treturn query\n\t}\n\tconst filter_obj = context.tree.args?.filter\n\tif (!filter_obj) {\n\t\treturn query\n\t}\n\tif (!is_plain_object(filter_obj)) {\n\t\tthrow new Error(`Invalid filter: ${filter_obj}, must be object.`)\n\t}\n\tfor (const [field, value] of Object.entries(filter_obj)) {\n\t\tif (value === undefined) {\n\t\t\t// Support optional GraphQL arguments in filter\n\t\t\tcontinue\n\t\t}\n\t\tif (modifiers?.[field]) {\n\t\t\tquery = modifiers[field](query, value, context)\n\t\t} else {\n\t\t\tconst [table_field, op0] = field.split(\"__\")\n\t\t\tconst op = op0?.toLowerCase()\n\t\t\t// TODO: validate op\n\t\t\tquery = context.graph.orm.where(query, table_field, op, value)\n\t\t}\n\t}\n\treturn query\n}\n","import { apply_filters, ApplyFiltersModifier } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport { run_after_query } from \"../utils/run-after\"\nimport { defineFieldResolver, FieldResolver } from \"./field\"\nimport type { GraphResolveContext, GraphResolver } from \"./graph\"\nimport { defineRelationResolver } from \"./relation\"\n\nexport interface TableResolverOptions<Orm extends OrmAdapter, Context> {\n\t/** allow to resolve all table fields without explicitly listing them */\n\tallowAllFields?: boolean\n\t/** allow to filter all table fields without explicitly listing them */\n\tallowAllFilters?: boolean\n\tfields?: Record<string, SimpleFieldResolver<Orm, Context>>\n\tmodifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\tmodify?: TableResolveModifier<Orm, Context>\n\ttransform?(instance: any, context: any): void | PromiseLike<void>\n}\n\nexport type SimpleFieldResolver<Orm extends OrmAdapter, Context> =\n\t| true\n\t| string\n\t| FieldResolver<Orm, Context>\n\nexport type TableResolveModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tcontext: TableResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport interface TableResolveContext<Orm extends OrmAdapter, Context>\n\textends GraphResolveContext<Context> {\n\tgraph: GraphResolver<Orm, Context>\n\t/** GraphQL type */\n\ttype: string\n}\n\nexport class TableResolver<Orm extends OrmAdapter, Context> {\n\t// Introspection results\n\treadonly relations: Set<string>\n\treadonly virtual_fields: Set<string>\n\treadonly modifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\n\treadonly table_field_resolvers?: Record<string, FieldResolver<Orm, Context>>\n\n\tconstructor(\n\t\treadonly orm: Orm,\n\t\treadonly table: Orm[\"Table\"],\n\t\treadonly options: TableResolverOptions<Orm, Context> = {},\n\t) {\n\t\tthis.relations = new Set(orm.get_table_relations(table))\n\t\tthis.virtual_fields = new Set(orm.get_table_virtual_fields(table))\n\t\tthis.modifiers = { ...orm.get_table_modifiers(table), ...options.modifiers }\n\n\t\t// Pre-create field resolvers\n\t\tconst { fields } = options\n\t\tif (fields) {\n\t\t\tthis.table_field_resolvers = Object.keys(fields).reduce<\n\t\t\t\tRecord<string, FieldResolver<Orm, Context>>\n\t\t\t>((resolvers, field) => {\n\t\t\t\tconst r0 = fields[field]\n\t\t\t\tconst r: FieldResolver<Orm, Context> | undefined =\n\t\t\t\t\ttypeof r0 === \"function\"\n\t\t\t\t\t\t? r0\n\t\t\t\t\t\t: r0 === true\n\t\t\t\t\t\t\t? this._get_default_field_resolver(field)\n\t\t\t\t\t\t\t: typeof r0 === \"string\"\n\t\t\t\t\t\t\t\t? this._get_default_field_resolver(field, r0)\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\tif (r === undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Field resolver must be a function, string, or true; found ${typeof r0}.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tresolvers[field] = r\n\t\t\t\treturn resolvers\n\t\t\t}, {})\n\t\t}\n\t}\n\n\t/** Modify query to select fields/relations and filter the result set. */\n\tresolve(query: Orm[\"Query\"], context: TableResolveContext<Orm, Context>) {\n\t\tconst { modify, transform } = this.options\n\t\tconst { graph, tree, type, filters } = context\n\n\t\tconst query_table = this.orm.get_query_table(query)\n\t\tconst table_table = this.orm.get_table_table(this.table)\n\n\t\tif (query_table !== table_table) {\n\t\t\tthrow new Error(\n\t\t\t\t`Mismatching query table for type ${type}: expected ${table_table}, received ${query_table}.`,\n\t\t\t)\n\t\t}\n\n\t\tconst allow_all_fields =\n\t\t\tthis.options.allowAllFields ??\n\t\t\tgraph.options.allowAllFields ??\n\t\t\t!this.options.fields\n\n\t\tif (!allow_all_fields && !this.table_field_resolvers) {\n\t\t\tthrow new Error(\n\t\t\t\t`Resolver for type ${type} must either allow all fields or specify options.fields.`,\n\t\t\t)\n\t\t}\n\n\t\tif (modify) {\n\t\t\tquery = modify(query, context)\n\t\t}\n\n\t\tfor (const subtree of Object.values(tree.fieldsByTypeName[type])) {\n\t\t\tconst field = subtree.name\n\t\t\tconst r: FieldResolver<Orm, Context> | undefined =\n\t\t\t\tthis.table_field_resolvers?.[field] ||\n\t\t\t\t(allow_all_fields ? this._get_default_field_resolver(field) : undefined)\n\t\t\tif (!r) {\n\t\t\t\tthrow new Error(`No field resolver defined for field ${type}.${field}.`)\n\t\t\t}\n\t\t\tif (r) {\n\t\t\t\tquery = r(query, { ...context, tree: subtree, field })\n\t\t\t}\n\t\t}\n\n\t\tconst allow_all_filters =\n\t\t\tthis.options.allowAllFilters ?? graph.options.allowAllFilters\n\n\t\tconst effective_filters = allow_all_filters ? true : filters\n\n\t\tif (effective_filters) {\n\t\t\tquery = apply_filters<Orm, Context>(query, {\n\t\t\t\tfilters: effective_filters,\n\t\t\t\tmodifiers: this.modifiers,\n\t\t\t\tcontext,\n\t\t\t})\n\t\t}\n\n\t\tif (transform) {\n\t\t\tquery = run_after_query(this.orm, query, (instance) => {\n\t\t\t\treturn transform(instance, context)\n\t\t\t})\n\t\t}\n\n\t\tquery = this.orm.prevent_select_all(query)\n\n\t\treturn query\n\t}\n\n\t/**\n\t * Create field resolver which will modify query to resolve GraphQL field.\n\t */\n\t_get_default_field_resolver(\n\t\tfield: string,\n\t\ttableField?: string,\n\t): FieldResolver<Orm, Context> {\n\t\tconst table_field_lookup = tableField || field\n\t\tif (\n\t\t\tthis.options.modifiers?.[table_field_lookup] ||\n\t\t\tthis.virtual_fields.has(table_field_lookup)\n\t\t) {\n\t\t\t// Keep query as is.\n\t\t\treturn (query) => query\n\t\t} else if (this.relations.has(table_field_lookup)) {\n\t\t\t// TODO: pre-create and cache\n\t\t\treturn defineRelationResolver({ tableField })\n\t\t} else {\n\t\t\t// TODO: create simplified resolver?\n\t\t\treturn defineFieldResolver({ tableField })\n\t\t}\n\t}\n}\n","import { OrmAdapter } from \"graphql-orm\"\nimport type { Query, Table } from \"orchid-orm\"\nimport { raw } from \"orchid-orm\"\n\nexport type OrchidOrm = OrmAdapter<\n\tTable,\n\tQuery,\n\t// TODO: Type as QueryTransform once it's published.\n\tPick<Promise<any>, \"then\" | \"catch\">\n>\n\nexport const orm: OrchidOrm = {\n\tTable: undefined as unknown as OrchidOrm[\"Table\"],\n\tQuery: undefined as unknown as OrchidOrm[\"Query\"],\n\tQueryTransform: undefined as unknown as OrchidOrm[\"QueryTransform\"],\n\n\t// Reflection\n\n\tget_table_table(table) {\n\t\treturn table.table!\n\t},\n\n\tget_table_relations(table) {\n\t\treturn Object.keys(table.relations)\n\t},\n\n\tget_table_virtual_fields() {\n\t\t// Not supported by Orchid.\n\t\treturn []\n\t},\n\n\tget_table_modifiers() {\n\t\treturn undefined\n\t},\n\n\tget_query_table(query) {\n\t\tif (!query.table) {\n\t\t\tthrow new Error(\"Query must have table.\")\n\t\t}\n\t\treturn query.table\n\t},\n\n\t// Select\n\n\tselect_field(query, { field, as }) {\n\t\treturn query.select({ [as]: field })\n\t},\n\n\tselect_relation(query, { relation, as, modify }) {\n\t\t// as any casts needed in orchid-orm 1.31+\n\t\treturn query.select({\n\t\t\t[as]: (q: any) => modify(q[relation]),\n\t\t} as any)\n\t},\n\n\t// Find\n\n\twhere(query, field, op, value) {\n\t\treturn query.where({ [field]: op ? { [op]: value } : value })\n\t},\n\n\twhere_raw(query, expression, bindings) {\n\t\treturn query.where(raw({ raw: expression, values: bindings }))\n\t},\n\n\t// Order & Limit\n\n\treset_query_order(query) {\n\t\treturn query.clear(\"order\")\n\t},\n\n\tadd_query_order(query, field, desc) {\n\t\treturn query.order({ [field]: desc ? \"DESC\" : \"ASC\" })\n\t},\n\n\tset_query_limit(query, limit) {\n\t\treturn query.limit(limit)\n\t},\n\n\t// Pagination helpers\n\n\tset_query_page_result(query, get_page) {\n\t\treturn query.transform((nodes) => get_page(nodes as any))\n\t},\n\n\tmodify_subquery_pagination(subquery) {\n\t\treturn subquery\n\t},\n\n\tfinish_query_pagination(query) {\n\t\treturn query\n\t},\n\n\t// Misc\n\n\trun_after_query(query, fn) {\n\t\treturn query.afterQuery((data) => fn(data))\n\t},\n\n\tprevent_select_all(query) {\n\t\t// Not needed in Orchid\n\t\treturn query\n\t},\n}\n","import {\n\tGraphResolveOptions,\n\tGraphResolver,\n\tGraphResolverOptions,\n\tTableResolver,\n} from \"graphql-orm\"\nimport { Query } from \"orchid-orm\"\n\nimport { OrchidOrm, orm } from \"../orm/orm\"\n\nexport function createGraphResolver<Context = unknown>(\n\ttypes: Record<string, TableResolver<OrchidOrm, Context>>,\n\toptions?: GraphResolverOptions<OrchidOrm, Context>,\n) {\n\treturn new OrchidGraphResolver<Context>(types, options)\n}\n\nclass OrchidGraphResolver<Context> extends GraphResolver<OrchidOrm, Context> {\n\tconstructor(\n\t\tpublic readonly types: Record<string, TableResolver<OrchidOrm, Context>>,\n\t\tpublic readonly options: GraphResolverOptions<OrchidOrm, Context> = {},\n\t) {\n\t\tsuper(orm, types, options)\n\t}\n\n\tresolve<T>(\n\t\tquery: Query & {\n\t\t\treturnType: unknown extends T\n\t\t\t\t? any\n\t\t\t\t: T extends unknown[]\n\t\t\t\t\t? undefined | \"all\"\n\t\t\t\t\t: T extends undefined\n\t\t\t\t\t\t? \"one\"\n\t\t\t\t\t\t: \"oneOrThrow\"\n\t\t},\n\t\toptions: GraphResolveOptions<Context>,\n\t): Promise<T> {\n\t\treturn super.resolve(query, options)\n\t}\n}\n","import { TableResolver, TableResolverOptions } from \"graphql-orm\"\nimport { Table } from \"orchid-orm\"\n\nimport { OrchidOrm, orm } from \"../orm/orm\"\n\nexport function defineTableResolver<Context = unknown>(\n\ttable: Table,\n\toptions: TableResolverOptions<OrchidOrm, Context> = {},\n) {\n\treturn new TableResolver(orm, table as any, options)\n}\n"],"mappings":"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","names":["orm","cursor","orm","orm","type","orm"]}
|
|
1
|
+
{"version":3,"sources":["../../base/src/paginators/cursor.ts","../../base/src/utils/run-after.ts","../../base/src/resolvers/field.ts","../../base/src/resolvers/graph.ts","../../base/src/resolvers/page.ts","../../base/src/resolvers/relation.ts","../../base/src/utils/is-plain-object.ts","../../base/src/filters/filters.ts","../../base/src/resolvers/table.ts","../src/orm/orm.ts","../src/resolvers/graph.ts","../src/resolvers/table.ts"],"sourcesContent":["import { Buffer } from \"node:buffer\"\n\nimport { OrmAdapter, SortOrder } from \"../orm/orm\"\nimport { PaginateContext, Paginator } from \"./base\"\n\nexport function defineCursorPaginator(\n\toptions: Partial<CursorPaginatorOptions> = {},\n) {\n\treturn new CursorPaginator(options)\n}\n\nexport interface CursorPaginatorOptions {\n\tfields?: string[]\n\ttake?: number\n}\n\nexport interface CursorPaginatorArgs {\n\tcursor?: string\n\ttake?: number\n}\n\nexport interface CursorPaginatorPage<M> {\n\tnodes: M[]\n\tcursor?: string\n}\n\nclass CursorPaginator<Orm extends OrmAdapter, Context>\n\timplements Paginator<Orm, Context>\n{\n\treadonly path = [\"nodes\"]\n\n\treadonly pageSize: number\n\n\treadonly fields?: Array<{\n\t\tname: string\n\t\tdesc: boolean\n\t}>\n\n\tconstructor(options: CursorPaginatorOptions = {}) {\n\t\tthis.pageSize = options.take ?? 10\n\t\tthis.fields = options.fields?.map((field) => {\n\t\t\tif (field.startsWith(\"-\")) {\n\t\t\t\treturn { name: field.slice(1), desc: true }\n\t\t\t} else {\n\t\t\t\treturn { name: field, desc: false }\n\t\t\t}\n\t\t})\n\t}\n\n\tpaginate(query: Orm[\"Query\"], context: PaginateContext<Orm, Context>) {\n\t\tconst { orm } = context.graph\n\t\tconst { args } = context.tree\n\n\t\tconst pageSize = (args.take as number | undefined) ?? this.pageSize\n\t\tconst cursor = args.cursor as string | undefined\n\n\t\tconst table = orm.get_query_table(query)\n\n\t\tconst orderFields = (\n\t\t\tthis.fields\n\t\t\t\t? this.fields.map<SortOrder>((f) => ({\n\t\t\t\t\t\tfield: f.name,\n\t\t\t\t\t\tdir: f.desc ? \"DESC\" : \"ASC\",\n\t\t\t\t\t}))\n\t\t\t\t: orm.get_query_order(query)\n\t\t).map((o) => ({ ...o, alias: \"_order_\" + o.field }))\n\n\t\tif (this.fields) {\n\t\t\tquery = orm.reset_query_order(query)\n\t\t\tfor (const { alias, dir } of orderFields) {\n\t\t\t\tquery = orm.add_query_order(query, { field: alias, dir })\n\t\t\t}\n\t\t}\n\n\t\tif (!orderFields.length) {\n\t\t\tthrow new Error(\"Query must be ordered.\")\n\t\t}\n\n\t\tfor (const { field, alias } of orderFields) {\n\t\t\tquery = orm.select_field(query, { field, as: alias })\n\t\t}\n\n\t\tif (cursor) {\n\t\t\tconst parsedCursor = parseCursor(cursor)\n\t\t\t// Prepare raw SQL.\n\t\t\t// For example, for (amount asc, id asc) order, that would be:\n\t\t\t// (amount, $id) >= ($amount, id)\n\t\t\tconst left: string[] = []\n\t\t\tconst right: string[] = []\n\t\t\tfor (let i = 0; i < orderFields.length; ++i) {\n\t\t\t\tconst { field, alias, dir } = orderFields[i]\n\t\t\t\tconst [expressions, placeholders] =\n\t\t\t\t\tdir === \"ASC\" ? [left, right] : [right, left]\n\t\t\t\texpressions.push(`\"${table}\".\"${field}\"`)\n\t\t\t\tplaceholders.push(\"$\" + alias)\n\t\t\t}\n\t\t\tconst sqlExpr = `(${left.join(\",\")}) > (${right.join(\",\")})`\n\t\t\tconst bindings = Object.fromEntries(\n\t\t\t\torderFields.map(({ alias }, i) => [alias, parsedCursor[i]]),\n\t\t\t)\n\t\t\tquery = orm.where_raw(query, sqlExpr, bindings)\n\t\t}\n\t\tquery = orm.set_query_limit(query, pageSize + 1)\n\n\t\t// TODO add support for reverse cursor, borrow implementation from orchid-pagination.\n\t\tfunction createNodeCursor(node: any) {\n\t\t\treturn createCursor(\n\t\t\t\torderFields.map(({ field, alias }) => {\n\t\t\t\t\tconst value = node[alias]\n\t\t\t\t\t// TODO add support for custom serializer(s).\n\t\t\t\t\tif (value === undefined) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Unable to create cursor: undefined field ${field} (${alias})`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\treturn String(value)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\treturn orm.set_query_page_result(query, (nodes) => {\n\t\t\tlet cursor: string | undefined\n\t\t\tif (nodes.length > pageSize) {\n\t\t\t\tcursor = createNodeCursor(nodes[pageSize - 1])\n\t\t\t\tnodes = nodes.slice(0, pageSize)\n\t\t\t}\n\t\t\treturn { nodes, cursor }\n\t\t})\n\t}\n}\n\nfunction createCursor(parts: string[]) {\n\treturn Buffer.from(parts.map(String).join(String.fromCharCode(0))).toString(\n\t\t\"base64url\",\n\t)\n}\n\nfunction parseCursor(cursor: string): string[] {\n\treturn Buffer.from(cursor, \"base64url\")\n\t\t.toString()\n\t\t.split(String.fromCharCode(0))\n}\n","import { OrmAdapter } from \"../orm/orm\"\n\nexport function run_after_query<Orm extends OrmAdapter>(\n\torm: Orm,\n\tquery: Orm[\"Query\"],\n\ttransform: (instance: any) => any,\n): Orm[\"Query\"] {\n\treturn orm.run_after_query(query, async (result) => {\n\t\t// FIXME: returning result is ignored in orchid (unlike objection). Add some hacks instead.\n\t\tif (Array.isArray(result)) {\n\t\t\tconst result1 = await Promise.all(result.map(transform))\n\t\t\treturn result1.filter(Boolean) // Skip empty objects\n\t\t} else if (result) {\n\t\t\treturn transform(result)\n\t\t} else {\n\t\t\t// Supposedly, single query returning NULL\n\t\t\treturn result\n\t\t}\n\t})\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { run_after_query } from \"../utils/run-after\"\nimport { TableResolveContext } from \"./table\"\n\nexport interface FieldResolverOptions<Orm extends OrmAdapter, Context> {\n\t/** Table field (if different from GraphQL field) */\n\ttableField?: string\n\t/** Legacy alias for `tableField`. */\n\tmodelField?: string\n\t/** Custom query modifier (if different than simply selecting a field). */\n\tmodify?: FieldResolveModifier<Orm, Context>\n\t/** Post-process selected value. Return a new value or a promise. */\n\ttransform?(\n\t\tvalue: any,\n\t\tinstance: any,\n\t\tcontext: FieldResolveContext<Orm, Context>,\n\t): any\n}\n\nexport type FieldResolveModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tcontext: FieldResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport interface FieldResolveContext<Orm extends OrmAdapter, Context>\n\textends TableResolveContext<Orm, Context> {\n\t/** GraphQL field */\n\tfield: string\n}\n\n// That is a coincidence for now.\nexport type FieldResolver<\n\tOrm extends OrmAdapter,\n\tContext,\n> = FieldResolveModifier<Orm, Context>\n\nexport function parse_field_options<\n\tO extends Pick<FieldResolverOptions<any, any>, \"modelField\" | \"tableField\">,\n>(options: O): Omit<O, \"modelField\"> {\n\tconst { tableField, modelField } = options\n\tif (tableField && modelField) {\n\t\tthrow new Error(\n\t\t\t`Both tableField and modelField are defined. Use only one of them.`,\n\t\t)\n\t}\n\treturn { ...options, tableField: tableField || modelField }\n}\n\nexport function defineFieldResolver<Orm extends OrmAdapter, Context>(\n\toptions: FieldResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, modify, transform } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { field } = context\n\t\tif (modify) {\n\t\t\tquery = modify(query, context)\n\t\t} else {\n\t\t\tquery = context.graph.orm.select_field(query, {\n\t\t\t\tfield: tableField || field,\n\t\t\t\tas: field,\n\t\t\t})\n\t\t}\n\t\tif (transform) {\n\t\t\tquery = run_after_query(context.graph.orm, query, async (instance) => {\n\t\t\t\tinstance[field] = await transform(instance[field], instance, context)\n\t\t\t\treturn instance\n\t\t\t})\n\t\t}\n\t\treturn query\n\t}\n}\n","import type { GraphQLResolveInfo } from \"graphql\"\nimport { parseResolveInfo, ResolveTree } from \"graphql-parse-resolve-info\"\n\nimport { FiltersDef } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport { Paginator } from \"../paginators/base\"\nimport type { TableResolver, TableResolverOptions } from \"./table\"\n\nexport type GraphResolverOptions<Orm extends OrmAdapter, Context> = Pick<\n\tTableResolverOptions<Orm, Context>,\n\t\"allowAllFields\" | \"allowAllFilters\"\n>\n\nexport interface GraphResolveOptions<Context> {\n\tinfo: GraphQLResolveInfo\n\tcontext: Context\n\tfilters?: FiltersDef\n\t/** Subfield path if not resolving root query, e.g.: ['user'] */\n\tpath?: string[]\n}\n\nexport type GraphResolveContext<Context> = Omit<\n\tGraphResolveOptions<Context>,\n\t\"info\"\n> & {\n\ttree: ResolveTree\n}\n\nexport class GraphResolver<Orm extends OrmAdapter, Context> {\n\tconstructor(\n\t\treadonly orm: Orm,\n\t\treadonly type_resolvers: Record<string, TableResolver<Orm, Context>>,\n\t\treadonly options: GraphResolverOptions<Orm, Context> = {},\n\t) {}\n\n\tresolve<T>(\n\t\tquery: Orm[\"Query\"],\n\t\t{ info, ...context }: GraphResolveOptions<Context>,\n\t): Promise<T> {\n\t\tconst tree = this._get_resolve_tree(info)\n\t\treturn this._resolve_type(query, { ...context, tree })\n\t}\n\n\tresolvePage(\n\t\tquery: Orm[\"Query\"],\n\t\tpaginator: Paginator<Orm, Context>,\n\t\t{ info, ...context }: GraphResolveOptions<Context>,\n\t) {\n\t\tconst tree = this._get_resolve_tree(info)\n\t\treturn this._resolve_page(query, paginator, { ...context, tree })\n\t}\n\n\t_get_resolve_tree(info: GraphQLResolveInfo) {\n\t\treturn parseResolveInfo(info) as ResolveTree\n\t}\n\n\t_resolve_type(\n\t\tquery: Orm[\"Query\"],\n\t\tcontext: GraphResolveContext<Context>,\n\t): Orm[\"Query\"] {\n\t\tlet { tree } = context\n\t\t// Dive into subtree if requested.\n\t\tif (context.path) {\n\t\t\tfor (const field of context.path) {\n\t\t\t\tconst type = Object.keys(tree.fieldsByTypeName)[0]\n\t\t\t\ttree = tree.fieldsByTypeName[type][field]\n\t\t\t\tif (!tree) {\n\t\t\t\t\t// This graphql field was never requested, ignore.\n\t\t\t\t\t// This happens when a user resolves a graph for a root subfield which was not requested by the client (and is thus not present in the tree).\n\t\t\t\t\t//\n\t\t\t\t\t// FIXME: this break typings contract. We are supposed to return a query.\n\t\t\t\t\treturn Promise.resolve()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst type = Object.keys(tree.fieldsByTypeName)[0]\n\t\tconst type_resolver = this.type_resolvers[type]\n\t\tif (!type_resolver) {\n\t\t\tthrow new Error(`Resolver not found for type ${type}.`)\n\t\t}\n\t\treturn type_resolver.resolve(query, {\n\t\t\t...context,\n\t\t\tgraph: this,\n\t\t\ttree,\n\t\t\ttype,\n\t\t\tpath: undefined,\n\t\t})\n\t}\n\n\t_resolve_page(\n\t\tquery: Orm[\"Query\"],\n\t\tpaginator: Paginator<Orm, Context>,\n\t\tcontext: GraphResolveContext<Context>,\n\t) {\n\t\tif (context.path) {\n\t\t\t// TODO: handle non-empty context.path\n\t\t\tthrow new Error(\"Paginating under non-root path not yet supported.\")\n\t\t}\n\t\tquery = this._resolve_type(query, { ...context, path: paginator.path })\n\t\treturn paginator.paginate(query, {\n\t\t\t...context,\n\t\t\tgraph: this,\n\t\t})\n\t}\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { Paginator } from \"../paginators/base\"\nimport { FieldResolver, parse_field_options } from \"./field\"\nimport { RelationResolverOptions } from \"./relation\"\n\nexport function definePageResolver<Orm extends OrmAdapter, Context>(\n\tpaginator: Paginator<Orm, Context>,\n\toptions: RelationResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, modify } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { graph, field } = context\n\t\t// Objection.js requires a workaround to handle paginated content,\n\t\t// it must be saved into context and re-injected later.\n\t\t// The modify + finish is a no-op in Orchid.\n\t\tconst pagination_context = {}\n\t\tquery = graph.orm.select_relation(query, {\n\t\t\trelation: tableField || field,\n\t\t\tas: field,\n\t\t\tmodify(subquery) {\n\t\t\t\tsubquery = modify ? modify(subquery, context) : subquery\n\t\t\t\tsubquery = graph._resolve_page(subquery, paginator, context)\n\t\t\t\tsubquery = graph.orm.modify_subquery_pagination(\n\t\t\t\t\tsubquery,\n\t\t\t\t\tpagination_context,\n\t\t\t\t)\n\t\t\t\treturn subquery\n\t\t\t},\n\t\t})\n\t\tquery = graph.orm.finish_query_pagination(query, field, pagination_context)\n\t\treturn query\n\t}\n}\n","import { FiltersDef } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport {\n\tFieldResolver,\n\tFieldResolverOptions,\n\tparse_field_options,\n} from \"./field\"\nimport { TableResolveModifier } from \"./table\"\n\nexport interface RelationResolverOptions<Orm extends OrmAdapter, Context>\n\textends Omit<FieldResolverOptions<Orm, Context>, \"modify\"> {\n\tfilters?: FiltersDef\n\tmodify?: TableResolveModifier<Orm, Context>\n}\n\nexport function defineRelationResolver<Orm extends OrmAdapter, Context>(\n\toptions: RelationResolverOptions<Orm, Context> = {},\n): FieldResolver<Orm, Context> {\n\tconst { tableField, filters, modify } = parse_field_options(options)\n\n\treturn function resolve(query, context) {\n\t\tconst { graph, field } = context\n\t\treturn graph.orm.select_relation(query, {\n\t\t\trelation: tableField || field,\n\t\t\tas: field,\n\t\t\tmodify(subquery) {\n\t\t\t\tsubquery = graph._resolve_type(subquery, { ...context, filters })\n\t\t\t\treturn modify ? modify(subquery, context) : subquery\n\t\t\t},\n\t\t})\n\t}\n}\n","export function is_plain_object(obj: any): obj is Record<string, any> {\n\treturn typeof obj === \"object\" && !Array.isArray(obj)\n}\n","import { OrmAdapter } from \"../orm/orm\"\nimport { TableResolveContext } from \"../resolvers/table\"\nimport { is_plain_object } from \"../utils/is-plain-object\"\n\n// TODO: per-field definitions\nexport type FiltersDef = boolean\n\nexport type FilterScalarValue = null | string | number | boolean\nexport type FilterValue = FilterScalarValue | Exclude<FilterScalarValue, null>[]\nexport type Filter = { [property: string]: FilterValue }\n\ninterface ApplyFiltersOptions<Orm extends OrmAdapter, Context> {\n\tfilters: FiltersDef\n\tmodifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\tcontext: TableResolveContext<Orm, Context>\n}\n\nexport type ApplyFiltersModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tvalue: any,\n\tcontext: TableResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport function apply_filters<Orm extends OrmAdapter, Context>(\n\tquery: Orm[\"Query\"],\n\t{ filters, modifiers, context }: ApplyFiltersOptions<Orm, Context>,\n): Orm[\"Query\"] {\n\tif (!filters) {\n\t\treturn query\n\t}\n\tconst filter_obj = context.tree.args?.filter\n\tif (!filter_obj) {\n\t\treturn query\n\t}\n\tif (!is_plain_object(filter_obj)) {\n\t\tthrow new Error(`Invalid filter: ${filter_obj}, must be object.`)\n\t}\n\tfor (const [field, value] of Object.entries(filter_obj)) {\n\t\tif (value === undefined) {\n\t\t\t// Support optional GraphQL arguments in filter\n\t\t\tcontinue\n\t\t}\n\t\tif (modifiers?.[field]) {\n\t\t\tquery = modifiers[field](query, value, context)\n\t\t} else {\n\t\t\tconst [table_field, op0] = field.split(\"__\")\n\t\t\tconst op = op0?.toLowerCase()\n\t\t\t// TODO: validate op\n\t\t\tquery = context.graph.orm.where(query, table_field, op, value)\n\t\t}\n\t}\n\treturn query\n}\n","import { apply_filters, ApplyFiltersModifier } from \"../filters/filters\"\nimport { OrmAdapter } from \"../orm/orm\"\nimport { run_after_query } from \"../utils/run-after\"\nimport { defineFieldResolver, FieldResolver } from \"./field\"\nimport type { GraphResolveContext, GraphResolver } from \"./graph\"\nimport { defineRelationResolver } from \"./relation\"\n\nexport interface TableResolverOptions<Orm extends OrmAdapter, Context> {\n\t/** allow to resolve all table fields without explicitly listing them */\n\tallowAllFields?: boolean\n\t/** allow to filter all table fields without explicitly listing them */\n\tallowAllFilters?: boolean\n\tfields?: Record<string, SimpleFieldResolver<Orm, Context>>\n\tmodifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\tmodify?: TableResolveModifier<Orm, Context>\n\ttransform?(instance: any, context: any): void | PromiseLike<void>\n}\n\nexport type SimpleFieldResolver<Orm extends OrmAdapter, Context> =\n\t| true\n\t| string\n\t| FieldResolver<Orm, Context>\n\nexport type TableResolveModifier<Orm extends OrmAdapter, Context> = (\n\tquery: Orm[\"Query\"],\n\tcontext: TableResolveContext<Orm, Context>,\n) => Orm[\"Query\"]\n\nexport interface TableResolveContext<Orm extends OrmAdapter, Context>\n\textends GraphResolveContext<Context> {\n\tgraph: GraphResolver<Orm, Context>\n\t/** GraphQL type */\n\ttype: string\n}\n\nexport class TableResolver<Orm extends OrmAdapter, Context> {\n\t// Introspection results\n\treadonly relations: Set<string>\n\treadonly virtual_fields: Set<string>\n\treadonly modifiers?: Record<string, ApplyFiltersModifier<Orm, Context>>\n\n\treadonly table_field_resolvers?: Record<string, FieldResolver<Orm, Context>>\n\n\tconstructor(\n\t\treadonly orm: Orm,\n\t\treadonly table: Orm[\"Table\"],\n\t\treadonly options: TableResolverOptions<Orm, Context> = {},\n\t) {\n\t\tthis.relations = new Set(orm.get_table_relations(table))\n\t\tthis.virtual_fields = new Set(orm.get_table_virtual_fields(table))\n\t\tthis.modifiers = { ...orm.get_table_modifiers(table), ...options.modifiers }\n\n\t\t// Pre-create field resolvers\n\t\tconst { fields } = options\n\t\tif (fields) {\n\t\t\tthis.table_field_resolvers = Object.keys(fields).reduce<\n\t\t\t\tRecord<string, FieldResolver<Orm, Context>>\n\t\t\t>((resolvers, field) => {\n\t\t\t\tconst r0 = fields[field]\n\t\t\t\tconst r: FieldResolver<Orm, Context> | undefined =\n\t\t\t\t\ttypeof r0 === \"function\"\n\t\t\t\t\t\t? r0\n\t\t\t\t\t\t: r0 === true\n\t\t\t\t\t\t\t? this._get_default_field_resolver(field)\n\t\t\t\t\t\t\t: typeof r0 === \"string\"\n\t\t\t\t\t\t\t\t? this._get_default_field_resolver(field, r0)\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\tif (r === undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Field resolver must be a function, string, or true; found ${typeof r0}.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tresolvers[field] = r\n\t\t\t\treturn resolvers\n\t\t\t}, {})\n\t\t}\n\t}\n\n\t/** Modify query to select fields/relations and filter the result set. */\n\tresolve(query: Orm[\"Query\"], context: TableResolveContext<Orm, Context>) {\n\t\tconst { modify, transform } = this.options\n\t\tconst { graph, tree, type, filters } = context\n\n\t\tconst query_table = this.orm.get_query_table(query)\n\t\tconst table_table = this.orm.get_table_table(this.table)\n\n\t\tif (query_table !== table_table) {\n\t\t\tthrow new Error(\n\t\t\t\t`Mismatching query table for type ${type}: expected ${table_table}, received ${query_table}.`,\n\t\t\t)\n\t\t}\n\n\t\tconst allow_all_fields =\n\t\t\tthis.options.allowAllFields ??\n\t\t\tgraph.options.allowAllFields ??\n\t\t\t!this.options.fields\n\n\t\tif (!allow_all_fields && !this.table_field_resolvers) {\n\t\t\tthrow new Error(\n\t\t\t\t`Resolver for type ${type} must either allow all fields or specify options.fields.`,\n\t\t\t)\n\t\t}\n\n\t\tif (modify) {\n\t\t\tquery = modify(query, context)\n\t\t}\n\n\t\tfor (const subtree of Object.values(tree.fieldsByTypeName[type])) {\n\t\t\tconst field = subtree.name\n\t\t\tconst r: FieldResolver<Orm, Context> | undefined =\n\t\t\t\tthis.table_field_resolvers?.[field] ||\n\t\t\t\t(allow_all_fields ? this._get_default_field_resolver(field) : undefined)\n\t\t\tif (!r) {\n\t\t\t\tthrow new Error(`No field resolver defined for field ${type}.${field}.`)\n\t\t\t}\n\t\t\tif (r) {\n\t\t\t\tquery = r(query, { ...context, tree: subtree, field })\n\t\t\t}\n\t\t}\n\n\t\tconst allow_all_filters =\n\t\t\tthis.options.allowAllFilters ?? graph.options.allowAllFilters\n\n\t\tconst effective_filters = allow_all_filters ? true : filters\n\n\t\tif (effective_filters) {\n\t\t\tquery = apply_filters<Orm, Context>(query, {\n\t\t\t\tfilters: effective_filters,\n\t\t\t\tmodifiers: this.modifiers,\n\t\t\t\tcontext,\n\t\t\t})\n\t\t}\n\n\t\tif (transform) {\n\t\t\tquery = run_after_query(this.orm, query, (instance) => {\n\t\t\t\treturn transform(instance, context)\n\t\t\t})\n\t\t}\n\n\t\tquery = this.orm.prevent_select_all(query)\n\n\t\treturn query\n\t}\n\n\t/**\n\t * Create field resolver which will modify query to resolve GraphQL field.\n\t */\n\t_get_default_field_resolver(\n\t\tfield: string,\n\t\ttableField?: string,\n\t): FieldResolver<Orm, Context> {\n\t\tconst table_field_lookup = tableField || field\n\t\tif (\n\t\t\tthis.options.modifiers?.[table_field_lookup] ||\n\t\t\tthis.virtual_fields.has(table_field_lookup)\n\t\t) {\n\t\t\t// Keep query as is.\n\t\t\treturn (query) => query\n\t\t} else if (this.relations.has(table_field_lookup)) {\n\t\t\t// TODO: pre-create and cache\n\t\t\treturn defineRelationResolver({ tableField })\n\t\t} else {\n\t\t\t// TODO: create simplified resolver?\n\t\t\treturn defineFieldResolver({ tableField })\n\t\t}\n\t}\n}\n","import { OrmAdapter, SortOrder } from \"graphql-orm\"\nimport type { Query, SelectQueryData, Table } from \"orchid-orm\"\nimport { raw } from \"orchid-orm\"\n\nexport type OrchidOrm = OrmAdapter<\n\tTable,\n\tQuery,\n\t// TODO: Type as QueryTransform once it's published.\n\tPick<Promise<any>, \"then\" | \"catch\">\n>\n\nexport const orm: OrchidOrm = {\n\tTable: undefined as unknown as OrchidOrm[\"Table\"],\n\tQuery: undefined as unknown as OrchidOrm[\"Query\"],\n\tQueryTransform: undefined as unknown as OrchidOrm[\"QueryTransform\"],\n\n\t// Reflection\n\n\tget_table_table(table) {\n\t\treturn table.table!\n\t},\n\n\tget_table_relations(table) {\n\t\treturn Object.keys(table.relations)\n\t},\n\n\tget_table_virtual_fields() {\n\t\t// Not supported by Orchid.\n\t\treturn []\n\t},\n\n\tget_table_modifiers() {\n\t\treturn undefined\n\t},\n\n\tget_query_table(query) {\n\t\tif (!query.table) {\n\t\t\tthrow new Error(\"Query must have table.\")\n\t\t}\n\t\treturn query.table\n\t},\n\n\t// Select\n\n\tselect_field(query, { field, as }) {\n\t\treturn query.select({ [as]: field })\n\t},\n\n\tselect_relation(query, { relation, as, modify }) {\n\t\t// as any casts needed in orchid-orm 1.31+\n\t\treturn query.select({\n\t\t\t[as]: (q: any) => modify(q[relation]),\n\t\t} as any)\n\t},\n\n\t// Find\n\n\twhere(query, field, op, value) {\n\t\treturn query.where({ [field]: op ? { [op]: value } : value })\n\t},\n\n\twhere_raw(query, expression, bindings) {\n\t\treturn query.where(raw({ raw: expression, values: bindings }))\n\t},\n\n\t// Order & Limit\n\n\treset_query_order(query) {\n\t\treturn query.clear(\"order\")\n\t},\n\n\tadd_query_order(query, { field, dir }) {\n\t\treturn query.order({ [field]: dir })\n\t},\n\n\tget_query_order(query) {\n\t\treturn (\n\t\t\t(query.q as SelectQueryData).order?.flatMap<SortOrder>((orderItem) => {\n\t\t\t\tif (typeof orderItem === \"string\") {\n\t\t\t\t\treturn { field: \"orderItem\", dir: \"ASC\" }\n\t\t\t\t} else if (typeof orderItem === \"object\") {\n\t\t\t\t\treturn Object.entries(orderItem).map<SortOrder>(([field, order]) => {\n\t\t\t\t\t\tconst [dir] = order.split(\" \", 1)\n\t\t\t\t\t\tif (dir === \"ASC\" || dir === \"DESC\") {\n\t\t\t\t\t\t\treturn { field, dir }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new Error(\"Unsupported order: \" + order)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthrow new TypeError(\"Unsupported order type: \" + orderItem)\n\t\t\t\t}\n\t\t\t}) || []\n\t\t)\n\t},\n\n\tset_query_limit(query, limit) {\n\t\treturn query.limit(limit)\n\t},\n\n\t// Pagination helpers\n\n\tset_query_page_result(query, get_page) {\n\t\treturn query.transform((nodes) => get_page(nodes as any))\n\t},\n\n\tmodify_subquery_pagination(subquery) {\n\t\treturn subquery\n\t},\n\n\tfinish_query_pagination(query) {\n\t\treturn query\n\t},\n\n\t// Misc\n\n\trun_after_query(query, fn) {\n\t\treturn query.afterQuery((data) => fn(data))\n\t},\n\n\tprevent_select_all(query) {\n\t\t// Not needed in Orchid\n\t\treturn query\n\t},\n}\n","import {\n\tGraphResolveOptions,\n\tGraphResolver,\n\tGraphResolverOptions,\n\tTableResolver,\n} from \"graphql-orm\"\nimport { Query } from \"orchid-orm\"\n\nimport { OrchidOrm, orm } from \"../orm/orm\"\n\nexport function createGraphResolver<Context = unknown>(\n\ttypes: Record<string, TableResolver<OrchidOrm, Context>>,\n\toptions?: GraphResolverOptions<OrchidOrm, Context>,\n) {\n\treturn new OrchidGraphResolver<Context>(types, options)\n}\n\nclass OrchidGraphResolver<Context> extends GraphResolver<OrchidOrm, Context> {\n\tconstructor(\n\t\tpublic readonly types: Record<string, TableResolver<OrchidOrm, Context>>,\n\t\tpublic readonly options: GraphResolverOptions<OrchidOrm, Context> = {},\n\t) {\n\t\tsuper(orm, types, options)\n\t}\n\n\tresolve<T>(\n\t\tquery: Query & {\n\t\t\treturnType: unknown extends T\n\t\t\t\t? any\n\t\t\t\t: T extends unknown[]\n\t\t\t\t\t? undefined | \"all\"\n\t\t\t\t\t: T extends undefined\n\t\t\t\t\t\t? \"one\"\n\t\t\t\t\t\t: \"oneOrThrow\"\n\t\t},\n\t\toptions: GraphResolveOptions<Context>,\n\t): Promise<T> {\n\t\treturn super.resolve(query, options)\n\t}\n}\n","import { TableResolver, TableResolverOptions } from \"graphql-orm\"\nimport { Table } from \"orchid-orm\"\n\nimport { OrchidOrm, orm } from \"../orm/orm\"\n\nexport function defineTableResolver<Context = unknown>(\n\ttable: Table,\n\toptions: TableResolverOptions<OrchidOrm, Context> = {},\n) {\n\treturn new TableResolver(orm, table as any, options)\n}\n"],"mappings":"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","names":["orm","cursor","orm","orm","type","orm"]}
|
package/package.json
CHANGED
package/src/orm/orm.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { OrmAdapter } from "graphql-orm"
|
|
2
|
-
import type { Query, Table } from "orchid-orm"
|
|
1
|
+
import { OrmAdapter, SortOrder } from "graphql-orm"
|
|
2
|
+
import type { Query, SelectQueryData, Table } from "orchid-orm"
|
|
3
3
|
import { raw } from "orchid-orm"
|
|
4
4
|
|
|
5
5
|
export type OrchidOrm = OrmAdapter<
|
|
@@ -69,8 +69,29 @@ export const orm: OrchidOrm = {
|
|
|
69
69
|
return query.clear("order")
|
|
70
70
|
},
|
|
71
71
|
|
|
72
|
-
add_query_order(query, field,
|
|
73
|
-
return query.order({ [field]:
|
|
72
|
+
add_query_order(query, { field, dir }) {
|
|
73
|
+
return query.order({ [field]: dir })
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
get_query_order(query) {
|
|
77
|
+
return (
|
|
78
|
+
(query.q as SelectQueryData).order?.flatMap<SortOrder>((orderItem) => {
|
|
79
|
+
if (typeof orderItem === "string") {
|
|
80
|
+
return { field: "orderItem", dir: "ASC" }
|
|
81
|
+
} else if (typeof orderItem === "object") {
|
|
82
|
+
return Object.entries(orderItem).map<SortOrder>(([field, order]) => {
|
|
83
|
+
const [dir] = order.split(" ", 1)
|
|
84
|
+
if (dir === "ASC" || dir === "DESC") {
|
|
85
|
+
return { field, dir }
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error("Unsupported order: " + order)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
} else {
|
|
91
|
+
throw new TypeError("Unsupported order type: " + orderItem)
|
|
92
|
+
}
|
|
93
|
+
}) || []
|
|
94
|
+
)
|
|
74
95
|
},
|
|
75
96
|
|
|
76
97
|
set_query_limit(query, limit) {
|