@snowtop/ent 0.1.0-alpha3 → 0.1.0-alpha8

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 (60) hide show
  1. package/action/action.d.ts +2 -0
  2. package/action/executor.d.ts +1 -1
  3. package/action/orchestrator.d.ts +10 -2
  4. package/action/orchestrator.js +128 -34
  5. package/core/base.d.ts +5 -1
  6. package/core/base.js +16 -0
  7. package/core/clause.d.ts +24 -3
  8. package/core/clause.js +246 -5
  9. package/core/config.d.ts +18 -0
  10. package/core/config.js +17 -0
  11. package/core/db.d.ts +3 -3
  12. package/core/db.js +2 -0
  13. package/core/ent.d.ts +2 -4
  14. package/core/ent.js +70 -23
  15. package/core/loaders/assoc_edge_loader.d.ts +1 -1
  16. package/core/loaders/assoc_edge_loader.js +5 -4
  17. package/core/loaders/index_loader.js +1 -0
  18. package/core/loaders/object_loader.d.ts +7 -2
  19. package/core/loaders/object_loader.js +59 -4
  20. package/core/privacy.js +3 -0
  21. package/core/viewer.d.ts +1 -0
  22. package/core/viewer.js +4 -0
  23. package/graphql/graphql.d.ts +3 -2
  24. package/graphql/graphql.js +22 -21
  25. package/graphql/index.d.ts +1 -0
  26. package/graphql/index.js +3 -1
  27. package/graphql/mutations/union.d.ts +2 -0
  28. package/graphql/mutations/union.js +35 -0
  29. package/graphql/node_resolver.d.ts +0 -1
  30. package/index.d.ts +16 -1
  31. package/index.js +18 -5
  32. package/package.json +2 -2
  33. package/parse_schema/parse.d.ts +11 -4
  34. package/parse_schema/parse.js +50 -6
  35. package/schema/base_schema.d.ts +36 -1
  36. package/schema/base_schema.js +48 -2
  37. package/schema/field.js +1 -1
  38. package/schema/index.d.ts +2 -2
  39. package/schema/index.js +8 -1
  40. package/schema/schema.d.ts +50 -1
  41. package/schema/schema.js +113 -5
  42. package/schema/union_field.d.ts +2 -1
  43. package/schema/union_field.js +32 -14
  44. package/scripts/custom_graphql.js +122 -15
  45. package/scripts/transform_schema.js +204 -55
  46. package/testutils/builder.d.ts +5 -1
  47. package/testutils/builder.js +46 -2
  48. package/testutils/context/test_context.d.ts +2 -2
  49. package/testutils/context/test_context.js +7 -1
  50. package/testutils/db/test_db.d.ts +2 -1
  51. package/testutils/db/test_db.js +13 -4
  52. package/testutils/ent-graphql-tests/index.d.ts +2 -0
  53. package/testutils/ent-graphql-tests/index.js +7 -5
  54. package/testutils/fake_data/fake_contact.d.ts +2 -6
  55. package/testutils/fake_data/fake_contact.js +9 -16
  56. package/testutils/fake_data/fake_event.d.ts +2 -6
  57. package/testutils/fake_data/fake_event.js +17 -24
  58. package/testutils/fake_data/fake_user.d.ts +2 -6
  59. package/testutils/fake_data/fake_user.js +10 -17
  60. package/testutils/fake_data/test_helpers.js +1 -1
@@ -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,17 @@ class ObjectLoaderFactory {
142
187
  constructor(options) {
143
188
  this.options = options;
144
189
  this.toPrime = [];
145
- this.name = `${options.tableName}:${options.key}`;
190
+ // we don't wanna do it here because we want it to be delayed
191
+ let instanceKey = "";
192
+ if (typeof this.options.clause === "function") {
193
+ if (!options.instanceKey) {
194
+ throw new Error(`need to pass an instanceKey to ObjectLoader if clause is a function`);
195
+ }
196
+ }
197
+ else if (this.options.clause) {
198
+ instanceKey = this.options.clause.instanceKey();
199
+ }
200
+ this.name = `${options.tableName}:${options.key}:${instanceKey}`;
146
201
  }
147
202
  createLoader(context) {
148
203
  return (0, loader_1.getLoader)(this, () => {
package/core/privacy.js CHANGED
@@ -464,6 +464,9 @@ async function applyPrivacyPolicyX(v, policy, ent, throwErr) {
464
464
  if (res.error) {
465
465
  throw res.error;
466
466
  }
467
+ if (res.getError) {
468
+ throw res.getError(policy, rule, ent);
469
+ }
467
470
  if (throwErr) {
468
471
  throw throwErr();
469
472
  }
package/core/viewer.d.ts CHANGED
@@ -17,6 +17,7 @@ export declare class IDViewer implements Viewer {
17
17
  context?: Context;
18
18
  constructor(viewerID: ID, opts?: Partial<IDViewerOptions>);
19
19
  constructor(opts: IDViewerOptions);
20
+ setContext(ctx: Context): this;
20
21
  viewer(): Promise<Ent | null>;
21
22
  instanceKey(): string;
22
23
  }
package/core/viewer.js CHANGED
@@ -27,6 +27,10 @@ class IDViewer {
27
27
  this.ent = opts?.ent || null;
28
28
  this.context = opts?.context;
29
29
  }
30
+ setContext(ctx) {
31
+ this.context = ctx;
32
+ return this;
33
+ }
30
34
  async viewer() {
31
35
  return this.ent;
32
36
  }
@@ -82,6 +82,9 @@ declare enum NullableResult {
82
82
  CONTENTS_AND_LIST = "contentsAndList",
83
83
  ITEM = "true"
84
84
  }
85
+ export declare const knownAllowedNames: Map<string, string>;
86
+ export declare const knownDisAllowedNames: Map<string, boolean>;
87
+ export declare const isCustomType: (type: Type) => type is CustomType;
85
88
  export declare const addCustomType: (type: CustomType) => void;
86
89
  export declare class GQLCapture {
87
90
  private static enabled;
@@ -107,8 +110,6 @@ export declare class GQLCapture {
107
110
  static getProcessedCustomMutations(): ProcessedCustomField[];
108
111
  static getProcessedCustomQueries(): ProcessedCustomField[];
109
112
  private static getProcessedCustomFieldsImpl;
110
- private static knownAllowedNames;
111
- private static knownDisAllowedNames;
112
113
  private static getResultFromMetadata;
113
114
  static gqlField(options?: gqlFieldOptions): any;
114
115
  private static getCustomField;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gqlFileUpload = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = exports.GQLCapture = exports.addCustomType = exports.CustomFieldType = void 0;
3
+ exports.gqlFileUpload = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = exports.GQLCapture = exports.addCustomType = exports.isCustomType = exports.knownDisAllowedNames = exports.knownAllowedNames = exports.CustomFieldType = void 0;
4
4
  require("reflect-metadata");
5
5
  // export interface gqlTopLevelOptions
6
6
  // name?: string;
@@ -20,6 +20,22 @@ var NullableResult;
20
20
  NullableResult["CONTENTS_AND_LIST"] = "contentsAndList";
21
21
  NullableResult["ITEM"] = "true";
22
22
  })(NullableResult || (NullableResult = {}));
23
+ exports.knownAllowedNames = new Map([
24
+ ["Date", "Date"],
25
+ ["Boolean", "boolean"],
26
+ ["Number", "number"],
27
+ ["String", "string"],
28
+ // TODO not right to have this and Number
29
+ ["Int", "number"],
30
+ ["Float", "number"],
31
+ ["ID", "ID"],
32
+ ]);
33
+ exports.knownDisAllowedNames = new Map([
34
+ ["Function", true],
35
+ ["Object", true],
36
+ ["Array", true],
37
+ ["Promise", true],
38
+ ]);
23
39
  const isArray = (type) => {
24
40
  if (typeof type === "function") {
25
41
  return false;
@@ -41,6 +57,7 @@ const isString = (type) => {
41
57
  const isCustomType = (type) => {
42
58
  return type.importPath !== undefined;
43
59
  };
60
+ exports.isCustomType = isCustomType;
44
61
  const isGraphQLScalarType = (type) => {
45
62
  return type.serialize !== undefined;
46
63
  };
@@ -92,7 +109,7 @@ const getType = (typ, result) => {
92
109
  }
93
110
  return;
94
111
  }
95
- if (isCustomType(typ)) {
112
+ if ((0, exports.isCustomType)(typ)) {
96
113
  result.type = typ.type;
97
114
  (0, exports.addCustomType)(typ);
98
115
  return;
@@ -197,20 +214,20 @@ class GQLCapture {
197
214
  connection = r.connection;
198
215
  type = r.type;
199
216
  }
200
- if (GQLCapture.knownDisAllowedNames.has(type)) {
217
+ if (exports.knownDisAllowedNames.has(type)) {
201
218
  throw new Error(`${type} isn't a valid type for accessor/function/property`);
202
219
  }
203
220
  let result = {
204
221
  name: metadata.paramName || "",
205
222
  type,
206
- tsType: this.knownAllowedNames.get(type) || this.customTypes.get(type)?.tsType,
223
+ tsType: exports.knownAllowedNames.get(type) || this.customTypes.get(type)?.tsType,
207
224
  nullable: options?.nullable,
208
225
  list: list,
209
226
  connection: connection,
210
227
  isContextArg: metadata.isContextArg,
211
228
  };
212
229
  // unknown type. we need to flag that this field needs to eventually be resolved
213
- if (!GQLCapture.knownAllowedNames.has(type)) {
230
+ if (!exports.knownAllowedNames.has(type)) {
214
231
  if (scalarType) {
215
232
  throw new Error(`custom scalar type ${type} is not supported this way. use CustomType syntax. see \`gqlFileUpload\` as an example`);
216
233
  }
@@ -461,22 +478,6 @@ GQLCapture.customArgs = new Map();
461
478
  GQLCapture.customInputObjects = new Map();
462
479
  GQLCapture.customObjects = new Map();
463
480
  GQLCapture.customTypes = new Map();
464
- GQLCapture.knownAllowedNames = new Map([
465
- ["Date", "Date"],
466
- ["Boolean", "boolean"],
467
- ["Number", "number"],
468
- ["String", "string"],
469
- // TODO not right to have this and Number
470
- ["Int", "number"],
471
- ["Float", "number"],
472
- ["ID", "ID"],
473
- ]);
474
- GQLCapture.knownDisAllowedNames = new Map([
475
- ["Function", true],
476
- ["Object", true],
477
- ["Array", true],
478
- ["Promise", true],
479
- ]);
480
481
  // User -> add -> [{name, options}, {}, {}]
481
482
  GQLCapture.argMap = new Map();
482
483
  // why is this a static class lol?
@@ -8,3 +8,4 @@ export { GraphQLConnectionInterface } from "./builtins/connection";
8
8
  export { GraphQLEdgeInterface } from "./builtins/edge";
9
9
  export { NodeResolver, EntNodeResolver, registerResolver, clearResolvers, resolveID, nodeIDEncoder, mustDecodeIDFromGQLID, mustDecodeNullableIDFromGQLID, encodeGQLID, } from "./node_resolver";
10
10
  export { convertFromGQLEnum, convertToGQLEnum } from "./enums";
11
+ export { transformUnionTypes } from "./mutations/union";
package/graphql/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertToGQLEnum = exports.convertFromGQLEnum = exports.encodeGQLID = exports.mustDecodeNullableIDFromGQLID = exports.mustDecodeIDFromGQLID = exports.nodeIDEncoder = exports.resolveID = exports.clearResolvers = exports.registerResolver = exports.EntNodeResolver = exports.GraphQLEdgeInterface = exports.GraphQLConnectionInterface = exports.GraphQLNodeInterface = exports.GraphQLConnectionType = exports.GraphQLEdgeType = exports.GraphQLEdgeConnection = exports.GraphQLPageInfo = exports.GraphQLTime = exports.gqlFileUpload = exports.GQLCapture = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = void 0;
3
+ exports.transformUnionTypes = exports.convertToGQLEnum = exports.convertFromGQLEnum = exports.encodeGQLID = exports.mustDecodeNullableIDFromGQLID = exports.mustDecodeIDFromGQLID = exports.nodeIDEncoder = exports.resolveID = exports.clearResolvers = exports.registerResolver = exports.EntNodeResolver = exports.GraphQLEdgeInterface = exports.GraphQLConnectionInterface = exports.GraphQLNodeInterface = exports.GraphQLConnectionType = exports.GraphQLEdgeType = exports.GraphQLEdgeConnection = exports.GraphQLPageInfo = exports.GraphQLTime = exports.gqlFileUpload = exports.GQLCapture = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = void 0;
4
4
  var graphql_1 = require("./graphql");
5
5
  Object.defineProperty(exports, "gqlField", { enumerable: true, get: function () { return graphql_1.gqlField; } });
6
6
  Object.defineProperty(exports, "gqlArg", { enumerable: true, get: function () { return graphql_1.gqlArg; } });
@@ -40,3 +40,5 @@ Object.defineProperty(exports, "encodeGQLID", { enumerable: true, get: function
40
40
  var enums_1 = require("./enums");
41
41
  Object.defineProperty(exports, "convertFromGQLEnum", { enumerable: true, get: function () { return enums_1.convertFromGQLEnum; } });
42
42
  Object.defineProperty(exports, "convertToGQLEnum", { enumerable: true, get: function () { return enums_1.convertToGQLEnum; } });
43
+ var union_1 = require("./mutations/union");
44
+ Object.defineProperty(exports, "transformUnionTypes", { enumerable: true, get: function () { return union_1.transformUnionTypes; } });
@@ -0,0 +1,2 @@
1
+ import { Data } from "../../core/base";
2
+ export declare function transformUnionTypes<T extends Data>(input: T, pathsList: string[][]): T;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformUnionTypes = void 0;
4
+ // this transforms an input for union types from graphql format to TS format
5
+ // in graphql, we represent it as UnionType = {foo: FooType, bar: BarType, baz: BazType}
6
+ // in TS, we repseent it as UnionType = FooType | BarType | BazType
7
+ // this takes an input, paths to unions and transforms them as needed
8
+ // only works on fields that are defined. depends on graphql to handle nullable/missing fields
9
+ function transformUnionTypes(input, pathsList) {
10
+ for (const paths of pathsList) {
11
+ const lastPath = paths[paths.length - 1];
12
+ let last = input;
13
+ for (const path of paths) {
14
+ let curr = last[path];
15
+ if (curr === undefined) {
16
+ break;
17
+ }
18
+ if (path === lastPath) {
19
+ let count = 0;
20
+ let lastKey = undefined;
21
+ for (const k in curr) {
22
+ count++;
23
+ lastKey = k;
24
+ }
25
+ if (count != 1) {
26
+ throw new Error(`can only only pass one key of union. passed ${count}`);
27
+ }
28
+ last[path] = curr[lastKey];
29
+ }
30
+ last = curr;
31
+ }
32
+ }
33
+ return input;
34
+ }
35
+ exports.transformUnionTypes = transformUnionTypes;
@@ -5,7 +5,6 @@ interface Node {
5
5
  id: ID;
6
6
  }
7
7
  export interface NodeResolver {
8
- encode(node: Node): string;
9
8
  decodeObj(viewer: Viewer, id: string): Promise<Node | null>;
10
9
  }
11
10
  interface loadEnt {
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "./core/base";
2
- export { loadEnt, loadCustomData, loadCustomEnts, loadEntX, loadEnts, CustomQuery, loadDerivedEnt, loadDerivedEntX, loadEntViaKey, loadEntXViaKey, applyPrivacyPolicyForEnt, applyPrivacyPolicyForEntX, performRawQuery, loadRowX, loadRow, loadRows, DataOperation, EditNodeOptions, EditNodeOperation, EdgeOperation, DeleteNodeOperation, AssocEdge, AssocEdgeInputOptions, AssocEdgeInput, AssocEdgeData, loadEdgeData, loadEdgeDatas, loadEdges, loadUniqueEdge, loadUniqueNode, loadRawEdgeCountX, loadEdgeForID2, loadNodesByEdge, getEdgeTypeInGroup, } from "./core/ent";
2
+ export { loadEnt, loadCustomData, loadCustomEnts, loadEntX, loadEnts, CustomQuery, loadDerivedEnt, loadDerivedEntX, loadEntViaKey, loadEntXViaKey, performRawQuery, loadRowX, loadRow, loadRows, DataOperation, EditNodeOptions, EditNodeOperation, EdgeOperation, DeleteNodeOperation, AssocEdge, AssocEdgeInputOptions, AssocEdgeInput, AssocEdgeData, loadEdgeData, loadEdgeDatas, loadEdges, loadUniqueEdge, loadUniqueNode, loadRawEdgeCountX, loadEdgeForID2, loadNodesByEdge, getEdgeTypeInGroup, } from "./core/ent";
3
3
  import DB from "./core/db";
4
4
  export * from "./core/loaders";
5
5
  export { DB };
@@ -11,12 +11,27 @@ declare const query: {
11
11
  Eq: typeof q.Eq;
12
12
  NotEq: typeof q.NotEq;
13
13
  And: typeof q.And;
14
+ AndOptional: typeof q.AndOptional;
14
15
  Or: typeof q.Or;
15
16
  In: typeof q.In;
16
17
  Greater: typeof q.Greater;
17
18
  Less: typeof q.Less;
18
19
  GreaterEq: typeof q.GreaterEq;
19
20
  LessEq: typeof q.LessEq;
21
+ ArrayEq: typeof q.ArrayEq;
22
+ ArrayNotEq: typeof q.ArrayNotEq;
23
+ ArrayGreater: typeof q.ArrayGreater;
24
+ ArrayLess: typeof q.ArrayLess;
25
+ ArrayGreaterEq: typeof q.ArrayGreaterEq;
26
+ ArrayLessEq: typeof q.ArrayLessEq;
27
+ TsQuery: typeof q.TsQuery;
28
+ PlainToTsQuery: typeof q.PlainToTsQuery;
29
+ PhraseToTsQuery: typeof q.PhraseToTsQuery;
30
+ WebsearchToTsQuery: typeof q.WebsearchToTsQuery;
31
+ TsVectorColTsQuery: typeof q.TsVectorColTsQuery;
32
+ TsVectorPlainToTsQuery: typeof q.TsVectorPlainToTsQuery;
33
+ TsVectorPhraseToTsQuery: typeof q.TsVectorPhraseToTsQuery;
34
+ TsVectorWebsearchToTsQuery: typeof q.TsVectorWebsearchToTsQuery;
20
35
  };
21
36
  export { query };
22
37
  export { RequestContext, ContextCache } from "./core/context";
package/index.js CHANGED
@@ -25,8 +25,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
25
25
  return (mod && mod.__esModule) ? mod : { "default": mod };
26
26
  };
27
27
  Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.DenyIfViewerOutboundEdgeExistsRule = exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.AllowIfFuncRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedOutRule = exports.DenyIfLoggedInRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = exports.DB = exports.getEdgeTypeInGroup = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadEdges = exports.loadEdgeDatas = exports.loadEdgeData = exports.AssocEdgeData = exports.AssocEdge = exports.DeleteNodeOperation = exports.EdgeOperation = exports.EditNodeOperation = exports.loadRows = exports.loadRow = exports.loadRowX = exports.performRawQuery = exports.applyPrivacyPolicyForEntX = exports.applyPrivacyPolicyForEnt = exports.loadEntXViaKey = exports.loadEntViaKey = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadEnts = exports.loadEntX = exports.loadCustomEnts = exports.loadCustomData = exports.loadEnt = void 0;
29
- exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = exports.DenyIfViewerInboundEdgeDoesNotExistRule = exports.DenyIfEdgeDoesNotExistRule = void 0;
28
+ exports.DenyIfViewerInboundEdgeDoesNotExistRule = exports.DenyIfEdgeDoesNotExistRule = exports.DenyIfViewerOutboundEdgeExistsRule = exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.AllowIfFuncRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedOutRule = exports.DenyIfLoggedInRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = exports.DB = exports.getEdgeTypeInGroup = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadEdges = exports.loadEdgeDatas = exports.loadEdgeData = exports.AssocEdgeData = exports.AssocEdge = exports.DeleteNodeOperation = exports.EdgeOperation = exports.EditNodeOperation = exports.loadRows = exports.loadRow = exports.loadRowX = exports.performRawQuery = exports.loadEntXViaKey = exports.loadEntViaKey = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadEnts = exports.loadEntX = exports.loadCustomEnts = exports.loadCustomData = exports.loadEnt = void 0;
29
+ exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = void 0;
30
30
  __exportStar(require("./core/base"), exports);
31
31
  var ent_1 = require("./core/ent");
32
32
  Object.defineProperty(exports, "loadEnt", { enumerable: true, get: function () { return ent_1.loadEnt; } });
@@ -38,8 +38,6 @@ Object.defineProperty(exports, "loadDerivedEnt", { enumerable: true, get: functi
38
38
  Object.defineProperty(exports, "loadDerivedEntX", { enumerable: true, get: function () { return ent_1.loadDerivedEntX; } });
39
39
  Object.defineProperty(exports, "loadEntViaKey", { enumerable: true, get: function () { return ent_1.loadEntViaKey; } });
40
40
  Object.defineProperty(exports, "loadEntXViaKey", { enumerable: true, get: function () { return ent_1.loadEntXViaKey; } });
41
- Object.defineProperty(exports, "applyPrivacyPolicyForEnt", { enumerable: true, get: function () { return ent_1.applyPrivacyPolicyForEnt; } });
42
- Object.defineProperty(exports, "applyPrivacyPolicyForEntX", { enumerable: true, get: function () { return ent_1.applyPrivacyPolicyForEntX; } });
43
41
  Object.defineProperty(exports, "performRawQuery", { enumerable: true, get: function () { return ent_1.performRawQuery; } });
44
42
  // even these 3 need to change...
45
43
  Object.defineProperty(exports, "loadRowX", { enumerable: true, get: function () { return ent_1.loadRowX; } });
@@ -62,7 +60,7 @@ Object.defineProperty(exports, "getEdgeTypeInGroup", { enumerable: true, get: fu
62
60
  const db_1 = __importDefault(require("./core/db"));
63
61
  exports.DB = db_1.default;
64
62
  __exportStar(require("./core/loaders"), exports);
65
- // TODO figure out if this should be its own
63
+ // TODO figure out if this should be its own import path e.g. @snowtop/ent/privacy
66
64
  var privacy_1 = require("./core/privacy");
67
65
  Object.defineProperty(exports, "EntPrivacyError", { enumerable: true, get: function () { return privacy_1.EntPrivacyError; } });
68
66
  Object.defineProperty(exports, "AlwaysAllowRule", { enumerable: true, get: function () { return privacy_1.AlwaysAllowRule; } });
@@ -109,12 +107,27 @@ const query = {
109
107
  Eq: q.Eq,
110
108
  NotEq: q.NotEq,
111
109
  And: q.And,
110
+ AndOptional: q.AndOptional,
112
111
  Or: q.Or,
113
112
  In: q.In,
114
113
  Greater: q.Greater,
115
114
  Less: q.Less,
116
115
  GreaterEq: q.GreaterEq,
117
116
  LessEq: q.LessEq,
117
+ ArrayEq: q.ArrayEq,
118
+ ArrayNotEq: q.ArrayNotEq,
119
+ ArrayGreater: q.ArrayGreater,
120
+ ArrayLess: q.ArrayLess,
121
+ ArrayGreaterEq: q.ArrayGreaterEq,
122
+ ArrayLessEq: q.ArrayLessEq,
123
+ TsQuery: q.TsQuery,
124
+ PlainToTsQuery: q.PlainToTsQuery,
125
+ PhraseToTsQuery: q.PhraseToTsQuery,
126
+ WebsearchToTsQuery: q.WebsearchToTsQuery,
127
+ TsVectorColTsQuery: q.TsVectorColTsQuery,
128
+ TsVectorPlainToTsQuery: q.TsVectorPlainToTsQuery,
129
+ TsVectorPhraseToTsQuery: q.TsVectorPhraseToTsQuery,
130
+ TsVectorWebsearchToTsQuery: q.TsVectorWebsearchToTsQuery,
118
131
  };
119
132
  exports.query = query;
120
133
  var context_1 = require("./core/context");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.1.0-alpha3",
3
+ "version": "0.1.0-alpha8",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "json5": "^2.1.3",
18
18
  "luxon": "^1.25.0",
19
19
  "memoizee": "^0.4.15",
20
- "minimist": "^1.2.5",
20
+ "minimist": "^1.2.6",
21
21
  "pascal-case": "^3.1.2",
22
22
  "pg": "^8.0.3",
23
23
  "prettier": "^2.3.2",
@@ -1,5 +1,5 @@
1
- import { Schema, Field, AssocEdge, AssocEdgeGroup, Action, Type } from "../schema";
2
- import { ActionField } from "../schema/schema";
1
+ import { Schema, Field, AssocEdge, AssocEdgeGroup, Action } from "../schema";
2
+ import { ActionField, Type } from "../schema/schema";
3
3
  declare enum NullableResult {
4
4
  CONTENTS = "contents",
5
5
  CONTENTS_AND_LIST = "contentsAndList",
@@ -12,7 +12,13 @@ declare type ProcessedAssocEdge = Omit<AssocEdge, "actionOnlyFields" | "edgeActi
12
12
  patternName?: string;
13
13
  edgeActions?: OutputAction[];
14
14
  };
15
- declare type ProcessedSchema = Omit<Schema, "edges" | "actions" | "edgeGroups" | "fields"> & {
15
+ interface TransformFlags {
16
+ transformsSelect?: boolean;
17
+ transformsDelete?: boolean;
18
+ transformsInsert?: boolean;
19
+ transformsUpdate?: boolean;
20
+ }
21
+ declare type ProcessedSchema = Omit<Schema, "edges" | "actions" | "edgeGroups" | "fields"> & TransformFlags & {
16
22
  actions: OutputAction[];
17
23
  assocEdges: ProcessedAssocEdge[];
18
24
  assocEdgeGroups: ProcessedAssocEdgeGroup[];
@@ -37,11 +43,12 @@ declare type ProcessedType = Omit<Type, "subFields" | "listElemType" | "unionFie
37
43
  listElemType?: ProcessedType;
38
44
  unionFields?: ProcessedField[];
39
45
  };
40
- declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate" | "type"> & {
46
+ declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate" | "privacyPolicy" | "type"> & {
41
47
  name: string;
42
48
  hasDefaultValueOnCreate?: boolean;
43
49
  hasDefaultValueOnEdit?: boolean;
44
50
  patternName?: string;
51
+ hasFieldPrivacy?: boolean;
45
52
  derivedFields?: ProcessedField[];
46
53
  type: ProcessedType;
47
54
  };
@@ -22,6 +22,7 @@ function processFields(src, patternName) {
22
22
  let f = { name, ...field };
23
23
  f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
24
24
  f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
25
+ f.hasFieldPrivacy = field.privacyPolicy !== undefined;
25
26
  if (field.polymorphic) {
26
27
  // convert boolean into object
27
28
  // we keep boolean as an option to keep API simple
@@ -46,6 +47,7 @@ function processFields(src, patternName) {
46
47
  if (patternName) {
47
48
  f.patternName = patternName;
48
49
  }
50
+ transformType(field.type);
49
51
  if (field.getDerivedFields) {
50
52
  f.derivedFields = processFields(field.getDerivedFields(name));
51
53
  }
@@ -65,6 +67,24 @@ function processFields(src, patternName) {
65
67
  }
66
68
  return ret;
67
69
  }
70
+ function transformImportType(typ) {
71
+ if (!typ.importType) {
72
+ return;
73
+ }
74
+ typ.importType = {
75
+ ...typ.importType,
76
+ // these 2 needed for forwards compatibility with new go schema
77
+ importPath: typ.importType.path,
78
+ import: typ.importType.type,
79
+ };
80
+ }
81
+ function transformType(typ) {
82
+ if (!typ) {
83
+ return;
84
+ }
85
+ transformImportType(typ);
86
+ transformType(typ.listElemType);
87
+ }
68
88
  function processEdges(src, patternName) {
69
89
  const ret = [];
70
90
  for (const edge of src) {
@@ -89,6 +109,9 @@ function processEdgeGroups(processedSchema, edgeGroups) {
89
109
  }
90
110
  }
91
111
  function processPattern(patterns, pattern, processedSchema) {
112
+ let ret = {
113
+ ...pattern,
114
+ };
92
115
  const name = pattern.name;
93
116
  const fields = processFields(pattern.fields, pattern.name);
94
117
  processedSchema.fields.push(...fields);
@@ -96,6 +119,10 @@ function processPattern(patterns, pattern, processedSchema) {
96
119
  const edges = processEdges(pattern.edges, pattern.name);
97
120
  processedSchema.assocEdges.push(...edges);
98
121
  }
122
+ // flag transformsSelect
123
+ if (pattern.transformRead) {
124
+ ret.transformsSelect = true;
125
+ }
99
126
  if (patterns[name] === undefined) {
100
127
  // intentionally processing separately and not passing pattern.name
101
128
  const edges = processEdges(pattern.edges || []);
@@ -109,6 +136,7 @@ function processPattern(patterns, pattern, processedSchema) {
109
136
  // TODO ideally we want to make sure that different patterns don't have the same name
110
137
  // can't do a deepEqual check because function calls and therefore different instances in fields
111
138
  }
139
+ return ret;
112
140
  }
113
141
  var NullableResult;
114
142
  (function (NullableResult) {
@@ -149,11 +177,15 @@ function parseSchema(potentialSchemas) {
149
177
  for (const key in potentialSchemas) {
150
178
  const value = potentialSchemas[key];
151
179
  let schema;
152
- if (value.constructor == Object) {
153
- schema = value;
154
- }
155
- else {
156
- schema = new value();
180
+ const name = value.constructor.name;
181
+ // named class e.g. new BaseEntSchema
182
+ switch (name) {
183
+ case "Function":
184
+ schema = new value();
185
+ break;
186
+ default:
187
+ // implicit schema or named class
188
+ schema = value;
157
189
  }
158
190
  let processedSchema = {
159
191
  fields: [],
@@ -171,7 +203,19 @@ function parseSchema(potentialSchemas) {
171
203
  // ¯\_(ツ)_/¯
172
204
  if (schema.patterns) {
173
205
  for (const pattern of schema.patterns) {
174
- processPattern(patterns, pattern, processedSchema);
206
+ const ret = processPattern(patterns, pattern, processedSchema);
207
+ if (ret.transformsSelect) {
208
+ if (processedSchema.transformsSelect) {
209
+ throw new Error(`can only have one pattern which transforms default querying behavior`);
210
+ }
211
+ processedSchema.transformsSelect = true;
212
+ }
213
+ if (ret.transformsDelete) {
214
+ if (processedSchema.transformsDelete) {
215
+ throw new Error(`can only have one pattern which transforms default deletion behavior`);
216
+ }
217
+ processedSchema.transformsDelete = true;
218
+ }
175
219
  }
176
220
  }
177
221
  const fields = processFields(schema.fields);
@@ -1,6 +1,41 @@
1
- import { Pattern } from "./schema";
1
+ import { Field, FieldMap, Pattern } from "./schema";
2
+ import { Action, AssocEdgeGroup, Constraint, Edge, Index, Schema } from ".";
2
3
  export declare const Timestamps: Pattern;
3
4
  export declare const Node: Pattern;
5
+ export interface SchemaConfig extends Schema {
6
+ }
7
+ export declare class EntSchema implements Schema {
8
+ fields: FieldMap | Field[];
9
+ tableName: string | undefined;
10
+ patterns: Pattern[];
11
+ edges: Edge[] | undefined;
12
+ edgeGroups: AssocEdgeGroup[] | undefined;
13
+ actions: Action[] | undefined;
14
+ enumTable: boolean | undefined;
15
+ dbRows: {
16
+ [key: string]: any;
17
+ }[] | undefined;
18
+ constraints: Constraint[] | undefined;
19
+ indices: Index[] | undefined;
20
+ hideFromGraphQL?: boolean;
21
+ constructor(cfg: SchemaConfig);
22
+ }
23
+ export declare class EntSchemaWithTZ {
24
+ fields: FieldMap | Field[];
25
+ tableName: string | undefined;
26
+ patterns: Pattern[];
27
+ edges: Edge[] | undefined;
28
+ edgeGroups: AssocEdgeGroup[] | undefined;
29
+ actions: Action[] | undefined;
30
+ enumTable: boolean | undefined;
31
+ dbRows: {
32
+ [key: string]: any;
33
+ }[] | undefined;
34
+ constraints: Constraint[] | undefined;
35
+ indices: Index[] | undefined;
36
+ hideFromGraphQL?: boolean;
37
+ constructor(cfg: SchemaConfig);
38
+ }
4
39
  export declare abstract class BaseEntSchema {
5
40
  addPatterns(...patterns: Pattern[]): void;
6
41
  patterns: Pattern[];