@snowtop/ent 0.1.0-alpha7 → 0.1.0-alpha73

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 (112) hide show
  1. package/action/action.d.ts +28 -24
  2. package/action/executor.d.ts +4 -4
  3. package/action/executor.js +2 -2
  4. package/action/experimental_action.d.ts +29 -22
  5. package/action/experimental_action.js +29 -6
  6. package/action/orchestrator.d.ts +44 -16
  7. package/action/orchestrator.js +287 -73
  8. package/action/privacy.d.ts +2 -2
  9. package/core/base.d.ts +35 -23
  10. package/core/base.js +16 -0
  11. package/core/clause.d.ts +69 -3
  12. package/core/clause.js +420 -5
  13. package/core/config.d.ts +26 -0
  14. package/core/config.js +17 -0
  15. package/core/context.d.ts +2 -2
  16. package/core/context.js +2 -2
  17. package/core/convert.d.ts +1 -1
  18. package/core/db.d.ts +3 -4
  19. package/core/db.js +2 -0
  20. package/core/ent.d.ts +62 -27
  21. package/core/ent.js +272 -63
  22. package/core/loaders/assoc_count_loader.d.ts +2 -2
  23. package/core/loaders/assoc_count_loader.js +6 -1
  24. package/core/loaders/assoc_edge_loader.d.ts +3 -3
  25. package/core/loaders/assoc_edge_loader.js +5 -4
  26. package/core/loaders/index_loader.js +1 -0
  27. package/core/loaders/loader.js +5 -5
  28. package/core/loaders/object_loader.d.ts +10 -5
  29. package/core/loaders/object_loader.js +58 -4
  30. package/core/loaders/query_loader.d.ts +2 -2
  31. package/core/loaders/raw_count_loader.d.ts +2 -2
  32. package/core/logger.d.ts +1 -1
  33. package/core/logger.js +1 -0
  34. package/core/privacy.d.ts +25 -25
  35. package/core/privacy.js +5 -5
  36. package/core/query/assoc_query.d.ts +6 -6
  37. package/core/query/custom_query.d.ts +5 -5
  38. package/core/query/query.d.ts +1 -1
  39. package/core/query/shared_assoc_test.d.ts +1 -1
  40. package/core/query/shared_assoc_test.js +17 -5
  41. package/core/query/shared_test.d.ts +3 -0
  42. package/core/query/shared_test.js +95 -17
  43. package/core/viewer.d.ts +4 -3
  44. package/core/viewer.js +4 -0
  45. package/graphql/builtins/connection.js +3 -3
  46. package/graphql/builtins/edge.js +2 -2
  47. package/graphql/builtins/node.js +1 -1
  48. package/graphql/graphql.d.ts +3 -2
  49. package/graphql/graphql.js +30 -23
  50. package/graphql/node_resolver.d.ts +0 -1
  51. package/graphql/query/connection_type.js +6 -6
  52. package/graphql/query/edge_connection.d.ts +9 -9
  53. package/graphql/query/page_info.d.ts +1 -1
  54. package/graphql/query/page_info.js +4 -4
  55. package/graphql/query/shared_assoc_test.js +2 -2
  56. package/graphql/scalars/time.d.ts +1 -1
  57. package/index.d.ts +21 -1
  58. package/index.js +24 -5
  59. package/package.json +3 -3
  60. package/parse_schema/parse.d.ts +24 -5
  61. package/parse_schema/parse.js +90 -8
  62. package/schema/base_schema.d.ts +36 -1
  63. package/schema/base_schema.js +51 -2
  64. package/schema/field.d.ts +34 -6
  65. package/schema/field.js +67 -2
  66. package/schema/index.d.ts +2 -2
  67. package/schema/index.js +8 -1
  68. package/schema/schema.d.ts +100 -2
  69. package/schema/schema.js +127 -5
  70. package/scripts/custom_graphql.js +127 -16
  71. package/scripts/{transform_schema.d.ts → migrate_v0.1.d.ts} +0 -0
  72. package/scripts/migrate_v0.1.js +36 -0
  73. package/scripts/read_schema.js +25 -2
  74. package/testutils/builder.d.ts +36 -22
  75. package/testutils/builder.js +110 -13
  76. package/testutils/context/test_context.d.ts +2 -2
  77. package/testutils/context/test_context.js +7 -1
  78. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +17 -4
  79. package/testutils/db/{test_db.js → temp_db.js} +76 -19
  80. package/testutils/ent-graphql-tests/index.d.ts +2 -0
  81. package/testutils/ent-graphql-tests/index.js +26 -17
  82. package/testutils/fake_data/fake_contact.d.ts +5 -9
  83. package/testutils/fake_data/fake_contact.js +17 -21
  84. package/testutils/fake_data/fake_event.d.ts +5 -9
  85. package/testutils/fake_data/fake_event.js +24 -28
  86. package/testutils/fake_data/fake_user.d.ts +6 -10
  87. package/testutils/fake_data/fake_user.js +25 -29
  88. package/testutils/fake_data/test_helpers.d.ts +2 -2
  89. package/testutils/fake_data/test_helpers.js +6 -6
  90. package/testutils/fake_data/user_query.d.ts +2 -2
  91. package/testutils/fake_log.d.ts +3 -3
  92. package/testutils/parse_sql.d.ts +6 -0
  93. package/testutils/parse_sql.js +16 -2
  94. package/testutils/test_edge_global_schema.d.ts +15 -0
  95. package/testutils/test_edge_global_schema.js +58 -0
  96. package/testutils/write.d.ts +2 -2
  97. package/testutils/write.js +3 -3
  98. package/tsc/ast.d.ts +44 -0
  99. package/tsc/ast.js +267 -0
  100. package/tsc/compilerOptions.d.ts +6 -0
  101. package/tsc/compilerOptions.js +40 -1
  102. package/tsc/move_generated.d.ts +1 -0
  103. package/tsc/move_generated.js +160 -0
  104. package/tsc/transform.d.ts +21 -0
  105. package/tsc/transform.js +167 -0
  106. package/tsc/transform_action.d.ts +22 -0
  107. package/tsc/transform_action.js +179 -0
  108. package/tsc/transform_ent.d.ts +17 -0
  109. package/tsc/transform_ent.js +59 -0
  110. package/tsc/transform_schema.d.ts +27 -0
  111. package/tsc/transform_schema.js +379 -0
  112. package/scripts/transform_schema.js +0 -288
@@ -1,14 +1,16 @@
1
- import { Ent, ID, Viewer, Data, EntConstructor } from "../core/base";
1
+ import { Ent, ID, Viewer, Data, EntConstructor, PrivacyPolicy } from "../core/base";
2
2
  import { Orchestrator } from "../action/orchestrator";
3
3
  import { Action, Builder, Changeset, WriteOperation, Validator, Trigger, Observer } from "../action";
4
- import { Schema } from "../schema";
4
+ import { FieldMap, Schema } from "../schema";
5
+ import { SchemaConfig } from "../schema/base_schema";
6
+ import { FieldInfoMap } from "../schema/schema";
5
7
  export declare class User implements Ent {
6
8
  viewer: Viewer;
7
9
  data: Data;
8
10
  id: ID;
9
11
  accountID: string;
10
12
  nodeType: string;
11
- privacyPolicy: import("../core/base").PrivacyPolicy<Ent>;
13
+ getPrivacyPolicy(): PrivacyPolicy<this>;
12
14
  firstName: string;
13
15
  constructor(viewer: Viewer, data: Data);
14
16
  }
@@ -18,7 +20,7 @@ export declare class Event implements Ent {
18
20
  id: ID;
19
21
  accountID: string;
20
22
  nodeType: string;
21
- privacyPolicy: import("../core/base").PrivacyPolicy<Ent>;
23
+ getPrivacyPolicy(): PrivacyPolicy<this>;
22
24
  constructor(viewer: Viewer, data: Data);
23
25
  }
24
26
  export declare class Contact implements Ent {
@@ -27,7 +29,7 @@ export declare class Contact implements Ent {
27
29
  id: ID;
28
30
  accountID: string;
29
31
  nodeType: string;
30
- privacyPolicy: import("../core/base").PrivacyPolicy<Ent>;
32
+ getPrivacyPolicy(): PrivacyPolicy<this>;
31
33
  constructor(viewer: Viewer, data: Data);
32
34
  }
33
35
  export declare class Group implements Ent {
@@ -36,7 +38,7 @@ export declare class Group implements Ent {
36
38
  id: ID;
37
39
  accountID: string;
38
40
  nodeType: string;
39
- privacyPolicy: import("../core/base").PrivacyPolicy<Ent>;
41
+ getPrivacyPolicy(): PrivacyPolicy<this>;
40
42
  constructor(viewer: Viewer, data: Data);
41
43
  }
42
44
  export declare class Message implements Ent {
@@ -45,7 +47,7 @@ export declare class Message implements Ent {
45
47
  id: ID;
46
48
  accountID: string;
47
49
  nodeType: string;
48
- privacyPolicy: import("../core/base").PrivacyPolicy<Ent>;
50
+ getPrivacyPolicy(): PrivacyPolicy<this>;
49
51
  constructor(viewer: Viewer, data: Data);
50
52
  }
51
53
  export declare class Address implements Ent {
@@ -54,26 +56,37 @@ export declare class Address implements Ent {
54
56
  id: ID;
55
57
  accountID: string;
56
58
  nodeType: string;
57
- privacyPolicy: import("../core/base").PrivacyPolicy<Ent>;
59
+ getPrivacyPolicy(): PrivacyPolicy<this>;
58
60
  constructor(viewer: Viewer, data: Data);
59
61
  }
60
62
  export interface BuilderSchema<T extends Ent> extends Schema {
61
63
  ent: EntConstructor<T>;
62
64
  }
65
+ export declare function getBuilderSchema<T extends Ent>(cfg: SchemaConfig, ent: EntConstructor<T>): BuilderSchema<T>;
66
+ export declare function getBuilderSchemaFromFields<T extends Ent>(fields: FieldMap, ent: EntConstructor<T>): BuilderSchema<T>;
67
+ export declare function getBuilderSchemaTZFromFields<T extends Ent>(fields: FieldMap, ent: EntConstructor<T>): BuilderSchema<T>;
63
68
  export declare function getSchemaName(value: BuilderSchema<Ent>): string;
64
69
  export declare function getTableName(value: BuilderSchema<Ent>): string;
65
- export declare class SimpleBuilder<T extends Ent> implements Builder<T> {
70
+ export declare function getFieldInfo(value: BuilderSchema<Ent>): FieldInfoMap;
71
+ declare type MaybeNull<T extends Ent> = T | null;
72
+ declare type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
73
+ export declare class SimpleBuilder<T extends Ent, TExistingEnt extends TMaybleNullableEnt<T> = MaybeNull<T>> implements Builder<T, Viewer, TExistingEnt> {
66
74
  viewer: Viewer;
67
75
  private schema;
68
76
  operation: WriteOperation;
69
- existingEnt: T | undefined;
70
- ent: EntConstructor<T>;
77
+ existingEnt: TExistingEnt;
78
+ ent: EntConstructor<T, Viewer>;
71
79
  placeholderID: ID;
72
- orchestrator: Orchestrator<T, Data>;
80
+ orchestrator: Orchestrator<T, Data, Viewer, TExistingEnt>;
73
81
  fields: Map<string, any>;
74
82
  nodeType: string;
75
- constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation?: WriteOperation, existingEnt?: T | undefined, action?: Action<T, SimpleBuilder<T>, Data> | undefined);
76
- build(): Promise<Changeset<T>>;
83
+ m: Map<string, any>;
84
+ constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation: WriteOperation, existingEnt: TExistingEnt, action?: Action<T, SimpleBuilder<T, TExistingEnt>, Viewer, Data, TExistingEnt> | undefined);
85
+ getInput(): Data;
86
+ updateInput(input: Data): void;
87
+ storeData(k: string, v: any): void;
88
+ getStoredData(k: string): any;
89
+ build(): Promise<Changeset>;
77
90
  editedEnt(): Promise<T | null>;
78
91
  editedEntX(): Promise<T>;
79
92
  save(): Promise<void>;
@@ -84,20 +97,21 @@ export declare class SimpleBuilder<T extends Ent> implements Builder<T> {
84
97
  interface viewerEntLoadFunc {
85
98
  (data: Data): Viewer | Promise<Viewer>;
86
99
  }
87
- export declare class SimpleAction<T extends Ent> implements Action<T, SimpleBuilder<T>, Data> {
100
+ export declare class SimpleAction<T extends Ent, TExistingEnt extends TMaybleNullableEnt<T> = MaybeNull<T>> implements Action<T, SimpleBuilder<T, TExistingEnt>, Viewer, Data, TExistingEnt> {
88
101
  viewer: Viewer;
89
102
  private fields;
90
- builder: SimpleBuilder<T>;
91
- validators: Validator<SimpleBuilder<T>, Data>[];
92
- triggers: Trigger<SimpleBuilder<T>, Data>[];
93
- observers: Observer<SimpleBuilder<T>, Data>[];
103
+ builder: SimpleBuilder<T, TExistingEnt>;
94
104
  viewerForEntLoad: viewerEntLoadFunc | undefined;
95
- constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation?: WriteOperation, existingEnt?: T | undefined);
96
- getPrivacyPolicy(): import("../core/base").PrivacyPolicy<Ent>;
105
+ constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation: WriteOperation | undefined, existingEnt: TExistingEnt);
106
+ getTriggers(): (Trigger<T, SimpleBuilder<T>> | Array<Trigger<T, SimpleBuilder<T>>>)[];
107
+ getValidators(): Validator<T, SimpleBuilder<T>>[];
108
+ getObservers(): Observer<T, SimpleBuilder<T>>[];
109
+ getPrivacyPolicy(): PrivacyPolicy<Ent<Viewer<Ent<any> | null, ID | null>>, Viewer<Ent<any> | null, ID | null>>;
97
110
  getInput(): Data;
98
- changeset(): Promise<Changeset<T>>;
111
+ changeset(): Promise<Changeset>;
99
112
  valid(): Promise<boolean>;
100
113
  validX(): Promise<void>;
114
+ validWithErrors(): Promise<Error[]>;
101
115
  save(): Promise<T | null>;
102
116
  saveX(): Promise<T>;
103
117
  editedEnt(): Promise<T | null>;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SimpleAction = exports.SimpleBuilder = exports.getTableName = exports.getSchemaName = exports.Address = exports.Message = exports.Group = exports.Contact = exports.Event = exports.User = void 0;
6
+ exports.SimpleAction = exports.SimpleBuilder = exports.getFieldInfo = exports.getTableName = exports.getSchemaName = exports.getBuilderSchemaTZFromFields = exports.getBuilderSchemaFromFields = exports.getBuilderSchema = exports.Address = exports.Message = exports.Group = exports.Contact = exports.Event = exports.User = void 0;
7
7
  const privacy_1 = require("../core/privacy");
8
8
  const orchestrator_1 = require("../action/orchestrator");
9
9
  const action_1 = require("../action");
@@ -14,18 +14,22 @@ const snake_case_1 = require("snake-case");
14
14
  const loaders_1 = require("../core/loaders");
15
15
  const convert_1 = require("../core/convert");
16
16
  const camel_case_1 = require("camel-case");
17
+ const base_schema_1 = require("../schema/base_schema");
18
+ const schema_2 = require("../schema/schema");
17
19
  class User {
18
20
  constructor(viewer, data) {
19
21
  this.viewer = viewer;
20
22
  this.data = data;
21
23
  this.accountID = "";
22
24
  this.nodeType = "User";
23
- this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
24
25
  this.data.created_at = (0, convert_1.convertDate)(data.created_at);
25
26
  this.data.updated_at = (0, convert_1.convertDate)(data.updated_at);
26
27
  this.id = data.id;
27
28
  this.firstName = data.first_name;
28
29
  }
30
+ getPrivacyPolicy() {
31
+ return privacy_1.AlwaysAllowPrivacyPolicy;
32
+ }
29
33
  }
30
34
  exports.User = User;
31
35
  class Event {
@@ -34,9 +38,11 @@ class Event {
34
38
  this.data = data;
35
39
  this.accountID = "";
36
40
  this.nodeType = "Event";
37
- this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
38
41
  this.id = data.id;
39
42
  }
43
+ getPrivacyPolicy() {
44
+ return privacy_1.AlwaysAllowPrivacyPolicy;
45
+ }
40
46
  }
41
47
  exports.Event = Event;
42
48
  class Contact {
@@ -45,11 +51,13 @@ class Contact {
45
51
  this.data = data;
46
52
  this.accountID = "";
47
53
  this.nodeType = "Contact";
48
- this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
49
54
  this.data.created_at = (0, convert_1.convertDate)(data.created_at);
50
55
  this.data.updated_at = (0, convert_1.convertDate)(data.updated_at);
51
56
  this.id = data.id;
52
57
  }
58
+ getPrivacyPolicy() {
59
+ return privacy_1.AlwaysAllowPrivacyPolicy;
60
+ }
53
61
  }
54
62
  exports.Contact = Contact;
55
63
  class Group {
@@ -58,9 +66,11 @@ class Group {
58
66
  this.data = data;
59
67
  this.accountID = "";
60
68
  this.nodeType = "Group";
61
- this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
62
69
  this.id = data.id;
63
70
  }
71
+ getPrivacyPolicy() {
72
+ return privacy_1.AlwaysAllowPrivacyPolicy;
73
+ }
64
74
  }
65
75
  exports.Group = Group;
66
76
  class Message {
@@ -69,9 +79,11 @@ class Message {
69
79
  this.data = data;
70
80
  this.accountID = "";
71
81
  this.nodeType = "Message";
72
- this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
73
82
  this.id = data.id;
74
83
  }
84
+ getPrivacyPolicy() {
85
+ return privacy_1.AlwaysAllowPrivacyPolicy;
86
+ }
75
87
  }
76
88
  exports.Message = Message;
77
89
  class Address {
@@ -80,11 +92,34 @@ class Address {
80
92
  this.data = data;
81
93
  this.accountID = "";
82
94
  this.nodeType = "Address";
83
- this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
84
95
  this.id = data.id;
85
96
  }
97
+ getPrivacyPolicy() {
98
+ return privacy_1.AlwaysAllowPrivacyPolicy;
99
+ }
86
100
  }
87
101
  exports.Address = Address;
102
+ function getBuilderSchema(cfg, ent) {
103
+ return {
104
+ ...new base_schema_1.EntSchema(cfg),
105
+ ent,
106
+ };
107
+ }
108
+ exports.getBuilderSchema = getBuilderSchema;
109
+ function getBuilderSchemaFromFields(fields, ent) {
110
+ return {
111
+ ...new base_schema_1.EntSchema({ fields }),
112
+ ent,
113
+ };
114
+ }
115
+ exports.getBuilderSchemaFromFields = getBuilderSchemaFromFields;
116
+ function getBuilderSchemaTZFromFields(fields, ent) {
117
+ return {
118
+ ...new base_schema_1.EntSchemaWithTZ({ fields }),
119
+ ent,
120
+ };
121
+ }
122
+ exports.getBuilderSchemaTZFromFields = getBuilderSchemaTZFromFields;
88
123
  function getSchemaName(value) {
89
124
  return value.ent.name;
90
125
  }
@@ -96,13 +131,26 @@ exports.getTableName = getTableName;
96
131
  function randomNum() {
97
132
  return Math.random().toString(10).substring(2);
98
133
  }
134
+ function getFieldInfo(value) {
135
+ const fields = (0, schema_1.getFields)(value);
136
+ let ret = {};
137
+ for (const [k, f] of fields) {
138
+ ret[k] = {
139
+ dbCol: (0, schema_2.getStorageKey)(f, k),
140
+ inputKey: (0, camel_case_1.camelCase)(k),
141
+ };
142
+ }
143
+ return ret;
144
+ }
145
+ exports.getFieldInfo = getFieldInfo;
99
146
  // reuses orchestrator and standard things
100
147
  class SimpleBuilder {
101
- constructor(viewer, schema, fields, operation = action_1.WriteOperation.Insert, existingEnt = undefined, action) {
148
+ constructor(viewer, schema, fields, operation = action_1.WriteOperation.Insert, existingEnt, action) {
102
149
  this.viewer = viewer;
103
150
  this.schema = schema;
104
151
  this.operation = operation;
105
152
  this.existingEnt = existingEnt;
153
+ this.m = new Map();
106
154
  // create dynamic placeholder
107
155
  // TODO: do we need to use this as the node when there's an existingEnt
108
156
  // same for generated builders.
@@ -128,11 +176,13 @@ class SimpleBuilder {
128
176
  this.ent = schema.ent;
129
177
  const tableName = getTableName(schema);
130
178
  this.nodeType = (0, camel_case_1.camelCase)(schema.ent.name);
179
+ const fieldInfo = getFieldInfo(schema);
131
180
  this.orchestrator = new orchestrator_1.Orchestrator({
132
181
  viewer: this.viewer,
133
182
  operation: operation,
134
183
  tableName: tableName,
135
184
  key,
185
+ fieldInfo,
136
186
  loaderOptions: {
137
187
  loaderFactory: new loaders_1.ObjectLoaderFactory({
138
188
  tableName: tableName,
@@ -142,15 +192,53 @@ class SimpleBuilder {
142
192
  ent: schema.ent,
143
193
  tableName: tableName,
144
194
  fields: [],
195
+ fieldPrivacy: (0, schema_1.getFieldsWithPrivacy)(schema, fieldInfo),
145
196
  },
146
197
  builder: this,
147
198
  action: action,
148
199
  schema: this.schema,
149
200
  editedFields: () => {
150
- return this.fields;
201
+ // to simulate what we do in generated builders where we return a new Map
202
+ const m = new Map();
203
+ for (const [k, v] of this.fields) {
204
+ m.set(k, v);
205
+ }
206
+ return m;
151
207
  },
208
+ updateInput: this.updateInput.bind(this),
152
209
  });
153
210
  }
211
+ getInput() {
212
+ let ret = {};
213
+ for (const [k, v] of this.fields) {
214
+ ret[k] = v;
215
+ }
216
+ return ret;
217
+ }
218
+ updateInput(input) {
219
+ const knownFields = (0, schema_1.getFields)(this.schema);
220
+ for (const k in input) {
221
+ if (knownFields.has(k)) {
222
+ this.fields.set(k, input[k]);
223
+ }
224
+ else {
225
+ // related to #510. we do camelCase to pass fields in here but fields may be snakeCase and we want that to pass in tests
226
+ // we do camelCase in
227
+ const sc = (0, snake_case_1.snakeCase)(k);
228
+ if (knownFields.has(sc)) {
229
+ this.fields.set(sc, input[k]);
230
+ }
231
+ }
232
+ }
233
+ }
234
+ // store data in Builder that can be retrieved by another validator, trigger, observer later in the action
235
+ storeData(k, v) {
236
+ this.m.set(k, v);
237
+ }
238
+ // retrieve data stored in this Builder with key
239
+ getStoredData(k) {
240
+ return this.m.get(k);
241
+ }
154
242
  build() {
155
243
  return this.orchestrator.build();
156
244
  }
@@ -175,14 +263,20 @@ class SimpleBuilder {
175
263
  }
176
264
  exports.SimpleBuilder = SimpleBuilder;
177
265
  class SimpleAction {
178
- constructor(viewer, schema, fields, operation = action_1.WriteOperation.Insert, existingEnt = undefined) {
266
+ constructor(viewer, schema, fields, operation = action_1.WriteOperation.Insert, existingEnt) {
179
267
  this.viewer = viewer;
180
268
  this.fields = fields;
181
- this.validators = [];
182
- this.triggers = [];
183
- this.observers = [];
184
269
  this.builder = new SimpleBuilder(this.viewer, schema, fields, operation, existingEnt, this);
185
270
  }
271
+ getTriggers() {
272
+ return [];
273
+ }
274
+ getValidators() {
275
+ return [];
276
+ }
277
+ getObservers() {
278
+ return [];
279
+ }
186
280
  getPrivacyPolicy() {
187
281
  return privacy_1.AlwaysAllowPrivacyPolicy;
188
282
  }
@@ -202,6 +296,9 @@ class SimpleAction {
202
296
  validX() {
203
297
  return this.builder.orchestrator.validX();
204
298
  }
299
+ validWithErrors() {
300
+ return this.builder.orchestrator.validWithErrors();
301
+ }
205
302
  async save() {
206
303
  await (0, action_1.saveBuilder)(this.builder);
207
304
  if (this.builder.operation !== action_1.WriteOperation.Delete) {
@@ -1,8 +1,8 @@
1
1
  import { Context, Viewer } from "../../core/base";
2
2
  import { ContextCache } from "../../core/context";
3
- import { LoggedOutViewer } from "../../core/viewer";
4
3
  export declare class TestContext implements Context {
4
+ constructor(viewer?: Viewer);
5
5
  cache: ContextCache;
6
- viewer: LoggedOutViewer;
6
+ viewer: Viewer;
7
7
  getViewer(): Viewer;
8
8
  }
@@ -4,9 +4,15 @@ exports.TestContext = void 0;
4
4
  const context_1 = require("../../core/context");
5
5
  const viewer_1 = require("../../core/viewer");
6
6
  class TestContext {
7
- constructor() {
7
+ constructor(viewer) {
8
8
  this.cache = new context_1.ContextCache();
9
9
  this.viewer = new viewer_1.LoggedOutViewer(this);
10
+ if (viewer) {
11
+ this.viewer = viewer;
12
+ if (viewer.setContext !== undefined) {
13
+ viewer.setContext(this);
14
+ }
15
+ }
10
16
  }
11
17
  getViewer() {
12
18
  return this.viewer;
@@ -1,6 +1,7 @@
1
1
  import { Client as PGClient } from "pg";
2
2
  import { Dialect } from "../../core/db";
3
3
  import { Database as SqliteDatabase } from "better-sqlite3";
4
+ import { Field } from "../../schema";
4
5
  import { BuilderSchema } from "../builder";
5
6
  import { Ent } from "../../core/base";
6
7
  interface SchemaItem {
@@ -12,6 +13,7 @@ interface Column extends SchemaItem {
12
13
  primaryKey?: boolean;
13
14
  unique?: boolean;
14
15
  default?: string;
16
+ index?: boolean | indexOptions;
15
17
  foreignKey?: {
16
18
  table: string;
17
19
  col: string;
@@ -20,21 +22,29 @@ interface Column extends SchemaItem {
20
22
  interface Constraint extends SchemaItem {
21
23
  generate(): string;
22
24
  }
25
+ interface Index extends SchemaItem {
26
+ generate(): string;
27
+ }
23
28
  export interface CoreConcept {
24
29
  name: string;
25
30
  create(): string;
31
+ postCreate?(): string[];
26
32
  drop(): string;
27
33
  }
28
34
  export interface Table extends CoreConcept {
29
35
  columns: Column[];
30
36
  constraints?: Constraint[];
31
37
  }
32
- declare type options = Pick<Column, "nullable" | "primaryKey" | "default" | "foreignKey" | "unique">;
38
+ declare type options = Pick<Column, "nullable" | "primaryKey" | "default" | "foreignKey" | "unique" | "index">;
33
39
  export declare function primaryKey(name: string, cols: string[]): Constraint;
34
40
  export declare function foreignKey(name: string, cols: string[], fkey: {
35
41
  table: string;
36
42
  cols: string[];
37
43
  }): Constraint;
44
+ interface indexOptions {
45
+ type: string;
46
+ }
47
+ export declare function index(tableName: string, cols: string[], opts?: indexOptions): Index;
38
48
  export declare function uniqueIndex(name: string): Constraint;
39
49
  export declare function uuid(name: string, opts?: options): Column;
40
50
  export declare function text(name: string, opts?: options): Column;
@@ -71,19 +81,22 @@ export declare class TempDB {
71
81
  constructor(tables: CoreConcept[]);
72
82
  getDialect(): Dialect;
73
83
  getTables(): Map<string, CoreConcept>;
74
- beforeAll(): Promise<void>;
84
+ beforeAll(setupConnString?: boolean): Promise<void>;
85
+ createImpl(table: CoreConcept): Promise<void>;
75
86
  getSqliteClient(): SqliteDatabase;
76
87
  getPostgresClient(): PGClient;
77
88
  afterAll(): Promise<void>;
89
+ getDB(): string;
78
90
  dropAll(): Promise<void>;
79
91
  drop(...tables: string[]): Promise<void>;
80
92
  create(...tables: CoreConcept[]): Promise<void>;
81
93
  }
82
94
  export declare function assoc_edge_config_table(): Table;
83
- export declare function assoc_edge_table(name: string): Table;
95
+ export declare function assoc_edge_table(name: string, global?: boolean): Table;
84
96
  interface sqliteSetupOptions {
85
97
  disableDeleteAfterEachTest?: boolean;
86
98
  }
87
- export declare function setupSqlite(connString: string, tables: () => Table[], opts?: sqliteSetupOptions): void;
99
+ export declare function setupSqlite(connString: string, tables: () => Table[], opts?: sqliteSetupOptions): TempDB;
88
100
  export declare function getSchemaTable(schema: BuilderSchema<Ent>, dialect: Dialect): Table;
101
+ export declare function getColumnFromField(fieldName: string, f: Field, dialect: Dialect): Column;
89
102
  export {};
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.getSchemaTable = exports.setupSqlite = exports.assoc_edge_table = exports.assoc_edge_config_table = exports.TempDB = exports.enumType = exports.table = exports.boolList = exports.dateList = exports.timetzList = exports.timeList = exports.timestamptzList = exports.timestampList = exports.uuidList = exports.integerList = exports.textList = exports.jsonb = exports.json = exports.float = exports.integer = exports.bool = exports.date = exports.timetz = exports.time = exports.timestamptz = exports.timestamp = exports.enumCol = exports.text = exports.uuid = exports.uniqueIndex = exports.foreignKey = exports.primaryKey = void 0;
25
+ exports.getColumnFromField = exports.getSchemaTable = exports.setupSqlite = exports.assoc_edge_table = exports.assoc_edge_config_table = exports.TempDB = exports.enumType = exports.table = exports.boolList = exports.dateList = exports.timetzList = exports.timeList = exports.timestamptzList = exports.timestampList = exports.uuidList = exports.integerList = exports.textList = exports.jsonb = exports.json = exports.float = exports.integer = exports.bool = exports.date = exports.timetz = exports.time = exports.timestamptz = exports.timestamp = exports.enumCol = exports.text = exports.uuid = exports.uniqueIndex = exports.index = exports.foreignKey = exports.primaryKey = void 0;
26
26
  const pg_1 = require("pg");
27
27
  const db_1 = __importStar(require("../../core/db"));
28
28
  // this should only be used in tests so we expect to be able to import without shenanigans
@@ -32,6 +32,7 @@ const fs = __importStar(require("fs"));
32
32
  const schema_1 = require("../../schema");
33
33
  const snake_case_1 = require("snake-case");
34
34
  const builder_1 = require("../builder");
35
+ const test_edge_global_schema_1 = require("../test_edge_global_schema");
35
36
  function primaryKey(name, cols) {
36
37
  return {
37
38
  name: name,
@@ -50,6 +51,16 @@ function foreignKey(name, cols, fkey) {
50
51
  };
51
52
  }
52
53
  exports.foreignKey = foreignKey;
54
+ function index(tableName, cols, opts) {
55
+ const name = `${tableName}_${cols.join("_")}_idx`;
56
+ return {
57
+ name,
58
+ generate() {
59
+ return `CREATE INDEX ${name} ON ${tableName} USING ${opts?.type || "btree"} (${cols.join(",")});`;
60
+ },
61
+ };
62
+ }
63
+ exports.index = index;
53
64
  function uniqueIndex(name) {
54
65
  return {
55
66
  name: "",
@@ -248,9 +259,24 @@ exports.boolList = boolList;
248
259
  function table(name, ...items) {
249
260
  let cols = [];
250
261
  let constraints = [];
262
+ let indexes = [];
251
263
  for (const item of items) {
252
264
  if (item.datatype !== undefined) {
253
265
  const col = item;
266
+ if (col.index) {
267
+ let opts = {
268
+ type: "btree",
269
+ };
270
+ if (col.index === true) {
271
+ opts = {
272
+ type: "btree",
273
+ };
274
+ }
275
+ else {
276
+ opts = col.index;
277
+ }
278
+ indexes.push(index(name, [col.name], opts));
279
+ }
254
280
  // add it as a constraint
255
281
  if (col.foreignKey) {
256
282
  constraints.push(foreignKey(`${name}_${col.name}_fkey`, [col.name], {
@@ -288,6 +314,9 @@ function table(name, ...items) {
288
314
  constraints.forEach((constraint) => schemaStr.push(constraint.generate()));
289
315
  return `CREATE TABLE IF NOT EXISTS ${name} (\n ${schemaStr})`;
290
316
  },
317
+ postCreate() {
318
+ return indexes.map((index) => index.generate());
319
+ },
291
320
  drop() {
292
321
  return `DROP TABLE IF EXISTS ${name}`;
293
322
  },
@@ -336,7 +365,7 @@ class TempDB {
336
365
  getTables() {
337
366
  return this.tables;
338
367
  }
339
- async beforeAll() {
368
+ async beforeAll(setupConnString = true) {
340
369
  if (this.dialect === db_1.Dialect.Postgres) {
341
370
  const user = process.env.POSTGRES_USER || "";
342
371
  const password = process.env.POSTGRES_PASSWORD || "";
@@ -348,11 +377,17 @@ class TempDB {
348
377
  await this.client.connect();
349
378
  this.db = randomDB();
350
379
  await this.client.query(`CREATE DATABASE ${this.db}`);
351
- if (user && password) {
352
- process.env.DB_CONNECTION_STRING = `postgres://${user}:${password}@localhost:5432/${this.db}`;
380
+ if (setupConnString) {
381
+ if (user && password) {
382
+ process.env.DB_CONNECTION_STRING = `postgres://${user}:${password}@localhost:5432/${this.db}`;
383
+ }
384
+ else {
385
+ process.env.DB_CONNECTION_STRING = `postgres://localhost/${this.db}?`;
386
+ }
353
387
  }
354
388
  else {
355
- process.env.DB_CONNECTION_STRING = `postgres://localhost/${this.db}?`;
389
+ // will probably be setup via loadConfig
390
+ delete process.env.DB_CONNECTION_STRING;
356
391
  }
357
392
  this.dbClient = new pg_1.Client({
358
393
  host: "localhost",
@@ -370,11 +405,24 @@ class TempDB {
370
405
  this.sqlite = (0, better_sqlite3_1.default)(filePath);
371
406
  }
372
407
  for (const [_, table] of this.tables) {
373
- if (this.dialect == db_1.Dialect.Postgres) {
374
- await this.dbClient.query(table.create());
408
+ await this.createImpl(table);
409
+ }
410
+ }
411
+ async createImpl(table) {
412
+ if (this.dialect == db_1.Dialect.Postgres) {
413
+ await this.dbClient.query(table.create());
414
+ if (table.postCreate) {
415
+ for (const q of table.postCreate()) {
416
+ await this.dbClient.query(q);
417
+ }
375
418
  }
376
- else {
377
- this.sqlite.exec(table.create());
419
+ }
420
+ else {
421
+ this.sqlite.exec(table.create());
422
+ if (table.postCreate) {
423
+ for (const q of table.postCreate()) {
424
+ this.sqlite.exec(q);
425
+ }
378
426
  }
379
427
  }
380
428
  }
@@ -397,6 +445,9 @@ class TempDB {
397
445
  await this.client.query(`DROP DATABASE ${this.db}`);
398
446
  await this.client.end();
399
447
  }
448
+ getDB() {
449
+ return this.db;
450
+ }
400
451
  async dropAll() {
401
452
  for (const [t, _] of this.tables) {
402
453
  await this.drop(t);
@@ -422,12 +473,7 @@ class TempDB {
422
473
  if (this.tables.has(table.name)) {
423
474
  throw new Error(`table with name ${table.name} already exists`);
424
475
  }
425
- if (this.dialect === db_1.Dialect.Postgres) {
426
- await this.dbClient.query(table.create());
427
- }
428
- else {
429
- this.sqlite.exec(table.create());
430
- }
476
+ await this.createImpl(table);
431
477
  this.tables.set(table.name, table);
432
478
  }
433
479
  }
@@ -439,18 +485,26 @@ function assoc_edge_config_table() {
439
485
  text("edge_type", { primaryKey: true }), text("edge_name"), bool("symmetric_edge", { default: "FALSE" }), text("inverse_edge_type", { nullable: true }), text("edge_table"), timestamptz("created_at"), timestamptz("updated_at"));
440
486
  }
441
487
  exports.assoc_edge_config_table = assoc_edge_config_table;
442
- function assoc_edge_table(name) {
443
- return table(name, uuid("id1"), text("id1_type"),
488
+ // if global flag is true, add any column from testEdgeGlobalSchema
489
+ // up to caller to set/clear that as needed
490
+ function assoc_edge_table(name, global) {
491
+ const t = table(name, uuid("id1"), text("id1_type"),
444
492
  // same as in assoc_edge_config_table
445
493
  text("edge_type"), uuid("id2"), text("id2_type"), timestamptz("time"), text("data", { nullable: true }), primaryKey(`${name}_pkey`, ["id1", "id2", "edge_type"]));
494
+ if (global) {
495
+ for (const k in test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields) {
496
+ const col = getColumnFromField(k, test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields[k], db_1.Dialect.Postgres);
497
+ t.columns.push(col);
498
+ }
499
+ }
500
+ return t;
446
501
  }
447
502
  exports.assoc_edge_table = assoc_edge_table;
448
503
  function setupSqlite(connString, tables, opts) {
449
- let tdb;
504
+ let tdb = new TempDB(db_1.Dialect.SQLite, tables());
450
505
  beforeAll(async () => {
451
506
  process.env.DB_CONNECTION_STRING = connString;
452
507
  (0, config_1.loadConfig)();
453
- tdb = new TempDB(db_1.Dialect.SQLite, tables());
454
508
  await tdb.beforeAll();
455
509
  const conn = db_1.default.getInstance().getConnection();
456
510
  expect(conn.db.memory).toBe(false);
@@ -473,7 +527,9 @@ function setupSqlite(connString, tables, opts) {
473
527
  afterAll(async () => {
474
528
  await tdb.afterAll();
475
529
  fs.rmSync(tdb.getSqliteClient().name);
530
+ delete process.env.DB_CONNECTION_STRING;
476
531
  });
532
+ return tdb;
477
533
  }
478
534
  exports.setupSqlite = setupSqlite;
479
535
  function getSchemaTable(schema, dialect) {
@@ -540,6 +596,7 @@ function getColumnFromField(fieldName, f, dialect) {
540
596
  return getColumn(fieldName, f, fn);
541
597
  }
542
598
  }
599
+ exports.getColumnFromField = getColumnFromField;
543
600
  function getColumn(fieldName, f, col) {
544
601
  return col(storageKey(fieldName, f), buildOpts(f));
545
602
  }