@snowtop/ent 0.0.34 → 0.0.37

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/base.d.ts CHANGED
@@ -108,6 +108,7 @@ declare enum privacyResult {
108
108
  export interface PrivacyResult {
109
109
  result: privacyResult;
110
110
  error?: PrivacyError;
111
+ getError?(policy: PrivacyPolicy, rule: PrivacyPolicyRule, ent?: Ent): PrivacyError;
111
112
  }
112
113
  export interface PrivacyError extends Error {
113
114
  privacyPolicy: PrivacyPolicy;
@@ -116,7 +117,7 @@ export interface PrivacyError extends Error {
116
117
  export declare function Allow(): PrivacyResult;
117
118
  export declare function Skip(): PrivacyResult;
118
119
  export declare function Deny(): PrivacyResult;
119
- export declare function DenyWithReason(e: PrivacyError): PrivacyResult;
120
+ export declare function DenyWithReason(e: PrivacyError | string): PrivacyResult;
120
121
  export interface PrivacyPolicyRule {
121
122
  apply(v: Viewer, ent?: Ent): Promise<PrivacyResult>;
122
123
  }
package/core/base.js CHANGED
@@ -30,7 +30,23 @@ function Deny() {
30
30
  return deny;
31
31
  }
32
32
  exports.Deny = Deny;
33
+ class DenyWithReasonError extends Error {
34
+ constructor(privacyPolicy, rule, msg, ent) {
35
+ super(msg);
36
+ this.privacyPolicy = privacyPolicy;
37
+ this.privacyRule = rule;
38
+ this.ent = ent;
39
+ }
40
+ }
33
41
  function DenyWithReason(e) {
42
+ if (typeof e === "string") {
43
+ return {
44
+ result: privacyResult.Deny,
45
+ getError(policy, rule, ent) {
46
+ return new DenyWithReasonError(policy, rule, e, ent);
47
+ },
48
+ };
49
+ }
34
50
  return {
35
51
  result: privacyResult.Deny,
36
52
  error: e,
@@ -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
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.0.34",
3
+ "version": "0.0.37",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1,4 +1,4 @@
1
- import { Schema, AssocEdge, AssocEdgeGroup, Action } from "../schema";
1
+ import { Schema, Field, AssocEdge, AssocEdgeGroup, Action } from "../schema";
2
2
  import { ActionField } from "../schema/schema";
3
3
  declare enum NullableResult {
4
4
  CONTENTS = "contents",
@@ -12,10 +12,11 @@ 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"> & {
15
+ declare type ProcessedSchema = Omit<Schema, "edges" | "actions" | "edgeGroups" | "fields"> & {
16
16
  actions: OutputAction[];
17
17
  assocEdges: ProcessedAssocEdge[];
18
18
  assocEdgeGroups: ProcessedAssocEdgeGroup[];
19
+ fields: ProcessedField[];
19
20
  };
20
21
  declare type ProcessedAssocEdgeGroup = Omit<AssocEdgeGroup, "edgeAction"> & {
21
22
  edgeAction?: OutputAction;
@@ -29,7 +30,13 @@ interface schemasDict {
29
30
  interface ProcessedPattern {
30
31
  name: string;
31
32
  assocEdges: ProcessedAssocEdge[];
33
+ fields: ProcessedField[];
32
34
  }
35
+ declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate"> & {
36
+ hasDefaultValueOnCreate?: boolean;
37
+ hasDefaultValueOnEdit?: boolean;
38
+ patternName?: string;
39
+ };
33
40
  interface patternsDict {
34
41
  [key: string]: ProcessedPattern;
35
42
  }
@@ -1,21 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseSchema = void 0;
4
- function processFields(processedSchema, src) {
4
+ function processFields(src, patternName) {
5
+ const ret = [];
5
6
  for (const field of src) {
6
7
  let f = { ...field };
7
- f["hasDefaultValueOnCreate"] = field.defaultValueOnCreate != undefined;
8
- f["hasDefaultValueOnEdit"] = field.defaultValueOnEdit != undefined;
8
+ f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
9
+ f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
9
10
  if (field.polymorphic) {
10
11
  // convert boolean into object
11
12
  // we keep boolean as an option to keep API simple
12
13
  if (typeof field.polymorphic === "boolean") {
13
- f["polymorphic"] = {};
14
+ f.polymorphic = {};
14
15
  }
15
16
  else {
16
- f["polymorphic"] = field.polymorphic;
17
+ f.polymorphic = field.polymorphic;
17
18
  }
18
19
  }
20
+ else {
21
+ delete f.polymorphic;
22
+ }
19
23
  // convert string to object to make API consumed by go simple
20
24
  if (f.fieldEdge && f.fieldEdge.inverseEdge) {
21
25
  if (typeof f.fieldEdge.inverseEdge === "string") {
@@ -24,16 +28,41 @@ function processFields(processedSchema, src) {
24
28
  };
25
29
  }
26
30
  }
27
- processedSchema.fields.push(f);
31
+ if (patternName) {
32
+ f.patternName = patternName;
33
+ }
34
+ transformType(field.type);
35
+ ret.push(f);
36
+ }
37
+ return ret;
38
+ }
39
+ function transformImportType(typ) {
40
+ if (!typ.importType) {
41
+ return;
42
+ }
43
+ typ.importType = {
44
+ ...typ.importType,
45
+ // these 2 needed for forwards compatibility with new go schema
46
+ importPath: typ.importType.path,
47
+ import: typ.importType.type,
48
+ };
49
+ }
50
+ function transformType(typ) {
51
+ if (!typ) {
52
+ return;
28
53
  }
54
+ transformImportType(typ);
55
+ transformType(typ.listElemType);
29
56
  }
30
- function processEdges(dst, src, patternName) {
57
+ function processEdges(src, patternName) {
58
+ const ret = [];
31
59
  for (const edge of src) {
32
60
  let edge2 = { ...edge };
33
61
  edge2.edgeActions = edge.edgeActions?.map((action) => processAction(action));
34
62
  edge2.patternName = patternName;
35
- dst.push(edge2);
63
+ ret.push(edge2);
36
64
  }
65
+ return ret;
37
66
  }
38
67
  function processEdgeGroups(processedSchema, edgeGroups) {
39
68
  // array-ify this
@@ -49,26 +78,26 @@ function processEdgeGroups(processedSchema, edgeGroups) {
49
78
  }
50
79
  }
51
80
  function processPattern(patterns, pattern, processedSchema) {
52
- // TODO kill
53
- let name = pattern.name || "node";
81
+ const name = pattern.name;
82
+ const fields = processFields(pattern.fields, pattern.name);
83
+ processedSchema.fields.push(...fields);
84
+ if (pattern.edges) {
85
+ const edges = processEdges(pattern.edges, pattern.name);
86
+ processedSchema.assocEdges.push(...edges);
87
+ }
54
88
  if (patterns[name] === undefined) {
55
- const edges = [];
56
- if (pattern.edges) {
57
- processEdges(edges, pattern.edges);
58
- }
89
+ // intentionally processing separately and not passing pattern.name
90
+ const edges = processEdges(pattern.edges || []);
59
91
  patterns[name] = {
60
92
  name: pattern.name,
61
93
  assocEdges: edges,
94
+ fields: fields,
62
95
  };
63
96
  }
64
97
  else {
65
98
  // TODO ideally we want to make sure that different patterns don't have the same name
66
99
  // can't do a deepEqual check because function calls and therefore different instances in fields
67
100
  }
68
- processFields(processedSchema, pattern.fields);
69
- if (pattern.edges) {
70
- processEdges(processedSchema.assocEdges, pattern.edges, pattern.name);
71
- }
72
101
  }
73
102
  var NullableResult;
74
103
  (function (NullableResult) {
@@ -84,6 +113,7 @@ function processAction(action) {
84
113
  let actionOnlyFields = action.actionOnlyFields.map((f) => {
85
114
  let f2 = f;
86
115
  if (!f.nullable) {
116
+ delete f2.nullable;
87
117
  return f2;
88
118
  }
89
119
  if (typeof f.nullable === "boolean") {
@@ -133,9 +163,11 @@ function parseSchema(potentialSchemas) {
133
163
  processPattern(patterns, pattern, processedSchema);
134
164
  }
135
165
  }
136
- processFields(processedSchema, schema.fields);
166
+ const fields = processFields(schema.fields);
167
+ processedSchema.fields.push(...fields);
137
168
  if (schema.edges) {
138
- processEdges(processedSchema.assocEdges, schema.edges);
169
+ const edges = processEdges(schema.edges);
170
+ processedSchema.assocEdges.push(...edges);
139
171
  }
140
172
  if (schema.edgeGroups) {
141
173
  processEdgeGroups(processedSchema, schema.edgeGroups);
@@ -82,6 +82,7 @@ export declare enum DBType {
82
82
  export interface ImportType {
83
83
  path: string;
84
84
  type: string;
85
+ [x: string]: any;
85
86
  }
86
87
  declare type EnumMap = {
87
88
  [key: string]: string;
@@ -131,6 +132,7 @@ export interface FieldOptions {
131
132
  fieldEdge?: FieldEdge;
132
133
  primaryKey?: boolean;
133
134
  disableUserEditable?: boolean;
135
+ disableUserGraphQLEditable?: boolean;
134
136
  defaultValueOnCreate?(builder: Builder<Ent>, input: Data): any;
135
137
  defaultToViewerOnCreate?: boolean;
136
138
  defaultValueOnEdit?(builder: Builder<Ent>, input: Data): any;
@@ -16,6 +16,8 @@ interface queryConfig {
16
16
  callback?: (res: supertest.Response) => void;
17
17
  inlineFragmentRoot?: string;
18
18
  customHandlers?: RequestHandler[];
19
+ server?: any;
20
+ graphQLPath?: string;
19
21
  }
20
22
  export interface queryRootConfig extends queryConfig {
21
23
  root: string;
@@ -56,7 +56,7 @@ function server(config) {
56
56
  };
57
57
  return doWork();
58
58
  }));
59
- app.use("/graphql", ...handlers);
59
+ app.use(config.graphQLPath || "/graphql", ...handlers);
60
60
  return app;
61
61
  }
62
62
  function getInnerType(typ, list) {
@@ -72,14 +72,14 @@ function makeGraphQLRequest(config, query, fieldArgs) {
72
72
  let test;
73
73
  if (config.test) {
74
74
  if (typeof config.test === "function") {
75
- test = config.test(server(config));
75
+ test = config.test(config.server ? config.server : server(config));
76
76
  }
77
77
  else {
78
78
  test = config.test;
79
79
  }
80
80
  }
81
81
  else {
82
- test = (0, supertest_1.default)(server(config));
82
+ test = (0, supertest_1.default)(config.server ? config.server : server(config));
83
83
  }
84
84
  let files = new Map();
85
85
  // handle files
@@ -104,7 +104,9 @@ function makeGraphQLRequest(config, query, fieldArgs) {
104
104
  }
105
105
  });
106
106
  if (files.size) {
107
- let ret = test.post("/graphql").set(config.headers || {});
107
+ let ret = test
108
+ .post(config.graphQLPath || "/graphql")
109
+ .set(config.headers || {});
108
110
  ret.field("operations", JSON.stringify({
109
111
  query: query,
110
112
  variables: config.args,
@@ -130,7 +132,7 @@ function makeGraphQLRequest(config, query, fieldArgs) {
130
132
  return [
131
133
  test,
132
134
  test
133
- .post("/graphql")
135
+ .post(config.graphQLPath || "/graphql")
134
136
  .set(config.headers || {})
135
137
  .send({
136
138
  query: query,