@snowtop/ent 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/config.d.ts CHANGED
@@ -12,6 +12,9 @@ interface CodegenConfig {
12
12
  defaultEntPolicy?: PrivacyConfig;
13
13
  defaultActionPolicy?: PrivacyConfig;
14
14
  prettier?: PrettierConfig;
15
+ relativeImports?: boolean;
16
+ disableGraphQLRoot?: boolean;
17
+ generatedHeader?: string;
15
18
  }
16
19
  interface PrettierConfig {
17
20
  custom?: boolean;
@@ -4,6 +4,7 @@ import { AssocEdgeCountLoaderFactory } from "../loaders/assoc_count_loader";
4
4
  import { AssocEdgeLoaderFactory } from "../loaders/assoc_edge_loader";
5
5
  import { EdgeQuery, BaseEdgeQuery } from "./query";
6
6
  export declare type EdgeQuerySource<T extends Ent> = T | T[] | ID | ID[] | EdgeQuery<T, AssocEdge>;
7
+ declare type loaderOptionsFunc = (type: string) => LoadEntOptions<Ent>;
7
8
  export declare class AssocEdgeQueryBase<TSource extends Ent, TDest extends Ent, TEdge extends AssocEdge> extends BaseEdgeQuery<TDest, TEdge> {
8
9
  viewer: Viewer;
9
10
  src: EdgeQuerySource<TSource>;
@@ -12,7 +13,7 @@ export declare class AssocEdgeQueryBase<TSource extends Ent, TDest extends Ent,
12
13
  private options;
13
14
  private idsResolved;
14
15
  private resolvedIDs;
15
- constructor(viewer: Viewer, src: EdgeQuerySource<TSource>, countLoaderFactory: AssocEdgeCountLoaderFactory, dataLoaderFactory: AssocEdgeLoaderFactory<TEdge>, options: LoadEntOptions<TDest>);
16
+ constructor(viewer: Viewer, src: EdgeQuerySource<TSource>, countLoaderFactory: AssocEdgeCountLoaderFactory, dataLoaderFactory: AssocEdgeLoaderFactory<TEdge>, options: LoadEntOptions<TDest> | loaderOptionsFunc);
16
17
  private resolveIDs;
17
18
  private isEdgeQuery;
18
19
  private addID;
@@ -28,3 +29,4 @@ export declare class AssocEdgeQueryBase<TSource extends Ent, TDest extends Ent,
28
29
  export interface EdgeQueryCtr<T extends Ent, TEdge extends AssocEdge> {
29
30
  new (viewer: Viewer, src: EdgeQuerySource<T>): EdgeQuery<T, TEdge>;
30
31
  }
32
+ export {};
@@ -4,7 +4,10 @@ exports.AssocEdgeQueryBase = void 0;
4
4
  const ent_1 = require("../ent");
5
5
  const query_1 = require("./query");
6
6
  class AssocEdgeQueryBase extends query_1.BaseEdgeQuery {
7
- constructor(viewer, src, countLoaderFactory, dataLoaderFactory, options) {
7
+ constructor(viewer, src, countLoaderFactory, dataLoaderFactory,
8
+ // if function, it's a polymorphic edge and need to provide
9
+ // a function that goes from edgeType to LoadEntOptions
10
+ options) {
8
11
  super(viewer, "time");
9
12
  this.viewer = viewer;
10
13
  this.src = src;
@@ -70,6 +73,35 @@ class AssocEdgeQueryBase extends query_1.BaseEdgeQuery {
70
73
  return results;
71
74
  }
72
75
  async loadEntsFromEdges(id, edges) {
76
+ if (typeof this.options === "function") {
77
+ const m = new Map();
78
+ for (const edge of edges) {
79
+ const nodeType = edge.id2Type;
80
+ let data = m.get(nodeType);
81
+ if (data === undefined) {
82
+ const opts = this.options(nodeType);
83
+ if (opts === undefined) {
84
+ throw new Error(`getLoaderOptions returned undefined for type ${nodeType}`);
85
+ }
86
+ data = {
87
+ ids: [],
88
+ options: opts,
89
+ };
90
+ }
91
+ data.ids.push(edge.id2);
92
+ m.set(nodeType, data);
93
+ }
94
+ let promises = [];
95
+ for (const [_, value] of m) {
96
+ promises.push((0, ent_1.loadEnts)(this.viewer, value.options, ...value.ids));
97
+ }
98
+ const entss = await Promise.all(promises);
99
+ const r = [];
100
+ for (const ents of entss) {
101
+ r.push(...ents);
102
+ }
103
+ return r;
104
+ }
73
105
  const ids = edges.map((edge) => edge.id2);
74
106
  return await (0, ent_1.loadEnts)(this.viewer, this.options, ...ids);
75
107
  }
@@ -425,5 +425,145 @@ function assocTests() {
425
425
  await filter.testEnts();
426
426
  });
427
427
  });
428
+ class PolymorphicID2sTestQueryFilter {
429
+ constructor(filter, ents, limit) {
430
+ this.filter = filter;
431
+ this.ents = ents;
432
+ this.limit = limit;
433
+ this.users = [];
434
+ this.events = [];
435
+ }
436
+ async beforeEach() {
437
+ this.users = [];
438
+ this.events = [];
439
+ this.user = await (0, test_helpers_1.createTestUser)();
440
+ for (let i = 0; i < 5; i++) {
441
+ (0, jest_date_mock_1.advanceBy)(100);
442
+ const builder = (0, index_1.getUserBuilder)(this.user.viewer, (0, test_helpers_1.getUserInput)());
443
+ builder.orchestrator.addOutboundEdge(this.user.id, index_1.EdgeType.ObjectToFollowedUsers, index_1.NodeType.FakeUser);
444
+ await builder.saveX();
445
+ const user2 = await builder.editedEntX();
446
+ this.users.push(user2);
447
+ }
448
+ for (let i = 0; i < 5; i++) {
449
+ (0, jest_date_mock_1.advanceBy)(100);
450
+ const builder = (0, index_1.getEventBuilder)(this.user.viewer, (0, test_helpers_1.getEventInput)(this.user));
451
+ builder.orchestrator.addOutboundEdge(this.user.id, index_1.EdgeType.ObjectToFollowedUsers, index_1.NodeType.FakeUser);
452
+ await builder.saveX();
453
+ const event = await builder.editedEntX();
454
+ this.events.push(event);
455
+ }
456
+ //order is users, then events
457
+ this.expCount = this.ents([...this.users, ...this.events]).length;
458
+ db_mock_1.QueryRecorder.clearQueries();
459
+ }
460
+ getQuery(viewer) {
461
+ return this.filter(index_1.UserToFollowingQuery.query(viewer || new viewer_1.IDViewer(this.user.id), this.user));
462
+ }
463
+ async testIDs() {
464
+ const ids = await this.getQuery().queryIDs();
465
+ expect(ids.length).toBe(this.expCount);
466
+ const expIDs = this.users
467
+ .map((user) => user.id)
468
+ .concat(this.events.map((event) => event.id))
469
+ .reverse();
470
+ expect(expIDs).toEqual(ids);
471
+ verifyQuery({
472
+ length: 1,
473
+ numQueries: 1,
474
+ limit: this.limit || ent_1.DefaultLimit,
475
+ });
476
+ }
477
+ // rawCount isn't affected by filters...
478
+ async testRawCount() {
479
+ const count = await this.getQuery().queryRawCount();
480
+ expect(count).toBe(this.expCount);
481
+ verifyCountQuery({ numQueries: 1, length: 1 });
482
+ }
483
+ async testCount() {
484
+ const count = await this.getQuery().queryCount();
485
+ expect(count).toBe(this.expCount);
486
+ verifyQuery({
487
+ length: 1,
488
+ numQueries: 1,
489
+ limit: this.limit || ent_1.DefaultLimit,
490
+ });
491
+ }
492
+ async testEdges() {
493
+ const edges = await this.getQuery().queryEdges();
494
+ expect(edges.length).toBe(this.expCount);
495
+ let userCount = 0;
496
+ let eventCount = 0;
497
+ edges.forEach((edge) => {
498
+ if (edge.id2Type === index_1.NodeType.FakeEvent) {
499
+ eventCount++;
500
+ }
501
+ if (edge.id2Type === index_1.NodeType.FakeUser) {
502
+ userCount++;
503
+ }
504
+ });
505
+ expect(userCount).toBe(this.expCount / 2);
506
+ expect(eventCount).toBe(this.expCount / 2);
507
+ verifyQuery({
508
+ length: 1,
509
+ numQueries: 1,
510
+ limit: this.limit || ent_1.DefaultLimit,
511
+ });
512
+ }
513
+ async testEnts() {
514
+ // privacy...
515
+ const ents = await this.getQuery().queryEnts();
516
+ expect(ents.length).toBe(this.expCount);
517
+ let userCount = 0;
518
+ let eventCount = 0;
519
+ ents.forEach((ent) => {
520
+ if (ent instanceof index_1.FakeEvent) {
521
+ eventCount++;
522
+ }
523
+ if (ent instanceof index_1.FakeUser) {
524
+ userCount++;
525
+ }
526
+ });
527
+ expect(userCount).toBe(this.expCount / 2);
528
+ expect(eventCount).toBe(this.expCount / 2);
529
+ // when doing privacy checks, hard to say what will be fetched
530
+ // verifyQuery({
531
+ // // 1 for edges, 1 for users, 1 for events
532
+ // length: 3,
533
+ // numQueries: 3,
534
+ // limit: this.limit || DefaultLimit,
535
+ // });
536
+ }
537
+ }
538
+ describe("polymorphic id2s", () => {
539
+ const filter = new PolymorphicID2sTestQueryFilter((q) => {
540
+ // no filters
541
+ return q;
542
+ }, (ents) => {
543
+ // nothing to do here
544
+ // reverse because edges are most recent first
545
+ return ents.reverse();
546
+ });
547
+ // TODO not working when it's a beforeAll
548
+ // working with beforeEach but we should only need to create this data once
549
+ beforeEach(async () => {
550
+ await filter.beforeEach();
551
+ });
552
+ test("ids", async () => {
553
+ await filter.testIDs();
554
+ });
555
+ test("rawCount", async () => {
556
+ await filter.testRawCount();
557
+ });
558
+ test("count", async () => {
559
+ await filter.testCount();
560
+ });
561
+ test("edges", async () => {
562
+ await filter.testEdges();
563
+ });
564
+ test("ents", async () => {
565
+ await filter.testEnts();
566
+ });
567
+ });
428
568
  }
429
569
  exports.assocTests = assocTests;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -37,6 +37,9 @@
37
37
  "optional": true
38
38
  }
39
39
  },
40
+ "engines": {
41
+ "node": "^16.1.0"
42
+ },
40
43
  "devDependencies": {},
41
44
  "scripts": {},
42
45
  "bin": {
@@ -0,0 +1,41 @@
1
+ import { Schema, AssocEdge, AssocEdgeGroup, Action } from "../schema";
2
+ import { ActionField } from "../schema/schema";
3
+ declare enum NullableResult {
4
+ CONTENTS = "contents",
5
+ CONTENTS_AND_LIST = "contentsAndList",
6
+ ITEM = "true"
7
+ }
8
+ declare type ProcessedActionField = Omit<ActionField, "nullable"> & {
9
+ nullable?: NullableResult;
10
+ };
11
+ declare type ProcessedAssocEdge = Omit<AssocEdge, "actionOnlyFields" | "edgeActions"> & {
12
+ patternName?: string;
13
+ edgeActions?: OutputAction[];
14
+ };
15
+ declare type ProcessedSchema = Omit<Schema, "edges" | "actions" | "edgeGroups"> & {
16
+ actions: OutputAction[];
17
+ assocEdges: ProcessedAssocEdge[];
18
+ assocEdgeGroups: ProcessedAssocEdgeGroup[];
19
+ };
20
+ declare type ProcessedAssocEdgeGroup = Omit<AssocEdgeGroup, "edgeAction"> & {
21
+ edgeAction?: OutputAction;
22
+ };
23
+ declare type OutputAction = Omit<Action, "actionOnlyFields"> & {
24
+ actionOnlyFields?: ProcessedActionField[];
25
+ };
26
+ interface schemasDict {
27
+ [key: string]: ProcessedSchema;
28
+ }
29
+ interface ProcessedPattern {
30
+ name: string;
31
+ assocEdges: ProcessedAssocEdge[];
32
+ }
33
+ interface patternsDict {
34
+ [key: string]: ProcessedPattern;
35
+ }
36
+ interface Result {
37
+ schemas: schemasDict;
38
+ patterns: patternsDict;
39
+ }
40
+ export declare function parseSchema(potentialSchemas: {}): Result;
41
+ export {};
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSchema = void 0;
4
+ function processFields(processedSchema, src) {
5
+ for (const field of src) {
6
+ let f = { ...field };
7
+ f["hasDefaultValueOnCreate"] = field.defaultValueOnCreate != undefined;
8
+ f["hasDefaultValueOnEdit"] = field.defaultValueOnEdit != undefined;
9
+ if (field.polymorphic) {
10
+ // convert boolean into object
11
+ // we keep boolean as an option to keep API simple
12
+ if (typeof field.polymorphic === "boolean") {
13
+ f["polymorphic"] = {};
14
+ }
15
+ else {
16
+ f["polymorphic"] = field.polymorphic;
17
+ }
18
+ }
19
+ processedSchema.fields.push(f);
20
+ }
21
+ }
22
+ function processEdges(dst, src, patternName) {
23
+ for (const edge of src) {
24
+ let edge2 = { ...edge };
25
+ edge2.edgeActions = edge.edgeActions?.map((action) => processAction(action));
26
+ edge2.patternName = patternName;
27
+ dst.push(edge2);
28
+ }
29
+ }
30
+ function processEdgeGroups(processedSchema, edgeGroups) {
31
+ // array-ify this
32
+ for (const group of edgeGroups) {
33
+ if (group.nullStates && !Array.isArray(group.nullStates)) {
34
+ group.nullStates = [group.nullStates];
35
+ }
36
+ let group2 = { ...group };
37
+ if (group.edgeAction) {
38
+ group2.edgeAction = processAction(group.edgeAction);
39
+ }
40
+ processedSchema.assocEdgeGroups.push(group2);
41
+ }
42
+ }
43
+ function processPattern(patterns, pattern, processedSchema) {
44
+ // TODO kill
45
+ let name = pattern.name || "node";
46
+ if (patterns[name] === undefined) {
47
+ const edges = [];
48
+ if (pattern.edges) {
49
+ processEdges(edges, pattern.edges);
50
+ }
51
+ patterns[name] = {
52
+ name: pattern.name,
53
+ assocEdges: edges,
54
+ };
55
+ }
56
+ else {
57
+ // TODO ideally we want to make sure that different patterns don't have the same name
58
+ // can't do a deepEqual check because function calls and therefore different instances in fields
59
+ }
60
+ processFields(processedSchema, pattern.fields);
61
+ if (pattern.edges) {
62
+ processEdges(processedSchema.assocEdges, pattern.edges, pattern.name);
63
+ }
64
+ }
65
+ var NullableResult;
66
+ (function (NullableResult) {
67
+ NullableResult["CONTENTS"] = "contents";
68
+ NullableResult["CONTENTS_AND_LIST"] = "contentsAndList";
69
+ NullableResult["ITEM"] = "true";
70
+ })(NullableResult || (NullableResult = {}));
71
+ function processAction(action) {
72
+ if (!action.actionOnlyFields) {
73
+ return { ...action };
74
+ }
75
+ let ret = { ...action };
76
+ let actionOnlyFields = action.actionOnlyFields.map((f) => {
77
+ let f2 = f;
78
+ if (!f.nullable) {
79
+ return f2;
80
+ }
81
+ if (typeof f.nullable === "boolean") {
82
+ f2.nullable = NullableResult.ITEM;
83
+ }
84
+ else {
85
+ if (f.nullable === "contentsAndList") {
86
+ f2.nullable = NullableResult.CONTENTS_AND_LIST;
87
+ }
88
+ else {
89
+ f2.nullable = NullableResult.CONTENTS;
90
+ }
91
+ }
92
+ return f2;
93
+ });
94
+ ret.actionOnlyFields = actionOnlyFields;
95
+ return ret;
96
+ }
97
+ function parseSchema(potentialSchemas) {
98
+ let schemas = {};
99
+ let patterns = {};
100
+ for (const key in potentialSchemas) {
101
+ const value = potentialSchemas[key];
102
+ let schema;
103
+ if (value.constructor == Object) {
104
+ schema = value;
105
+ }
106
+ else {
107
+ schema = new value();
108
+ }
109
+ let processedSchema = {
110
+ fields: [],
111
+ tableName: schema.tableName,
112
+ enumTable: schema.enumTable,
113
+ dbRows: schema.dbRows,
114
+ constraints: schema.constraints,
115
+ indices: schema.indices,
116
+ hideFromGraphQL: schema.hideFromGraphQL,
117
+ actions: schema.actions?.map((action) => processAction(action)) || [],
118
+ assocEdges: [],
119
+ assocEdgeGroups: [],
120
+ };
121
+ // let's put patterns first just so we have id, created_at, updated_at first
122
+ // ¯\_(ツ)_/¯
123
+ if (schema.patterns) {
124
+ for (const pattern of schema.patterns) {
125
+ processPattern(patterns, pattern, processedSchema);
126
+ }
127
+ }
128
+ processFields(processedSchema, schema.fields);
129
+ if (schema.edges) {
130
+ processEdges(processedSchema.assocEdges, schema.edges);
131
+ }
132
+ if (schema.edgeGroups) {
133
+ processEdgeGroups(processedSchema, schema.edgeGroups);
134
+ }
135
+ schemas[key] = processedSchema;
136
+ }
137
+ return { schemas, patterns };
138
+ }
139
+ exports.parseSchema = parseSchema;
@@ -2,8 +2,10 @@ import { Pattern } from "./schema";
2
2
  export declare const Timestamps: Pattern;
3
3
  export declare const Node: Pattern;
4
4
  export declare abstract class BaseEntSchema {
5
+ addPatterns(...patterns: Pattern[]): void;
5
6
  patterns: Pattern[];
6
7
  }
7
8
  export declare abstract class BaseEntSchemaWithTZ {
9
+ addPatterns(...patterns: Pattern[]): void;
8
10
  patterns: Pattern[];
9
11
  }
@@ -26,6 +26,7 @@ let tsFields = [
26
26
  ];
27
27
  // Timestamps is a Pattern that adds a createdAt and updatedAt timestamp fields to the ent
28
28
  exports.Timestamps = {
29
+ name: "timestamps",
29
30
  fields: tsFields,
30
31
  };
31
32
  let nodeField = (0, field_1.UUIDType)({
@@ -63,6 +64,7 @@ let nodeFieldsWithTZ = [
63
64
  ];
64
65
  // Node is a Pattern that adds 3 fields to the ent: (id, createdAt, and updatedAt timestamps)
65
66
  exports.Node = {
67
+ name: "node",
66
68
  fields: nodeFields,
67
69
  };
68
70
  // Base ent schema. has Node Pattern by default.
@@ -71,15 +73,23 @@ class BaseEntSchema {
71
73
  constructor() {
72
74
  this.patterns = [exports.Node];
73
75
  }
76
+ addPatterns(...patterns) {
77
+ this.patterns.push(...patterns);
78
+ }
74
79
  }
75
80
  exports.BaseEntSchema = BaseEntSchema;
76
81
  class BaseEntSchemaWithTZ {
77
82
  constructor() {
78
83
  this.patterns = [
79
84
  {
85
+ // default schema added
86
+ name: "nodeWithTZ",
80
87
  fields: nodeFieldsWithTZ,
81
88
  },
82
89
  ];
83
90
  }
91
+ addPatterns(...patterns) {
92
+ this.patterns.push(...patterns);
93
+ }
84
94
  }
85
95
  exports.BaseEntSchemaWithTZ = BaseEntSchemaWithTZ;
@@ -24,6 +24,7 @@ export interface AssocEdge {
24
24
  tableName?: string;
25
25
  edgeActions?: EdgeAction[];
26
26
  hideFromGraphQL?: boolean;
27
+ edgeConstName?: string;
27
28
  }
28
29
  export interface EdgeAction {
29
30
  operation: ActionOperation;
@@ -34,6 +35,7 @@ export interface EdgeAction {
34
35
  }
35
36
  export interface InverseAssocEdge {
36
37
  name: string;
38
+ edgeConstName?: string;
37
39
  }
38
40
  export interface EdgeGroupAction {
39
41
  operation: ActionOperation.EdgeGroup;
@@ -54,7 +56,9 @@ export interface AssocEdgeGroup {
54
56
  }
55
57
  export declare type Edge = AssocEdge;
56
58
  export interface Pattern {
59
+ name: string;
57
60
  fields: Field[];
61
+ edges?: Edge[];
58
62
  }
59
63
  export declare enum DBType {
60
64
  UUID = "UUID",
@@ -27,56 +27,7 @@ const path = __importStar(require("path"));
27
27
  const pascal_case_1 = require("pascal-case");
28
28
  const minimist_1 = __importDefault(require("minimist"));
29
29
  const process_1 = require("process");
30
- function processFields(dst, src) {
31
- for (const field of src) {
32
- let f = {};
33
- f = field;
34
- f["hasDefaultValueOnCreate"] = field.defaultValueOnCreate != undefined;
35
- f["hasDefaultValueOnEdit"] = field.defaultValueOnEdit != undefined;
36
- if (field.polymorphic) {
37
- // convert boolean into object
38
- // we keep boolean as an option to keep API simple
39
- if (typeof field.polymorphic === "boolean") {
40
- f["polymorphic"] = {};
41
- }
42
- else {
43
- f["polymorphic"] = field.polymorphic;
44
- }
45
- }
46
- dst.push(f);
47
- }
48
- }
49
- var NullableResult;
50
- (function (NullableResult) {
51
- NullableResult["CONTENTS"] = "contents";
52
- NullableResult["CONTENTS_AND_LIST"] = "contentsAndList";
53
- NullableResult["ITEM"] = "true";
54
- })(NullableResult || (NullableResult = {}));
55
- function processAction(action) {
56
- if (!action.actionOnlyFields) {
57
- return action;
58
- }
59
- let ret = action;
60
- ret.actionOnlyFields = action.actionOnlyFields.map((f) => {
61
- let f2 = f;
62
- if (!f.nullable) {
63
- return f2;
64
- }
65
- if (typeof f.nullable === "boolean") {
66
- f2.nullable = NullableResult.ITEM;
67
- }
68
- else {
69
- if (f.nullable === "contentsAndList") {
70
- f2.nullable = NullableResult.CONTENTS_AND_LIST;
71
- }
72
- else {
73
- f2.nullable = NullableResult.CONTENTS;
74
- }
75
- }
76
- return f2;
77
- });
78
- return ret;
79
- }
30
+ const parse_1 = require("../parse_schema/parse");
80
31
  function main() {
81
32
  const options = (0, minimist_1.default)(process.argv.slice(2));
82
33
  if (!options.path) {
@@ -96,61 +47,8 @@ function main() {
96
47
  potentialSchemas[(0, pascal_case_1.pascalCase)(match[1])] = require(p).default;
97
48
  }
98
49
  // console.log(potentialSchemas);
99
- let schemas = {};
100
- for (const key in potentialSchemas) {
101
- const value = potentialSchemas[key];
102
- let schema;
103
- if (value.constructor == Object) {
104
- schema = value;
105
- }
106
- else {
107
- schema = new value();
108
- }
109
- // let's put patterns first just so we have id, created_at, updated_at first
110
- // ¯\_(ツ)_/¯
111
- let fields = [];
112
- if (schema.patterns) {
113
- for (const pattern of schema.patterns) {
114
- processFields(fields, pattern.fields);
115
- }
116
- }
117
- processFields(fields, schema.fields);
118
- let assocEdges = [];
119
- let assocEdgeGroups = [];
120
- if (schema.edges) {
121
- for (const edge of schema.edges) {
122
- let edge2 = edge;
123
- edge2.edgeActions = edge.edgeActions?.map((action) => processAction(action));
124
- assocEdges.push(edge2);
125
- }
126
- }
127
- if (schema.edgeGroups) {
128
- // array-ify this
129
- for (const group of schema.edgeGroups) {
130
- if (group.nullStates && !Array.isArray(group.nullStates)) {
131
- group.nullStates = [group.nullStates];
132
- }
133
- let group2 = group;
134
- if (group.edgeAction) {
135
- group2.edgeAction = processAction(group.edgeAction);
136
- }
137
- assocEdgeGroups.push(group2);
138
- }
139
- }
140
- schemas[key] = {
141
- tableName: schema.tableName,
142
- fields: fields,
143
- assocEdges: assocEdges,
144
- assocEdgeGroups: assocEdgeGroups,
145
- actions: schema.actions?.map((action) => processAction(action)),
146
- enumTable: schema.enumTable,
147
- dbRows: schema.dbRows,
148
- constraints: schema.constraints,
149
- indices: schema.indices,
150
- hideFromGraphQL: schema.hideFromGraphQL,
151
- };
152
- }
153
- console.log(JSON.stringify(schemas));
50
+ const result = (0, parse_1.parseSchema)(potentialSchemas);
51
+ console.log(JSON.stringify(result));
154
52
  }
155
53
  try {
156
54
  main();
@@ -354,11 +354,9 @@ class TempDB {
354
354
  await this.dbClient.query(table.create());
355
355
  }
356
356
  else {
357
- // console.log(table.create());
358
357
  this.sqlite.exec(table.create());
359
358
  }
360
359
  }
361
- // await this.sqlite.exec("nonsense");
362
360
  }
363
361
  getSqliteClient() {
364
362
  return this.sqlite;
@@ -1,3 +1,4 @@
1
+ import { Ent, LoadEntOptions } from "../../core/base";
1
2
  export declare enum EdgeType {
2
3
  UserToContacts = "userToContacts",
3
4
  UserToFriends = "userToFriends",
@@ -10,7 +11,9 @@ export declare enum EdgeType {
10
11
  EventToHosts = "eventToHosts",
11
12
  UserToHostedEvents = "userToHostedEvents",
12
13
  UserToFriendRequests = "userToFriendRequests",
13
- UserToIncomingFriendRequests = "userToIncomingFriendRequests"
14
+ UserToIncomingFriendRequests = "userToIncomingFriendRequests",
15
+ UserToFollowing = "userToFollowing",
16
+ ObjectToFollowedUsers = "objectToFollowedUsers"
14
17
  }
15
18
  export declare enum NodeType {
16
19
  FakeUser = "user",
@@ -19,3 +22,4 @@ export declare enum NodeType {
19
22
  }
20
23
  export declare const SymmetricEdges: Set<string>;
21
24
  export declare const InverseEdges: Map<EdgeType, EdgeType>;
25
+ export declare function getLoaderOptions(type: NodeType): LoadEntOptions<Ent>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InverseEdges = exports.SymmetricEdges = exports.NodeType = exports.EdgeType = void 0;
3
+ exports.getLoaderOptions = exports.InverseEdges = exports.SymmetricEdges = exports.NodeType = exports.EdgeType = void 0;
4
+ const internal_1 = require("./internal");
4
5
  var EdgeType;
5
6
  (function (EdgeType) {
6
7
  EdgeType["UserToContacts"] = "userToContacts";
@@ -16,6 +17,10 @@ var EdgeType;
16
17
  EdgeType["UserToHostedEvents"] = "userToHostedEvents";
17
18
  EdgeType["UserToFriendRequests"] = "userToFriendRequests";
18
19
  EdgeType["UserToIncomingFriendRequests"] = "userToIncomingFriendRequests";
20
+ // can follow users or events...
21
+ // so a polymorphic edge
22
+ EdgeType["UserToFollowing"] = "userToFollowing";
23
+ EdgeType["ObjectToFollowedUsers"] = "objectToFollowedUsers";
19
24
  })(EdgeType = exports.EdgeType || (exports.EdgeType = {}));
20
25
  var NodeType;
21
26
  (function (NodeType) {
@@ -32,4 +37,17 @@ exports.InverseEdges = new Map([
32
37
  [EdgeType.EventToHosts, EdgeType.UserToHostedEvents],
33
38
  [EdgeType.UserToFriendRequests, EdgeType.UserToIncomingFriendRequests],
34
39
  [EdgeType.UserToIncomingFriendRequests, EdgeType.UserToFriendRequests],
40
+ [EdgeType.UserToFollowing, EdgeType.ObjectToFollowedUsers],
41
+ [EdgeType.ObjectToFollowedUsers, EdgeType.UserToFollowing],
35
42
  ]);
43
+ function getLoaderOptions(type) {
44
+ switch (type) {
45
+ case NodeType.FakeContact:
46
+ return internal_1.FakeContact.loaderOptions();
47
+ case NodeType.FakeUser:
48
+ return internal_1.FakeUser.loaderOptions();
49
+ case NodeType.FakeEvent:
50
+ return internal_1.FakeEvent.loaderOptions();
51
+ }
52
+ }
53
+ exports.getLoaderOptions = getLoaderOptions;
@@ -31,6 +31,8 @@ class FakeUser {
31
31
  privacy_1.AllowIfViewerRule,
32
32
  //can view user if friends
33
33
  new privacy_1.AllowIfViewerInboundEdgeExistsRule(internal_1.EdgeType.UserToFriends),
34
+ //can view user if following
35
+ new privacy_1.AllowIfViewerInboundEdgeExistsRule(internal_1.EdgeType.UserToFollowing),
34
36
  new privacy_1.AllowIfConditionAppliesRule((viewer, ent) => {
35
37
  if (!(viewer instanceof ViewerWithAccessToken)) {
36
38
  return false;
@@ -1,4 +1,4 @@
1
- import { ID, Viewer } from "../../core/base";
1
+ import { Ent, ID, Viewer } from "../../core/base";
2
2
  import { CustomEdgeQueryBase } from "../../core/query/custom_query";
3
3
  import { AssocEdge } from "../../core/ent";
4
4
  import * as clause from "../../core/clause";
@@ -81,3 +81,7 @@ export declare class UserToEventsInNextWeekQuery extends CustomEdgeQueryBase<Fak
81
81
  constructor(viewer: Viewer, src: ID | FakeUser);
82
82
  static query(viewer: Viewer, src: FakeUser | ID): UserToEventsInNextWeekQuery;
83
83
  }
84
+ export declare class UserToFollowingQuery extends AssocEdgeQueryBase<FakeUser, Ent, AssocEdge> {
85
+ constructor(viewer: Viewer, src: EdgeQuerySource<FakeUser>);
86
+ static query(viewer: Viewer, src: EdgeQuerySource<FakeUser>): UserToFollowingQuery;
87
+ }
@@ -19,7 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
19
19
  return result;
20
20
  };
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.UserToEventsInNextWeekQuery = exports.userToEventsInNextWeekDataLoaderFactory = exports.userToEventsInNextWeekCountLoaderFactory = exports.getCompleteClause = exports.getNextWeekClause = exports.UserToHostedEventsQuery = exports.UserToEventsAttendingQuery = exports.UserToIncomingFriendRequestsQuery = exports.UserToFriendRequestsQuery = exports.UserToCustomEdgeQuery = exports.CustomEdge = exports.UserToFriendsQuery = exports.UserToContactsFkeyQuery = exports.userToContactsDataLoaderFactory = exports.userToContactsCountLoaderFactory = exports.UserToContactsQuery = void 0;
22
+ exports.UserToFollowingQuery = exports.UserToEventsInNextWeekQuery = exports.userToEventsInNextWeekDataLoaderFactory = exports.userToEventsInNextWeekCountLoaderFactory = exports.getCompleteClause = exports.getNextWeekClause = exports.UserToHostedEventsQuery = exports.UserToEventsAttendingQuery = exports.UserToIncomingFriendRequestsQuery = exports.UserToFriendRequestsQuery = exports.UserToCustomEdgeQuery = exports.CustomEdge = exports.UserToFriendsQuery = exports.UserToContactsFkeyQuery = exports.userToContactsDataLoaderFactory = exports.userToContactsCountLoaderFactory = exports.UserToContactsQuery = void 0;
23
23
  const custom_query_1 = require("../../core/query/custom_query");
24
24
  const ent_1 = require("../../core/ent");
25
25
  const clause = __importStar(require("../../core/clause"));
@@ -34,6 +34,7 @@ const jest_date_mock_1 = require("jest-date-mock");
34
34
  const luxon_1 = require("luxon");
35
35
  const query_loader_1 = require("../../core/loaders/query_loader");
36
36
  const mock_date_1 = require("./../mock_date");
37
+ const _1 = require(".");
37
38
  class UserToContactsQuery extends assoc_query_1.AssocEdgeQueryBase {
38
39
  constructor(viewer, src) {
39
40
  super(viewer, src, new assoc_count_loader_1.AssocEdgeCountLoaderFactory(internal_1.EdgeType.UserToContacts), new assoc_edge_loader_1.AssocEdgeLoaderFactory(internal_1.EdgeType.UserToContacts, ent_1.AssocEdge), internal_1.FakeContact.loaderOptions());
@@ -257,3 +258,12 @@ class UserToEventsInNextWeekQuery extends custom_query_1.CustomEdgeQueryBase {
257
258
  }
258
259
  }
259
260
  exports.UserToEventsInNextWeekQuery = UserToEventsInNextWeekQuery;
261
+ class UserToFollowingQuery extends assoc_query_1.AssocEdgeQueryBase {
262
+ constructor(viewer, src) {
263
+ super(viewer, src, new assoc_count_loader_1.AssocEdgeCountLoaderFactory(internal_1.EdgeType.UserToFollowing), new assoc_edge_loader_1.AssocEdgeLoaderFactory(internal_1.EdgeType.UserToFollowing, ent_1.AssocEdge), _1.getLoaderOptions);
264
+ }
265
+ static query(viewer, src) {
266
+ return new UserToFollowingQuery(viewer, src);
267
+ }
268
+ }
269
+ exports.UserToFollowingQuery = UserToFollowingQuery;