@snowtop/ent 0.0.40-alpha6 → 0.1.0-alpha10

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 (65) hide show
  1. package/action/action.d.ts +14 -14
  2. package/action/executor.d.ts +1 -1
  3. package/action/experimental_action.d.ts +20 -20
  4. package/action/experimental_action.js +1 -1
  5. package/action/orchestrator.d.ts +10 -10
  6. package/action/orchestrator.js +14 -14
  7. package/core/base.d.ts +6 -6
  8. package/core/ent.d.ts +2 -1
  9. package/core/ent.js +14 -10
  10. package/core/privacy.d.ts +1 -1
  11. package/core/query/assoc_query.js +2 -2
  12. package/core/query/query.d.ts +1 -1
  13. package/graphql/builtins/connection.js +3 -3
  14. package/graphql/builtins/edge.js +2 -2
  15. package/graphql/builtins/node.js +1 -1
  16. package/graphql/graphql.js +2 -2
  17. package/graphql/index.d.ts +1 -0
  18. package/graphql/index.js +3 -1
  19. package/graphql/mutations/union.d.ts +2 -0
  20. package/graphql/mutations/union.js +35 -0
  21. package/graphql/query/connection_type.js +6 -6
  22. package/graphql/query/page_info.js +4 -4
  23. package/graphql/query/shared_assoc_test.js +2 -2
  24. package/graphql/scalars/time.d.ts +1 -1
  25. package/imports/index.d.ts +0 -1
  26. package/imports/index.js +3 -36
  27. package/package.json +2 -2
  28. package/parse_schema/parse.d.ts +15 -3
  29. package/parse_schema/parse.js +42 -7
  30. package/schema/base_schema.d.ts +36 -1
  31. package/schema/base_schema.js +63 -17
  32. package/schema/field.d.ts +25 -25
  33. package/schema/field.js +42 -33
  34. package/schema/index.d.ts +4 -2
  35. package/schema/index.js +5 -1
  36. package/schema/json_field.d.ts +6 -6
  37. package/schema/json_field.js +2 -2
  38. package/schema/schema.d.ts +11 -6
  39. package/schema/schema.js +46 -12
  40. package/schema/struct_field.d.ts +17 -0
  41. package/schema/struct_field.js +102 -0
  42. package/schema/union_field.d.ts +23 -0
  43. package/schema/union_field.js +79 -0
  44. package/scripts/custom_compiler.js +2 -19
  45. package/scripts/read_schema.js +15 -1
  46. package/scripts/transform_code.d.ts +1 -0
  47. package/scripts/transform_code.js +114 -0
  48. package/scripts/transform_schema.d.ts +1 -0
  49. package/scripts/transform_schema.js +357 -0
  50. package/testutils/builder.d.ts +19 -15
  51. package/testutils/builder.js +41 -7
  52. package/testutils/db/test_db.js +9 -9
  53. package/testutils/ent-graphql-tests/index.js +19 -12
  54. package/testutils/fake_data/fake_contact.d.ts +3 -7
  55. package/testutils/fake_data/fake_contact.js +14 -26
  56. package/testutils/fake_data/fake_event.d.ts +3 -7
  57. package/testutils/fake_data/fake_event.js +20 -33
  58. package/testutils/fake_data/fake_user.d.ts +3 -7
  59. package/testutils/fake_data/fake_user.js +22 -36
  60. package/testutils/fake_data/test_helpers.js +1 -1
  61. package/testutils/fake_data/user_query.d.ts +2 -2
  62. package/tsc/ast.d.ts +20 -0
  63. package/tsc/ast.js +131 -0
  64. package/tsc/compilerOptions.d.ts +7 -0
  65. package/tsc/compilerOptions.js +95 -0
@@ -33,24 +33,24 @@ export interface Changeset<T extends Ent> {
33
33
  dependencies?: Map<ID, Builder<Ent>>;
34
34
  }
35
35
  export declare type TriggerReturn = void | Promise<Changeset<Ent> | void | (Changeset<Ent> | void)[]> | Promise<Changeset<Ent>>[];
36
- export interface Trigger<T extends Ent> {
37
- changeset(builder: Builder<T>, input: Data): TriggerReturn;
36
+ export interface Trigger<TBuilder extends Builder<Ent>, TData extends Data> {
37
+ changeset(builder: TBuilder, input: TData): TriggerReturn;
38
38
  }
39
- export interface Observer<T extends Ent> {
40
- observe(builder: Builder<T>, input: Data): void | Promise<void>;
39
+ export interface Observer<TBuilder extends Builder<Ent>, TData extends Data> {
40
+ observe(builder: TBuilder, input: TData): void | Promise<void>;
41
41
  }
42
- export interface Validator<T extends Ent> {
43
- validate(builder: Builder<T>, input: Data): Promise<void> | void;
42
+ export interface Validator<TBuilder extends Builder<Ent>, TData extends Data> {
43
+ validate(builder: TBuilder, input: TData): Promise<void> | void;
44
44
  }
45
- export interface Action<T extends Ent> {
45
+ export interface Action<TEnt extends Ent, TBuilder extends Builder<TEnt>, TData extends Data> {
46
46
  readonly viewer: Viewer;
47
- changeset(): Promise<Changeset<T>>;
48
- builder: Builder<T>;
49
- getPrivacyPolicy(): PrivacyPolicy;
50
- triggers?: Trigger<T>[];
51
- observers?: Observer<T>[];
52
- validators?: Validator<T>[];
53
- getInput(): Data;
47
+ changeset(): Promise<Changeset<TEnt>>;
48
+ builder: TBuilder;
49
+ getPrivacyPolicy(): PrivacyPolicy<TEnt>;
50
+ triggers?: Trigger<TBuilder, TData>[];
51
+ observers?: Observer<TBuilder, TData>[];
52
+ validators?: Validator<TBuilder, TData>[];
53
+ getInput(): TData;
54
54
  transformWrite?: <T2 extends Ent>(stmt: UpdateOperation<T2>) => Promise<TransformedUpdateOperation<T2>> | TransformedUpdateOperation<T2> | undefined;
55
55
  valid(): Promise<boolean>;
56
56
  validX(): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { ID, Data, Ent, Viewer, Context } from "../core/base";
1
+ import { ID, Ent, Viewer, Context, Data } from "../core/base";
2
2
  import { DataOperation } from "../core/ent";
3
3
  import { Changeset, Executor } from "../action/action";
4
4
  import { Builder } from "../action";
@@ -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> | Promise<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;
@@ -44,7 +44,7 @@ export declare class Orchestrator<T extends Ent> {
44
44
  private actualOperation;
45
45
  private existingEnt?;
46
46
  private disableTransformations;
47
- constructor(options: OrchestratorOptions<T, Data>);
47
+ constructor(options: OrchestratorOptions<TEnt, TData>);
48
48
  private addEdge;
49
49
  setDisableTransformations(val: boolean): void;
50
50
  addInboundEdge<T2 extends Ent>(id1: ID | Builder<T2>, edgeType: string, nodeType: string, options?: AssocEdgeInputOptions): void;
@@ -60,7 +60,7 @@ export declare class Orchestrator<T extends Ent> {
60
60
  private getEntForPrivacyPolicyImpl;
61
61
  private getSQLStatementOperation;
62
62
  private getWriteOpForSQLStamentOp;
63
- getPossibleUnsafeEntForPrivacy(): Promise<T | undefined>;
63
+ getPossibleUnsafeEntForPrivacy(): Promise<TEnt | undefined>;
64
64
  private getFieldsInfo;
65
65
  private validate;
66
66
  private triggers;
@@ -72,11 +72,11 @@ export declare class Orchestrator<T extends Ent> {
72
72
  private formatAndValidateFields;
73
73
  valid(): Promise<boolean>;
74
74
  validX(): Promise<void>;
75
- build(): Promise<EntChangeset<T>>;
75
+ build(): Promise<EntChangeset<TEnt>>;
76
76
  private viewerForEntLoad;
77
77
  returnedRow(): Promise<Data | null>;
78
- editedEnt(): Promise<T | null>;
79
- editedEntX(): Promise<T>;
78
+ editedEnt(): Promise<TEnt | null>;
79
+ editedEntX(): Promise<TEnt>;
80
80
  }
81
81
  export declare class EntChangeset<T extends Ent> implements Changeset<T> {
82
82
  viewer: Viewer;
@@ -386,7 +386,7 @@ class Orchestrator {
386
386
  if (field.format) {
387
387
  val = field.format(transformed.data[k]);
388
388
  }
389
- let dbKey = (0, schema_1.getStorageKey)(field);
389
+ let dbKey = (0, schema_1.getStorageKey)(field, k);
390
390
  data[dbKey] = val;
391
391
  this.defaultFieldsByTSName[(0, camel_case_1.camelCase)(k)] = val;
392
392
  // hmm do we need this?
@@ -404,7 +404,7 @@ class Orchestrator {
404
404
  for (const [fieldName, field] of schemaFields) {
405
405
  let value = editedFields.get(fieldName);
406
406
  let defaultValue = undefined;
407
- let dbKey = (0, schema_1.getStorageKey)(field);
407
+ let dbKey = (0, schema_1.getStorageKey)(field, fieldName);
408
408
  if (value === undefined) {
409
409
  if (this.actualOperation === action_1.WriteOperation.Insert) {
410
410
  if (field.defaultToViewerOnCreate && field.defaultValueOnCreate) {
@@ -416,7 +416,7 @@ class Orchestrator {
416
416
  if (field.defaultValueOnCreate) {
417
417
  defaultValue = field.defaultValueOnCreate(builder, input);
418
418
  if (defaultValue === undefined) {
419
- throw new Error(`defaultValueOnCreate() returned undefined for field ${field.name}`);
419
+ throw new Error(`defaultValueOnCreate() returned undefined for field ${fieldName}`);
420
420
  }
421
421
  }
422
422
  }
@@ -455,11 +455,11 @@ class Orchestrator {
455
455
  }
456
456
  return false;
457
457
  }
458
- async transformFieldValue(field, dbKey, value) {
458
+ async transformFieldValue(fieldName, field, dbKey, value) {
459
459
  // now format and validate...
460
460
  if (value === null) {
461
461
  if (!field.nullable) {
462
- throw new Error(`field ${field.name} set to null for non-nullable field`);
462
+ throw new Error(`field ${fieldName} set to null for non-nullable field`);
463
463
  }
464
464
  }
465
465
  else if (value === undefined) {
@@ -470,14 +470,14 @@ class Orchestrator {
470
470
  // server default allowed
471
471
  field.serverDefault === undefined &&
472
472
  this.actualOperation === action_1.WriteOperation.Insert) {
473
- throw new Error(`required field ${field.name} not set`);
473
+ throw new Error(`required field ${fieldName} not set`);
474
474
  }
475
475
  }
476
476
  else if (this.isBuilder(value)) {
477
477
  if (field.valid) {
478
- const valid = await Promise.resolve(field.valid(value));
478
+ const valid = await field.valid(value);
479
479
  if (!valid) {
480
- throw new Error(`invalid field ${field.name} with value ${value}`);
480
+ throw new Error(`invalid field ${fieldName} with value ${value}`);
481
481
  }
482
482
  }
483
483
  // keep track of dependencies to resolve
@@ -488,9 +488,9 @@ class Orchestrator {
488
488
  else {
489
489
  if (field.valid) {
490
490
  // TODO this could be async. handle this better
491
- const valid = await Promise.resolve(field.valid(value));
491
+ const valid = await field.valid(value);
492
492
  if (!valid) {
493
- throw new Error(`invalid field ${field.name} with value ${value}`);
493
+ throw new Error(`invalid field ${fieldName} with value ${value}`);
494
494
  }
495
495
  }
496
496
  if (field.format) {
@@ -514,8 +514,8 @@ class Orchestrator {
514
514
  // null allowed
515
515
  value = this.defaultFieldsByFieldName[fieldName];
516
516
  }
517
- let dbKey = (0, schema_1.getStorageKey)(field);
518
- value = await this.transformFieldValue(field, dbKey, value);
517
+ let dbKey = (0, schema_1.getStorageKey)(field, fieldName);
518
+ value = await this.transformFieldValue(fieldName, field, dbKey, value);
519
519
  if (value !== undefined) {
520
520
  data[dbKey] = value;
521
521
  logValues[dbKey] = field.logValue(value);
@@ -527,10 +527,10 @@ class Orchestrator {
527
527
  for (const fieldName in this.defaultFieldsByFieldName) {
528
528
  const defaultValue = this.defaultFieldsByFieldName[fieldName];
529
529
  let field = schemaFields.get(fieldName);
530
- let dbKey = (0, schema_1.getStorageKey)(field);
530
+ let dbKey = (0, schema_1.getStorageKey)(field, fieldName);
531
531
  // no value, let's just default
532
532
  if (data[dbKey] === undefined) {
533
- const value = await this.transformFieldValue(field, dbKey, defaultValue);
533
+ const value = await this.transformFieldValue(fieldName, field, dbKey, defaultValue);
534
534
  data[dbKey] = value;
535
535
  logValues[dbKey] = field.logValue(value);
536
536
  }
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
+ getPrivacyPolicy(): PrivacyPolicy<this>;
47
47
  nodeType: string;
48
48
  }
49
49
  export declare type Data = {
@@ -114,17 +114,17 @@ export interface PrivacyResult {
114
114
  getError?(policy: PrivacyPolicy, rule: PrivacyPolicyRule, ent?: Ent): PrivacyError;
115
115
  }
116
116
  export interface PrivacyError extends Error {
117
- privacyPolicy: PrivacyPolicy;
117
+ privacyPolicy: PrivacyPolicy<Ent>;
118
118
  ent?: Ent;
119
119
  }
120
120
  export declare function Allow(): PrivacyResult;
121
121
  export declare function Skip(): PrivacyResult;
122
122
  export declare function Deny(): PrivacyResult;
123
123
  export declare function DenyWithReason(e: PrivacyError | string): PrivacyResult;
124
- export interface PrivacyPolicyRule {
125
- apply(v: Viewer, ent?: Ent): Promise<PrivacyResult>;
124
+ export interface PrivacyPolicyRule<TEnt extends Ent = Ent> {
125
+ apply(v: Viewer, ent?: TEnt): Promise<PrivacyResult>;
126
126
  }
127
- export interface PrivacyPolicy {
128
- rules: PrivacyPolicyRule[];
127
+ export interface PrivacyPolicy<TEnt extends Ent = Ent> {
128
+ rules: PrivacyPolicyRule<TEnt>[];
129
129
  }
130
130
  export {};
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,7 @@ 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.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.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.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
26
  const db_1 = __importStar(require("./db"));
27
27
  const privacy_1 = require("./privacy");
28
28
  const clause = __importStar(require("./clause"));
@@ -144,7 +144,7 @@ async function loadEntXFromClause(viewer, options, clause) {
144
144
  exports.loadEntXFromClause = loadEntXFromClause;
145
145
  async function loadEnts(viewer, options, ...ids) {
146
146
  if (!ids.length) {
147
- return [];
147
+ return new Map();
148
148
  }
149
149
  let loaded = false;
150
150
  let rows = [];
@@ -174,12 +174,16 @@ async function loadEnts(viewer, options, ...ids) {
174
174
  // this is always "id" if not using an ObjectLoaderFactory
175
175
  clause.In("id", ...ids), options);
176
176
  }
177
+ return m;
177
178
  // TODO do we want to change this to be a map not a list so that it's easy to check for existence?
178
179
  // TODO eventually this should be doing a cache then db queyr and maybe depend on dataloader to get all the results at once
179
- // we need to get the result and re-sort... because the raw db access doesn't guarantee it in same order
180
- // apparently
181
- // let m = await loadEntsFromClause(viewer, clause.In("id", ...ids), options);
182
- let result = [];
180
+ }
181
+ exports.loadEnts = loadEnts;
182
+ // calls loadEnts and returns the results sorted in the order they were passed in
183
+ // useful for EntQuery and other paths where the order matters
184
+ async function loadEntsList(viewer, options, ...ids) {
185
+ const m = await loadEnts(viewer, options, ...ids);
186
+ const result = [];
183
187
  ids.forEach((id) => {
184
188
  let ent = m.get(id);
185
189
  if (ent) {
@@ -188,7 +192,7 @@ async function loadEnts(viewer, options, ...ids) {
188
192
  });
189
193
  return result;
190
194
  }
191
- exports.loadEnts = loadEnts;
195
+ exports.loadEntsList = loadEntsList;
192
196
  // we return a map here so that any sorting for queries that exist
193
197
  // can be done in O(N) time
194
198
  async function loadEntsFromClause(viewer, clause, options) {
@@ -266,7 +270,7 @@ exports.loadDerivedEntX = loadDerivedEntX;
266
270
  // TODO is there a smarter way to not instantiate two objects here?
267
271
  async function applyPrivacyPolicyForEnt(viewer, ent, data, fieldPrivacyOptions) {
268
272
  if (ent) {
269
- const visible = await (0, privacy_1.applyPrivacyPolicy)(viewer, ent.privacyPolicy, ent);
273
+ const visible = await (0, privacy_1.applyPrivacyPolicy)(viewer, ent.getPrivacyPolicy(), ent);
270
274
  if (!visible) {
271
275
  return null;
272
276
  }
@@ -276,7 +280,7 @@ async function applyPrivacyPolicyForEnt(viewer, ent, data, fieldPrivacyOptions)
276
280
  }
277
281
  async function applyPrivacyPolicyForEntX(viewer, ent, data, options) {
278
282
  // this will throw
279
- await (0, privacy_1.applyPrivacyPolicyX)(viewer, ent.privacyPolicy, ent);
283
+ await (0, privacy_1.applyPrivacyPolicyX)(viewer, ent.getPrivacyPolicy(), ent);
280
284
  return doFieldPrivacy(viewer, ent, data, options);
281
285
  }
282
286
  async function doFieldPrivacy(viewer, ent, data, options) {
@@ -1182,7 +1186,7 @@ async function loadNodesByEdge(viewer, id1, edgeType, options) {
1182
1186
  });
1183
1187
  // extract id2s
1184
1188
  const ids = rows.map((row) => row.id2);
1185
- return loadEnts(viewer, options, ...ids);
1189
+ return loadEntsList(viewer, options, ...ids);
1186
1190
  }
1187
1191
  exports.loadNodesByEdge = loadNodesByEdge;
1188
1192
  async function applyPrivacyPolicyForRow(viewer, options, row) {
package/core/privacy.d.ts CHANGED
@@ -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;
@@ -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,13 +11,13 @@ exports.GraphQLConnectionInterface = new graphql_1.GraphQLInterfaceType({
11
11
  description: "connection interface",
12
12
  fields: () => ({
13
13
  edges: {
14
- type: (0, graphql_1.GraphQLNonNull)((0, graphql_1.GraphQLList)((0, graphql_1.GraphQLNonNull)(edge_1.GraphQLEdgeInterface))),
14
+ type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(edge_1.GraphQLEdgeInterface))),
15
15
  },
16
16
  nodes: {
17
- type: (0, graphql_1.GraphQLNonNull)((0, graphql_1.GraphQLList)((0, graphql_1.GraphQLNonNull)(node_1.GraphQLNodeInterface))),
17
+ type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(node_1.GraphQLNodeInterface))),
18
18
  },
19
19
  pageInfo: {
20
- type: (0, graphql_1.GraphQLNonNull)(page_info_1.GraphQLPageInfo),
20
+ type: new graphql_1.GraphQLNonNull(page_info_1.GraphQLPageInfo),
21
21
  },
22
22
  }),
23
23
  });
@@ -9,10 +9,10 @@ exports.GraphQLEdgeInterface = new graphql_1.GraphQLInterfaceType({
9
9
  description: "edge interface",
10
10
  fields: () => ({
11
11
  node: {
12
- type: (0, graphql_1.GraphQLNonNull)(node_1.GraphQLNodeInterface),
12
+ type: new graphql_1.GraphQLNonNull(node_1.GraphQLNodeInterface),
13
13
  },
14
14
  cursor: {
15
- type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLString),
15
+ type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
16
16
  },
17
17
  }),
18
18
  });
@@ -8,7 +8,7 @@ exports.GraphQLNodeInterface = new graphql_1.GraphQLInterfaceType({
8
8
  description: "node interface",
9
9
  fields: () => ({
10
10
  id: {
11
- type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLID),
11
+ type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
12
12
  },
13
13
  }),
14
14
  });
@@ -79,8 +79,8 @@ const addCustomType = (type) => {
79
79
  description: ct.description,
80
80
  name: ct.name,
81
81
  };
82
- if (ct.specifiedByUrl) {
83
- type.scalarInfo.specifiedByUrl = ct.specifiedByUrl;
82
+ if (ct.specifiedByURL) {
83
+ type.scalarInfo.specifiedByUrl = ct.specifiedByURL;
84
84
  }
85
85
  }
86
86
  }
@@ -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;
@@ -15,10 +15,10 @@ class GraphQLEdgeType extends graphql_1.GraphQLObjectType {
15
15
  name: `${name}Edge`,
16
16
  fields: () => ({
17
17
  node: {
18
- type: (0, graphql_1.GraphQLNonNull)(nodeType),
18
+ type: new graphql_1.GraphQLNonNull(nodeType),
19
19
  },
20
20
  cursor: {
21
- type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLString),
21
+ type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
22
22
  },
23
23
  ...optional,
24
24
  }),
@@ -34,25 +34,25 @@ class GraphQLConnectionType extends graphql_1.GraphQLObjectType {
34
34
  name: `${name}Connection`,
35
35
  fields: () => ({
36
36
  edges: {
37
- type: (0, graphql_1.GraphQLNonNull)((0, graphql_1.GraphQLList)((0, graphql_1.GraphQLNonNull)(edgeType))),
37
+ type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(edgeType))),
38
38
  resolve: (source) => {
39
39
  return source.queryEdges();
40
40
  },
41
41
  },
42
42
  nodes: {
43
- type: (0, graphql_1.GraphQLNonNull)((0, graphql_1.GraphQLList)((0, graphql_1.GraphQLNonNull)(nodeType))),
43
+ type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(nodeType))),
44
44
  resolve: (source) => {
45
45
  return source.queryNodes();
46
46
  },
47
47
  },
48
48
  pageInfo: {
49
- type: (0, graphql_1.GraphQLNonNull)(page_info_1.GraphQLPageInfo),
49
+ type: new graphql_1.GraphQLNonNull(page_info_1.GraphQLPageInfo),
50
50
  resolve: (source) => {
51
51
  return source.queryPageInfo();
52
52
  },
53
53
  },
54
54
  rawCount: {
55
- type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLInt),
55
+ type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLInt),
56
56
  resolve: (source) => {
57
57
  return source.queryTotalCount();
58
58
  },
@@ -7,22 +7,22 @@ exports.GraphQLPageInfo = new graphql_1.GraphQLObjectType({
7
7
  name: "PageInfo",
8
8
  fields: () => ({
9
9
  hasNextPage: {
10
- type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLBoolean),
10
+ type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLBoolean),
11
11
  resolve: (source) => {
12
12
  return source.hasNextPage || false;
13
13
  },
14
14
  },
15
15
  hasPreviousPage: {
16
- type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLBoolean),
16
+ type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLBoolean),
17
17
  resolve: (source) => {
18
18
  return source.hasPreviousPage || false;
19
19
  },
20
20
  },
21
21
  startCursor: {
22
- type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLString),
22
+ type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
23
23
  },
24
24
  endCursor: {
25
- type: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLString),
25
+ type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
26
26
  },
27
27
  }),
28
28
  });