@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.
- package/action/action.d.ts +14 -14
- package/action/executor.d.ts +1 -1
- package/action/experimental_action.d.ts +20 -20
- package/action/experimental_action.js +1 -1
- package/action/orchestrator.d.ts +10 -10
- package/action/orchestrator.js +14 -14
- package/core/base.d.ts +6 -6
- package/core/ent.d.ts +2 -1
- package/core/ent.js +14 -10
- package/core/privacy.d.ts +1 -1
- package/core/query/assoc_query.js +2 -2
- package/core/query/query.d.ts +1 -1
- package/graphql/builtins/connection.js +3 -3
- package/graphql/builtins/edge.js +2 -2
- package/graphql/builtins/node.js +1 -1
- package/graphql/graphql.js +2 -2
- package/graphql/index.d.ts +1 -0
- package/graphql/index.js +3 -1
- package/graphql/mutations/union.d.ts +2 -0
- package/graphql/mutations/union.js +35 -0
- package/graphql/query/connection_type.js +6 -6
- package/graphql/query/page_info.js +4 -4
- package/graphql/query/shared_assoc_test.js +2 -2
- package/graphql/scalars/time.d.ts +1 -1
- package/imports/index.d.ts +0 -1
- package/imports/index.js +3 -36
- package/package.json +2 -2
- package/parse_schema/parse.d.ts +15 -3
- package/parse_schema/parse.js +42 -7
- package/schema/base_schema.d.ts +36 -1
- package/schema/base_schema.js +63 -17
- package/schema/field.d.ts +25 -25
- package/schema/field.js +42 -33
- package/schema/index.d.ts +4 -2
- package/schema/index.js +5 -1
- package/schema/json_field.d.ts +6 -6
- package/schema/json_field.js +2 -2
- package/schema/schema.d.ts +11 -6
- package/schema/schema.js +46 -12
- package/schema/struct_field.d.ts +17 -0
- package/schema/struct_field.js +102 -0
- package/schema/union_field.d.ts +23 -0
- package/schema/union_field.js +79 -0
- package/scripts/custom_compiler.js +2 -19
- package/scripts/read_schema.js +15 -1
- package/scripts/transform_code.d.ts +1 -0
- package/scripts/transform_code.js +114 -0
- package/scripts/transform_schema.d.ts +1 -0
- package/scripts/transform_schema.js +357 -0
- package/testutils/builder.d.ts +19 -15
- package/testutils/builder.js +41 -7
- package/testutils/db/test_db.js +9 -9
- package/testutils/ent-graphql-tests/index.js +19 -12
- package/testutils/fake_data/fake_contact.d.ts +3 -7
- package/testutils/fake_data/fake_contact.js +14 -26
- package/testutils/fake_data/fake_event.d.ts +3 -7
- package/testutils/fake_data/fake_event.js +20 -33
- package/testutils/fake_data/fake_user.d.ts +3 -7
- package/testutils/fake_data/fake_user.js +22 -36
- package/testutils/fake_data/test_helpers.js +1 -1
- package/testutils/fake_data/user_query.d.ts +2 -2
- package/tsc/ast.d.ts +20 -0
- package/tsc/ast.js +131 -0
- package/tsc/compilerOptions.d.ts +7 -0
- package/tsc/compilerOptions.js +95 -0
package/action/action.d.ts
CHANGED
|
@@ -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<
|
|
37
|
-
changeset(builder:
|
|
36
|
+
export interface Trigger<TBuilder extends Builder<Ent>, TData extends Data> {
|
|
37
|
+
changeset(builder: TBuilder, input: TData): TriggerReturn;
|
|
38
38
|
}
|
|
39
|
-
export interface Observer<
|
|
40
|
-
observe(builder:
|
|
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<
|
|
43
|
-
validate(builder:
|
|
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<
|
|
45
|
+
export interface Action<TEnt extends Ent, TBuilder extends Builder<TEnt>, TData extends Data> {
|
|
46
46
|
readonly viewer: Viewer;
|
|
47
|
-
changeset(): Promise<Changeset<
|
|
48
|
-
builder:
|
|
49
|
-
getPrivacyPolicy(): PrivacyPolicy
|
|
50
|
-
triggers?: Trigger<
|
|
51
|
-
observers?: Observer<
|
|
52
|
-
validators?: Validator<
|
|
53
|
-
getInput():
|
|
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>;
|
package/action/executor.d.ts
CHANGED
|
@@ -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<
|
|
16
|
+
export declare class BaseAction<TEnt extends Ent, TData extends Data> implements Action<TEnt, EntBuilder<TEnt>, TData> {
|
|
17
17
|
viewer: Viewer;
|
|
18
|
-
builderCtr: BuilderConstructor<
|
|
19
|
-
builder: EntBuilder<
|
|
18
|
+
builderCtr: BuilderConstructor<TEnt, TData>;
|
|
19
|
+
builder: EntBuilder<TEnt>;
|
|
20
20
|
private input;
|
|
21
|
-
triggers: Trigger<
|
|
22
|
-
observers: Observer<
|
|
23
|
-
validators: Validator<
|
|
24
|
-
getPrivacyPolicy(): import("../core/base").PrivacyPolicy
|
|
25
|
-
constructor(viewer: Viewer, builderCtr: BuilderConstructor<
|
|
26
|
-
static createBuilder<
|
|
27
|
-
static bulkAction<
|
|
28
|
-
changeset(): Promise<Changeset<
|
|
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<
|
|
32
|
-
saveX(): Promise<
|
|
33
|
-
getInput():
|
|
31
|
+
save(): Promise<TEnt | null>;
|
|
32
|
+
saveX(): Promise<TEnt>;
|
|
33
|
+
getInput(): TData;
|
|
34
34
|
}
|
|
35
|
-
interface BuilderConstructor<
|
|
36
|
-
new (viewer: Viewer, operation: WriteOperation, action: Action<
|
|
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 {};
|
package/action/orchestrator.d.ts
CHANGED
|
@@ -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<
|
|
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<
|
|
10
|
+
loaderOptions: LoadEntOptions<TEnt>;
|
|
11
11
|
key: string;
|
|
12
|
-
builder: Builder<
|
|
13
|
-
action?: Action<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
75
|
+
build(): Promise<EntChangeset<TEnt>>;
|
|
76
76
|
private viewerForEntLoad;
|
|
77
77
|
returnedRow(): Promise<Data | null>;
|
|
78
|
-
editedEnt(): Promise<
|
|
79
|
-
editedEntX(): Promise<
|
|
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;
|
package/action/orchestrator.js
CHANGED
|
@@ -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 ${
|
|
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 ${
|
|
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 ${
|
|
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
|
|
478
|
+
const valid = await field.valid(value);
|
|
479
479
|
if (!valid) {
|
|
480
|
-
throw new Error(`invalid field ${
|
|
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
|
|
491
|
+
const valid = await field.valid(value);
|
|
492
492
|
if (!valid) {
|
|
493
|
-
throw new Error(`invalid field ${
|
|
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
|
-
|
|
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?:
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
86
|
+
return (0, ent_1.loadEntsList)(this.viewer, this.options, ...ids);
|
|
87
87
|
}
|
|
88
88
|
dataToID(edge) {
|
|
89
89
|
return edge.id2;
|
package/core/query/query.d.ts
CHANGED
|
@@ -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:
|
|
14
|
+
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(edge_1.GraphQLEdgeInterface))),
|
|
15
15
|
},
|
|
16
16
|
nodes: {
|
|
17
|
-
type:
|
|
17
|
+
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(node_1.GraphQLNodeInterface))),
|
|
18
18
|
},
|
|
19
19
|
pageInfo: {
|
|
20
|
-
type:
|
|
20
|
+
type: new graphql_1.GraphQLNonNull(page_info_1.GraphQLPageInfo),
|
|
21
21
|
},
|
|
22
22
|
}),
|
|
23
23
|
});
|
package/graphql/builtins/edge.js
CHANGED
|
@@ -9,10 +9,10 @@ exports.GraphQLEdgeInterface = new graphql_1.GraphQLInterfaceType({
|
|
|
9
9
|
description: "edge interface",
|
|
10
10
|
fields: () => ({
|
|
11
11
|
node: {
|
|
12
|
-
type:
|
|
12
|
+
type: new graphql_1.GraphQLNonNull(node_1.GraphQLNodeInterface),
|
|
13
13
|
},
|
|
14
14
|
cursor: {
|
|
15
|
-
type:
|
|
15
|
+
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
|
|
16
16
|
},
|
|
17
17
|
}),
|
|
18
18
|
});
|
package/graphql/builtins/node.js
CHANGED
|
@@ -8,7 +8,7 @@ exports.GraphQLNodeInterface = new graphql_1.GraphQLInterfaceType({
|
|
|
8
8
|
description: "node interface",
|
|
9
9
|
fields: () => ({
|
|
10
10
|
id: {
|
|
11
|
-
type:
|
|
11
|
+
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
|
|
12
12
|
},
|
|
13
13
|
}),
|
|
14
14
|
});
|
package/graphql/graphql.js
CHANGED
|
@@ -79,8 +79,8 @@ const addCustomType = (type) => {
|
|
|
79
79
|
description: ct.description,
|
|
80
80
|
name: ct.name,
|
|
81
81
|
};
|
|
82
|
-
if (ct.
|
|
83
|
-
type.scalarInfo.specifiedByUrl = ct.
|
|
82
|
+
if (ct.specifiedByURL) {
|
|
83
|
+
type.scalarInfo.specifiedByUrl = ct.specifiedByURL;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
package/graphql/index.d.ts
CHANGED
|
@@ -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,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:
|
|
18
|
+
type: new graphql_1.GraphQLNonNull(nodeType),
|
|
19
19
|
},
|
|
20
20
|
cursor: {
|
|
21
|
-
type:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
22
|
+
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
|
|
23
23
|
},
|
|
24
24
|
endCursor: {
|
|
25
|
-
type:
|
|
25
|
+
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
|
|
26
26
|
},
|
|
27
27
|
}),
|
|
28
28
|
});
|