@snowtop/ent 0.0.2 → 0.0.3-5.alpha.2

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 (104) hide show
  1. package/action/action.d.ts +6 -6
  2. package/action/action.js +2 -2
  3. package/action/executor.d.ts +7 -12
  4. package/action/executor.js +39 -33
  5. package/action/experimental_action.d.ts +4 -2
  6. package/action/experimental_action.js +27 -2
  7. package/action/index.d.ts +1 -1
  8. package/action/orchestrator.d.ts +14 -6
  9. package/action/orchestrator.js +188 -99
  10. package/action/privacy.js +4 -4
  11. package/auth/auth.js +2 -2
  12. package/core/base.d.ts +6 -0
  13. package/core/base.js +12 -9
  14. package/core/clause.d.ts +1 -0
  15. package/core/clause.js +6 -2
  16. package/core/config.d.ts +20 -0
  17. package/core/config.js +2 -2
  18. package/core/context.js +3 -3
  19. package/core/convert.d.ts +4 -0
  20. package/core/convert.js +25 -2
  21. package/core/db.d.ts +18 -1
  22. package/core/db.js +4 -7
  23. package/core/ent.d.ts +17 -10
  24. package/core/ent.js +38 -15
  25. package/core/loaders/assoc_count_loader.js +5 -5
  26. package/core/loaders/assoc_edge_loader.js +10 -10
  27. package/core/loaders/loader.js +3 -3
  28. package/core/loaders/object_loader.js +6 -6
  29. package/core/loaders/query_loader.js +7 -7
  30. package/core/loaders/raw_count_loader.js +4 -4
  31. package/core/logger.js +2 -2
  32. package/core/privacy.d.ts +21 -1
  33. package/core/privacy.js +91 -47
  34. package/core/query/assoc_query.d.ts +12 -12
  35. package/core/query/assoc_query.js +86 -51
  36. package/core/query/custom_query.d.ts +10 -7
  37. package/core/query/custom_query.js +29 -3
  38. package/core/query/query.d.ts +24 -8
  39. package/core/query/query.js +41 -4
  40. package/core/query/shared_assoc_test.js +257 -13
  41. package/core/query/shared_test.d.ts +1 -1
  42. package/core/query/shared_test.js +11 -11
  43. package/core/viewer.js +1 -0
  44. package/graphql/builtins/connection.js +4 -3
  45. package/graphql/builtins/edge.js +3 -2
  46. package/graphql/builtins/node.js +2 -1
  47. package/graphql/graphql.d.ts +2 -0
  48. package/graphql/graphql.js +83 -61
  49. package/graphql/index.d.ts +1 -1
  50. package/graphql/index.js +2 -1
  51. package/graphql/node_resolver.d.ts +1 -0
  52. package/graphql/node_resolver.js +14 -1
  53. package/graphql/query/connection_type.d.ts +5 -4
  54. package/graphql/query/connection_type.js +6 -6
  55. package/graphql/query/edge_connection.d.ts +7 -7
  56. package/graphql/query/page_info.js +5 -4
  57. package/graphql/query/shared_assoc_test.js +9 -9
  58. package/graphql/query/shared_edge_connection.d.ts +1 -1
  59. package/graphql/query/shared_edge_connection.js +4 -4
  60. package/graphql/scalars/time.js +1 -1
  61. package/imports/dataz/example1/_auth.js +8 -8
  62. package/imports/dataz/example1/_viewer.js +4 -4
  63. package/imports/index.d.ts +1 -1
  64. package/imports/index.js +3 -5
  65. package/index.d.ts +2 -1
  66. package/index.js +6 -2
  67. package/package.json +17 -10
  68. package/parse_schema/parse.d.ts +48 -0
  69. package/parse_schema/parse.js +160 -0
  70. package/schema/base_schema.d.ts +2 -0
  71. package/schema/base_schema.js +17 -7
  72. package/schema/field.d.ts +52 -15
  73. package/schema/field.js +234 -47
  74. package/schema/index.d.ts +1 -0
  75. package/schema/index.js +1 -0
  76. package/schema/json_field.d.ts +17 -0
  77. package/schema/json_field.js +48 -0
  78. package/schema/schema.d.ts +39 -4
  79. package/schema/schema.js +2 -0
  80. package/scripts/custom_compiler.js +8 -10
  81. package/scripts/custom_graphql.js +45 -10
  82. package/scripts/read_schema.js +6 -108
  83. package/testutils/builder.d.ts +6 -3
  84. package/testutils/builder.js +31 -15
  85. package/testutils/db/test_db.d.ts +16 -8
  86. package/testutils/db/test_db.js +65 -9
  87. package/testutils/db_mock.js +5 -5
  88. package/testutils/ent-graphql-tests/index.d.ts +1 -0
  89. package/testutils/ent-graphql-tests/index.js +13 -13
  90. package/testutils/fake_comms.d.ts +1 -0
  91. package/testutils/fake_comms.js +4 -0
  92. package/testutils/fake_data/const.d.ts +5 -1
  93. package/testutils/fake_data/const.js +19 -1
  94. package/testutils/fake_data/events_query.d.ts +16 -11
  95. package/testutils/fake_data/events_query.js +15 -0
  96. package/testutils/fake_data/fake_contact.js +9 -9
  97. package/testutils/fake_data/fake_event.js +14 -14
  98. package/testutils/fake_data/fake_user.js +12 -10
  99. package/testutils/fake_data/test_helpers.d.ts +5 -1
  100. package/testutils/fake_data/test_helpers.js +49 -16
  101. package/testutils/fake_data/user_query.d.ts +25 -9
  102. package/testutils/fake_data/user_query.js +52 -5
  103. package/testutils/parse_sql.js +19 -3
  104. package/testutils/write.js +6 -6
@@ -1,5 +1,5 @@
1
- import { ID, Ent, Viewer, EdgeQueryableDataOptions, Data } from "../base";
2
- export interface EdgeQuery<T extends Ent, TEdge extends Data> {
1
+ import { ID, Ent, Viewer, EdgeQueryableDataOptions, Data, PrivacyPolicy } from "../base";
2
+ export interface EdgeQuery<TSource extends Ent, TDest extends Ent, TEdge extends Data> {
3
3
  queryEdges(): Promise<TEdge[]>;
4
4
  queryAllEdges(): Promise<Map<ID, TEdge[]>>;
5
5
  queryIDs(): Promise<ID[]>;
@@ -8,13 +8,15 @@ export interface EdgeQuery<T extends Ent, TEdge extends Data> {
8
8
  queryAllCount(): Promise<Map<ID, number>>;
9
9
  queryRawCount(): Promise<number>;
10
10
  queryAllRawCount(): Promise<Map<ID, number>>;
11
- queryEnts(): Promise<T[]>;
12
- queryAllEnts(): Promise<Map<ID, T[]>>;
13
- first(n: number, after?: string): EdgeQuery<T, TEdge>;
14
- last(n: number, before?: string): EdgeQuery<T, TEdge>;
11
+ queryEnts(): Promise<TDest[]>;
12
+ queryAllEnts(): Promise<Map<ID, TDest[]>>;
13
+ first(n: number, after?: string): EdgeQuery<TSource, TDest, TEdge>;
14
+ last(n: number, before?: string): EdgeQuery<TSource, TDest, TEdge>;
15
15
  paginationInfo(): Map<ID, PaginationInfo>;
16
16
  getCursor(row: TEdge): string;
17
17
  dataToID(edge: TEdge): ID;
18
+ getPrivacyPolicy(): PrivacyPolicy;
19
+ sourceEnt(id: ID): Promise<Ent | null>;
18
20
  }
19
21
  export interface EdgeQueryFilter<T extends Data> {
20
22
  filter?(id: ID, edges: T[]): T[];
@@ -27,7 +29,7 @@ export interface PaginationInfo {
27
29
  startCursor: string;
28
30
  endCursor: string;
29
31
  }
30
- export declare abstract class BaseEdgeQuery<TDest extends Ent, TEdge extends Data> {
32
+ export declare abstract class BaseEdgeQuery<TSource extends Ent, TDest extends Ent, TEdge extends Data> implements EdgeQuery<TSource, TDest, TEdge> {
31
33
  viewer: Viewer;
32
34
  private sortCol;
33
35
  private filters;
@@ -35,11 +37,18 @@ export declare abstract class BaseEdgeQuery<TDest extends Ent, TEdge extends Dat
35
37
  protected edges: Map<ID, TEdge[]>;
36
38
  private pagination;
37
39
  private memoizedloadEdges;
40
+ protected genIDInfosToFetch: () => Promise<IDInfo[]>;
41
+ private idMap;
42
+ private idsToFetch;
38
43
  constructor(viewer: Viewer, sortCol: string);
44
+ getPrivacyPolicy(): PrivacyPolicy;
45
+ abstract sourceEnt(id: ID): Promise<Ent | null>;
39
46
  first(n: number, after?: string): this;
40
47
  last(n: number, before?: string): this;
41
48
  private querySingleEdge;
42
49
  readonly queryEdges: () => Promise<TEdge[]>;
50
+ abstract queryRawCount(): Promise<number>;
51
+ abstract queryAllRawCount(): Promise<Map<ID, number>>;
43
52
  readonly queryAllEdges: () => Promise<Map<ID, TEdge[]>>;
44
53
  abstract dataToID(edge: TEdge): ID;
45
54
  readonly queryIDs: () => Promise<ID[]>;
@@ -52,7 +61,14 @@ export declare abstract class BaseEdgeQuery<TDest extends Ent, TEdge extends Dat
52
61
  paginationInfo(): Map<ID, PaginationInfo>;
53
62
  private assertQueryDispatched;
54
63
  private assertQueryNotDispatched;
55
- protected abstract loadRawData(options: EdgeQueryableDataOptions): Promise<void>;
64
+ protected abstract loadRawIDs(addID: (src: ID | TSource) => void): Promise<void>;
65
+ protected abstract loadRawData(infos: IDInfo[], options: EdgeQueryableDataOptions): Promise<void>;
66
+ private addID;
67
+ protected genIDInfosToFetchImpl(): Promise<IDInfo[]>;
56
68
  private loadEdges;
57
69
  getCursor(row: TEdge): string;
58
70
  }
71
+ export interface IDInfo {
72
+ id: ID;
73
+ invalidated?: boolean;
74
+ }
@@ -26,6 +26,7 @@ exports.BaseEdgeQuery = void 0;
26
26
  const ent_1 = require("../ent");
27
27
  const clause = __importStar(require("../clause"));
28
28
  const memoizee_1 = __importDefault(require("memoizee"));
29
+ const privacy_1 = require("../privacy");
29
30
  // TODO can we generalize EdgeQuery to support any clause
30
31
  function assertPositive(n) {
31
32
  if (n < 0) {
@@ -173,6 +174,8 @@ class BaseEdgeQuery {
173
174
  this.filters = [];
174
175
  this.edges = new Map();
175
176
  this.pagination = new Map();
177
+ this.idMap = new Map();
178
+ this.idsToFetch = [];
176
179
  // this is basically just raw rows
177
180
  this.queryEdges = async () => {
178
181
  return await this.querySingleEdge("queryEdges");
@@ -223,7 +226,12 @@ class BaseEdgeQuery {
223
226
  await Promise.all(promises);
224
227
  return results;
225
228
  };
226
- this.memoizedloadEdges = memoizee_1.default(this.loadEdges.bind(this));
229
+ this.memoizedloadEdges = (0, memoizee_1.default)(this.loadEdges.bind(this));
230
+ this.genIDInfosToFetch = (0, memoizee_1.default)(this.genIDInfosToFetchImpl.bind(this));
231
+ }
232
+ getPrivacyPolicy() {
233
+ // default PrivacyPolicy is always allow. nothing to do here
234
+ return privacy_1.AlwaysAllowPrivacyPolicy;
227
235
  }
228
236
  first(n, after) {
229
237
  this.assertQueryNotDispatched("first");
@@ -269,9 +277,23 @@ class BaseEdgeQuery {
269
277
  throw new Error(`cannot call ${str} after query is dispatched`);
270
278
  }
271
279
  }
280
+ addID(id) {
281
+ if (typeof id === "object") {
282
+ this.idMap.set(id.id, id);
283
+ this.idsToFetch.push(id.id);
284
+ }
285
+ else {
286
+ this.idsToFetch.push(id);
287
+ }
288
+ }
289
+ async genIDInfosToFetchImpl() {
290
+ await this.loadRawIDs(this.addID.bind(this));
291
+ return applyPrivacyPolicyForEdgeQ(this.viewer, this, this.idsToFetch, this.idMap);
292
+ }
272
293
  async loadEdges() {
273
- // if no filter, we add the firstN filter to ensure we get pagination info
294
+ const idsInfo = await this.genIDInfosToFetch();
274
295
  if (!this.filters.length) {
296
+ // if no filter, we add the firstN filter to ensure we get pagination info
275
297
  this.first(ent_1.DefaultLimit);
276
298
  }
277
299
  let options = {};
@@ -283,7 +305,7 @@ class BaseEdgeQuery {
283
305
  options = filter.query(options);
284
306
  }
285
307
  });
286
- await this.loadRawData(options);
308
+ await this.loadRawData(idsInfo, options);
287
309
  // no filters. nothing to do here.
288
310
  if (!this.filters.length) {
289
311
  return this.edges;
@@ -307,7 +329,7 @@ class BaseEdgeQuery {
307
329
  return this.edges;
308
330
  }
309
331
  getCursor(row) {
310
- return ent_1.getCursor({
332
+ return (0, ent_1.getCursor)({
311
333
  row,
312
334
  col: this.sortCol,
313
335
  conv: (datum) => {
@@ -324,3 +346,18 @@ class BaseEdgeQuery {
324
346
  }
325
347
  }
326
348
  exports.BaseEdgeQuery = BaseEdgeQuery;
349
+ async function applyPrivacyPolicyForEdgeQ(viewer, edgeQ, ids, map) {
350
+ const result = [];
351
+ await Promise.all(ids.map(async (id) => {
352
+ let ent = map.get(id);
353
+ if (!ent) {
354
+ ent = await edgeQ.sourceEnt(id);
355
+ }
356
+ const r = await (0, privacy_1.applyPrivacyPolicy)(viewer, edgeQ.getPrivacyPolicy(), ent || undefined);
357
+ result.push({
358
+ id,
359
+ invalidated: !r,
360
+ });
361
+ }));
362
+ return result;
363
+ }
@@ -31,8 +31,8 @@ function assocTests() {
31
31
  describe("custom edge", () => {
32
32
  let user1, user2;
33
33
  beforeEach(async () => {
34
- user2 = await test_helpers_1.createTestUser();
35
- const builder = index_1.getUserBuilder(new viewer_1.LoggedOutViewer(), test_helpers_1.getUserInput());
34
+ user2 = await (0, test_helpers_1.createTestUser)();
35
+ const builder = (0, index_1.getUserBuilder)(new viewer_1.LoggedOutViewer(), (0, test_helpers_1.getUserInput)());
36
36
  builder.orchestrator.addOutboundEdge(user2.id, index_1.EdgeType.UserToCustomEdge, index_1.NodeType.FakeUser);
37
37
  await builder.saveX();
38
38
  user1 = await builder.editedEntX();
@@ -92,6 +92,8 @@ function assocTests() {
92
92
  expect(query.qs?.whereClause).toBe(`id1 = $1 AND edge_type = $2`);
93
93
  }
94
94
  }
95
+ // TODO need to test multi-ids with id1s that aren't visible...
96
+ // so 2 user's friend requests at the same time
95
97
  class MultiIDsTestQueryFilter {
96
98
  constructor(filter, ents, limit) {
97
99
  this.filter = filter;
@@ -101,9 +103,9 @@ function assocTests() {
101
103
  }
102
104
  async beforeEach() {
103
105
  let [user1, user2, user3] = await Promise.all([
104
- test_helpers_1.createAllContacts({ firstName: "Jon", lastName: "Snow" }),
105
- test_helpers_1.createAllContacts({ firstName: "Aegon", lastName: "Targaryen" }),
106
- test_helpers_1.createAllContacts({ firstName: "Ned", lastName: "Stark" }),
106
+ (0, test_helpers_1.createAllContacts)({ firstName: "Jon", lastName: "Snow" }),
107
+ (0, test_helpers_1.createAllContacts)({ firstName: "Aegon", lastName: "Targaryen" }),
108
+ (0, test_helpers_1.createAllContacts)({ firstName: "Ned", lastName: "Stark" }),
107
109
  ]);
108
110
  // modify contacts as needed
109
111
  user1[1] = this.ents(user1[1]);
@@ -156,7 +158,7 @@ function assocTests() {
156
158
  expect(edgesMap.size).toBe(this.dataz.length);
157
159
  for (let i = 0; i < this.dataz.length; i++) {
158
160
  let data = this.dataz[i];
159
- test_helpers_1.verifyUserToContactEdges(data[0], edgesMap.get(data[0].id) || [], data[1]);
161
+ (0, test_helpers_1.verifyUserToContactEdges)(data[0], edgesMap.get(data[0].id) || [], data[1]);
160
162
  }
161
163
  verifyQuery({
162
164
  length: this.dataz.length,
@@ -170,14 +172,14 @@ function assocTests() {
170
172
  expect(entsMap.size).toBe(this.dataz.length);
171
173
  for (let i = 0; i < this.dataz.length; i++) {
172
174
  let data = this.dataz[i];
173
- test_helpers_1.verifyUserToContacts(data[0], entsMap.get(data[0].id) || [], []);
175
+ (0, test_helpers_1.verifyUserToContacts)(data[0], entsMap.get(data[0].id) || [], []);
174
176
  }
175
177
  // privacy. only data for the first id is visible in this case
176
178
  const entsMap2 = await this.getQuery(new viewer_1.IDViewer(this.dataz[0][0].id)).queryAllEnts();
177
179
  expect(entsMap2.size).toBe(this.dataz.length);
178
180
  for (let i = 0; i < this.dataz.length; i++) {
179
181
  let data = this.dataz[i];
180
- test_helpers_1.verifyUserToContacts(data[0], entsMap2.get(data[0].id) || [], i == 0 ? data[1] : []);
182
+ (0, test_helpers_1.verifyUserToContacts)(data[0], entsMap2.get(data[0].id) || [], i == 0 ? data[1] : []);
181
183
  }
182
184
  verifyQuery({
183
185
  // extra query for the nodes
@@ -270,13 +272,13 @@ function assocTests() {
270
272
  this.lastHopFilter = lastHopFilter;
271
273
  }
272
274
  async beforeEach() {
273
- this.user = await test_helpers_1.createTestUser();
274
- this.event = await test_helpers_1.createTestEvent(this.user);
275
- this.event2 = await test_helpers_1.createTestEvent(this.user, { title: "Red Wedding" });
275
+ this.user = await (0, test_helpers_1.createTestUser)();
276
+ this.event = await (0, test_helpers_1.createTestEvent)(this.user);
277
+ this.event2 = await (0, test_helpers_1.createTestEvent)(this.user, { title: "Red Wedding" });
276
278
  this.friends = await Promise.all(test_helpers_1.inputs.map(async (input) => {
277
279
  // just to make times deterministic so that tests can consistently work
278
- jest_date_mock_1.advanceBy(100);
279
- const builder = index_1.getUserBuilder(this.user.viewer, test_helpers_1.getUserInput(input));
280
+ (0, jest_date_mock_1.advanceBy)(100);
281
+ const builder = (0, index_1.getUserBuilder)(this.user.viewer, (0, test_helpers_1.getUserInput)(input));
280
282
  // add edge from user to contact
281
283
  builder.orchestrator.addOutboundEdge(this.user.id, index_1.EdgeType.UserToFriends, index_1.NodeType.FakeUser, {
282
284
  time: new Date(), // set time to advanceBy time
@@ -425,5 +427,247 @@ function assocTests() {
425
427
  await filter.testEnts();
426
428
  });
427
429
  });
430
+ class PolymorphicID2sTestQueryFilter {
431
+ constructor(filter, ents, limit) {
432
+ this.filter = filter;
433
+ this.ents = ents;
434
+ this.limit = limit;
435
+ this.users = [];
436
+ this.events = [];
437
+ }
438
+ async beforeEach() {
439
+ this.users = [];
440
+ this.events = [];
441
+ this.user = await (0, test_helpers_1.createTestUser)();
442
+ for (let i = 0; i < 5; i++) {
443
+ (0, jest_date_mock_1.advanceBy)(100);
444
+ const builder = (0, index_1.getUserBuilder)(this.user.viewer, (0, test_helpers_1.getUserInput)());
445
+ builder.orchestrator.addOutboundEdge(this.user.id, index_1.EdgeType.ObjectToFollowedUsers, index_1.NodeType.FakeUser);
446
+ await builder.saveX();
447
+ const user2 = await builder.editedEntX();
448
+ this.users.push(user2);
449
+ }
450
+ for (let i = 0; i < 5; i++) {
451
+ (0, jest_date_mock_1.advanceBy)(100);
452
+ const builder = (0, index_1.getEventBuilder)(this.user.viewer, (0, test_helpers_1.getEventInput)(this.user));
453
+ builder.orchestrator.addOutboundEdge(this.user.id, index_1.EdgeType.ObjectToFollowedUsers, index_1.NodeType.FakeUser);
454
+ await builder.saveX();
455
+ const event = await builder.editedEntX();
456
+ this.events.push(event);
457
+ }
458
+ //order is users, then events
459
+ this.expCount = this.ents([...this.users, ...this.events]).length;
460
+ db_mock_1.QueryRecorder.clearQueries();
461
+ }
462
+ getQuery(viewer) {
463
+ return this.filter(index_1.UserToFollowingQuery.query(viewer || new viewer_1.IDViewer(this.user.id), this.user));
464
+ }
465
+ async testIDs() {
466
+ const ids = await this.getQuery().queryIDs();
467
+ expect(ids.length).toBe(this.expCount);
468
+ const expIDs = this.users
469
+ .map((user) => user.id)
470
+ .concat(this.events.map((event) => event.id))
471
+ .reverse();
472
+ expect(expIDs).toEqual(ids);
473
+ verifyQuery({
474
+ length: 1,
475
+ numQueries: 1,
476
+ limit: this.limit || ent_1.DefaultLimit,
477
+ });
478
+ }
479
+ // rawCount isn't affected by filters...
480
+ async testRawCount() {
481
+ const count = await this.getQuery().queryRawCount();
482
+ expect(count).toBe(this.expCount);
483
+ verifyCountQuery({ numQueries: 1, length: 1 });
484
+ }
485
+ async testCount() {
486
+ const count = await this.getQuery().queryCount();
487
+ expect(count).toBe(this.expCount);
488
+ verifyQuery({
489
+ length: 1,
490
+ numQueries: 1,
491
+ limit: this.limit || ent_1.DefaultLimit,
492
+ });
493
+ }
494
+ async testEdges() {
495
+ const edges = await this.getQuery().queryEdges();
496
+ expect(edges.length).toBe(this.expCount);
497
+ let userCount = 0;
498
+ let eventCount = 0;
499
+ edges.forEach((edge) => {
500
+ if (edge.id2Type === index_1.NodeType.FakeEvent) {
501
+ eventCount++;
502
+ }
503
+ if (edge.id2Type === index_1.NodeType.FakeUser) {
504
+ userCount++;
505
+ }
506
+ });
507
+ expect(userCount).toBe(this.expCount / 2);
508
+ expect(eventCount).toBe(this.expCount / 2);
509
+ verifyQuery({
510
+ length: 1,
511
+ numQueries: 1,
512
+ limit: this.limit || ent_1.DefaultLimit,
513
+ });
514
+ }
515
+ async testEnts() {
516
+ // privacy...
517
+ const ents = await this.getQuery().queryEnts();
518
+ expect(ents.length).toBe(this.expCount);
519
+ let userCount = 0;
520
+ let eventCount = 0;
521
+ ents.forEach((ent) => {
522
+ if (ent instanceof index_1.FakeEvent) {
523
+ eventCount++;
524
+ }
525
+ if (ent instanceof index_1.FakeUser) {
526
+ userCount++;
527
+ }
528
+ });
529
+ expect(userCount).toBe(this.expCount / 2);
530
+ expect(eventCount).toBe(this.expCount / 2);
531
+ // when doing privacy checks, hard to say what will be fetched
532
+ // verifyQuery({
533
+ // // 1 for edges, 1 for users, 1 for events
534
+ // length: 3,
535
+ // numQueries: 3,
536
+ // limit: this.limit || DefaultLimit,
537
+ // });
538
+ }
539
+ }
540
+ describe("polymorphic id2s", () => {
541
+ const filter = new PolymorphicID2sTestQueryFilter((q) => {
542
+ // no filters
543
+ return q;
544
+ }, (ents) => {
545
+ // nothing to do here
546
+ // reverse because edges are most recent first
547
+ return ents.reverse();
548
+ });
549
+ // TODO not working when it's a beforeAll
550
+ // working with beforeEach but we should only need to create this data once
551
+ beforeEach(async () => {
552
+ await filter.beforeEach();
553
+ });
554
+ test("ids", async () => {
555
+ await filter.testIDs();
556
+ });
557
+ test("rawCount", async () => {
558
+ await filter.testRawCount();
559
+ });
560
+ test("count", async () => {
561
+ await filter.testCount();
562
+ });
563
+ test("edges", async () => {
564
+ await filter.testEdges();
565
+ });
566
+ test("ents", async () => {
567
+ await filter.testEnts();
568
+ });
569
+ });
570
+ describe("privacy", () => {
571
+ let user;
572
+ let friendRequests;
573
+ let user2;
574
+ beforeEach(async () => {
575
+ [user, friendRequests] = await (0, test_helpers_1.createUserPlusFriendRequests)();
576
+ user2 = await (0, test_helpers_1.createTestUser)();
577
+ });
578
+ function getQuery(viewer) {
579
+ return index_1.UserToIncomingFriendRequestsQuery.query(viewer, user.id);
580
+ }
581
+ test("ids", async () => {
582
+ const ids = await getQuery(user2.viewer).queryIDs();
583
+ expect(ids.length).toBe(0);
584
+ const idsFromUser = await getQuery(user.viewer).queryIDs();
585
+ expect(idsFromUser.length).toBe(friendRequests.length);
586
+ });
587
+ test("count", async () => {
588
+ const count = await getQuery(user2.viewer).queryCount();
589
+ expect(count).toBe(0);
590
+ const countFromUser = await getQuery(user.viewer).queryCount();
591
+ expect(countFromUser).toBe(friendRequests.length);
592
+ });
593
+ test("rawCount", async () => {
594
+ const rawCount = await getQuery(user2.viewer).queryRawCount();
595
+ expect(rawCount).toBe(0);
596
+ const rawCountFromUser = await getQuery(user.viewer).queryRawCount();
597
+ expect(rawCountFromUser).toBe(friendRequests.length);
598
+ });
599
+ test("edges", async () => {
600
+ const edges = await getQuery(user2.viewer).queryEdges();
601
+ expect(edges.length).toBe(0);
602
+ const edgesFromUser = await getQuery(user.viewer).queryEdges();
603
+ expect(edgesFromUser.length).toBe(friendRequests.length);
604
+ });
605
+ test("ents", async () => {
606
+ const ents = await getQuery(user2.viewer).queryEnts();
607
+ expect(ents.length).toBe(0);
608
+ const entsFromUser = await getQuery(user.viewer).queryEnts();
609
+ expect(entsFromUser.length).toBe(0);
610
+ const entsFromUserVCToken = await getQuery(new index_1.ViewerWithAccessToken(user.id, {
611
+ tokens: {
612
+ allow_incoming_friend_request: true,
613
+ },
614
+ })).queryEnts();
615
+ expect(entsFromUserVCToken.length).toBe(friendRequests.length);
616
+ });
617
+ });
618
+ describe("multi-ids privacy", () => {
619
+ let user;
620
+ let friendRequests;
621
+ let user2;
622
+ let friendRequests2;
623
+ beforeEach(async () => {
624
+ [user, friendRequests] = await (0, test_helpers_1.createUserPlusFriendRequests)();
625
+ [user2, friendRequests2] = await (0, test_helpers_1.createUserPlusFriendRequests)();
626
+ });
627
+ function getQuery(viewer) {
628
+ return index_1.UserToIncomingFriendRequestsQuery.query(viewer || user.viewer, [
629
+ user.id,
630
+ user2.id,
631
+ ]);
632
+ }
633
+ test("ids", async () => {
634
+ const idsMap = await getQuery().queryAllIDs();
635
+ expect(idsMap.size).toBe(2);
636
+ expect(idsMap.get(user.id)?.length).toBe(friendRequests.length);
637
+ expect(idsMap.get(user2.id)?.length).toBe(0);
638
+ });
639
+ test("count", async () => {
640
+ const countMap = await getQuery().queryAllCount();
641
+ expect(countMap.size).toBe(2);
642
+ expect(countMap.get(user.id)).toBe(friendRequests.length);
643
+ expect(countMap.get(user2.id)).toBe(0);
644
+ });
645
+ test("count", async () => {
646
+ const countMap = await getQuery().queryAllRawCount();
647
+ expect(countMap.size).toBe(2);
648
+ expect(countMap.get(user.id)).toBe(friendRequests.length);
649
+ expect(countMap.get(user2.id)).toBe(0);
650
+ });
651
+ test("edges", async () => {
652
+ const edgesMap = await getQuery().queryAllEdges();
653
+ expect(edgesMap.size).toBe(2);
654
+ expect(edgesMap.get(user.id)?.length).toBe(friendRequests.length);
655
+ expect(edgesMap.get(user2.id)?.length).toBe(0);
656
+ });
657
+ test("ents", async () => {
658
+ const entsMap = await getQuery().queryAllEnts();
659
+ expect(entsMap.size).toBe(2);
660
+ expect(entsMap.get(user.id)?.length).toBe(0);
661
+ expect(entsMap.get(user2.id)?.length).toBe(0);
662
+ const entsMapFromUserVCToken = await getQuery(new index_1.ViewerWithAccessToken(user.id, {
663
+ tokens: {
664
+ allow_incoming_friend_request: true,
665
+ },
666
+ })).queryAllEnts();
667
+ expect(entsMapFromUserVCToken.size).toBe(2);
668
+ expect(entsMapFromUserVCToken.get(user.id)?.length).toBe(friendRequests.length);
669
+ expect(entsMapFromUserVCToken.get(user2.id)?.length).toBe(0);
670
+ });
671
+ });
428
672
  }
429
673
  exports.assocTests = assocTests;
@@ -2,7 +2,7 @@ import { Data, Viewer } from "../base";
2
2
  import { FakeUser, FakeContact } from "../../testutils/fake_data/index";
3
3
  import { EdgeQuery } from "./query";
4
4
  interface options<TData extends Data> {
5
- newQuery: (v: Viewer, user: FakeUser) => EdgeQuery<FakeContact, TData>;
5
+ newQuery: (v: Viewer, user: FakeUser) => EdgeQuery<FakeUser, FakeContact, TData>;
6
6
  tableName: string;
7
7
  entsLength?: number;
8
8
  where: string;
@@ -20,7 +20,7 @@ class TestQueryFilter {
20
20
  }
21
21
  async beforeEach() {
22
22
  // console.log("sss");
23
- [this.user, this.allContacts] = await test_helpers_1.createAllContacts();
23
+ [this.user, this.allContacts] = await (0, test_helpers_1.createAllContacts)();
24
24
  // console.log(this.user, this.contacts);
25
25
  // this.allContacts = this.allContacts.reverse();
26
26
  this.filteredContacts = this.ents(this.allContacts);
@@ -59,10 +59,10 @@ class TestQueryFilter {
59
59
  const q = this.getQuery();
60
60
  // TODO sad not generic enough
61
61
  if (q instanceof index_1.UserToContactsFkeyQuery) {
62
- test_helpers_1.verifyUserToContactRawData(this.user, edges, this.filteredContacts);
62
+ (0, test_helpers_1.verifyUserToContactRawData)(this.user, edges, this.filteredContacts);
63
63
  }
64
64
  else {
65
- test_helpers_1.verifyUserToContactEdges(this.user, edges, this.filteredContacts);
65
+ (0, test_helpers_1.verifyUserToContactEdges)(this.user, edges, this.filteredContacts);
66
66
  }
67
67
  }
68
68
  async testEnts() {
@@ -70,7 +70,7 @@ class TestQueryFilter {
70
70
  this.verifyEnts(entsMap);
71
71
  }
72
72
  verifyEnts(ents) {
73
- test_helpers_1.verifyUserToContacts(this.user, ents, this.filteredContacts);
73
+ (0, test_helpers_1.verifyUserToContacts)(this.user, ents, this.filteredContacts);
74
74
  }
75
75
  async testAll() {
76
76
  const query = this.getQuery(new viewer_1.IDViewer(this.user.id));
@@ -156,7 +156,7 @@ const commonTests = (opts) => {
156
156
  // based on getContactBuilder
157
157
  // so regardless of if we're doing assoc or custom queries, we can get the time
158
158
  // from the created_at field
159
- return ent_1.getCursor({
159
+ return (0, ent_1.getCursor)({
160
160
  row: contacts[idx],
161
161
  col: "createdAt",
162
162
  conv: (t) => {
@@ -174,20 +174,20 @@ const commonTests = (opts) => {
174
174
  let tdb;
175
175
  if (opts.sqlite) {
176
176
  // tableName just to make it unique
177
- test_db_1.setupSqlite(`sqlite:///shared_test+${opts.tableName}.db`, test_helpers_1.tempDBTables);
177
+ (0, test_db_1.setupSqlite)(`sqlite:///shared_test+${opts.tableName}.db`, test_helpers_1.tempDBTables);
178
178
  }
179
179
  beforeAll(async () => {
180
180
  // want error on by default in tests?
181
- logger_1.setLogLevels(["error", "warn", "info"]);
181
+ (0, logger_1.setLogLevels)(["error", "warn", "info"]);
182
182
  if (opts.livePostgresDB) {
183
- tdb = await test_helpers_1.setupTempDB();
183
+ tdb = await (0, test_helpers_1.setupTempDB)();
184
184
  }
185
185
  });
186
186
  beforeEach(async () => {
187
187
  if (opts.livePostgresDB) {
188
188
  return;
189
189
  }
190
- await test_helpers_1.createEdges();
190
+ await (0, test_helpers_1.createEdges)();
191
191
  });
192
192
  afterAll(async () => {
193
193
  if (opts.livePostgresDB && tdb) {
@@ -338,7 +338,7 @@ const commonTests = (opts) => {
338
338
  });
339
339
  });
340
340
  test("first. after each cursor", async () => {
341
- let [user, contacts] = await test_helpers_1.createAllContacts();
341
+ let [user, contacts] = await (0, test_helpers_1.createAllContacts)();
342
342
  contacts = contacts.reverse();
343
343
  const edges = await opts.newQuery(getViewer(), user).queryEdges();
344
344
  let query;
@@ -406,7 +406,7 @@ const commonTests = (opts) => {
406
406
  });
407
407
  });
408
408
  test("last. before each cursor", async () => {
409
- let [user, contacts] = await test_helpers_1.createAllContacts();
409
+ let [user, contacts] = await (0, test_helpers_1.createAllContacts)();
410
410
  contacts = contacts.reverse();
411
411
  const edges = await opts.newQuery(getViewer(), user).queryEdges();
412
412
  let query;
package/core/viewer.js CHANGED
@@ -4,6 +4,7 @@ exports.IDViewer = exports.LoggedOutViewer = void 0;
4
4
  class LoggedOutViewer {
5
5
  constructor(context) {
6
6
  this.context = context;
7
+ this.viewerID = null;
7
8
  }
8
9
  async viewer() {
9
10
  return null;
@@ -5,18 +5,19 @@ const graphql_1 = require("graphql");
5
5
  const node_1 = require("./node");
6
6
  const edge_1 = require("./edge");
7
7
  const page_info_1 = require("../query/page_info");
8
+ // NB: if this changes, need to update renderer.go also
8
9
  exports.GraphQLConnectionInterface = new graphql_1.GraphQLInterfaceType({
9
10
  name: "Connection",
10
11
  description: "connection interface",
11
12
  fields: () => ({
12
13
  edges: {
13
- type: graphql_1.GraphQLNonNull(graphql_1.GraphQLList(graphql_1.GraphQLNonNull(edge_1.GraphQLEdgeInterface))),
14
+ type: (0, graphql_1.GraphQLNonNull)((0, graphql_1.GraphQLList)((0, graphql_1.GraphQLNonNull)(edge_1.GraphQLEdgeInterface))),
14
15
  },
15
16
  nodes: {
16
- type: graphql_1.GraphQLNonNull(graphql_1.GraphQLList(graphql_1.GraphQLNonNull(node_1.GraphQLNodeInterface))),
17
+ type: (0, graphql_1.GraphQLNonNull)((0, graphql_1.GraphQLList)((0, graphql_1.GraphQLNonNull)(node_1.GraphQLNodeInterface))),
17
18
  },
18
19
  pageInfo: {
19
- type: graphql_1.GraphQLNonNull(page_info_1.GraphQLPageInfo),
20
+ type: (0, graphql_1.GraphQLNonNull)(page_info_1.GraphQLPageInfo),
20
21
  },
21
22
  }),
22
23
  });
@@ -3,15 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GraphQLEdgeInterface = void 0;
4
4
  const graphql_1 = require("graphql");
5
5
  const node_1 = require("./node");
6
+ // NB: if this changes, need to update renderer.go also
6
7
  exports.GraphQLEdgeInterface = new graphql_1.GraphQLInterfaceType({
7
8
  name: "Edge",
8
9
  description: "edge interface",
9
10
  fields: () => ({
10
11
  node: {
11
- type: graphql_1.GraphQLNonNull(node_1.GraphQLNodeInterface),
12
+ type: (0, graphql_1.GraphQLNonNull)(node_1.GraphQLNodeInterface),
12
13
  },
13
14
  cursor: {
14
- type: graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
15
+ type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLString),
15
16
  },
16
17
  }),
17
18
  });
@@ -2,12 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GraphQLNodeInterface = void 0;
4
4
  const graphql_1 = require("graphql");
5
+ // NB: if this changes, need to update renderer.go also
5
6
  exports.GraphQLNodeInterface = new graphql_1.GraphQLInterfaceType({
6
7
  name: "Node",
7
8
  description: "node interface",
8
9
  fields: () => ({
9
10
  id: {
10
- type: graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
11
+ type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLID),
11
12
  },
12
13
  }),
13
14
  });
@@ -8,6 +8,7 @@ export interface CustomType {
8
8
  importPath: string;
9
9
  tsType?: string;
10
10
  tsImportPath?: string;
11
+ [x: string]: any;
11
12
  }
12
13
  declare type Type = GraphQLScalarType | ClassType | string | CustomType;
13
14
  export declare type GraphQLConnection<T> = {
@@ -81,6 +82,7 @@ declare enum NullableResult {
81
82
  CONTENTS_AND_LIST = "contentsAndList",
82
83
  ITEM = "true"
83
84
  }
85
+ export declare const addCustomType: (type: CustomType) => void;
84
86
  export declare class GQLCapture {
85
87
  private static enabled;
86
88
  static enable(enabled: boolean): void;