@snowtop/ent 0.0.35 → 0.1.0-alpha3

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 (44) hide show
  1. package/action/action.d.ts +14 -14
  2. package/action/experimental_action.d.ts +20 -20
  3. package/action/experimental_action.js +1 -1
  4. package/action/orchestrator.d.ts +9 -9
  5. package/action/orchestrator.js +11 -11
  6. package/core/base.d.ts +7 -8
  7. package/core/base.js +0 -16
  8. package/core/ent.d.ts +2 -1
  9. package/core/ent.js +13 -8
  10. package/core/privacy.js +0 -3
  11. package/core/query/assoc_query.js +2 -2
  12. package/core/query/query.d.ts +1 -1
  13. package/imports/index.d.ts +0 -1
  14. package/imports/index.js +3 -36
  15. package/package.json +1 -1
  16. package/parse_schema/parse.d.ts +10 -2
  17. package/parse_schema/parse.js +32 -2
  18. package/schema/base_schema.js +15 -15
  19. package/schema/field.d.ts +25 -25
  20. package/schema/field.js +41 -32
  21. package/schema/index.d.ts +3 -1
  22. package/schema/index.js +2 -0
  23. package/schema/json_field.d.ts +6 -6
  24. package/schema/json_field.js +2 -2
  25. package/schema/schema.d.ts +10 -5
  26. package/schema/schema.js +18 -5
  27. package/schema/struct_field.d.ts +17 -0
  28. package/schema/struct_field.js +102 -0
  29. package/schema/union_field.d.ts +22 -0
  30. package/schema/union_field.js +61 -0
  31. package/scripts/custom_compiler.js +2 -19
  32. package/scripts/transform_schema.d.ts +1 -0
  33. package/scripts/transform_schema.js +288 -0
  34. package/testutils/builder.d.ts +13 -13
  35. package/testutils/db/test_db.js +9 -9
  36. package/testutils/fake_data/fake_contact.d.ts +2 -2
  37. package/testutils/fake_data/fake_contact.js +6 -13
  38. package/testutils/fake_data/fake_event.d.ts +2 -2
  39. package/testutils/fake_data/fake_event.js +8 -16
  40. package/testutils/fake_data/fake_user.d.ts +2 -2
  41. package/testutils/fake_data/fake_user.js +7 -16
  42. package/testutils/fake_data/user_query.d.ts +2 -2
  43. package/tsc/compilerOptions.d.ts +2 -0
  44. package/tsc/compilerOptions.js +61 -0
@@ -32,24 +32,24 @@ export interface Changeset<T extends Ent> {
32
32
  dependencies?: Map<ID, Builder<Ent>>;
33
33
  }
34
34
  export declare type TriggerReturn = void | Promise<Changeset<Ent> | void | (Changeset<Ent> | void)[]> | Promise<Changeset<Ent>>[];
35
- export interface Trigger<T extends Ent> {
36
- changeset(builder: Builder<T>, input: Data): TriggerReturn;
35
+ export interface Trigger<TBuilder extends Builder<Ent>, TData extends Data> {
36
+ changeset(builder: TBuilder, input: TData): TriggerReturn;
37
37
  }
38
- export interface Observer<T extends Ent> {
39
- observe(builder: Builder<T>, input: Data): void | Promise<void>;
38
+ export interface Observer<TBuilder extends Builder<Ent>, TData extends Data> {
39
+ observe(builder: TBuilder, input: TData): void | Promise<void>;
40
40
  }
41
- export interface Validator<T extends Ent> {
42
- validate(builder: Builder<T>, input: Data): Promise<void> | void;
41
+ export interface Validator<TBuilder extends Builder<Ent>, TData extends Data> {
42
+ validate(builder: TBuilder, input: TData): Promise<void> | void;
43
43
  }
44
- export interface Action<T extends Ent> {
44
+ export interface Action<TEnt extends Ent, TBuilder extends Builder<TEnt>, TData extends Data> {
45
45
  readonly viewer: Viewer;
46
- changeset(): Promise<Changeset<T>>;
47
- builder: Builder<T>;
48
- getPrivacyPolicy(): PrivacyPolicy;
49
- triggers?: Trigger<T>[];
50
- observers?: Observer<T>[];
51
- validators?: Validator<T>[];
52
- getInput(): Data;
46
+ changeset(): Promise<Changeset<TEnt>>;
47
+ builder: TBuilder;
48
+ getPrivacyPolicy(): PrivacyPolicy<TEnt>;
49
+ triggers?: Trigger<TBuilder, TData>[];
50
+ observers?: Observer<TBuilder, TData>[];
51
+ validators?: Validator<TBuilder, TData>[];
52
+ getInput(): TData;
53
53
  valid(): Promise<boolean>;
54
54
  validX(): Promise<void>;
55
55
  viewerForEntLoad?(data: Data): Viewer | Promise<Viewer>;
@@ -1,8 +1,8 @@
1
1
  import { Viewer, Ent, Data } from "../core/base";
2
2
  import { Action, WriteOperation, Builder, Trigger, Observer, Changeset, Validator } from "./action";
3
- export interface ActionOptions<T extends Ent> {
3
+ export interface ActionOptions<T extends Ent, TData extends Data> {
4
4
  existingEnt?: T | null;
5
- input?: {};
5
+ input?: TData;
6
6
  operation?: WriteOperation;
7
7
  }
8
8
  interface EntBuilder<T extends Ent> extends Builder<T> {
@@ -13,28 +13,28 @@ interface EntBuilder<T extends Ent> extends Builder<T> {
13
13
  editedEnt(): Promise<T | null>;
14
14
  editedEntX(): Promise<T>;
15
15
  }
16
- export declare class BaseAction<T extends Ent> implements Action<T> {
16
+ export declare class BaseAction<TEnt extends Ent, TData extends Data> implements Action<TEnt, EntBuilder<TEnt>, TData> {
17
17
  viewer: Viewer;
18
- builderCtr: BuilderConstructor<T>;
19
- builder: EntBuilder<T>;
18
+ builderCtr: BuilderConstructor<TEnt, TData>;
19
+ builder: EntBuilder<TEnt>;
20
20
  private input;
21
- triggers: Trigger<Ent>[];
22
- observers: Observer<Ent>[];
23
- validators: Validator<Ent>[];
24
- getPrivacyPolicy(): import("../core/base").PrivacyPolicy;
25
- constructor(viewer: Viewer, builderCtr: BuilderConstructor<T>, options?: ActionOptions<T> | null);
26
- static createBuilder<T extends Ent>(viewer: Viewer, builderCtr: BuilderConstructor<T>, options?: ActionOptions<T> | null): Builder<T>;
27
- static bulkAction<T extends Ent>(ent: T, builderCtr: BuilderConstructor<T>, ...actions: Action<Ent>[]): BaseAction<T>;
28
- changeset(): Promise<Changeset<T>>;
21
+ triggers: Trigger<EntBuilder<TEnt>, TData>[];
22
+ observers: Observer<EntBuilder<TEnt>, TData>[];
23
+ validators: Validator<EntBuilder<TEnt>, TData>[];
24
+ getPrivacyPolicy(): import("../core/base").PrivacyPolicy<Ent>;
25
+ constructor(viewer: Viewer, builderCtr: BuilderConstructor<TEnt, TData>, options?: ActionOptions<TEnt, TData> | null);
26
+ static createBuilder<TEnt extends Ent, TData extends Data>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt, TData>, options?: ActionOptions<TEnt, TData> | null): Builder<TEnt>;
27
+ static bulkAction<TEnt extends Ent, TData extends Data>(ent: TEnt, builderCtr: BuilderConstructor<TEnt, TData>, ...actions: Action<Ent, Builder<Ent>, Data>[]): BaseAction<TEnt, TData>;
28
+ changeset(): Promise<Changeset<TEnt>>;
29
29
  valid(): Promise<boolean>;
30
30
  validX(): Promise<void>;
31
- save(): Promise<T | null>;
32
- saveX(): Promise<T>;
33
- getInput(): {};
31
+ save(): Promise<TEnt | null>;
32
+ saveX(): Promise<TEnt>;
33
+ getInput(): TData;
34
34
  }
35
- interface BuilderConstructor<T extends Ent> {
36
- new (viewer: Viewer, operation: WriteOperation, action: Action<T>, existingEnt?: T | undefined): EntBuilder<T>;
35
+ interface BuilderConstructor<TEnt extends Ent, TData extends Data> {
36
+ new (viewer: Viewer, operation: WriteOperation, action: Action<TEnt, EntBuilder<TEnt>, TData>, existingEnt?: TEnt | undefined): EntBuilder<TEnt>;
37
37
  }
38
- export declare function updateRawObject<TEnt extends Ent, TInput extends Data>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt>, existingEnt: TEnt, input: TInput): Promise<TEnt>;
39
- export declare function getSimpleEditAction<TEnt extends Ent, TInput extends Data>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt>, existingEnt: TEnt, input: TInput): Action<TEnt>;
38
+ export declare function updateRawObject<TEnt extends Ent, TInput extends Data>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt, TInput>, existingEnt: TEnt, input: TInput): Promise<TEnt>;
39
+ export declare function getSimpleEditAction<TEnt extends Ent, TInput extends Data>(viewer: Viewer, builderCtr: BuilderConstructor<TEnt, TInput>, existingEnt: TEnt, input: TInput): Action<TEnt, Builder<TEnt>, TInput>;
40
40
  export {};
@@ -37,7 +37,7 @@ class BaseAction {
37
37
  });
38
38
  action.triggers = [
39
39
  {
40
- changeset: (builder, _input) => {
40
+ changeset: () => {
41
41
  return actions.map((action) => action.changeset());
42
42
  },
43
43
  },
@@ -3,14 +3,14 @@ import { AssocEdgeInputOptions, DataOperation } from "../core/ent";
3
3
  import { SchemaInputType } from "../schema/schema";
4
4
  import { Changeset, Executor } from "../action/action";
5
5
  import { WriteOperation, Builder, Action } from "../action";
6
- export interface OrchestratorOptions<T extends Ent, TData extends Data> {
6
+ export interface OrchestratorOptions<TEnt extends Ent, TData extends Data> {
7
7
  viewer: Viewer;
8
8
  operation: WriteOperation;
9
9
  tableName: string;
10
- loaderOptions: LoadEntOptions<T>;
10
+ loaderOptions: LoadEntOptions<TEnt>;
11
11
  key: string;
12
- builder: Builder<T>;
13
- action?: Action<T>;
12
+ builder: Builder<TEnt>;
13
+ action?: Action<TEnt, Builder<TEnt>, TData>;
14
14
  schema: SchemaInputType;
15
15
  editedFields(): Map<string, any>;
16
16
  updateInput?: (data: TData) => void;
@@ -28,7 +28,7 @@ export declare enum edgeDirection {
28
28
  inboundEdge = 0,
29
29
  outboundEdge = 1
30
30
  }
31
- export declare class Orchestrator<T extends Ent> {
31
+ export declare class Orchestrator<TEnt extends Ent, TData extends Data> {
32
32
  private options;
33
33
  private edgeSet;
34
34
  private edges;
@@ -41,7 +41,7 @@ export declare class Orchestrator<T extends Ent> {
41
41
  viewer: Viewer;
42
42
  private defaultFieldsByFieldName;
43
43
  private defaultFieldsByTSName;
44
- constructor(options: OrchestratorOptions<T, Data>);
44
+ constructor(options: OrchestratorOptions<TEnt, TData>);
45
45
  private addEdge;
46
46
  addInboundEdge<T2 extends Ent>(id1: ID | Builder<T2>, edgeType: string, nodeType: string, options?: AssocEdgeInputOptions): void;
47
47
  addOutboundEdge<T2 extends Ent>(id2: ID | Builder<T2>, edgeType: string, nodeType: string, options?: AssocEdgeInputOptions): void;
@@ -64,11 +64,11 @@ export declare class Orchestrator<T extends Ent> {
64
64
  private formatAndValidateFields;
65
65
  valid(): Promise<boolean>;
66
66
  validX(): Promise<void>;
67
- build(): Promise<EntChangeset<T>>;
67
+ build(): Promise<EntChangeset<TEnt>>;
68
68
  private viewerForEntLoad;
69
69
  returnedRow(): Promise<Data | null>;
70
- editedEnt(): Promise<T | null>;
71
- editedEntX(): Promise<T>;
70
+ editedEnt(): Promise<TEnt | null>;
71
+ editedEntX(): Promise<TEnt>;
72
72
  }
73
73
  export declare class EntChangeset<T extends Ent> implements Changeset<T> {
74
74
  viewer: Viewer;
@@ -309,7 +309,7 @@ class Orchestrator {
309
309
  for (const [fieldName, field] of schemaFields) {
310
310
  let value = editedFields.get(fieldName);
311
311
  let defaultValue = undefined;
312
- let dbKey = field.storageKey || (0, snake_case_1.snakeCase)(field.name);
312
+ let dbKey = field.storageKey || (0, snake_case_1.snakeCase)(fieldName);
313
313
  if (value === undefined) {
314
314
  if (this.options.operation === action_1.WriteOperation.Insert) {
315
315
  if (field.defaultToViewerOnCreate && field.defaultValueOnCreate) {
@@ -321,7 +321,7 @@ class Orchestrator {
321
321
  if (field.defaultValueOnCreate) {
322
322
  defaultValue = field.defaultValueOnCreate(builder, input);
323
323
  if (defaultValue === undefined) {
324
- throw new Error(`defaultValueOnCreate() returned undefined for field ${field.name}`);
324
+ throw new Error(`defaultValueOnCreate() returned undefined for field ${fieldName}`);
325
325
  }
326
326
  }
327
327
  }
@@ -360,11 +360,11 @@ class Orchestrator {
360
360
  }
361
361
  return false;
362
362
  }
363
- async transformFieldValue(field, dbKey, value) {
363
+ async transformFieldValue(fieldName, field, dbKey, value) {
364
364
  // now format and validate...
365
365
  if (value === null) {
366
366
  if (!field.nullable) {
367
- throw new Error(`field ${field.name} set to null for non-nullable field`);
367
+ throw new Error(`field ${fieldName} set to null for non-nullable field`);
368
368
  }
369
369
  }
370
370
  else if (value === undefined) {
@@ -375,14 +375,14 @@ class Orchestrator {
375
375
  // server default allowed
376
376
  field.serverDefault === undefined &&
377
377
  this.options.operation === action_1.WriteOperation.Insert) {
378
- throw new Error(`required field ${field.name} not set`);
378
+ throw new Error(`required field ${fieldName} not set`);
379
379
  }
380
380
  }
381
381
  else if (this.isBuilder(value)) {
382
382
  if (field.valid) {
383
383
  const valid = await Promise.resolve(field.valid(value));
384
384
  if (!valid) {
385
- throw new Error(`invalid field ${field.name} with value ${value}`);
385
+ throw new Error(`invalid field ${fieldName} with value ${value}`);
386
386
  }
387
387
  }
388
388
  // keep track of dependencies to resolve
@@ -395,7 +395,7 @@ class Orchestrator {
395
395
  // TODO this could be async. handle this better
396
396
  const valid = await Promise.resolve(field.valid(value));
397
397
  if (!valid) {
398
- throw new Error(`invalid field ${field.name} with value ${value}`);
398
+ throw new Error(`invalid field ${fieldName} with value ${value}`);
399
399
  }
400
400
  }
401
401
  if (field.format) {
@@ -420,8 +420,8 @@ class Orchestrator {
420
420
  // null allowed
421
421
  value = this.defaultFieldsByFieldName[fieldName];
422
422
  }
423
- let dbKey = field.storageKey || (0, snake_case_1.snakeCase)(field.name);
424
- value = await this.transformFieldValue(field, dbKey, value);
423
+ let dbKey = field.storageKey || (0, snake_case_1.snakeCase)(fieldName);
424
+ value = await this.transformFieldValue(fieldName, field, dbKey, value);
425
425
  if (value !== undefined) {
426
426
  data[dbKey] = value;
427
427
  logValues[dbKey] = field.logValue(value);
@@ -433,10 +433,10 @@ class Orchestrator {
433
433
  for (const fieldName in this.defaultFieldsByFieldName) {
434
434
  const defaultValue = this.defaultFieldsByFieldName[fieldName];
435
435
  let field = schemaFields.get(fieldName);
436
- let dbKey = field.storageKey || (0, snake_case_1.snakeCase)(field.name);
436
+ let dbKey = field.storageKey || (0, snake_case_1.snakeCase)(fieldName);
437
437
  // no value, let's just default
438
438
  if (data[dbKey] === undefined) {
439
- const value = await this.transformFieldValue(field, dbKey, defaultValue);
439
+ const value = await this.transformFieldValue(fieldName, field, dbKey, defaultValue);
440
440
  data[dbKey] = value;
441
441
  logValues[dbKey] = field.logValue(value);
442
442
  }
package/core/base.d.ts CHANGED
@@ -43,7 +43,7 @@ export interface Viewer {
43
43
  export interface Ent {
44
44
  id: ID;
45
45
  viewer: Viewer;
46
- privacyPolicy: PrivacyPolicy;
46
+ privacyPolicy: PrivacyPolicy<this>;
47
47
  nodeType: string;
48
48
  }
49
49
  export declare type Data = {
@@ -108,20 +108,19 @@ 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;
112
111
  }
113
112
  export interface PrivacyError extends Error {
114
- privacyPolicy: PrivacyPolicy;
113
+ privacyPolicy: PrivacyPolicy<Ent>;
115
114
  ent?: Ent;
116
115
  }
117
116
  export declare function Allow(): PrivacyResult;
118
117
  export declare function Skip(): PrivacyResult;
119
118
  export declare function Deny(): PrivacyResult;
120
- export declare function DenyWithReason(e: PrivacyError | string): PrivacyResult;
121
- export interface PrivacyPolicyRule {
122
- apply(v: Viewer, ent?: Ent): Promise<PrivacyResult>;
119
+ export declare function DenyWithReason(e: PrivacyError): PrivacyResult;
120
+ export interface PrivacyPolicyRule<TEnt extends Ent = Ent> {
121
+ apply(v: Viewer, ent?: TEnt): Promise<PrivacyResult>;
123
122
  }
124
- export interface PrivacyPolicy {
125
- rules: PrivacyPolicyRule[];
123
+ export interface PrivacyPolicy<TEnt extends Ent = Ent> {
124
+ rules: PrivacyPolicyRule<TEnt>[];
126
125
  }
127
126
  export {};
package/core/base.js CHANGED
@@ -30,23 +30,7 @@ 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
- }
41
33
  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
- }
50
34
  return {
51
35
  result: privacyResult.Deny,
52
36
  error: e,
package/core/ent.d.ts CHANGED
@@ -10,7 +10,8 @@ export declare function loadEntX<T extends Ent>(viewer: Viewer, id: ID, options:
10
10
  export declare function loadEntXViaKey<T extends Ent>(viewer: Viewer, key: any, options: LoadEntOptions<T>): Promise<T>;
11
11
  export declare function loadEntFromClause<T extends Ent>(viewer: Viewer, options: LoadEntOptions<T>, clause: clause.Clause): Promise<T | null>;
12
12
  export declare function loadEntXFromClause<T extends Ent>(viewer: Viewer, options: LoadEntOptions<T>, clause: clause.Clause): Promise<T>;
13
- export declare function loadEnts<T extends Ent>(viewer: Viewer, options: LoadEntOptions<T>, ...ids: ID[]): Promise<T[]>;
13
+ export declare function loadEnts<T extends Ent>(viewer: Viewer, options: LoadEntOptions<T>, ...ids: ID[]): Promise<Map<ID, T>>;
14
+ export declare function loadEntsList<T extends Ent>(viewer: Viewer, options: LoadEntOptions<T>, ...ids: ID[]): Promise<T[]>;
14
15
  export declare function loadEntsFromClause<T extends Ent>(viewer: Viewer, clause: clause.Clause, options: LoadEntOptions<T>): Promise<Map<ID, T>>;
15
16
  export declare function loadCustomEnts<T extends Ent>(viewer: Viewer, options: LoadCustomEntOptions<T>, query: CustomQuery): Promise<T[]>;
16
17
  interface rawQueryOptions {
package/core/ent.js CHANGED
@@ -22,7 +22,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.getEdgeTypeInGroup = exports.applyPrivacyPolicyForRows = exports.applyPrivacyPolicyForRowX = exports.applyPrivacyPolicyForRow = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadCustomEdges = exports.loadEdges = exports.defaultEdgeQueryOptions = exports.DefaultLimit = exports.loadEdgeDatas = exports.loadEdgeData = exports.assocEdgeLoader = exports.AssocEdgeData = exports.getCursor = exports.AssocEdge = exports.DeleteNodeOperation = exports.deleteRowsSync = exports.deleteRows = exports.editRowSync = exports.editRow = exports.buildUpdateQuery = exports.createRowSync = exports.createRow = exports.buildInsertQuery = exports.EdgeOperation = exports.EditNodeOperation = exports.buildGroupQuery = exports.buildQuery = exports.loadRows = exports.performRawQuery = exports.loadRow = exports.loadRowX = exports.applyPrivacyPolicyForEntX = exports.applyPrivacyPolicyForEnt = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadCustomData = exports.loadCustomEnts = exports.loadEntsFromClause = exports.loadEnts = exports.loadEntXFromClause = exports.loadEntFromClause = exports.loadEntXViaKey = exports.loadEntX = exports.loadEntViaKey = exports.loadEnt = void 0;
25
+ exports.applyPrivacyPolicyForRows = exports.applyPrivacyPolicyForRowX = exports.applyPrivacyPolicyForRow = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadCustomEdges = exports.loadEdges = exports.defaultEdgeQueryOptions = exports.DefaultLimit = exports.loadEdgeDatas = exports.loadEdgeData = exports.assocEdgeLoader = exports.AssocEdgeData = exports.getCursor = exports.AssocEdge = exports.DeleteNodeOperation = exports.deleteRowsSync = exports.deleteRows = exports.editRowSync = exports.editRow = exports.buildUpdateQuery = exports.createRowSync = exports.createRow = exports.buildInsertQuery = exports.EdgeOperation = exports.EditNodeOperation = exports.buildGroupQuery = exports.buildQuery = exports.loadRows = exports.performRawQuery = exports.loadRow = exports.loadRowX = exports.applyPrivacyPolicyForEntX = exports.applyPrivacyPolicyForEnt = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadCustomData = exports.loadCustomEnts = exports.loadEntsFromClause = exports.loadEntsList = exports.loadEnts = exports.loadEntXFromClause = exports.loadEntFromClause = exports.loadEntXViaKey = exports.loadEntX = exports.loadEntViaKey = exports.loadEnt = void 0;
26
+ exports.getEdgeTypeInGroup = void 0;
26
27
  const db_1 = __importStar(require("./db"));
27
28
  const privacy_1 = require("./privacy");
28
29
  const clause = __importStar(require("./clause"));
@@ -145,7 +146,7 @@ async function loadEntXFromClause(viewer, options, clause) {
145
146
  exports.loadEntXFromClause = loadEntXFromClause;
146
147
  async function loadEnts(viewer, options, ...ids) {
147
148
  if (!ids.length) {
148
- return [];
149
+ return new Map();
149
150
  }
150
151
  let loaded = false;
151
152
  let rows = [];
@@ -175,12 +176,16 @@ async function loadEnts(viewer, options, ...ids) {
175
176
  // this is always "id" if not using an ObjectLoaderFactory
176
177
  clause.In("id", ...ids), options);
177
178
  }
179
+ return m;
178
180
  // TODO do we want to change this to be a map not a list so that it's easy to check for existence?
179
181
  // TODO eventually this should be doing a cache then db queyr and maybe depend on dataloader to get all the results at once
180
- // we need to get the result and re-sort... because the raw db access doesn't guarantee it in same order
181
- // apparently
182
- // let m = await loadEntsFromClause(viewer, clause.In("id", ...ids), options);
183
- let result = [];
182
+ }
183
+ exports.loadEnts = loadEnts;
184
+ // calls loadEnts and returns the results sorted in the order they were passed in
185
+ // useful for EntQuery and other paths where the order matters
186
+ async function loadEntsList(viewer, options, ...ids) {
187
+ const m = await loadEnts(viewer, options, ...ids);
188
+ const result = [];
184
189
  ids.forEach((id) => {
185
190
  let ent = m.get(id);
186
191
  if (ent) {
@@ -189,7 +194,7 @@ async function loadEnts(viewer, options, ...ids) {
189
194
  });
190
195
  return result;
191
196
  }
192
- exports.loadEnts = loadEnts;
197
+ exports.loadEntsList = loadEntsList;
193
198
  // we return a map here so that any sorting for queries that exist
194
199
  // can be done in O(N) time
195
200
  async function loadEntsFromClause(viewer, clause, options) {
@@ -1133,7 +1138,7 @@ async function loadNodesByEdge(viewer, id1, edgeType, options) {
1133
1138
  });
1134
1139
  // extract id2s
1135
1140
  const ids = rows.map((row) => row.id2);
1136
- return loadEnts(viewer, options, ...ids);
1141
+ return loadEntsList(viewer, options, ...ids);
1137
1142
  }
1138
1143
  exports.loadNodesByEdge = loadNodesByEdge;
1139
1144
  async function applyPrivacyPolicyForRow(viewer, options, row) {
package/core/privacy.js CHANGED
@@ -464,9 +464,6 @@ 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
- }
470
467
  if (throwErr) {
471
468
  throw throwErr();
472
469
  }
@@ -73,7 +73,7 @@ class AssocEdgeQueryBase extends query_1.BaseEdgeQuery {
73
73
  }
74
74
  let promises = [];
75
75
  for (const [_, value] of m) {
76
- promises.push((0, ent_1.loadEnts)(this.viewer, value.options, ...value.ids));
76
+ promises.push((0, ent_1.loadEntsList)(this.viewer, value.options, ...value.ids));
77
77
  }
78
78
  const entss = await Promise.all(promises);
79
79
  const r = [];
@@ -83,7 +83,7 @@ class AssocEdgeQueryBase extends query_1.BaseEdgeQuery {
83
83
  return r;
84
84
  }
85
85
  const ids = edges.map((edge) => edge.id2);
86
- return await (0, ent_1.loadEnts)(this.viewer, this.options, ...ids);
86
+ return (0, ent_1.loadEntsList)(this.viewer, this.options, ...ids);
87
87
  }
88
88
  dataToID(edge) {
89
89
  return edge.id2;
@@ -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;
44
+ getPrivacyPolicy(): PrivacyPolicy<Ent>;
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;
@@ -11,7 +11,6 @@ interface classResult {
11
11
  file: file;
12
12
  }
13
13
  export declare function parseCustomImports(filePath: string, opts?: Options): PathResult;
14
- export declare function findTSConfigFile(filePath: string): string | null;
15
14
  export interface importInfo {
16
15
  name: string;
17
16
  importPath: string;
package/imports/index.js CHANGED
@@ -22,12 +22,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.findTSConfigFile = exports.parseCustomImports = void 0;
25
+ exports.parseCustomImports = void 0;
26
26
  const glob_1 = __importDefault(require("glob"));
27
27
  const typescript_1 = __importDefault(require("typescript"));
28
- const json5_1 = __importDefault(require("json5"));
29
28
  const fs = __importStar(require("fs"));
30
29
  const path = __importStar(require("path"));
30
+ const compilerOptions_1 = require("../tsc/compilerOptions");
31
31
  function getFiles(filePath, opts) {
32
32
  if (!path.isAbsolute(filePath)) {
33
33
  throw new Error("absolute file path required");
@@ -44,7 +44,7 @@ function getFiles(filePath, opts) {
44
44
  }
45
45
  function parseCustomImports(filePath, opts) {
46
46
  const files = getFiles(filePath, opts);
47
- const options = readCompilerOptions(filePath);
47
+ const options = (0, compilerOptions_1.readCompilerOptions)(filePath);
48
48
  let classMap = new Map();
49
49
  files.forEach((file) => {
50
50
  const sourceFile = typescript_1.default.createSourceFile(file, fs.readFileSync(file).toString(), options.target || typescript_1.default.ScriptTarget.ES2015);
@@ -77,39 +77,6 @@ function parseCustomImports(filePath, opts) {
77
77
  };
78
78
  }
79
79
  exports.parseCustomImports = parseCustomImports;
80
- function findTSConfigFile(filePath) {
81
- while (filePath != "/") {
82
- let configPath = `${filePath}/tsconfig.json`;
83
- if (fs.existsSync(configPath)) {
84
- return configPath;
85
- }
86
- filePath = path.join(filePath, "..");
87
- }
88
- return null;
89
- }
90
- exports.findTSConfigFile = findTSConfigFile;
91
- // inspiration taken from compiler.ts
92
- function readCompilerOptions(filePath) {
93
- let configPath = findTSConfigFile(filePath);
94
- if (!configPath) {
95
- return {};
96
- }
97
- let json = {};
98
- try {
99
- json = json5_1.default.parse(fs.readFileSync(configPath, {
100
- encoding: "utf8",
101
- }));
102
- }
103
- catch (e) {
104
- console.error("couldn't read tsconfig.json file");
105
- return {};
106
- }
107
- let options = json["compilerOptions"] || {};
108
- if (options.moduleResolution === "node") {
109
- options.moduleResolution = typescript_1.default.ModuleResolutionKind.NodeJs;
110
- }
111
- return options;
112
- }
113
80
  function traverse(sourceFile, f, classMap) {
114
81
  typescript_1.default.forEachChild(sourceFile, function (node) {
115
82
  switch (node.kind) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.0.35",
3
+ "version": "0.1.0-alpha3",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1,4 +1,4 @@
1
- import { Schema, Field, AssocEdge, AssocEdgeGroup, Action } from "../schema";
1
+ import { Schema, Field, AssocEdge, AssocEdgeGroup, Action, Type } from "../schema";
2
2
  import { ActionField } from "../schema/schema";
3
3
  declare enum NullableResult {
4
4
  CONTENTS = "contents",
@@ -32,10 +32,18 @@ interface ProcessedPattern {
32
32
  assocEdges: ProcessedAssocEdge[];
33
33
  fields: ProcessedField[];
34
34
  }
35
- declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate"> & {
35
+ declare type ProcessedType = Omit<Type, "subFields" | "listElemType" | "unionFields"> & {
36
+ subFields?: ProcessedField[];
37
+ listElemType?: ProcessedType;
38
+ unionFields?: ProcessedField[];
39
+ };
40
+ declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate" | "type"> & {
41
+ name: string;
36
42
  hasDefaultValueOnCreate?: boolean;
37
43
  hasDefaultValueOnEdit?: boolean;
38
44
  patternName?: string;
45
+ derivedFields?: ProcessedField[];
46
+ type: ProcessedType;
39
47
  };
40
48
  interface patternsDict {
41
49
  [key: string]: ProcessedPattern;
@@ -3,8 +3,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseSchema = void 0;
4
4
  function processFields(src, patternName) {
5
5
  const ret = [];
6
- for (const field of src) {
7
- let f = { ...field };
6
+ let m = {};
7
+ if (Array.isArray(src)) {
8
+ for (const field of src) {
9
+ const name = field.name;
10
+ if (!name) {
11
+ throw new Error(`name is required`);
12
+ }
13
+ m[name] = field;
14
+ }
15
+ }
16
+ else {
17
+ m = src;
18
+ }
19
+ for (const name in m) {
20
+ const field = m[name];
21
+ //@ts-ignore type and other changed fields with different type in ProcessedField vs Field
22
+ let f = { name, ...field };
8
23
  f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
9
24
  f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
10
25
  if (field.polymorphic) {
@@ -31,6 +46,21 @@ function processFields(src, patternName) {
31
46
  if (patternName) {
32
47
  f.patternName = patternName;
33
48
  }
49
+ if (field.getDerivedFields) {
50
+ f.derivedFields = processFields(field.getDerivedFields(name));
51
+ }
52
+ if (field.type.subFields) {
53
+ f.type.subFields = processFields(field.type.subFields);
54
+ }
55
+ if (field.type.unionFields) {
56
+ f.type.unionFields = processFields(field.type.unionFields);
57
+ }
58
+ if (field.type.listElemType &&
59
+ field.type.listElemType.subFields &&
60
+ // check to avoid ts-ignore below. exists just for tsc
61
+ f.type.listElemType) {
62
+ f.type.listElemType.subFields = processFields(field.type.listElemType.subFields);
63
+ }
34
64
  ret.push(f);
35
65
  }
36
66
  return ret;
@@ -3,17 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseEntSchemaWithTZ = exports.BaseEntSchema = exports.Node = exports.Timestamps = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  const field_1 = require("./field");
6
- let tsFields = [
7
- (0, field_1.TimestampType)({
8
- name: "createdAt",
6
+ let tsFields = {
7
+ createdAt: (0, field_1.TimestampType)({
9
8
  hideFromGraphQL: true,
10
9
  disableUserEditable: true,
11
10
  defaultValueOnCreate: () => {
12
11
  return new Date();
13
12
  },
14
13
  }),
15
- (0, field_1.TimestampType)({
16
- name: "updatedAt",
14
+ updatedAt: (0, field_1.TimestampType)({
17
15
  hideFromGraphQL: true,
18
16
  disableUserEditable: true,
19
17
  defaultValueOnCreate: () => {
@@ -23,25 +21,28 @@ let tsFields = [
23
21
  return new Date();
24
22
  },
25
23
  }),
26
- ];
24
+ };
27
25
  // Timestamps is a Pattern that adds a createdAt and updatedAt timestamp fields to the ent
28
26
  exports.Timestamps = {
29
27
  name: "timestamps",
30
28
  fields: tsFields,
31
29
  };
32
30
  let nodeField = (0, field_1.UUIDType)({
33
- name: "ID",
34
31
  primaryKey: true,
35
32
  disableUserEditable: true,
36
33
  defaultValueOnCreate: () => {
37
34
  return (0, uuid_1.v4)();
38
35
  },
39
36
  });
40
- let nodeFields = [nodeField, ...tsFields];
41
- let nodeFieldsWithTZ = [
42
- nodeField,
43
- (0, field_1.TimestampType)({
44
- name: "createdAt",
37
+ let nodeFields = {
38
+ // inconsistent naming :(
39
+ ID: nodeField,
40
+ ...tsFields,
41
+ };
42
+ let nodeFieldsWithTZ = {
43
+ // inconsistent naming :(
44
+ ID: nodeField,
45
+ createdAt: (0, field_1.TimestampType)({
45
46
  hideFromGraphQL: true,
46
47
  disableUserEditable: true,
47
48
  defaultValueOnCreate: () => {
@@ -49,8 +50,7 @@ let nodeFieldsWithTZ = [
49
50
  },
50
51
  withTimezone: true,
51
52
  }),
52
- (0, field_1.TimestampType)({
53
- name: "updatedAt",
53
+ updatedAt: (0, field_1.TimestampType)({
54
54
  hideFromGraphQL: true,
55
55
  disableUserEditable: true,
56
56
  defaultValueOnCreate: () => {
@@ -61,7 +61,7 @@ let nodeFieldsWithTZ = [
61
61
  },
62
62
  withTimezone: true,
63
63
  }),
64
- ];
64
+ };
65
65
  // Node is a Pattern that adds 3 fields to the ent: (id, createdAt, and updatedAt timestamps)
66
66
  exports.Node = {
67
67
  name: "node",