@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
@@ -20,8 +20,8 @@ export declare class AssocDirectEdgeLoader<T extends AssocEdge> implements Loade
20
20
  private edgeType;
21
21
  private edgeCtr;
22
22
  private options?;
23
- context?: Context | undefined;
24
- constructor(edgeType: string, edgeCtr: AssocEdgeConstructor<T>, options?: Partial<Pick<import("../base").QueryableDataOptions, "limit" | "orderby" | "clause">> | undefined, context?: Context | undefined);
23
+ context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
24
+ constructor(edgeType: string, edgeCtr: AssocEdgeConstructor<T>, options?: Partial<Pick<import("../base").QueryableDataOptions, "limit" | "orderby" | "clause">> | undefined, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined);
25
25
  load(id: ID): Promise<T[]>;
26
26
  loadEdgeForID2(id: ID, id2: ID): Promise<T | undefined>;
27
27
  clearAll(): void;
@@ -32,7 +32,7 @@ export declare class AssocEdgeLoaderFactory<T extends AssocEdge> implements Load
32
32
  name: string;
33
33
  constructor(edgeType: string, edgeCtr: AssocEdgeConstructor<T> | (() => AssocEdgeConstructor<T>));
34
34
  createLoader(context?: Context): AssocLoader<T>;
35
- private isFunction;
35
+ private isConstructor;
36
36
  createConfigurableLoader(options: EdgeQueryableDataOptions, context?: Context): AssocLoader<T>;
37
37
  }
38
38
  export {};
@@ -161,16 +161,17 @@ class AssocEdgeLoaderFactory {
161
161
  createLoader(context) {
162
162
  return this.createConfigurableLoader({}, context);
163
163
  }
164
- isFunction(edgeCtr) {
165
- // not constructor
166
- return !(edgeCtr.prototype && edgeCtr.prototype.constructor === edgeCtr);
164
+ isConstructor(edgeCtr) {
165
+ return (edgeCtr.prototype &&
166
+ edgeCtr.prototype.constructor &&
167
+ edgeCtr.prototype.constructor.name.length > 0);
167
168
  }
168
169
  createConfigurableLoader(options, context) {
169
170
  let edgeCtr = this.edgeCtr;
170
171
  // in generated code, the edge is not necessarily defined at the time of loading
171
172
  // so we call this as follows:
172
173
  // const loader = new AssocEdgeLoaderFactory(EdgeType.Foo, ()=>DerivedEdgeClass);
173
- if (this.isFunction(edgeCtr)) {
174
+ if (!this.isConstructor(edgeCtr)) {
174
175
  edgeCtr = edgeCtr();
175
176
  }
176
177
  // rename to make TS happy
@@ -4,6 +4,7 @@ exports.IndexLoaderFactory = void 0;
4
4
  const query_loader_1 = require("./query_loader");
5
5
  // we're keeping this for legacy reasons so as to not break existing callers
6
6
  // and to decouple the change here but all callers can safely be changed here to use QueryLoaderFactory
7
+ // @deprecated use QueryLoaderFactory
7
8
  class IndexLoaderFactory {
8
9
  constructor(options, col, opts) {
9
10
  this.factory = new query_loader_1.QueryLoaderFactory({
@@ -37,12 +37,12 @@ class cacheMap {
37
37
  // might be a lot?
38
38
  // TODO this is not the best log format
39
39
  // was designed for ObjectLoader time. Now we have different needs e.g. count, assoc etc
40
- (0, logger_1.log)("query", {
40
+ (0, logger_1.log)("cache", {
41
41
  "dataloader-cache-hit": key,
42
42
  "tableName": this.options.tableName,
43
43
  });
44
44
  // } else {
45
- // log("query", {
45
+ // log("cache", {
46
46
  // "dataloader-cache-miss": key,
47
47
  // "tableName": options.tableName,
48
48
  // });
@@ -50,21 +50,21 @@ class cacheMap {
50
50
  return ret;
51
51
  }
52
52
  set(key, value) {
53
- // log("query", {
53
+ // log("cache", {
54
54
  // "dataloader-cache-set": key,
55
55
  // "tableName": options.tableName,
56
56
  // });
57
57
  return this.m.set(key, value);
58
58
  }
59
59
  delete(key) {
60
- // log("query", {
60
+ // log("cache", {
61
61
  // "dataloader-cache-delete": key,
62
62
  // "tableName": options.tableName,
63
63
  // });
64
64
  return this.m.delete(key);
65
65
  }
66
66
  clear() {
67
- // log("query", {
67
+ // log("cache", {
68
68
  // "dataloader-cache-clear": true,
69
69
  // "tableName": options.tableName,
70
70
  // });
@@ -1,23 +1,28 @@
1
- import { Data, SelectDataOptions, Context, Loader, LoaderFactory } from "../base";
1
+ import { ID, Data, SelectDataOptions, Context, Loader, LoaderFactory } from "../base";
2
2
  export declare class ObjectLoader<T> implements Loader<T, Data | null> {
3
3
  private options;
4
- context?: Context | undefined;
4
+ context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
5
5
  private toPrime?;
6
6
  private loader;
7
7
  private primedLoaders;
8
8
  private memoizedInitPrime;
9
- constructor(options: SelectDataOptions, context?: Context | undefined, toPrime?: ObjectLoaderFactory<T>[] | undefined);
9
+ constructor(options: SelectDataOptions, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined, toPrime?: ObjectLoaderFactory<T>[] | undefined);
10
+ getOptions(): SelectDataOptions;
10
11
  private initPrime;
11
12
  load(key: T): Promise<Data | null>;
12
13
  clearAll(): void;
13
14
  loadMany(keys: T[]): Promise<Data[]>;
14
15
  prime(data: Data): void;
15
16
  }
17
+ interface ObjectLoaderOptions extends SelectDataOptions {
18
+ instanceKey?: string;
19
+ }
16
20
  export declare class ObjectLoaderFactory<T> implements LoaderFactory<T, Data | null> {
17
- options: SelectDataOptions;
21
+ options: ObjectLoaderOptions;
18
22
  name: string;
19
23
  private toPrime;
20
- constructor(options: SelectDataOptions);
24
+ constructor(options: ObjectLoaderOptions);
21
25
  createLoader(context?: Context): ObjectLoader<T>;
22
26
  addToPrime(factory: ObjectLoaderFactory<T>): void;
23
27
  }
28
+ export {};
@@ -29,6 +29,9 @@ const clause = __importStar(require("../clause"));
29
29
  const logger_1 = require("../logger");
30
30
  const loader_1 = require("./loader");
31
31
  const memoizee_1 = __importDefault(require("memoizee"));
32
+ // optional clause...
33
+ // so ObjectLoaderFactory and createDataLoader need to take a new optional field which is a clause that's always added here
34
+ // and we need a disableTransform which skips loader completely and uses loadRow...
32
35
  function createDataLoader(options) {
33
36
  const loaderOptions = {};
34
37
  // if query logging is enabled, we should log what's happening with loader
@@ -40,9 +43,22 @@ function createDataLoader(options) {
40
43
  return [];
41
44
  }
42
45
  let col = options.key;
46
+ let cls = clause.In(col, ...ids);
47
+ if (options.clause) {
48
+ let optionClause;
49
+ if (typeof options.clause === "function") {
50
+ optionClause = options.clause();
51
+ }
52
+ else {
53
+ optionClause = options.clause;
54
+ }
55
+ if (optionClause) {
56
+ cls = clause.And(optionClause, cls);
57
+ }
58
+ }
43
59
  const rowOptions = {
44
60
  ...options,
45
- clause: clause.In(col, ...ids),
61
+ clause: cls,
46
62
  };
47
63
  let m = new Map();
48
64
  let result = [];
@@ -77,6 +93,9 @@ class ObjectLoader {
77
93
  }
78
94
  this.memoizedInitPrime = (0, memoizee_1.default)(this.initPrime.bind(this));
79
95
  }
96
+ getOptions() {
97
+ return this.options;
98
+ }
80
99
  initPrime() {
81
100
  if (!this.context || !this.toPrime) {
82
101
  return;
@@ -107,9 +126,22 @@ class ObjectLoader {
107
126
  }
108
127
  return result;
109
128
  }
129
+ let cls = clause.Eq(this.options.key, key);
130
+ if (this.options.clause) {
131
+ let optionClause;
132
+ if (typeof this.options.clause === "function") {
133
+ optionClause = this.options.clause();
134
+ }
135
+ else {
136
+ optionClause = this.options.clause;
137
+ }
138
+ if (optionClause) {
139
+ cls = clause.And(optionClause, cls);
140
+ }
141
+ }
110
142
  const rowOptions = {
111
143
  ...this.options,
112
- clause: clause.Eq(this.options.key, key),
144
+ clause: cls,
113
145
  context: this.context,
114
146
  };
115
147
  return await (0, ent_1.loadRow)(rowOptions);
@@ -121,9 +153,22 @@ class ObjectLoader {
121
153
  if (this.loader) {
122
154
  return await this.loader.loadMany(keys);
123
155
  }
156
+ let cls = clause.In(this.options.key, ...keys);
157
+ if (this.options.clause) {
158
+ let optionClause;
159
+ if (typeof this.options.clause === "function") {
160
+ optionClause = this.options.clause();
161
+ }
162
+ else {
163
+ optionClause = this.options.clause;
164
+ }
165
+ if (optionClause) {
166
+ cls = clause.And(optionClause, cls);
167
+ }
168
+ }
124
169
  const rowOptions = {
125
170
  ...this.options,
126
- clause: clause.In(this.options.key, ...keys),
171
+ clause: cls,
127
172
  context: this.context,
128
173
  };
129
174
  return await (0, ent_1.loadRows)(rowOptions);
@@ -142,7 +187,16 @@ class ObjectLoaderFactory {
142
187
  constructor(options) {
143
188
  this.options = options;
144
189
  this.toPrime = [];
145
- this.name = `${options.tableName}:${options.key}`;
190
+ let instanceKey = options.instanceKey || "";
191
+ if (typeof this.options.clause === "function") {
192
+ if (!options.instanceKey) {
193
+ throw new Error(`need to pass an instanceKey to ObjectLoader if clause is a function`);
194
+ }
195
+ }
196
+ else if (this.options.clause) {
197
+ instanceKey = this.options.clause.instanceKey();
198
+ }
199
+ this.name = `${options.tableName}:${options.key}:${instanceKey}`;
146
200
  }
147
201
  createLoader(context) {
148
202
  return (0, loader_1.getLoader)(this, () => {
@@ -10,12 +10,12 @@ export declare class QueryDirectLoader<K extends any> implements Loader<K, Data[
10
10
  }
11
11
  export declare class QueryLoader<K extends any> implements Loader<K, Data[]> {
12
12
  private options;
13
- context?: Context | undefined;
13
+ context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
14
14
  private queryOptions?;
15
15
  private loader;
16
16
  private primedLoaders;
17
17
  private memoizedInitPrime;
18
- constructor(options: QueryOptions, context?: Context | undefined, queryOptions?: Partial<Pick<import("../base").QueryableDataOptions, "limit" | "orderby" | "clause">> | undefined);
18
+ constructor(options: QueryOptions, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined, queryOptions?: Partial<Pick<import("../base").QueryableDataOptions, "limit" | "orderby" | "clause">> | undefined);
19
19
  private initPrime;
20
20
  load(id: K): Promise<Data[]>;
21
21
  clearAll(): void;
@@ -9,9 +9,9 @@ interface QueryCountOptions {
9
9
  export declare function createCountDataLoader<K extends any>(options: QueryCountOptions): DataLoader<K, number, K>;
10
10
  export declare class RawCountLoader<K extends any> implements Loader<K, number> {
11
11
  private options;
12
- context?: Context | undefined;
12
+ context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
13
13
  private loader;
14
- constructor(options: QueryCountOptions, context?: Context | undefined);
14
+ constructor(options: QueryCountOptions, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined);
15
15
  load(id: K): Promise<number>;
16
16
  clearAll(): void;
17
17
  }
package/core/logger.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare type logType = "query" | "warn" | "info" | "error" | "debug";
1
+ declare type logType = "query" | "warn" | "info" | "error" | "debug" | "cache";
2
2
  export declare function setLogLevels(levels: logType | logType[]): void;
3
3
  export declare function clearLogLevels(): void;
4
4
  export declare function log(level: logType, msg: any): void;
package/core/logger.js CHANGED
@@ -7,6 +7,7 @@ var m = {
7
7
  info: "log",
8
8
  error: "error",
9
9
  debug: "debug",
10
+ cache: "log",
10
11
  };
11
12
  var logLevels = new Map();
12
13
  function setLogLevels(levels) {
package/core/privacy.d.ts CHANGED
@@ -6,22 +6,22 @@ export declare class EntPrivacyError extends Error implements PrivacyError {
6
6
  constructor(privacyPolicy: PrivacyPolicy, rule: PrivacyPolicyRule, ent?: Ent);
7
7
  }
8
8
  export declare const AlwaysAllowRule: {
9
- apply(_v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
9
+ apply(_v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
10
10
  };
11
11
  export declare const AlwaysDenyRule: {
12
- apply(_v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
12
+ apply(_v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
13
13
  };
14
14
  export declare const DenyIfLoggedOutRule: {
15
- apply(v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
15
+ apply(v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
16
16
  };
17
17
  export declare const DenyIfLoggedInRule: {
18
- apply(v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
18
+ apply(v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
19
19
  };
20
20
  export declare const AllowIfHasIdentity: {
21
- apply(v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
21
+ apply(v: Viewer, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
22
22
  };
23
23
  export declare const AllowIfViewerRule: {
24
- apply(v: Viewer, ent?: Ent | undefined): Promise<PrivacyResult>;
24
+ apply(v: Viewer, ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
25
25
  };
26
26
  export declare class AllowIfViewerEqualsRule {
27
27
  private id;
@@ -71,45 +71,45 @@ export declare class DenyIfEntPropertyIsRule<T extends Ent> implements PrivacyPo
71
71
  constructor(property: keyof T, val: any);
72
72
  apply(v: Viewer, ent?: T): Promise<PrivacyResult>;
73
73
  }
74
- export declare class AllowIfEntIsVisibleRule<T extends Ent> implements PrivacyPolicyRule {
74
+ export declare class AllowIfEntIsVisibleRule<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicyRule {
75
75
  private id;
76
76
  private options;
77
- constructor(id: ID, options: LoadEntOptions<T>);
78
- apply(v: Viewer, _ent?: Ent): Promise<PrivacyResult>;
77
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
78
+ apply(v: TViewer, _ent?: Ent): Promise<PrivacyResult>;
79
79
  }
80
- export declare class AllowIfEntIsNotVisibleRule<T extends Ent> implements PrivacyPolicyRule {
80
+ export declare class AllowIfEntIsNotVisibleRule<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicyRule {
81
81
  private id;
82
82
  private options;
83
- constructor(id: ID, options: LoadEntOptions<T>);
84
- apply(v: Viewer, _ent?: Ent): Promise<PrivacyResult>;
83
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
84
+ apply(v: TViewer, _ent?: Ent): Promise<PrivacyResult>;
85
85
  }
86
- export declare class AllowIfEntIsVisiblePolicy<T extends Ent> implements PrivacyPolicy {
86
+ export declare class AllowIfEntIsVisiblePolicy<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicy<TEnt, TViewer> {
87
87
  private id;
88
88
  private options;
89
- constructor(id: ID, options: LoadEntOptions<T>);
89
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
90
90
  rules: {
91
- apply(_v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
91
+ apply(_v: Viewer<Ent<any> | null, ID | null>, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
92
92
  }[];
93
93
  }
94
- export declare class DenyIfEntIsVisiblePolicy<T extends Ent> implements PrivacyPolicy {
94
+ export declare class DenyIfEntIsVisiblePolicy<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicy<TEnt, TViewer> {
95
95
  private id;
96
96
  private options;
97
- constructor(id: ID, options: LoadEntOptions<T>);
97
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
98
98
  rules: {
99
- apply(_v: Viewer, _ent?: Ent | undefined): Promise<PrivacyResult>;
99
+ apply(_v: Viewer<Ent<any> | null, ID | null>, _ent?: Ent<Viewer<Ent<any> | null, ID | null>> | undefined): Promise<PrivacyResult>;
100
100
  }[];
101
101
  }
102
- export declare class DenyIfEntIsVisibleRule<T extends Ent> implements PrivacyPolicyRule {
102
+ export declare class DenyIfEntIsVisibleRule<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicyRule<TEnt, TViewer> {
103
103
  private id;
104
104
  private options;
105
- constructor(id: ID, options: LoadEntOptions<T>);
106
- apply(v: Viewer, _ent?: Ent): Promise<PrivacyResult>;
105
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
106
+ apply(v: TViewer, _ent?: Ent): Promise<PrivacyResult>;
107
107
  }
108
- export declare class DenyIfEntIsNotVisibleRule<T extends Ent> implements PrivacyPolicyRule {
108
+ export declare class DenyIfEntIsNotVisibleRule<TEnt extends Ent<TViewer>, TViewer extends Viewer> implements PrivacyPolicyRule {
109
109
  private id;
110
110
  private options;
111
- constructor(id: ID, options: LoadEntOptions<T>);
112
- apply(v: Viewer, _ent?: Ent): Promise<PrivacyResult>;
111
+ constructor(id: ID, options: LoadEntOptions<TEnt, TViewer>);
112
+ apply(v: TViewer, _ent?: Ent): Promise<PrivacyResult>;
113
113
  }
114
114
  export declare class AllowIfEdgeExistsRule implements PrivacyPolicyRule {
115
115
  private id1;
@@ -121,7 +121,7 @@ export declare class AllowIfEdgeExistsRule implements PrivacyPolicyRule {
121
121
  export declare class AllowIfViewerInboundEdgeExistsRule implements PrivacyPolicyRule {
122
122
  private edgeType;
123
123
  constructor(edgeType: string);
124
- apply(v: Viewer, ent: Ent): Promise<PrivacyResult>;
124
+ apply(v: Viewer, ent?: Ent): Promise<PrivacyResult>;
125
125
  }
126
126
  export declare class AllowIfViewerOutboundEdgeExistsRule implements PrivacyPolicyRule {
127
127
  private edgeType;
package/core/privacy.js CHANGED
@@ -451,11 +451,8 @@ async function applyPrivacyPolicy(v, policy, ent) {
451
451
  exports.applyPrivacyPolicy = applyPrivacyPolicy;
452
452
  // this will throw an exception if fails or return error | null?
453
453
  async function applyPrivacyPolicyX(v, policy, ent, throwErr) {
454
- // right now we apply all at same time. todo: be smart about this in the future
455
- const results = await Promise.all(policy.rules.map((rule) => rule.apply(v, ent)));
456
- for (let i = 0; i < results.length; i++) {
457
- const res = results[i];
458
- const rule = policy.rules[i];
454
+ for (const rule of policy.rules) {
455
+ const res = await rule.apply(v, ent);
459
456
  if (res.result == privacyResult.Allow) {
460
457
  return true;
461
458
  }
@@ -464,6 +461,9 @@ async function applyPrivacyPolicyX(v, policy, ent, throwErr) {
464
461
  if (res.error) {
465
462
  throw res.error;
466
463
  }
464
+ if (res.getError) {
465
+ throw res.getError(policy, rule, ent);
466
+ }
467
467
  if (throwErr) {
468
468
  throw throwErr();
469
469
  }
@@ -3,15 +3,15 @@ import { AssocEdge } from "../ent";
3
3
  import { AssocEdgeCountLoaderFactory } from "../loaders/assoc_count_loader";
4
4
  import { AssocEdgeLoaderFactory } from "../loaders/assoc_edge_loader";
5
5
  import { EdgeQuery, BaseEdgeQuery, IDInfo } from "./query";
6
- export declare type EdgeQuerySource<TSource extends Ent, TDest extends Ent = Ent> = TSource | TSource[] | ID | ID[] | EdgeQuery<TDest, Ent, AssocEdge>;
7
- declare type loaderOptionsFunc = (type: string) => LoadEntOptions<Ent>;
8
- export declare abstract class AssocEdgeQueryBase<TSource extends Ent, TDest extends Ent, TEdge extends AssocEdge> extends BaseEdgeQuery<TSource, TDest, TEdge> implements EdgeQuery<TSource, TDest, TEdge> {
9
- viewer: Viewer;
10
- src: EdgeQuerySource<TSource, TDest>;
6
+ export declare type EdgeQuerySource<TSource extends Ent<TViewer>, TDest extends Ent<TViewer> = Ent<any>, TViewer extends Viewer = Viewer> = TSource | TSource[] | ID | ID[] | EdgeQuery<TDest, Ent, AssocEdge>;
7
+ declare type loaderOptionsFunc<TViewer extends Viewer> = (type: string) => LoadEntOptions<Ent, TViewer>;
8
+ export declare abstract class AssocEdgeQueryBase<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TEdge extends AssocEdge, TViewer extends Viewer = Viewer> extends BaseEdgeQuery<TSource, TDest, TEdge> implements EdgeQuery<TSource, TDest, TEdge> {
9
+ viewer: TViewer;
10
+ src: EdgeQuerySource<TSource, TDest, TViewer>;
11
11
  private countLoaderFactory;
12
12
  private dataLoaderFactory;
13
13
  private options;
14
- constructor(viewer: Viewer, src: EdgeQuerySource<TSource, TDest>, countLoaderFactory: AssocEdgeCountLoaderFactory, dataLoaderFactory: AssocEdgeLoaderFactory<TEdge>, options: LoadEntOptions<TDest> | loaderOptionsFunc);
14
+ constructor(viewer: TViewer, src: EdgeQuerySource<TSource, TDest, TViewer>, countLoaderFactory: AssocEdgeCountLoaderFactory, dataLoaderFactory: AssocEdgeLoaderFactory<TEdge>, options: LoadEntOptions<TDest, TViewer> | loaderOptionsFunc<TViewer>);
15
15
  private isEdgeQuery;
16
16
  abstract sourceEnt(id: ID): Promise<Ent | null>;
17
17
  private getSingleID;
@@ -1,17 +1,17 @@
1
1
  import { Data, Ent, ID, EdgeQueryableDataOptions, LoadEntOptions, Viewer, LoaderFactory, ConfigurableLoaderFactory } from "../base";
2
2
  import { BaseEdgeQuery, IDInfo, EdgeQuery } from "./query";
3
- export interface CustomEdgeQueryOptions<TSource extends Ent, TDest extends Ent> {
3
+ export interface CustomEdgeQueryOptions<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
4
4
  src: TSource | ID;
5
5
  countLoaderFactory: LoaderFactory<ID, number>;
6
6
  dataLoaderFactory: ConfigurableLoaderFactory<ID, Data[]>;
7
- options: LoadEntOptions<TDest>;
7
+ options: LoadEntOptions<TDest, TViewer>;
8
8
  sortColumn?: string;
9
9
  }
10
- export declare abstract class CustomEdgeQueryBase<TSource extends Ent, TDest extends Ent> extends BaseEdgeQuery<TSource, TDest, Data> implements EdgeQuery<TSource, TDest, Data> {
11
- viewer: Viewer;
10
+ export declare abstract class CustomEdgeQueryBase<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> extends BaseEdgeQuery<TSource, TDest, Data> implements EdgeQuery<TSource, TDest, Data> {
11
+ viewer: TViewer;
12
12
  private options;
13
13
  private id;
14
- constructor(viewer: Viewer, options: CustomEdgeQueryOptions<TSource, TDest>);
14
+ constructor(viewer: TViewer, options: CustomEdgeQueryOptions<TSource, TDest, TViewer>);
15
15
  abstract sourceEnt(id: ID): Promise<Ent | null>;
16
16
  private idVisible;
17
17
  queryRawCount(): Promise<number>;
@@ -41,7 +41,7 @@ export declare abstract class BaseEdgeQuery<TSource extends Ent, TDest extends E
41
41
  private idMap;
42
42
  private idsToFetch;
43
43
  constructor(viewer: Viewer, sortCol: string);
44
- getPrivacyPolicy(): PrivacyPolicy<Ent>;
44
+ getPrivacyPolicy(): PrivacyPolicy<Ent<Viewer<Ent<any> | null, ID | null>>, Viewer<Ent<any> | null, ID | null>>;
45
45
  abstract sourceEnt(id: ID): Promise<Ent | null>;
46
46
  first(n: number, after?: string): this;
47
47
  last(n: number, before?: string): this;
@@ -1 +1 @@
1
- export declare function assocTests(): void;
1
+ export declare function assocTests(global?: boolean): void;
@@ -27,7 +27,7 @@ const jest_date_mock_1 = require("jest-date-mock");
27
27
  const index_1 = require("../../testutils/fake_data/index");
28
28
  const test_helpers_1 = require("../../testutils/fake_data/test_helpers");
29
29
  const db_1 = __importStar(require("../db"));
30
- function assocTests() {
30
+ function assocTests(global = false) {
31
31
  describe("custom edge", () => {
32
32
  let user1, user2;
33
33
  beforeEach(async () => {
@@ -76,9 +76,16 @@ function assocTests() {
76
76
  for (let i = 0; i < numQueries; i++) {
77
77
  const query = queries[i];
78
78
  let expLimit = disablePaginationBump ? limit : limit + 1;
79
- expect(query.qs?.whereClause, `${i}`).toBe(
80
- // default limit
81
- `id1 = $1 AND edge_type = $2 ORDER BY time DESC LIMIT ${expLimit}`);
79
+ if (global) {
80
+ expect(query.qs?.whereClause, `${i}`).toBe(
81
+ // default limit
82
+ `id1 = $1 AND edge_type = $2 AND deleted_at IS NULL ORDER BY time DESC LIMIT ${expLimit}`);
83
+ }
84
+ else {
85
+ expect(query.qs?.whereClause, `${i}`).toBe(
86
+ // default limit
87
+ `id1 = $1 AND edge_type = $2 ORDER BY time DESC LIMIT ${expLimit}`);
88
+ }
82
89
  }
83
90
  }
84
91
  function verifyCountQuery({ length = 1, numQueries = 1 }) {
@@ -89,7 +96,12 @@ function assocTests() {
89
96
  expect(queries.length).toBe(length);
90
97
  for (let i = 0; i < numQueries; i++) {
91
98
  const query = queries[i];
92
- expect(query.qs?.whereClause).toBe(`id1 = $1 AND edge_type = $2`);
99
+ if (global) {
100
+ expect(query.qs?.whereClause).toBe(`id1 = $1 AND edge_type = $2 AND deleted_at IS NULL`);
101
+ }
102
+ else {
103
+ expect(query.qs?.whereClause).toBe(`id1 = $1 AND edge_type = $2`);
104
+ }
93
105
  }
94
106
  }
95
107
  // TODO need to test multi-ids with id1s that aren't visible...
@@ -4,11 +4,14 @@ import { EdgeQuery } from "./query";
4
4
  interface options<TData extends Data> {
5
5
  newQuery: (v: Viewer, user: FakeUser) => EdgeQuery<FakeUser, FakeContact, TData>;
6
6
  tableName: string;
7
+ uniqKey: string;
7
8
  entsLength?: number;
8
9
  where: string;
9
10
  sortCol: string;
10
11
  livePostgresDB?: boolean;
11
12
  sqlite?: boolean;
13
+ globalSchema?: boolean;
14
+ rawDataVerify?(user: FakeUser): Promise<void>;
12
15
  }
13
16
  export declare const commonTests: <TData extends Data>(opts: options<TData>) => void;
14
17
  export {};