@abedmurrar/objection 4.0.0-beta.3 → 4.0.0-beta.4

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.
@@ -1,15 +1,52 @@
1
- 'use strict';
2
- const parser = require('./parsers/relationExpressionParser');
3
- const { isObject, isNumber, isString, union } = require('../utils/objectUtils');
4
- const { RelationDoesNotExistError } = require('../model/RelationDoesNotExistError');
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DuplicateRelationError = exports.RelationExpressionParseError = exports.RelationExpression = void 0;
37
+ const parser = __importStar(require("./parsers/relationExpressionParser"));
38
+ const objectUtils_1 = require("../utils/objectUtils");
39
+ const RelationDoesNotExistError_1 = require("../model/RelationDoesNotExistError");
5
40
  class RelationExpressionParseError extends Error {
6
41
  }
42
+ exports.RelationExpressionParseError = RelationExpressionParseError;
7
43
  class DuplicateRelationError extends RelationExpressionParseError {
8
44
  constructor(relationName) {
9
45
  super();
10
46
  this.relationName = relationName;
11
47
  }
12
48
  }
49
+ exports.DuplicateRelationError = DuplicateRelationError;
13
50
  class RelationExpression {
14
51
  constructor(node = newNode(), recursionDepth = 0) {
15
52
  this.node = node;
@@ -18,7 +55,7 @@ class RelationExpression {
18
55
  // Create a relation expression from a string, a pojo or another
19
56
  // RelationExpression instance.
20
57
  static create(expr) {
21
- if (isObject(expr)) {
58
+ if ((0, objectUtils_1.isObject)(expr)) {
22
59
  if (expr.isObjectionRelationExpression) {
23
60
  return expr;
24
61
  }
@@ -26,7 +63,7 @@ class RelationExpression {
26
63
  return new RelationExpression(normalizeNode(expr));
27
64
  }
28
65
  }
29
- else if (isString(expr)) {
66
+ else if ((0, objectUtils_1.isString)(expr)) {
30
67
  if (expr.trim().length === 0) {
31
68
  return new RelationExpression();
32
69
  }
@@ -58,7 +95,7 @@ class RelationExpression {
58
95
  }
59
96
  }
60
97
  get maxRecursionDepth() {
61
- if (isNumber(this.node.$recursive)) {
98
+ if ((0, objectUtils_1.isNumber)(this.node.$recursive)) {
62
99
  return this.node.$recursive;
63
100
  }
64
101
  else {
@@ -143,7 +180,7 @@ class RelationExpression {
143
180
  const node = this.node[childName];
144
181
  const relation = modelClass.getRelationUnsafe(node.$relation);
145
182
  if (!relation) {
146
- throw new RelationDoesNotExistError(node.$relation);
183
+ throw new RelationDoesNotExistError_1.RelationDoesNotExistError(node.$relation);
147
184
  }
148
185
  const childExpr = new RelationExpression(node);
149
186
  cb(childExpr, relation);
@@ -156,6 +193,7 @@ class RelationExpression {
156
193
  clone() {
157
194
  return new RelationExpression(cloneNode(this.node), this.recursionDepth);
158
195
  }
196
+ // `null` for an empty expression.
159
197
  toString() {
160
198
  return toString(this.node);
161
199
  }
@@ -166,6 +204,7 @@ class RelationExpression {
166
204
  return this.toPojo();
167
205
  }
168
206
  }
207
+ exports.RelationExpression = RelationExpression;
169
208
  const parseCache = new Map();
170
209
  function parse(str) {
171
210
  const cachedNode = parseCache.get(str);
@@ -194,10 +233,12 @@ function getChildNames(node) {
194
233
  }
195
234
  function toString(node) {
196
235
  const childNames = node.$childNames;
197
- let childExpr = childNames.map((childName) => node[childName]).map(toString);
236
+ let childExpr = childNames
237
+ .map((childName) => node[childName])
238
+ .map(toString);
198
239
  let str = node.$relation;
199
240
  if (node.$recursive) {
200
- if (isNumber(node.$recursive)) {
241
+ if ((0, objectUtils_1.isNumber)(node.$recursive)) {
201
242
  str += '.^' + node.$recursive;
202
243
  }
203
244
  else {
@@ -277,8 +318,10 @@ function normalizeNode(node = null, name = null, allRecusive = false) {
277
318
  $childNames: normalizeChildNames(node),
278
319
  };
279
320
  for (const childName of normalized.$childNames) {
321
+ // `node` isn't null here, since a null node has no child names.
280
322
  const childNode = node[childName];
281
- if (isObject(childNode) || childNode === true) {
323
+ if ((0, objectUtils_1.isObject)(childNode) || childNode === true) {
324
+ // `true` is a node without any properties, like `{}`.
282
325
  normalized[childName] = normalizeNode(childNode, childName);
283
326
  }
284
327
  }
@@ -312,6 +355,7 @@ function findExpressionsAtPath(target, path, results) {
312
355
  }
313
356
  else {
314
357
  for (const childName of path.node.$childNames) {
358
+ // Not null, since `childName` is a child of `path`.
315
359
  const pathChild = path.childExpression(childName);
316
360
  const targetChild = target.childExpression(childName);
317
361
  if (targetChild) {
@@ -325,13 +369,13 @@ function mergeNodes(node1, node2) {
325
369
  const node = {
326
370
  $name: node1.$name,
327
371
  $relation: node1.$relation,
328
- $modify: union(node1.$modify, node2.$modify),
372
+ $modify: (0, objectUtils_1.union)(node1.$modify, node2.$modify),
329
373
  $recursive: mergeRecursion(node1.$recursive, node2.$recursive),
330
374
  $allRecursive: node1.$allRecursive || node2.$allRecursive,
331
375
  $childNames: null,
332
376
  };
333
377
  if (!node.$recursive && !node.$allRecursive) {
334
- node.$childNames = union(node1.$childNames, node2.$childNames);
378
+ node.$childNames = (0, objectUtils_1.union)(node1.$childNames, node2.$childNames);
335
379
  for (const childName of node.$childNames) {
336
380
  const child1 = node1[childName];
337
381
  const child2 = node2[childName];
@@ -346,13 +390,14 @@ function mergeNodes(node1, node2) {
346
390
  else {
347
391
  node.$childNames = [];
348
392
  }
393
+ // `$childNames` was set above.
349
394
  return node;
350
395
  }
351
396
  function mergeRecursion(rec1, rec2) {
352
397
  if (rec1 === true || rec2 === true) {
353
398
  return true;
354
399
  }
355
- else if (isNumber(rec1) && isNumber(rec2)) {
400
+ else if ((0, objectUtils_1.isNumber)(rec1) && (0, objectUtils_1.isNumber)(rec2)) {
356
401
  return Math.max(rec1, rec2);
357
402
  }
358
403
  else {
@@ -366,8 +411,3 @@ Object.defineProperties(RelationExpression.prototype, {
366
411
  value: true,
367
412
  },
368
413
  });
369
- module.exports = {
370
- RelationExpression,
371
- RelationExpressionParseError,
372
- DuplicateRelationError,
373
- };
@@ -1,15 +1,18 @@
1
- 'use strict';
2
- const { asArray, isObject } = require('../utils/objectUtils');
3
- const { buildArg } = require('../utils/buildUtils');
4
- const { isMySql } = require('../utils/knexUtils');
5
- const { toMySqlCastType, isBooleanType, toJsonSql } = require('../utils/mysqlJsonPath');
6
- const { addExpressionMethods } = require('./expressions');
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ValueBuilder = void 0;
4
+ exports.val = val;
5
+ const objectUtils_1 = require("../utils/objectUtils");
6
+ const buildUtils_1 = require("../utils/buildUtils");
7
+ const knexUtils_1 = require("../utils/knexUtils");
8
+ const mysqlJsonPath_1 = require("../utils/mysqlJsonPath");
9
+ const expressions_1 = require("./expressions");
7
10
  class ValueBuilder {
8
11
  constructor(value) {
9
12
  this._value = value;
10
13
  this._cast = null;
11
14
  // Cast objects and arrays to json by default.
12
- this._toJson = isObject(value);
15
+ this._toJson = (0, objectUtils_1.isObject)(value);
13
16
  this._toArray = false;
14
17
  this._alias = null;
15
18
  }
@@ -67,29 +70,30 @@ class ValueBuilder {
67
70
  sql = '?';
68
71
  }
69
72
  else if (this._toArray) {
70
- const values = asArray(this._value);
71
- bindings.push(...values.map((it) => buildArg(it, builder)));
73
+ const values = (0, objectUtils_1.asArray)(this._value);
74
+ bindings.push(...values.map((it) => (0, buildUtils_1.buildArg)(it, builder)));
72
75
  sql = `ARRAY[${values.map(() => '?').join(', ')}]`;
73
76
  }
74
77
  else {
78
+ // A value of the user, which knex binds as it is.
75
79
  bindings.push(this._value);
76
80
  sql = '?';
77
81
  }
78
82
  const knex = builder.unsafeKnex();
79
- const mysql = isMySql(knex);
83
+ const mysql = (0, knexUtils_1.isMySql)(knex);
80
84
  if (this._toJson && !this._cast && mysql) {
81
85
  // MySQL compares strings and JSON values as strings, so `{}` is never
82
86
  // equal to a JSON column without the cast. Postgres casts it implicitly.
83
- sql = toJsonSql(sql, knex);
87
+ sql = (0, mysqlJsonPath_1.toJsonSql)(sql, knex);
84
88
  }
85
89
  else if (this._cast && mysql) {
86
- const type = toMySqlCastType(this._cast);
90
+ const type = (0, mysqlJsonPath_1.toMySqlCastType)(this._cast);
87
91
  // MySQL can't cast to a boolean.
88
- if (isBooleanType(this._cast)) {
92
+ if ((0, mysqlJsonPath_1.isBooleanType)(this._cast)) {
89
93
  sql = `(${sql} <> 0)`;
90
94
  }
91
95
  else if (type === 'JSON') {
92
- sql = toJsonSql(sql, knex);
96
+ sql = (0, mysqlJsonPath_1.toJsonSql)(sql, knex);
93
97
  }
94
98
  else {
95
99
  sql = `CAST(${sql} AS ${type})`;
@@ -105,11 +109,8 @@ class ValueBuilder {
105
109
  return [sql, bindings];
106
110
  }
107
111
  }
108
- addExpressionMethods(ValueBuilder.prototype);
112
+ exports.ValueBuilder = ValueBuilder;
113
+ (0, expressions_1.addExpressionMethods)(ValueBuilder.prototype);
109
114
  function val(val) {
110
115
  return new ValueBuilder(val);
111
116
  }
112
- module.exports = {
113
- ValueBuilder,
114
- val,
115
- };
@@ -1,16 +1,8 @@
1
- 'use strict';
2
- const { isObject } = require('../utils/objectUtils');
3
- // Comparison, logic and arithmetic methods for `ref()`, `val()`, `fn()` and
4
- // `raw()`, so that expressions can be written without raw sql:
5
- //
6
- // Person.ref('age').gte(18).as('isAdult')
7
- // Pet.ref('order').plus(1)
8
- // Person.ref('firstName').isNotBlank().or(Person.ref('lastName').isNotBlank())
9
- //
10
- // Every method returns a new `FunctionBuilder`. The sql is wrapped in parentheses,
11
- // so expressions can be nested without thinking about operator precedence. The
12
- // arguments are bindings like the arguments of `fn()`: strings are values and
13
- // columns are passed with `ref()` or `Model.ref()`.
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addExpressionMethods = addExpressionMethods;
4
+ exports.expression = expression;
5
+ const objectUtils_1 = require("../utils/objectUtils");
14
6
  const COMPARISONS = {
15
7
  eq: '=',
16
8
  ne: '<>',
@@ -98,7 +90,9 @@ function createLogic(first, rest, operator) {
98
90
  return expression(`(${conditions.map(() => '?').join(` ${operator} `)})`, conditions);
99
91
  }
100
92
  function isSubquery(value) {
101
- return (isObject(value) && (value.isObjectionQueryBuilderBase || typeof value.toSQL === 'function'));
93
+ return ((0, objectUtils_1.isObject)(value) &&
94
+ (value.isObjectionQueryBuilderBase ||
95
+ typeof value.toSQL === 'function'));
102
96
  }
103
97
  function expression(sql, args) {
104
98
  // Required here because `FunctionBuilder` itself gets these methods.
@@ -115,7 +109,3 @@ function addExpressionMethods(prototype) {
115
109
  });
116
110
  }
117
111
  }
118
- module.exports = {
119
- addExpressionMethods,
120
- expression,
121
- };
@@ -1,35 +1,8 @@
1
- 'use strict';
2
- const { ref } = require('../ReferenceBuilder');
3
- // The MySQL 8.4 built-in functions, as `fn.*` helpers.
4
- //
5
- // Each entry is `[name, sql, params, result, options]`:
6
- //
7
- // name the name of the helper: `fn.dateFormat()`
8
- // sql the name of the SQL function: `DATE_FORMAT`
9
- // params the parameters, as TypeScript
10
- // result the type of the result, as TypeScript
11
- // options `json`: the arguments that are JSON documents. Objects and arrays
12
- // passed to them are cast to JSON. An array of indexes,
13
- // 'all', or 'even' (0, 2, 4, ...) / 'odd' (1, 3, 5, ...).
14
- // `portable`: the function works the same on postgres, so it
15
- // isn't limited to MySQL.
16
- // `build`: a function that builds the sql for functions with
17
- // keywords in their syntax, like `TIMESTAMPDIFF(DAY, ?, ?)`.
18
- // `aggregate`: the function is an aggregate that `filter()` works
19
- // with. `true` when every argument is aggregated, or a
20
- // function that returns how many of the first arguments are.
21
- // `window`: the function is a window function, which needs `over()`.
22
- //
23
- // The arguments are bindings, so strings are values. Columns are passed with
24
- // `ref()` or `Model.ref()`.
25
- //
26
- // The typings in `typings/objection/index.d.ts` are generated from this list
27
- // with `node scripts/generate-fn-typings.js`.
28
- //
29
- // Not included: spatial functions, operators, `CASE`, `JSON_TABLE()`, internal functions and functions
30
- // that are deprecated (`JSON_MERGE()`, `FOUND_ROWS()`, `VALUES()`,
31
- // `MASTER_POS_WAIT()`) or that need a component (`VALIDATE_PASSWORD_STRENGTH()`).
32
- // `fn('NAME', ...args)` calls any function.
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TIMESTAMP_UNITS = exports.INTERVAL_UNITS = exports.MARIADB_UNSUPPORTED = exports.FUNCTIONS = void 0;
4
+ exports.buildOrderBy = buildOrderBy;
5
+ const ReferenceBuilder_1 = require("../ReferenceBuilder");
33
6
  const STR = 'string | null';
34
7
  const NUM = 'number | null';
35
8
  const DEC = 'FnNumeric | null';
@@ -66,7 +39,9 @@ const INTERVAL_UNITS = [
66
39
  'DAY_HOUR',
67
40
  'YEAR_MONTH',
68
41
  ];
42
+ exports.INTERVAL_UNITS = INTERVAL_UNITS;
69
43
  const TIMESTAMP_UNITS = INTERVAL_UNITS.slice(0, 9);
44
+ exports.TIMESTAMP_UNITS = TIMESTAMP_UNITS;
70
45
  const CAST_TYPE = /^((BINARY|CHAR|NCHAR)(\(\d+\))?( CHARACTER SET \w+)?|DATE|(DATETIME|TIME)(\(\d\))?|DECIMAL(\(\d+(, ?\d+)?\))?|DOUBLE|FLOAT(\(\d+\))?|JSON|REAL|(SIGNED|UNSIGNED)( INTEGER)?|YEAR)$/i;
71
46
  const CHARSET = /^\w+$/;
72
47
  const MATCH_MODES = {
@@ -540,6 +515,7 @@ const FUNCTIONS = [
540
515
  { json: [0, 1], build: buildMemberOf },
541
516
  ],
542
517
  ];
518
+ exports.FUNCTIONS = FUNCTIONS;
543
519
  // Builders for the functions with keywords in their syntax. They return
544
520
  // `[sql, args]`. Keywords are checked against lists, since they can't be bindings.
545
521
  function buildDateAdd(name, sql, [date, amount, unit]) {
@@ -592,6 +568,7 @@ function buildTrim(name, sql, [str, options = {}]) {
592
568
  }
593
569
  }
594
570
  function buildChar(name, sql, [codes, options = {}]) {
571
+ // `codes`, `columns` and `exprs` below are arrays after the first line.
595
572
  codes = Array.isArray(codes) ? codes : [codes];
596
573
  const placeholders = codes.map(() => '?').join(', ');
597
574
  if (options.using === undefined) {
@@ -612,7 +589,10 @@ function buildMatch(name, sql, [columns, search, options = {}]) {
612
589
  }
613
590
  mode = ` ${mode}`;
614
591
  }
615
- return [`MATCH(${columns.map(() => '?').join(', ')}) AGAINST(?${mode})`, [...columns, search]];
592
+ return [
593
+ `MATCH(${columns.map(() => '?').join(', ')}) AGAINST(?${mode})`,
594
+ [...columns, search],
595
+ ];
616
596
  }
617
597
  function buildCountDistinct(name, sql, exprs) {
618
598
  return [`COUNT(DISTINCT ${exprs.map(() => '?').join(', ')})`, exprs];
@@ -653,7 +633,7 @@ function buildOrderBy(name, orderBy) {
653
633
  return [sql, args];
654
634
  }
655
635
  function toColumn(column) {
656
- return typeof column === 'string' ? ref(column) : column;
636
+ return typeof column === 'string' ? (0, ReferenceBuilder_1.ref)(column) : column;
657
637
  }
658
638
  function buildNtile(name, sql, [buckets]) {
659
639
  return [`NTILE(${integer(name, 'buckets', buckets, 1)})`, []];
@@ -751,12 +731,8 @@ const MARIADB_UNSUPPORTED = {
751
731
  regexpInstr: MAX_ARGS(2),
752
732
  regexpSubstr: MAX_ARGS(2),
753
733
  regexpReplace: MAX_ARGS(3),
754
- jsonValue: (args) => args[2] && args[2].returning !== undefined ? "can't use the returning option on MariaDB" : null,
755
- };
756
- module.exports = {
757
- FUNCTIONS,
758
- MARIADB_UNSUPPORTED,
759
- buildOrderBy,
760
- INTERVAL_UNITS,
761
- TIMESTAMP_UNITS,
734
+ jsonValue: (args) => args[2] && args[2].returning !== undefined
735
+ ? "can't use the returning option on MariaDB"
736
+ : null,
762
737
  };
738
+ exports.MARIADB_UNSUPPORTED = MARIADB_UNSUPPORTED;
@@ -1,11 +1,15 @@
1
- 'use strict';
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JoinResultColumn = void 0;
2
4
  class JoinResultColumn {
5
+ // The arguments are the properties of the column.
3
6
  constructor({ columnAlias, tableNode, name }) {
4
7
  this.columnAlias = columnAlias;
5
8
  this.tableNode = tableNode;
6
9
  this.name = name;
7
10
  }
8
11
  static create({ tableTree, columnAlias }) {
12
+ // The column aliases of the joined query are those of the table tree.
9
13
  const tableNode = tableTree.getNodeForColumnAlias(columnAlias);
10
14
  return new JoinResultColumn({
11
15
  columnAlias,
@@ -14,6 +18,4 @@ class JoinResultColumn {
14
18
  });
15
19
  }
16
20
  }
17
- module.exports = {
18
- JoinResultColumn,
19
- };
21
+ exports.JoinResultColumn = JoinResultColumn;
@@ -1,6 +1,8 @@
1
- 'use strict';
2
- const { JoinResultColumn } = require('./JoinResultColumn');
3
- const { groupBy } = require('../../utils/objectUtils');
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JoinResultParser = void 0;
4
+ const JoinResultColumn_1 = require("./JoinResultColumn");
5
+ const objectUtils_1 = require("../../utils/objectUtils");
4
6
  class JoinResultParser {
5
7
  constructor({ tableTree, omitColumnAliases = [] }) {
6
8
  this.tableTree = tableTree;
@@ -54,6 +56,8 @@ class JoinResultParser {
54
56
  }
55
57
  }
56
58
  const model = tableNode.modelClass.fromDatabaseJson(row);
59
+ // The child nodes and the node of a parent model always have a relation
60
+ // and a relation property.
57
61
  for (const childNode of tableNode.childNodes) {
58
62
  if (childNode.relation.isOneToOne()) {
59
63
  model[childNode.relationProperty] = null;
@@ -80,12 +84,13 @@ class JoinResultParser {
80
84
  }
81
85
  _createColumns(row) {
82
86
  const columns = Object.keys(row)
83
- .map((columnAlias) => JoinResultColumn.create({ tableTree: this.tableTree, columnAlias }))
87
+ .map((columnAlias) => JoinResultColumn_1.JoinResultColumn.create({ tableTree: this.tableTree, columnAlias }))
84
88
  // The omitted columns are filtered here once instead of for every model.
85
89
  .filter((column) => !this.omitColumnAliases.has(column.columnAlias));
86
- return groupBy(columns, getTableNode);
90
+ return (0, objectUtils_1.groupBy)(columns, getTableNode);
87
91
  }
88
92
  }
93
+ exports.JoinResultParser = JoinResultParser;
89
94
  function getTableNode(column) {
90
95
  return column.tableNode;
91
96
  }
@@ -101,6 +106,3 @@ function createChildMaps(tableNode) {
101
106
  }
102
107
  return maps;
103
108
  }
104
- module.exports = {
105
- JoinResultParser,
106
- };
@@ -1,13 +1,15 @@
1
- 'use strict';
2
- const { uniqBy } = require('../../utils/objectUtils');
3
- const { Selection } = require('../operations/select/Selection');
4
- const { createModifier } = require('../../utils/createModifier');
5
- const { map: mapPromise } = require('../../utils/promiseUtils');
6
- const { getReadConcurrency } = require('../../model/modelConcurrency');
7
- const { ValidationErrorType } = require('../../model/ValidationError');
8
- const { TableTree } = require('./TableTree');
9
- const { JoinResultParser } = require('./JoinResultParser');
10
- const { ID_LENGTH_LIMIT } = require('./utils');
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RelationJoiner = void 0;
4
+ const objectUtils_1 = require("../../utils/objectUtils");
5
+ const Selection_1 = require("../operations/select/Selection");
6
+ const createModifier_1 = require("../../utils/createModifier");
7
+ const promiseUtils_1 = require("../../utils/promiseUtils");
8
+ const modelConcurrency_1 = require("../../model/modelConcurrency");
9
+ const ValidationError_1 = require("../../model/ValidationError");
10
+ const TableTree_1 = require("./TableTree");
11
+ const JoinResultParser_1 = require("./JoinResultParser");
12
+ const utils_1 = require("./utils");
11
13
  /**
12
14
  * Given a relation expression, builds a query using joins to fetch it.
13
15
  */
@@ -47,8 +49,8 @@ class RelationJoiner {
47
49
  fetchColumnInfo(builder) {
48
50
  const tableTree = this._getTableTree(builder);
49
51
  const allModelClasses = new Set(tableTree.nodes.map((node) => node.modelClass));
50
- return mapPromise(Array.from(allModelClasses), (modelClass) => modelClass.fetchTableMetadata({ parentBuilder: builder }), {
51
- concurrency: getReadConcurrency(this.rootModelClass, builder.unsafeKnex()),
52
+ return (0, promiseUtils_1.map)(Array.from(allModelClasses), (modelClass) => modelClass.fetchTableMetadata({ parentBuilder: builder }), {
53
+ concurrency: (0, modelConcurrency_1.getReadConcurrency)(this.rootModelClass, builder.unsafeKnex()),
52
54
  });
53
55
  }
54
56
  build(builder, buildSelects = true) {
@@ -62,7 +64,7 @@ class RelationJoiner {
62
64
  }
63
65
  }
64
66
  parseResult(builder, flatRows) {
65
- const parser = JoinResultParser.create({
67
+ const parser = JoinResultParser_1.JoinResultParser.create({
66
68
  tableTree: this._getTableTree(builder),
67
69
  omitColumnAliases: this.internalSelections.map((it) => it.alias),
68
70
  });
@@ -71,7 +73,7 @@ class RelationJoiner {
71
73
  _getTableTree(builder) {
72
74
  if (!this.tableTree) {
73
75
  // Create the table tree lazily.
74
- this.tableTree = TableTree.create({
76
+ this.tableTree = TableTree_1.TableTree.create({
75
77
  rootModelClass: this.rootModelClass,
76
78
  rootTableAlias: builder.tableRef(),
77
79
  expression: this.expression,
@@ -80,7 +82,7 @@ class RelationJoiner {
80
82
  }
81
83
  return this.tableTree;
82
84
  }
83
- _buildJoinsForNode({ builder, tableNode, userSelectQueries }) {
85
+ _buildJoinsForNode({ builder, tableNode, userSelectQueries, }) {
84
86
  const subqueryToJoin = createSubqueryToJoin({
85
87
  builder,
86
88
  tableNode,
@@ -107,13 +109,14 @@ class RelationJoiner {
107
109
  this._buildJoinsForNode({ builder, tableNode: childNode, userSelectQueries });
108
110
  }
109
111
  }
110
- _buildSelects({ builder, tableNode, userSelectQueries }) {
112
+ _buildSelects({ builder, tableNode, userSelectQueries, }) {
111
113
  const { selections, internalSelections } = getSelectionsForNode({
112
114
  builder,
113
115
  tableNode,
114
116
  userSelectQueries,
115
117
  });
116
118
  for (const selection of selections) {
119
+ // The selections that are added here all have an alias.
117
120
  checkAliasLength(tableNode.modelClass, selection.name);
118
121
  }
119
122
  // Save the selections that were added internally (not by the user)
@@ -123,6 +126,7 @@ class RelationJoiner {
123
126
  builder.select(selectionsToStrings(selections));
124
127
  }
125
128
  }
129
+ exports.RelationJoiner = RelationJoiner;
126
130
  function defaultOptions() {
127
131
  return {
128
132
  joinOperation: 'leftJoin',
@@ -131,11 +135,11 @@ function defaultOptions() {
131
135
  aliases: {},
132
136
  };
133
137
  }
134
- function createSubqueryToJoin({ builder, tableNode, modifiers }) {
138
+ function createSubqueryToJoin({ builder, tableNode, modifiers, }) {
135
139
  const { relation, expression, modelClass } = tableNode;
136
140
  const modifierQuery = modelClass.query().childQueryOf(builder);
137
141
  for (const modifierName of expression.node.$modify) {
138
- const modifier = createModifier({
142
+ const modifier = (0, createModifier_1.createModifier)({
139
143
  modifier: modifierName,
140
144
  modelClass,
141
145
  modifiers,
@@ -146,7 +150,7 @@ function createSubqueryToJoin({ builder, tableNode, modifiers }) {
146
150
  catch (err) {
147
151
  if (err instanceof modelClass.ModifierNotFoundError) {
148
152
  throw modelClass.createValidationError({
149
- type: ValidationErrorType.RelationExpression,
153
+ type: ValidationError_1.ValidationErrorType.RelationExpression,
150
154
  message: `could not find modifier "${modifierName}" for relation "${relation.name}"`,
151
155
  });
152
156
  }
@@ -157,19 +161,20 @@ function createSubqueryToJoin({ builder, tableNode, modifiers }) {
157
161
  }
158
162
  return modifierQuery;
159
163
  }
160
- function ensureIdAndRelationPropsAreSelected({ builder, tableNode }) {
164
+ function ensureIdAndRelationPropsAreSelected({ builder, tableNode, }) {
161
165
  const tableRef = builder.tableRef();
162
166
  const cols = [
163
167
  ...builder.modelClass().getIdColumnArray(),
164
168
  ...tableNode.relation.relatedProp.cols,
165
169
  ...tableNode.childNodes.reduce((cols, childNode) => [...cols, ...childNode.relation.ownerProp.cols], []),
166
170
  ];
167
- const selectStrings = uniqBy(cols)
171
+ const selectStrings = (0, objectUtils_1.uniqBy)(cols)
168
172
  .filter((col) => !builder.hasSelectionAs(col, col))
169
173
  .map((col) => `${tableRef}.${col}`);
170
174
  return builder.select(selectStrings);
171
175
  }
172
- function getSelectionsForNode({ builder, tableNode, userSelectQueries }) {
176
+ function getSelectionsForNode({ builder, tableNode, userSelectQueries, }) {
177
+ // Every node has a query: `build()` and `_buildJoinsForNode()` add them.
173
178
  const userSelectQuery = userSelectQueries.get(tableNode);
174
179
  const userSelections = userSelectQuery.findAllSelections();
175
180
  const userSelectedAllColumns = isSelectAllSelectionSet(userSelections);
@@ -189,6 +194,7 @@ function getSelectionsForNode({ builder, tableNode, userSelectQueries }) {
189
194
  else {
190
195
  const idSelections = getIdSelectionsForNode({ tableNode });
191
196
  for (const idSelection of idSelections) {
197
+ // The id selections have a column.
192
198
  if (!userSelectQuery.hasSelectionAs(idSelection.column, idSelection.column)) {
193
199
  selections.push(idSelection);
194
200
  internalSelections.push(idSelection);
@@ -205,29 +211,31 @@ function getSelectionsForNode({ builder, tableNode, userSelectQueries }) {
205
211
  internalSelections,
206
212
  };
207
213
  }
208
- function mapUserSelectionsFromSubqueryToMainQuery({ userSelections, tableNode }) {
214
+ function mapUserSelectionsFromSubqueryToMainQuery({ userSelections, tableNode, }) {
209
215
  return userSelections.filter(isNotSelectAll).map((selection) => {
210
- return new Selection(tableNode.alias, selection.name, tableNode.getColumnAliasForColumn(selection.name));
216
+ // A user selection that isn't `*` has a name.
217
+ return new Selection_1.Selection(tableNode.alias, selection.name, tableNode.getColumnAliasForColumn(selection.name));
211
218
  });
212
219
  }
213
- function getJoinTableExtraSelectionsForNode({ builder, tableNode }) {
220
+ function getJoinTableExtraSelectionsForNode({ builder, tableNode, }) {
214
221
  return tableNode.relation.joinTableExtras.map((extra) => {
215
- return new Selection(tableNode.getJoinTableAlias(builder), extra.joinTableCol, tableNode.getColumnAliasForColumn(extra.aliasCol));
222
+ // A many to many relation, which has a join table.
223
+ return new Selection_1.Selection(tableNode.getJoinTableAlias(builder), extra.joinTableCol, tableNode.getColumnAliasForColumn(extra.aliasCol));
216
224
  });
217
225
  }
218
- function getAllColumnSelectionsForNode({ builder, tableNode }) {
226
+ function getAllColumnSelectionsForNode({ builder, tableNode, }) {
219
227
  const table = builder.tableNameFor(tableNode.modelClass);
220
228
  const tableMeta = tableNode.modelClass.tableMetadata({ table });
221
229
  if (!tableMeta) {
222
230
  throw new Error(`table metadata has not been fetched for table '${table}'. Are you trying to call toKnexQuery() for a withGraphJoined query? To make sure the table metadata is fetched see the objection.initialize function.`);
223
231
  }
224
232
  return tableMeta.columns.map((columnName) => {
225
- return new Selection(tableNode.alias, columnName, tableNode.getColumnAliasForColumn(columnName));
233
+ return new Selection_1.Selection(tableNode.alias, columnName, tableNode.getColumnAliasForColumn(columnName));
226
234
  });
227
235
  }
228
236
  function getIdSelectionsForNode({ tableNode }) {
229
237
  return tableNode.modelClass.getIdColumnArray().map((columnName) => {
230
- return new Selection(tableNode.alias, columnName, tableNode.getColumnAliasForColumn(columnName));
238
+ return new Selection_1.Selection(tableNode.alias, columnName, tableNode.getColumnAliasForColumn(columnName));
231
239
  });
232
240
  }
233
241
  function selectionsToStrings(selections) {
@@ -246,13 +254,10 @@ function isSelectAllSelectionSet(selections) {
246
254
  return selections.length === 0 || selections.some(isSelectAll);
247
255
  }
248
256
  function checkAliasLength(modelClass, alias) {
249
- if (alias.length > ID_LENGTH_LIMIT) {
257
+ if (alias.length > utils_1.ID_LENGTH_LIMIT) {
250
258
  throw modelClass.createValidationError({
251
- type: ValidationErrorType.RelationExpression,
252
- message: `identifier ${alias} is over ${ID_LENGTH_LIMIT} characters long and would be truncated by the database engine.`,
259
+ type: ValidationError_1.ValidationErrorType.RelationExpression,
260
+ message: `identifier ${alias} is over ${utils_1.ID_LENGTH_LIMIT} characters long and would be truncated by the database engine.`,
253
261
  });
254
262
  }
255
263
  }
256
- module.exports = {
257
- RelationJoiner,
258
- };