orchid-graphql 1.8.1 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,7 +45,7 @@ const BaseTable = createBaseTable()
45
45
 
46
46
  class PostTable extends BaseTable {
47
47
  readonly table = "post"
48
- columns = this.setColumns((t) => ({
48
+ columns = this.setColumns(t => ({
49
49
  id: t.identity().primaryKey(),
50
50
  text: t.text(0, 5000),
51
51
  }))
@@ -285,8 +285,8 @@ const graph = r.graph(
285
285
  // (related table must be also registered in this graph resolver)
286
286
  author: true,
287
287
  // Modify query when this field is resolved
288
- preview: (q) =>
289
- q.select({ preview: q.sql<string>`substr(text,1,100)` }),
288
+ preview: q =>
289
+ q.select({ preview: q.sql <string>`substr(text,1,100)` }),
290
290
  // Same as text: true
291
291
  text: r.field(),
292
292
  // Custom field resolver
@@ -296,8 +296,8 @@ const graph = r.graph(
296
296
  }),
297
297
  preview2: r.field({
298
298
  // Modify query
299
- modify: (q) =>
300
- q.select({ preview2: q.sql<string>`substr(text,1,100)` }),
299
+ modify: q =>
300
+ q.select({ preview2: q.sql <string>`substr(text,1,100)` }),
301
301
  // Post-process selected value
302
302
  transform(
303
303
  // Selected value
package/dist/index.cjs CHANGED
@@ -18,8 +18,8 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
23
  createGraphResolver: () => createGraphResolver,
24
24
  cursor: () => defineCursorPaginator,
25
25
  defineCursorPaginator: () => defineCursorPaginator,
@@ -28,12 +28,42 @@ __export(src_exports, {
28
28
  defineRelationResolver: () => defineRelationResolver,
29
29
  defineTableResolver: () => defineTableResolver,
30
30
  field: () => defineFieldResolver,
31
+ filterQuery: () => filterQuery2,
31
32
  graph: () => createGraphResolver,
32
33
  page: () => definePageResolver,
33
34
  relation: () => defineRelationResolver,
34
35
  table: () => defineTableResolver
35
36
  });
36
- module.exports = __toCommonJS(src_exports);
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // ../base/src/utils/is-plain-object.ts
40
+ function isPlainObject(obj) {
41
+ return typeof obj === "object" && !Array.isArray(obj);
42
+ }
43
+
44
+ // ../base/src/filter/filter.ts
45
+ function filterQuery(orm2, query, filter, options) {
46
+ const { context, modifiers } = options ?? {};
47
+ if (!filter) {
48
+ return query;
49
+ }
50
+ if (!isPlainObject(filter)) {
51
+ throw new Error(`Invalid filter: ${filter}, must be plain object.`);
52
+ }
53
+ for (const [field, value] of Object.entries(filter)) {
54
+ if (value === void 0) {
55
+ continue;
56
+ }
57
+ if (modifiers?.[field]) {
58
+ query = modifiers[field](query, value, context);
59
+ } else {
60
+ const [tableField, op0] = field.split("__");
61
+ const op = op0?.toLowerCase();
62
+ query = orm2.where(query, tableField, op, value);
63
+ }
64
+ }
65
+ return query;
66
+ }
37
67
 
38
68
  // ../base/src/paginators/cursor.ts
39
69
  var import_node_buffer = require("buffer");
@@ -59,22 +89,22 @@ var CursorPaginator = class {
59
89
  const { args } = context.tree;
60
90
  const pageSize = args.take ?? this.pageSize;
61
91
  const cursor = args.cursor;
62
- const table = orm2.get_query_table(query);
92
+ const table = orm2.getQueryTable(query);
63
93
  const orderFields = (this.fields ? this.fields.map((f) => ({
64
94
  field: f.name,
65
95
  dir: f.desc ? "DESC" : "ASC"
66
- })) : orm2.get_query_order(query)).map((o) => ({ ...o, alias: "_order_" + o.field }));
96
+ })) : orm2.getQueryOrder(query)).map((o) => ({ ...o, alias: "_order_" + o.field }));
67
97
  if (this.fields) {
68
- query = orm2.reset_query_order(query);
98
+ query = orm2.resetQueryOrder(query);
69
99
  for (const { alias, dir } of orderFields) {
70
- query = orm2.add_query_order(query, { field: alias, dir });
100
+ query = orm2.addQueryOrder(query, { field: alias, dir });
71
101
  }
72
102
  }
73
103
  if (!orderFields.length) {
74
104
  throw new Error("Query must be ordered.");
75
105
  }
76
106
  for (const { field, alias } of orderFields) {
77
- query = orm2.select_field(query, { field, as: alias });
107
+ query = orm2.selectField(query, { field, as: alias });
78
108
  }
79
109
  if (cursor) {
80
110
  const parsedCursor = parseCursor(cursor);
@@ -90,9 +120,9 @@ var CursorPaginator = class {
90
120
  const bindings = Object.fromEntries(
91
121
  orderFields.map(({ alias }, i) => [alias, parsedCursor[i]])
92
122
  );
93
- query = orm2.where_raw(query, sqlExpr, bindings);
123
+ query = orm2.whereRaw(query, sqlExpr, bindings);
94
124
  }
95
- query = orm2.set_query_limit(query, pageSize + 1);
125
+ query = orm2.setQueryLimit(query, pageSize + 1);
96
126
  function createNodeCursor(node) {
97
127
  return createCursor(
98
128
  orderFields.map(({ field, alias }) => {
@@ -106,7 +136,7 @@ var CursorPaginator = class {
106
136
  })
107
137
  );
108
138
  }
109
- return orm2.set_query_page_result(query, (nodes) => {
139
+ return orm2.setQueryPageResult(query, (nodes) => {
110
140
  let cursor2;
111
141
  if (nodes.length > pageSize) {
112
142
  cursor2 = createNodeCursor(nodes[pageSize - 1]);
@@ -126,8 +156,8 @@ function parseCursor(cursor) {
126
156
  }
127
157
 
128
158
  // ../base/src/utils/run-after.ts
129
- function run_after_query(orm2, query, transform) {
130
- return orm2.run_after_query(query, async (result) => {
159
+ function runAfterQuery(orm2, query, transform) {
160
+ return orm2.runAfterQuery(query, async (result) => {
131
161
  if (Array.isArray(result)) {
132
162
  const result1 = await Promise.all(result.map(transform));
133
163
  return result1.filter(Boolean);
@@ -140,7 +170,7 @@ function run_after_query(orm2, query, transform) {
140
170
  }
141
171
 
142
172
  // ../base/src/resolvers/field.ts
143
- function parse_field_options(options) {
173
+ function parseFieldOptions(options) {
144
174
  const { tableField, modelField } = options;
145
175
  if (tableField && modelField) {
146
176
  throw new Error(
@@ -150,19 +180,19 @@ function parse_field_options(options) {
150
180
  return { ...options, tableField: tableField || modelField };
151
181
  }
152
182
  function defineFieldResolver(options = {}) {
153
- const { tableField, modify, transform } = parse_field_options(options);
183
+ const { tableField, modify, transform } = parseFieldOptions(options);
154
184
  return function resolve(query, context) {
155
185
  const { field } = context;
156
186
  if (modify) {
157
187
  query = modify(query, context);
158
188
  } else {
159
- query = context.graph.orm.select_field(query, {
189
+ query = context.graph.orm.selectField(query, {
160
190
  field: tableField || field,
161
191
  as: field
162
192
  });
163
193
  }
164
194
  if (transform) {
165
- query = run_after_query(context.graph.orm, query, async (instance) => {
195
+ query = runAfterQuery(context.graph.orm, query, async (instance) => {
166
196
  instance[field] = await transform(instance[field], instance, context);
167
197
  return instance;
168
198
  });
@@ -174,23 +204,23 @@ function defineFieldResolver(options = {}) {
174
204
  // ../base/src/resolvers/graph.ts
175
205
  var import_graphql_parse_resolve_info = require("graphql-parse-resolve-info");
176
206
  var GraphResolver = class {
177
- constructor(orm2, type_resolvers, options = {}) {
207
+ constructor(orm2, typeResolvers, options = {}) {
178
208
  this.orm = orm2;
179
- this.type_resolvers = type_resolvers;
209
+ this.typeResolvers = typeResolvers;
180
210
  this.options = options;
181
211
  }
182
212
  resolve(query, { info, ...context }) {
183
- const tree = this._get_resolve_tree(info);
184
- return this._resolve_type(query, { ...context, tree });
213
+ const tree = this._getResolveTree(info);
214
+ return this._resolveType(query, { ...context, tree });
185
215
  }
186
216
  resolvePage(query, paginator, { info, ...context }) {
187
- const tree = this._get_resolve_tree(info);
188
- return this._resolve_page(query, paginator, { ...context, tree });
217
+ const tree = this._getResolveTree(info);
218
+ return this._resolvePage(query, paginator, { ...context, tree });
189
219
  }
190
- _get_resolve_tree(info) {
220
+ _getResolveTree(info) {
191
221
  return (0, import_graphql_parse_resolve_info.parseResolveInfo)(info);
192
222
  }
193
- _resolve_type(query, context) {
223
+ _resolveType(query, context) {
194
224
  let { tree } = context;
195
225
  if (context.path) {
196
226
  for (const field of context.path) {
@@ -202,11 +232,11 @@ var GraphResolver = class {
202
232
  }
203
233
  }
204
234
  const type = Object.keys(tree.fieldsByTypeName)[0];
205
- const type_resolver = this.type_resolvers[type];
206
- if (!type_resolver) {
235
+ const typeResolver = this.typeResolvers[type];
236
+ if (!typeResolver) {
207
237
  throw new Error(`Resolver not found for type ${type}.`);
208
238
  }
209
- return type_resolver.resolve(query, {
239
+ return typeResolver.resolve(query, {
210
240
  ...context,
211
241
  graph: this,
212
242
  tree,
@@ -214,11 +244,11 @@ var GraphResolver = class {
214
244
  path: void 0
215
245
  });
216
246
  }
217
- _resolve_page(query, paginator, context) {
247
+ _resolvePage(query, paginator, context) {
218
248
  if (context.path) {
219
249
  throw new Error("Paginating under non-root path not yet supported.");
220
250
  }
221
- query = this._resolve_type(query, { ...context, path: paginator.path });
251
+ query = this._resolveType(query, { ...context, path: paginator.path });
222
252
  return paginator.paginate(query, {
223
253
  ...context,
224
254
  graph: this
@@ -228,90 +258,58 @@ var GraphResolver = class {
228
258
 
229
259
  // ../base/src/resolvers/page.ts
230
260
  function definePageResolver(paginator, options = {}) {
231
- const { tableField, modify } = parse_field_options(options);
261
+ const { tableField, modify } = parseFieldOptions(options);
232
262
  return function resolve(query, context) {
233
263
  const { graph, field } = context;
234
- const pagination_context = {};
235
- query = graph.orm.select_relation(query, {
264
+ const paginationContext = {};
265
+ query = graph.orm.selectRelation(query, {
236
266
  relation: tableField || field,
237
267
  as: field,
238
268
  modify(subquery) {
239
269
  subquery = modify ? modify(subquery, context) : subquery;
240
- subquery = graph._resolve_page(subquery, paginator, context);
241
- subquery = graph.orm.modify_subquery_pagination(
270
+ subquery = graph._resolvePage(subquery, paginator, context);
271
+ subquery = graph.orm.modifySubqueryPagination(
242
272
  subquery,
243
- pagination_context
273
+ paginationContext
244
274
  );
245
275
  return subquery;
246
276
  }
247
277
  });
248
- query = graph.orm.finish_query_pagination(query, field, pagination_context);
278
+ query = graph.orm.finishQueryPagination(query, field, paginationContext);
249
279
  return query;
250
280
  };
251
281
  }
252
282
 
253
283
  // ../base/src/resolvers/relation.ts
254
284
  function defineRelationResolver(options = {}) {
255
- const { tableField, filters, modify } = parse_field_options(options);
285
+ const { tableField, filters, modify } = parseFieldOptions(options);
256
286
  return function resolve(query, context) {
257
287
  const { graph, field } = context;
258
- return graph.orm.select_relation(query, {
288
+ return graph.orm.selectRelation(query, {
259
289
  relation: tableField || field,
260
290
  as: field,
261
291
  modify(subquery) {
262
- subquery = graph._resolve_type(subquery, { ...context, filters });
292
+ subquery = graph._resolveType(subquery, { ...context, filters });
263
293
  return modify ? modify(subquery, context) : subquery;
264
294
  }
265
295
  });
266
296
  };
267
297
  }
268
298
 
269
- // ../base/src/utils/is-plain-object.ts
270
- function is_plain_object(obj) {
271
- return typeof obj === "object" && !Array.isArray(obj);
272
- }
273
-
274
- // ../base/src/filters/filters.ts
275
- function apply_filters(query, { filters, modifiers, context }) {
276
- if (!filters) {
277
- return query;
278
- }
279
- const filter_obj = context.tree.args?.filter;
280
- if (!filter_obj) {
281
- return query;
282
- }
283
- if (!is_plain_object(filter_obj)) {
284
- throw new Error(`Invalid filter: ${filter_obj}, must be object.`);
285
- }
286
- for (const [field, value] of Object.entries(filter_obj)) {
287
- if (value === void 0) {
288
- continue;
289
- }
290
- if (modifiers?.[field]) {
291
- query = modifiers[field](query, value, context);
292
- } else {
293
- const [table_field, op0] = field.split("__");
294
- const op = op0?.toLowerCase();
295
- query = context.graph.orm.where(query, table_field, op, value);
296
- }
297
- }
298
- return query;
299
- }
300
-
301
299
  // ../base/src/resolvers/table.ts
302
300
  var TableResolver = class {
303
301
  constructor(orm2, table, options = {}) {
304
302
  this.orm = orm2;
305
303
  this.table = table;
306
304
  this.options = options;
307
- this.relations = new Set(orm2.get_table_relations(table));
308
- this.virtual_fields = new Set(orm2.get_table_virtual_fields(table));
309
- this.modifiers = { ...orm2.get_table_modifiers(table), ...options.modifiers };
305
+ this.relations = new Set(orm2.getTableRelations(table));
306
+ this.virtualFields = new Set(orm2.getTableVirtualFields(table));
307
+ this.modifiers = { ...orm2.getTableModifiers(table), ...options.modifiers };
310
308
  const { fields } = options;
311
309
  if (fields) {
312
- this.table_field_resolvers = Object.keys(fields).reduce((resolvers, field) => {
310
+ this.tableFieldResolvers = Object.keys(fields).reduce((resolvers, field) => {
313
311
  const r0 = fields[field];
314
- const r = typeof r0 === "function" ? r0 : r0 === true ? this._get_default_field_resolver(field) : typeof r0 === "string" ? this._get_default_field_resolver(field, r0) : void 0;
312
+ const r = typeof r0 === "function" ? r0 : r0 === true ? this._getDefaultFieldResolver(field) : typeof r0 === "string" ? this._getDefaultFieldResolver(field, r0) : void 0;
315
313
  if (r === void 0) {
316
314
  throw new Error(
317
315
  `Field resolver must be a function, string, or true; found ${typeof r0}.`
@@ -324,22 +322,22 @@ var TableResolver = class {
324
322
  }
325
323
  // Introspection results
326
324
  relations;
327
- virtual_fields;
325
+ virtualFields;
328
326
  modifiers;
329
- table_field_resolvers;
327
+ tableFieldResolvers;
330
328
  /** Modify query to select fields/relations and filter the result set. */
331
329
  resolve(query, context) {
332
330
  const { modify, transform } = this.options;
333
331
  const { graph, tree, type, filters } = context;
334
- const query_table = this.orm.get_query_table(query);
335
- const table_table = this.orm.get_table_table(this.table);
336
- if (query_table !== table_table) {
332
+ const queryTable = this.orm.getQueryTable(query);
333
+ const tableName = this.orm.getTableName(this.table);
334
+ if (queryTable !== tableName) {
337
335
  throw new Error(
338
- `Mismatching query table for type ${type}: expected ${table_table}, received ${query_table}.`
336
+ `Mismatching query table for type ${type}: expected ${tableName}, received ${queryTable}.`
339
337
  );
340
338
  }
341
- const allow_all_fields = this.options.allowAllFields ?? graph.options.allowAllFields ?? !this.options.fields;
342
- if (!allow_all_fields && !this.table_field_resolvers) {
339
+ const allowAllFields = this.options.allowAllFields ?? graph.options.allowAllFields ?? !this.options.fields;
340
+ if (!allowAllFields && !this.tableFieldResolvers) {
343
341
  throw new Error(
344
342
  `Resolver for type ${type} must either allow all fields or specify options.fields.`
345
343
  );
@@ -349,7 +347,7 @@ var TableResolver = class {
349
347
  }
350
348
  for (const subtree of Object.values(tree.fieldsByTypeName[type])) {
351
349
  const field = subtree.name;
352
- const r = this.table_field_resolvers?.[field] || (allow_all_fields ? this._get_default_field_resolver(field) : void 0);
350
+ const r = this.tableFieldResolvers?.[field] || (allowAllFields ? this._getDefaultFieldResolver(field) : void 0);
353
351
  if (!r) {
354
352
  throw new Error(`No field resolver defined for field ${type}.${field}.`);
355
353
  }
@@ -357,31 +355,33 @@ var TableResolver = class {
357
355
  query = r(query, { ...context, tree: subtree, field });
358
356
  }
359
357
  }
360
- const allow_all_filters = this.options.allowAllFilters ?? graph.options.allowAllFilters;
361
- const effective_filters = allow_all_filters ? true : filters;
362
- if (effective_filters) {
363
- query = apply_filters(query, {
364
- filters: effective_filters,
365
- modifiers: this.modifiers,
366
- context
367
- });
358
+ const filter = context.tree.args?.filter;
359
+ if (filter) {
360
+ const allowAllFilters = this.options.allowAllFilters ?? graph.options.allowAllFilters;
361
+ const filterConfig = allowAllFilters ? true : filters;
362
+ if (filterConfig) {
363
+ query = filterQuery(context.graph.orm, query, filter, {
364
+ modifiers: this.modifiers,
365
+ context
366
+ });
367
+ }
368
368
  }
369
369
  if (transform) {
370
- query = run_after_query(this.orm, query, (instance) => {
370
+ query = runAfterQuery(this.orm, query, (instance) => {
371
371
  return transform(instance, context);
372
372
  });
373
373
  }
374
- query = this.orm.prevent_select_all(query);
374
+ query = this.orm.preventSelectAll(query);
375
375
  return query;
376
376
  }
377
377
  /**
378
378
  * Create field resolver which will modify query to resolve GraphQL field.
379
379
  */
380
- _get_default_field_resolver(field, tableField) {
381
- const table_field_lookup = tableField || field;
382
- if (this.options.modifiers?.[table_field_lookup] || this.virtual_fields.has(table_field_lookup)) {
380
+ _getDefaultFieldResolver(field, tableField) {
381
+ const tableFieldLookup = tableField || field;
382
+ if (this.options.modifiers?.[tableFieldLookup] || this.virtualFields.has(tableFieldLookup)) {
383
383
  return (query) => query;
384
- } else if (this.relations.has(table_field_lookup)) {
384
+ } else if (this.relations.has(tableFieldLookup)) {
385
385
  return defineRelationResolver({ tableField });
386
386
  } else {
387
387
  return defineFieldResolver({ tableField });
@@ -396,29 +396,29 @@ var orm = {
396
396
  Query: void 0,
397
397
  QueryTransform: void 0,
398
398
  // Reflection
399
- get_table_table(table) {
399
+ getTableName(table) {
400
400
  return table.table;
401
401
  },
402
- get_table_relations(table) {
402
+ getTableRelations(table) {
403
403
  return Object.keys(table.relations);
404
404
  },
405
- get_table_virtual_fields() {
405
+ getTableVirtualFields() {
406
406
  return [];
407
407
  },
408
- get_table_modifiers() {
408
+ getTableModifiers() {
409
409
  return void 0;
410
410
  },
411
- get_query_table(query) {
411
+ getQueryTable(query) {
412
412
  if (!query.table) {
413
413
  throw new Error("Query must have table.");
414
414
  }
415
415
  return query.table;
416
416
  },
417
417
  // Select
418
- select_field(query, { field, as }) {
418
+ selectField(query, { field, as }) {
419
419
  return query.select({ [as]: field });
420
420
  },
421
- select_relation(query, { relation, as, modify }) {
421
+ selectRelation(query, { relation, as, modify }) {
422
422
  return query.select({
423
423
  [as]: (q) => modify(q[relation])
424
424
  });
@@ -427,17 +427,17 @@ var orm = {
427
427
  where(query, field, op, value) {
428
428
  return query.where({ [field]: op ? { [op]: value } : value });
429
429
  },
430
- where_raw(query, expression, bindings) {
430
+ whereRaw(query, expression, bindings) {
431
431
  return query.where((0, import_orchid_orm.raw)({ raw: expression, values: bindings }));
432
432
  },
433
433
  // Order & Limit
434
- reset_query_order(query) {
434
+ resetQueryOrder(query) {
435
435
  return query.clear("order");
436
436
  },
437
- add_query_order(query, { field, dir }) {
437
+ addQueryOrder(query, { field, dir }) {
438
438
  return query.order({ [field]: dir });
439
439
  },
440
- get_query_order(query) {
440
+ getQueryOrder(query) {
441
441
  return query.q.order?.flatMap((orderItem) => {
442
442
  if (typeof orderItem === "string") {
443
443
  return { field: "orderItem", dir: "ASC" };
@@ -455,28 +455,33 @@ var orm = {
455
455
  }
456
456
  }) || [];
457
457
  },
458
- set_query_limit(query, limit) {
458
+ setQueryLimit(query, limit) {
459
459
  return query.limit(limit);
460
460
  },
461
461
  // Pagination helpers
462
- set_query_page_result(query, get_page) {
462
+ setQueryPageResult(query, get_page) {
463
463
  return query.transform((nodes) => get_page(nodes));
464
464
  },
465
- modify_subquery_pagination(subquery) {
465
+ modifySubqueryPagination(subquery) {
466
466
  return subquery;
467
467
  },
468
- finish_query_pagination(query) {
468
+ finishQueryPagination(query) {
469
469
  return query;
470
470
  },
471
471
  // Misc
472
- run_after_query(query, fn) {
472
+ runAfterQuery(query, fn) {
473
473
  return query.afterQuery((data) => fn(data));
474
474
  },
475
- prevent_select_all(query) {
475
+ preventSelectAll(query) {
476
476
  return query;
477
477
  }
478
478
  };
479
479
 
480
+ // src/filter.ts
481
+ function filterQuery2(query, filter, options) {
482
+ return filterQuery(orm, query, filter, options);
483
+ }
484
+
480
485
  // src/resolvers/graph.ts
481
486
  function createGraphResolver(types, options) {
482
487
  return new OrchidGraphResolver(types, options);
@@ -506,6 +511,7 @@ function defineTableResolver(table, options = {}) {
506
511
  defineRelationResolver,
507
512
  defineTableResolver,
508
513
  field,
514
+ filterQuery,
509
515
  graph,
510
516
  page,
511
517
  relation,