@snowtop/ent 0.1.0-alpha95 → 0.1.0-alpha96

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.
Files changed (63) hide show
  1. package/action/action.d.ts +3 -3
  2. package/action/executor.js +6 -1
  3. package/action/experimental_action.d.ts +5 -2
  4. package/action/experimental_action.js +15 -12
  5. package/action/index.d.ts +2 -0
  6. package/action/index.js +7 -1
  7. package/action/orchestrator.d.ts +4 -2
  8. package/action/orchestrator.js +6 -0
  9. package/action/relative_value.d.ts +47 -0
  10. package/action/relative_value.js +125 -0
  11. package/action/transaction.d.ts +10 -0
  12. package/action/transaction.js +23 -0
  13. package/auth/auth.d.ts +1 -1
  14. package/core/base.d.ts +4 -2
  15. package/core/clause.d.ts +6 -1
  16. package/core/clause.js +25 -4
  17. package/core/config.d.ts +2 -1
  18. package/core/config.js +2 -0
  19. package/core/date.js +1 -5
  20. package/core/db.d.ts +9 -6
  21. package/core/db.js +14 -6
  22. package/core/ent.d.ts +3 -1
  23. package/core/ent.js +76 -26
  24. package/core/logger.d.ts +1 -1
  25. package/core/query/assoc_query.d.ts +2 -2
  26. package/core/query/shared_assoc_test.js +1 -2
  27. package/core/query/shared_test.js +0 -1
  28. package/graphql/graphql.d.ts +6 -6
  29. package/graphql/graphql.js +1 -0
  30. package/graphql/query/connection_type.d.ts +1 -1
  31. package/graphql/query/shared_assoc_test.js +1 -1
  32. package/graphql/query/shared_edge_connection.js +0 -4
  33. package/imports/index.d.ts +6 -1
  34. package/imports/index.js +14 -3
  35. package/index.d.ts +1 -0
  36. package/package.json +16 -16
  37. package/parse_schema/parse.d.ts +7 -7
  38. package/schema/base_schema.d.ts +3 -3
  39. package/schema/field.js +2 -2
  40. package/schema/schema.d.ts +11 -10
  41. package/schema/schema.js +3 -13
  42. package/scripts/custom_graphql.js +30 -4
  43. package/testutils/action/complex_schemas.d.ts +69 -0
  44. package/testutils/action/complex_schemas.js +398 -0
  45. package/testutils/builder.d.ts +21 -36
  46. package/testutils/builder.js +39 -45
  47. package/testutils/db/temp_db.d.ts +6 -3
  48. package/testutils/db/temp_db.js +79 -7
  49. package/testutils/db/value.d.ts +1 -0
  50. package/testutils/db/value.js +2 -2
  51. package/testutils/db_mock.d.ts +16 -4
  52. package/testutils/db_mock.js +48 -5
  53. package/testutils/ent-graphql-tests/index.d.ts +7 -1
  54. package/testutils/ent-graphql-tests/index.js +17 -5
  55. package/testutils/fake_data/fake_contact.d.ts +1 -0
  56. package/testutils/fake_data/fake_contact.js +6 -5
  57. package/testutils/fake_data/fake_event.d.ts +1 -0
  58. package/testutils/fake_data/fake_event.js +4 -3
  59. package/testutils/fake_data/fake_tag.d.ts +2 -1
  60. package/testutils/fake_data/fake_tag.js +6 -5
  61. package/testutils/fake_data/fake_user.d.ts +2 -1
  62. package/testutils/fake_data/fake_user.js +14 -13
  63. package/tsc/ast.d.ts +1 -1
@@ -4,8 +4,8 @@ import { Queryer } from "../core/db";
4
4
  import { TransformedUpdateOperation, UpdateOperation } from "../schema";
5
5
  import { FieldInfoMap } from "../schema/schema";
6
6
  export { WriteOperation };
7
- declare type MaybeNull<T extends Ent> = T | null;
8
- declare type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
7
+ type MaybeNull<T extends Ent> = T | null;
8
+ type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
9
9
  interface BuilderOrchestrator {
10
10
  __getOptions(): {
11
11
  fieldInfo: FieldInfoMap;
@@ -38,7 +38,7 @@ export interface Changeset {
38
38
  changesets?: Changeset[];
39
39
  dependencies?: Map<ID, Builder<Ent>>;
40
40
  }
41
- export declare type TriggerReturn = void | Promise<Changeset | void | (Changeset | void)[]> | Promise<Changeset>[];
41
+ export type TriggerReturn = void | Promise<Changeset | void | (Changeset | void)[]> | Promise<Changeset>[];
42
42
  export interface Trigger<TEnt extends Ent<TViewer>, TBuilder extends Builder<TEnt, TViewer, TExistingEnt>, TViewer extends Viewer = Viewer, TInput extends Data = Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
43
43
  changeset(builder: TBuilder, input: TInput): TriggerReturn;
44
44
  }
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.executeOperations = exports.ComplexExecutor = exports.ListBasedExecutor = void 0;
7
7
  const graph_data_structure_1 = __importDefault(require("graph-data-structure"));
8
+ const ent_1 = require("../core/ent");
8
9
  const db_1 = __importDefault(require("../core/db"));
9
10
  const logger_1 = require("../core/logger");
10
11
  // private to ent
@@ -98,7 +99,7 @@ class ComplexExecutor {
98
99
  changesetMap.set(c.placeholderID.toString(), c);
99
100
  graph.addNode(c.placeholderID.toString());
100
101
  if (c.dependencies) {
101
- for (let [key, builder] of c.dependencies) {
102
+ for (let [_, builder] of c.dependencies) {
102
103
  // dependency should go first...
103
104
  graph.addEdge(builder.placeholderID.toString(), c.placeholderID.toString(), 1);
104
105
  }
@@ -258,6 +259,7 @@ async function executeOperations(executor, context, trackOps) {
258
259
  });
259
260
  }
260
261
  else {
262
+ (0, ent_1.logQuery)("BEGIN", []);
261
263
  await client.query("BEGIN");
262
264
  for (const operation of executor) {
263
265
  if (trackOps) {
@@ -269,6 +271,7 @@ async function executeOperations(executor, context, trackOps) {
269
271
  }
270
272
  await operation.performWrite(client, context);
271
273
  }
274
+ (0, ent_1.logQuery)("COMMIT", []);
272
275
  await client.query("COMMIT");
273
276
  }
274
277
  if (executor.postFetch) {
@@ -280,6 +283,8 @@ async function executeOperations(executor, context, trackOps) {
280
283
  }
281
284
  catch (e) {
282
285
  if (!isSyncClient(client)) {
286
+ // TODO these changes break tests
287
+ (0, ent_1.logQuery)("ROLLBACK", []);
283
288
  await client.query("ROLLBACK");
284
289
  }
285
290
  (0, logger_1.log)("error", e);
@@ -6,8 +6,8 @@ export interface ActionOptions<TEnt extends Ent<TViewer>, TViewer extends Viewer
6
6
  input?: TData;
7
7
  operation?: WriteOperation;
8
8
  }
9
- declare type MaybeNull<T extends Ent> = T | null;
10
- declare type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
9
+ type MaybeNull<T extends Ent> = T | null;
10
+ type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
11
11
  export interface EntBuilder<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> extends Builder<TEnt, TViewer, TExistingEnt> {
12
12
  valid(): Promise<boolean>;
13
13
  validX(): Promise<void>;
@@ -29,6 +29,9 @@ export declare class BaseAction<TEnt extends Ent<TViewer>, TViewer extends Viewe
29
29
  getValidators(): Validator<TEnt, EntBuilder<TEnt, TViewer, TInput, TExistingEnt>, TViewer, TInput, TExistingEnt>[];
30
30
  constructor(viewer: TViewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TExistingEnt>, options: ActionOptions<TEnt, TViewer, TInput, TExistingEnt>);
31
31
  static createBuilder<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TExistingEnt>, options: ActionOptions<TEnt, TViewer, TInput, TExistingEnt>): Builder<TEnt>;
32
+ /**
33
+ * @deprecated use Transaction
34
+ */
32
35
  static bulkAction<TEnt extends Ent<TViewer>, TViewer extends Viewer, TInput extends Data>(ent: TEnt, builderCtr: BuilderConstructor<TEnt, TViewer, TInput, TEnt>, ...actions: Action<Ent, Builder<Ent, any>>[]): BaseAction<TEnt, TViewer, TInput, TEnt>;
33
36
  changeset(): Promise<Changeset>;
34
37
  valid(): Promise<boolean>;
@@ -4,6 +4,18 @@ exports.getSimpleInsertAction = exports.getSimpleDeleteAction = exports.getSimpl
4
4
  const privacy_1 = require("../core/privacy");
5
5
  const action_1 = require("./action");
6
6
  class BaseAction {
7
+ getPrivacyPolicy() {
8
+ return privacy_1.AlwaysAllowPrivacyPolicy;
9
+ }
10
+ getTriggers() {
11
+ return [];
12
+ }
13
+ getObservers() {
14
+ return [];
15
+ }
16
+ getValidators() {
17
+ return [];
18
+ }
7
19
  constructor(viewer, builderCtr, options) {
8
20
  this.viewer = viewer;
9
21
  this.builderCtr = builderCtr;
@@ -19,24 +31,15 @@ class BaseAction {
19
31
  this.input = options?.input || {};
20
32
  this.builder = new builderCtr(viewer, operation, this, options.existingEnt);
21
33
  }
22
- getPrivacyPolicy() {
23
- return privacy_1.AlwaysAllowPrivacyPolicy;
24
- }
25
- getTriggers() {
26
- return [];
27
- }
28
- getObservers() {
29
- return [];
30
- }
31
- getValidators() {
32
- return [];
33
- }
34
34
  static createBuilder(viewer, builderCtr, options) {
35
35
  let action = new BaseAction(viewer, builderCtr, options);
36
36
  return action.builder;
37
37
  }
38
38
  // perform a bulk action in a transaction rooted on ent T
39
39
  // it ends up creating triggers and having all the given actions performed in a transaction
40
+ /**
41
+ * @deprecated use Transaction
42
+ */
40
43
  static bulkAction(ent, builderCtr, ...actions) {
41
44
  let action = new BaseAction(ent.viewer, builderCtr, {
42
45
  existingEnt: ent,
package/action/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { WriteOperation, Builder, Changeset, Trigger, Observer, Validator, Action, saveBuilder, saveBuilderX, setEdgeTypeInGroup, TriggerReturn, } from "./action";
2
2
  export { OrchestratorOptions, Orchestrator, EntChangeset, EdgeInputData, } from "./orchestrator";
3
3
  export { DenyIfBuilder, AllowIfBuilder } from "./privacy";
4
+ export { RelativeFieldValue, RelativeNumberValue, NumberOps, convertRelativeInput, maybeConvertRelativeInputPlusExpressions, } from "./relative_value";
5
+ export { Transaction } from "./transaction";
package/action/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AllowIfBuilder = exports.DenyIfBuilder = exports.EntChangeset = exports.Orchestrator = exports.setEdgeTypeInGroup = exports.saveBuilderX = exports.saveBuilder = exports.WriteOperation = void 0;
3
+ exports.Transaction = exports.maybeConvertRelativeInputPlusExpressions = exports.convertRelativeInput = exports.NumberOps = exports.AllowIfBuilder = exports.DenyIfBuilder = exports.EntChangeset = exports.Orchestrator = exports.setEdgeTypeInGroup = exports.saveBuilderX = exports.saveBuilder = exports.WriteOperation = void 0;
4
4
  var action_1 = require("./action");
5
5
  Object.defineProperty(exports, "WriteOperation", { enumerable: true, get: function () { return action_1.WriteOperation; } });
6
6
  Object.defineProperty(exports, "saveBuilder", { enumerable: true, get: function () { return action_1.saveBuilder; } });
@@ -12,3 +12,9 @@ Object.defineProperty(exports, "EntChangeset", { enumerable: true, get: function
12
12
  var privacy_1 = require("./privacy");
13
13
  Object.defineProperty(exports, "DenyIfBuilder", { enumerable: true, get: function () { return privacy_1.DenyIfBuilder; } });
14
14
  Object.defineProperty(exports, "AllowIfBuilder", { enumerable: true, get: function () { return privacy_1.AllowIfBuilder; } });
15
+ var relative_value_1 = require("./relative_value");
16
+ Object.defineProperty(exports, "NumberOps", { enumerable: true, get: function () { return relative_value_1.NumberOps; } });
17
+ Object.defineProperty(exports, "convertRelativeInput", { enumerable: true, get: function () { return relative_value_1.convertRelativeInput; } });
18
+ Object.defineProperty(exports, "maybeConvertRelativeInputPlusExpressions", { enumerable: true, get: function () { return relative_value_1.maybeConvertRelativeInputPlusExpressions; } });
19
+ var transaction_1 = require("./transaction");
20
+ Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.Transaction; } });
@@ -3,8 +3,9 @@ import { AssocEdgeInputOptions, DataOperation } from "../core/ent";
3
3
  import { SchemaInputType, FieldInfoMap } from "../schema/schema";
4
4
  import { Changeset, Executor } from "../action/action";
5
5
  import { WriteOperation, Builder, Action } from "../action";
6
- declare type MaybeNull<T extends Ent> = T | null;
7
- declare type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
6
+ import * as clause from "../core/clause";
7
+ type MaybeNull<T extends Ent> = T | null;
8
+ type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
8
9
  export interface OrchestratorOptions<TEnt extends Ent<TViewer>, TInput extends Data, TViewer extends Viewer, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
9
10
  viewer: Viewer;
10
11
  operation: WriteOperation;
@@ -16,6 +17,7 @@ export interface OrchestratorOptions<TEnt extends Ent<TViewer>, TInput extends D
16
17
  schema: SchemaInputType;
17
18
  editedFields(): Map<string, any> | Promise<Map<string, any>>;
18
19
  updateInput?: (data: TInput) => void;
20
+ expressions?: Map<string, clause.Clause>;
19
21
  fieldInfo: FieldInfoMap;
20
22
  }
21
23
  interface edgeInputDataOpts {
@@ -180,6 +180,10 @@ class Orchestrator {
180
180
  if (this.actualOperation === action_1.WriteOperation.Edit && !this.existingEnt) {
181
181
  throw new Error(`existing ent required with operation ${this.actualOperation}`);
182
182
  }
183
+ if (this.options.expressions &&
184
+ this.actualOperation !== action_1.WriteOperation.Edit) {
185
+ throw new Error(`expressions are only supported in edit operations for now`);
186
+ }
183
187
  const opts = {
184
188
  fields: this.validatedFields,
185
189
  tableName: this.options.tableName,
@@ -188,6 +192,7 @@ class Orchestrator {
188
192
  loadEntOptions: this.options.loaderOptions,
189
193
  placeholderID: this.options.builder.placeholderID,
190
194
  whereClause: clause.Eq(this.options.key, this.existingEnt?.id),
195
+ expressions: this.options.expressions,
191
196
  };
192
197
  if (this.logValues) {
193
198
  opts.fieldsToLog = this.logValues;
@@ -713,6 +718,7 @@ class Orchestrator {
713
718
  await this.validX();
714
719
  let ops = [this.buildMainOp()];
715
720
  await this.buildEdgeOps(ops);
721
+ // TODO throw if we try and create a new changeset after previously creating one
716
722
  return new EntChangeset(this.options.viewer, this.options.builder.placeholderID, this.options.loaderOptions.ent, ops, this.dependencies, this.changesets, this.options);
717
723
  }
718
724
  async viewerForEntLoad(data) {
@@ -0,0 +1,47 @@
1
+ import { Clause } from "../core/clause";
2
+ export interface RelativeFieldValue<T = BigInt | number> {
3
+ delta: T;
4
+ sqlExpression: (col: string) => Clause;
5
+ eval: (curr: T) => T;
6
+ }
7
+ export interface RelativeNumberValue<T> {
8
+ add?: T;
9
+ subtract?: T;
10
+ divide?: T;
11
+ multiply?: T;
12
+ modulo?: T;
13
+ }
14
+ declare function addNumber(delta: number): RelativeFieldValue<number>;
15
+ declare function addNumber(delta: BigInt): RelativeFieldValue<BigInt>;
16
+ declare function subtractNumber(delta: number): RelativeFieldValue<number>;
17
+ declare function subtractNumber(delta: BigInt): RelativeFieldValue<BigInt>;
18
+ declare function multiplyNumber(delta: number): RelativeFieldValue<number>;
19
+ declare function multiplyNumber(delta: BigInt): RelativeFieldValue<BigInt>;
20
+ declare function divideNumber(delta: number): RelativeFieldValue<number>;
21
+ declare function divideNumber(delta: BigInt): RelativeFieldValue<BigInt>;
22
+ declare function moduloNumber(delta: number): RelativeFieldValue<number>;
23
+ declare function moduloNumber(delta: BigInt): RelativeFieldValue<BigInt>;
24
+ export declare const NumberOps: {
25
+ addNumber: typeof addNumber;
26
+ moduloNumber: typeof moduloNumber;
27
+ divideNumber: typeof divideNumber;
28
+ subtractNumber: typeof subtractNumber;
29
+ multiplyNumber: typeof multiplyNumber;
30
+ };
31
+ export declare function convertRelativeInput(rel: RelativeNumberValue<BigInt>, col: string, existing: BigInt): {
32
+ value: BigInt;
33
+ clause: Clause;
34
+ };
35
+ export declare function convertRelativeInput(rel: RelativeNumberValue<number>, col: string, existing: number): {
36
+ value: number;
37
+ clause: Clause;
38
+ };
39
+ export declare function maybeConvertRelativeInputPlusExpressions(rel: number | RelativeNumberValue<number>, col: string, existing: number, expressions: Map<string, Clause>): number;
40
+ export declare function maybeConvertRelativeInputPlusExpressions(rel: number | RelativeNumberValue<number> | undefined, col: string, existing: number, expressions: Map<string, Clause>): number | undefined;
41
+ export declare function maybeConvertRelativeInputPlusExpressions(rel: number | RelativeNumberValue<number> | null, col: string, existing: number | null, expressions: Map<string, Clause>): number | null;
42
+ export declare function maybeConvertRelativeInputPlusExpressions(rel: number | RelativeNumberValue<number> | null | undefined, col: string, existing: number | null, expressions: Map<string, Clause>): number | undefined | null;
43
+ export declare function maybeConvertRelativeInputPlusExpressions(rel: BigInt | RelativeNumberValue<BigInt>, col: string, existing: BigInt, expressions: Map<string, Clause>): BigInt;
44
+ export declare function maybeConvertRelativeInputPlusExpressions(rel: BigInt | RelativeNumberValue<BigInt> | undefined, col: string, existing: BigInt, expressions: Map<string, Clause>): BigInt | undefined;
45
+ export declare function maybeConvertRelativeInputPlusExpressions(rel: BigInt | RelativeNumberValue<BigInt> | null, col: string, existing: BigInt | null, expressions: Map<string, Clause>): BigInt | null;
46
+ export declare function maybeConvertRelativeInputPlusExpressions(rel: BigInt | RelativeNumberValue<BigInt> | null | undefined, col: string, existing: BigInt | null, expressions: Map<string, Clause>): BigInt | null | undefined;
47
+ export {};
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.maybeConvertRelativeInputPlusExpressions = exports.convertRelativeInput = exports.NumberOps = void 0;
4
+ const clause_1 = require("../core/clause");
5
+ function addNumber(delta) {
6
+ return {
7
+ delta,
8
+ sqlExpression(col) {
9
+ return (0, clause_1.Add)(col, delta);
10
+ },
11
+ eval(curr) {
12
+ // @ts-expect-error
13
+ return curr + delta;
14
+ },
15
+ };
16
+ }
17
+ function subtractNumber(delta) {
18
+ return {
19
+ delta,
20
+ sqlExpression(col) {
21
+ return (0, clause_1.Subtract)(col, delta);
22
+ },
23
+ eval(curr) {
24
+ // @ts-expect-error
25
+ return curr - delta;
26
+ },
27
+ };
28
+ }
29
+ function multiplyNumber(delta) {
30
+ return {
31
+ delta,
32
+ sqlExpression(col) {
33
+ return (0, clause_1.Multiply)(col, delta);
34
+ },
35
+ eval(curr) {
36
+ // @ts-expect-error
37
+ return curr * delta;
38
+ },
39
+ };
40
+ }
41
+ function divideNumber(delta) {
42
+ return {
43
+ delta,
44
+ sqlExpression(col) {
45
+ return (0, clause_1.Divide)(col, delta);
46
+ },
47
+ eval(curr) {
48
+ // @ts-expect-error
49
+ return curr / delta;
50
+ },
51
+ };
52
+ }
53
+ function moduloNumber(delta) {
54
+ return {
55
+ delta,
56
+ sqlExpression(col) {
57
+ return (0, clause_1.Modulo)(col, delta);
58
+ },
59
+ eval(curr) {
60
+ // @ts-expect-error
61
+ return curr % delta;
62
+ },
63
+ };
64
+ }
65
+ exports.NumberOps = {
66
+ addNumber,
67
+ moduloNumber,
68
+ divideNumber,
69
+ subtractNumber,
70
+ multiplyNumber,
71
+ };
72
+ function convertRelativeInput(rel, col, existing) {
73
+ if (Object.keys(rel).length !== 1) {
74
+ throw new Error(`only 1 key is expected. ${Object.keys(rel).length} given`);
75
+ }
76
+ const ret = (relField) => {
77
+ return {
78
+ value: relField.eval(existing),
79
+ clause: relField.sqlExpression(col),
80
+ };
81
+ };
82
+ if (rel.add !== undefined) {
83
+ // @ts-expect-error
84
+ return ret(addNumber(rel.add));
85
+ }
86
+ if (rel.subtract !== undefined) {
87
+ // @ts-expect-error
88
+ return ret(subtractNumber(rel.subtract));
89
+ }
90
+ if (rel.multiply !== undefined) {
91
+ // @ts-expect-error
92
+ return ret(multiplyNumber(rel.multiply));
93
+ }
94
+ if (rel.divide !== undefined) {
95
+ // @ts-expect-error
96
+ return ret(divideNumber(rel.divide));
97
+ }
98
+ if (rel.modulo !== undefined) {
99
+ // @ts-expect-error
100
+ return ret(moduloNumber(rel.modulo));
101
+ }
102
+ throw new Error(`error in convertRelativeInput. shouldn't have gotten here`);
103
+ }
104
+ exports.convertRelativeInput = convertRelativeInput;
105
+ function maybeConvertRelativeInputPlusExpressions(rel, col, existing, expressions) {
106
+ if (rel === null) {
107
+ return rel;
108
+ }
109
+ if (rel === undefined) {
110
+ return rel;
111
+ }
112
+ if (typeof rel === "bigint" || typeof rel === "number") {
113
+ return rel;
114
+ }
115
+ // // TODO is this the behavior we want? should we coalesce as 0?
116
+ // if (existing === null) {
117
+ // throw new Error(`cannot perform a relative operation on null`);
118
+ // }
119
+ // @ts-ignore
120
+ // shouldn't be failing like it currently is. it thinks rel can be bigint and it shouldn't be???
121
+ const { clause, value } = convertRelativeInput(rel, col, existing);
122
+ expressions.set(col, clause);
123
+ return value;
124
+ }
125
+ exports.maybeConvertRelativeInputPlusExpressions = maybeConvertRelativeInputPlusExpressions;
@@ -0,0 +1,10 @@
1
+ import { Ent, Viewer } from "../core/base";
2
+ import { Action, Builder } from "./action";
3
+ type ActionAny = Action<Ent<Viewer<any, any>>, Builder<Ent<Viewer<any, any>>, Viewer<any, any>, any>, Viewer<any, any>, any, any>;
4
+ export declare class Transaction {
5
+ private viewer;
6
+ private actions;
7
+ constructor(viewer: Viewer, actions: ActionAny[]);
8
+ run(): Promise<void>;
9
+ }
10
+ export {};
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Transaction = void 0;
4
+ const executor_1 = require("./executor");
5
+ class Transaction {
6
+ constructor(viewer,
7
+ // independent operations
8
+ actions) {
9
+ this.viewer = viewer;
10
+ this.actions = actions;
11
+ }
12
+ async run() {
13
+ const changesets = [];
14
+ await Promise.all(this.actions.map(async (action) => {
15
+ const c = await action.changeset();
16
+ changesets.push(c);
17
+ }));
18
+ const executor = new executor_1.ComplexExecutor(this.viewer, "", // no placeholder, no opers
19
+ [], new Map(), changesets);
20
+ await executor.execute();
21
+ }
22
+ }
23
+ exports.Transaction = Transaction;
package/auth/auth.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import { Viewer } from "../core/base";
3
3
  import { RequestContext } from "../core/context";
4
4
  import { IncomingMessage, ServerResponse } from "http";
5
- export declare type AuthViewer = Viewer | null;
5
+ export type AuthViewer = Viewer | null;
6
6
  export interface AuthHandler {
7
7
  authViewer(ctx: RequestContext): AuthViewer | Promise<AuthViewer>;
8
8
  }
package/core/base.d.ts CHANGED
@@ -18,7 +18,7 @@ interface LoaderFactoryWithLoaderMany<T, V> extends LoaderFactory<T, V> {
18
18
  export interface ConfigurableLoaderFactory<T, V> extends LoaderFactory<T, V> {
19
19
  createConfigurableLoader(options: EdgeQueryableDataOptions, context?: Context): Loader<T, V>;
20
20
  }
21
- export declare type EdgeQueryableDataOptions = Partial<Pick<QueryableDataOptions, "limit" | "orderby" | "clause">>;
21
+ export type EdgeQueryableDataOptions = Partial<Pick<QueryableDataOptions, "limit" | "orderby" | "clause">>;
22
22
  export interface PrimableLoader<T, V> extends Loader<T, V> {
23
23
  prime(d: Data): void;
24
24
  primeAll?(d: Data): void;
@@ -53,6 +53,7 @@ export interface Ent<TViewer extends Viewer = Viewer> {
53
53
  viewer: TViewer;
54
54
  getPrivacyPolicy(): PrivacyPolicy<this, TViewer>;
55
55
  nodeType: string;
56
+ __setRawDBData<T extends Data = Data>(data: T): any;
56
57
  }
57
58
  export declare type Data = {
58
59
  [key: string]: any;
@@ -60,7 +61,7 @@ export declare type Data = {
60
61
  export interface EntConstructor<TEnt extends Ent, TViewer extends Viewer = Viewer> {
61
62
  new (viewer: TViewer, data: Data): TEnt;
62
63
  }
63
- export declare type ID = string | number;
64
+ export type ID = string | number;
64
65
  export interface DataOptions {
65
66
  tableName: string;
66
67
  context?: Context;
@@ -92,6 +93,7 @@ export interface CreateRowOptions extends DataOptions {
92
93
  }
93
94
  export interface EditRowOptions extends CreateRowOptions {
94
95
  whereClause: clause.Clause;
96
+ expressions?: Map<string, clause.Clause>;
95
97
  }
96
98
  interface LoadableEntOptions<TEnt extends Ent, TViewer extends Viewer = Viewer> {
97
99
  loaderFactory: LoaderFactoryWithOptions;
package/core/clause.d.ts CHANGED
@@ -117,7 +117,7 @@ export declare function TsVectorWebsearchToTsQuery(col: string, val: string | Ts
117
117
  export declare function sensitiveValue(val: any): SensitiveValue;
118
118
  export declare function JSONObjectFieldKeyASJSON(col: string, field: string): string;
119
119
  export declare function JSONObjectFieldKeyAsText(col: string, field: string): string;
120
- declare type predicate = "==" | ">" | "<" | "!=" | ">=" | "<=";
120
+ type predicate = "==" | ">" | "<" | "!=" | ">=" | "<=";
121
121
  export declare function JSONPathValuePredicate(dbCol: string, path: string, val: any, pred: predicate): Clause;
122
122
  declare class paginationMultipleColumnsSubQueryClause implements Clause {
123
123
  private col;
@@ -134,4 +134,9 @@ declare class paginationMultipleColumnsSubQueryClause implements Clause {
134
134
  instanceKey(): string;
135
135
  }
136
136
  export declare function PaginationMultipleColsSubQuery(col: string, op: string, tableName: string, uniqueCol: string, val: any): paginationMultipleColumnsSubQueryClause;
137
+ export declare function Add(col: string, value: any): Clause;
138
+ export declare function Subtract(col: string, value: any): Clause;
139
+ export declare function Multiply(col: string, value: any): Clause;
140
+ export declare function Divide(col: string, value: any): Clause;
141
+ export declare function Modulo(col: string, value: any): Clause;
137
142
  export {};
package/core/clause.js CHANGED
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.PaginationMultipleColsSubQuery = exports.JSONPathValuePredicate = exports.JSONObjectFieldKeyAsText = exports.JSONObjectFieldKeyASJSON = exports.sensitiveValue = exports.TsVectorWebsearchToTsQuery = exports.TsVectorPhraseToTsQuery = exports.TsVectorPlainToTsQuery = exports.TsVectorColTsQuery = exports.WebsearchToTsQuery = exports.PhraseToTsQuery = exports.PlainToTsQuery = exports.TsQuery = exports.In = exports.OrOptional = exports.Or = exports.AndOptional = exports.And = exports.LessEq = exports.GreaterEq = exports.Less = exports.Greater = exports.NotEq = exports.Eq = exports.ArrayNotEq = exports.ArrayEq = exports.PostgresArrayNotOverlaps = exports.PostgresArrayOverlaps = exports.PostgresArrayNotContains = exports.PostgresArrayNotContainsValue = exports.PostgresArrayContains = exports.PostgresArrayContainsValue = exports.inClause = void 0;
26
+ exports.Modulo = exports.Divide = exports.Multiply = exports.Subtract = exports.Add = exports.PaginationMultipleColsSubQuery = exports.JSONPathValuePredicate = exports.JSONObjectFieldKeyAsText = exports.JSONObjectFieldKeyASJSON = exports.sensitiveValue = exports.TsVectorWebsearchToTsQuery = exports.TsVectorPhraseToTsQuery = exports.TsVectorPlainToTsQuery = exports.TsVectorColTsQuery = exports.WebsearchToTsQuery = exports.PhraseToTsQuery = exports.PlainToTsQuery = exports.TsQuery = exports.In = exports.OrOptional = exports.Or = exports.AndOptional = exports.And = exports.LessEq = exports.GreaterEq = exports.Less = exports.Greater = exports.NotEq = exports.Eq = exports.ArrayNotEq = exports.ArrayEq = exports.PostgresArrayNotOverlaps = exports.PostgresArrayOverlaps = exports.PostgresArrayNotContains = exports.PostgresArrayNotContainsValue = exports.PostgresArrayContains = exports.PostgresArrayContainsValue = exports.inClause = void 0;
27
27
  const db_1 = __importStar(require("./db"));
28
28
  function isSensitive(val) {
29
29
  return (val !== null &&
@@ -229,14 +229,14 @@ class postgresArrayOperatorList extends postgresArrayOperator {
229
229
  }
230
230
  }
231
231
  class inClause {
232
+ static getPostgresInClauseValuesThreshold() {
233
+ return 70;
234
+ }
232
235
  constructor(col, value, type = "uuid") {
233
236
  this.col = col;
234
237
  this.value = value;
235
238
  this.type = type;
236
239
  }
237
- static getPostgresInClauseValuesThreshold() {
238
- return 70;
239
- }
240
240
  clause(idx) {
241
241
  // do a simple = when only one item
242
242
  if (this.value.length === 1) {
@@ -708,3 +708,24 @@ function PaginationMultipleColsSubQuery(col, op, tableName, uniqueCol, val) {
708
708
  return new paginationMultipleColumnsSubQueryClause(col, op, tableName, uniqueCol, val);
709
709
  }
710
710
  exports.PaginationMultipleColsSubQuery = PaginationMultipleColsSubQuery;
711
+ // These 5 are used on the RHS of an expression
712
+ function Add(col, value) {
713
+ return new simpleClause(col, value, "+", new isNullClause(col));
714
+ }
715
+ exports.Add = Add;
716
+ function Subtract(col, value) {
717
+ return new simpleClause(col, value, "-", new isNullClause(col));
718
+ }
719
+ exports.Subtract = Subtract;
720
+ function Multiply(col, value) {
721
+ return new simpleClause(col, value, "*", new isNullClause(col));
722
+ }
723
+ exports.Multiply = Multiply;
724
+ function Divide(col, value) {
725
+ return new simpleClause(col, value, "/", new isNullClause(col));
726
+ }
727
+ exports.Divide = Divide;
728
+ function Modulo(col, value) {
729
+ return new simpleClause(col, value, "%", new isNullClause(col));
730
+ }
731
+ exports.Modulo = Modulo;
package/core/config.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { Database, DBDict } from "./db";
3
- declare type logType = "query" | "warn" | "info" | "error" | "debug";
3
+ type logType = "query" | "warn" | "info" | "error" | "debug";
4
4
  declare enum graphqlMutationName {
5
5
  NOUN_VERB = "NounVerb",
6
6
  VERB_NOUN = "VerbNoun"
@@ -19,6 +19,7 @@ export interface Config {
19
19
  db?: Database | DBDict;
20
20
  log?: logType | logType[];
21
21
  codegen?: CodegenConfig;
22
+ logQueryWithError?: boolean;
22
23
  customGraphQLJSONPath?: string;
23
24
  globalSchemaPath?: string;
24
25
  }
package/core/config.js CHANGED
@@ -32,6 +32,7 @@ const js_yaml_1 = require("js-yaml");
32
32
  const db_1 = __importDefault(require("./db"));
33
33
  const path = __importStar(require("path"));
34
34
  const logger_1 = require("./logger");
35
+ const ent_1 = require("./ent");
35
36
  // ent.config.ts eventually. for now ent.yml
36
37
  // or ent.yml?
37
38
  var graphqlMutationName;
@@ -60,6 +61,7 @@ function setConfig(cfg) {
60
61
  db: cfg.db,
61
62
  });
62
63
  }
64
+ (0, ent_1.___setLogQueryErrorWithError)(cfg.logQueryWithError);
63
65
  }
64
66
  function isBuffer(b) {
65
67
  return b.write !== undefined;
package/core/date.js CHANGED
@@ -10,11 +10,7 @@ function parseDate(val, throwErr) {
10
10
  else if (typeof val === "string") {
11
11
  dt = luxon_1.DateTime.fromISO(val);
12
12
  if (!dt.isValid) {
13
- let ms = Date.parse(val);
14
- if (ms === NaN) {
15
- throw throwErr(`invalid input for type Time ${val}`);
16
- }
17
- dt = luxon_1.DateTime.fromMillis(ms);
13
+ dt = luxon_1.DateTime.fromMillis(Date.parse(val));
18
14
  }
19
15
  }
20
16
  else if (val instanceof Date) {
package/core/db.d.ts CHANGED
@@ -7,7 +7,7 @@ export interface Database extends PoolConfig {
7
7
  port?: number;
8
8
  sslmode?: string;
9
9
  }
10
- export declare type env = "production" | "test" | "development";
10
+ export type env = "production" | "test" | "development";
11
11
  export declare type DBDict = Partial<Record<env, Database>>;
12
12
  export declare enum Dialect {
13
13
  Postgres = "postgres",
@@ -18,6 +18,11 @@ interface DatabaseInfo {
18
18
  config: PoolConfig;
19
19
  filePath?: string;
20
20
  }
21
+ interface clientConfigArgs {
22
+ connectionString?: string;
23
+ dbFile?: string;
24
+ db?: Database | DBDict;
25
+ }
21
26
  export default class DB {
22
27
  db: DatabaseInfo;
23
28
  static instance: DB;
@@ -30,13 +35,10 @@ export default class DB {
30
35
  getNewClient(): Promise<Client>;
31
36
  getSQLiteClient(): Sqlite;
32
37
  endPool(): Promise<void>;
38
+ emitsExplicitTransactionStatements(): boolean;
33
39
  static getInstance(): DB;
34
40
  static getDialect(): Dialect;
35
- static initDB(args?: {
36
- connectionString?: string;
37
- dbFile?: string;
38
- db?: Database | DBDict;
39
- }): void;
41
+ static initDB(args?: clientConfigArgs): void;
40
42
  }
41
43
  export declare const defaultTimestampParser: any;
42
44
  export interface Queryer {
@@ -53,6 +55,7 @@ export interface Connection extends Queryer {
53
55
  self(): Queryer;
54
56
  newClient(): Promise<Client>;
55
57
  close(): Promise<void>;
58
+ runInTransaction?(cb: () => void | Promise<void>): any;
56
59
  }
57
60
  export interface QueryResultRow {
58
61
  [column: string]: any;