@snowtop/ent 0.0.33 → 0.1.0-alpha2
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 +15 -14
- package/action/experimental_action.d.ts +20 -20
- package/action/experimental_action.js +1 -1
- package/action/orchestrator.d.ts +9 -9
- package/action/orchestrator.js +11 -11
- package/core/base.d.ts +12 -6
- package/core/ent.d.ts +2 -1
- package/core/ent.js +13 -8
- package/core/query/assoc_query.js +2 -2
- package/core/query/query.d.ts +1 -1
- package/imports/index.d.ts +0 -1
- package/imports/index.js +3 -36
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +11 -2
- package/parse_schema/parse.js +52 -22
- package/schema/base_schema.js +15 -15
- package/schema/field.d.ts +24 -24
- package/schema/field.js +38 -40
- package/schema/index.d.ts +1 -1
- package/schema/json_field.d.ts +6 -6
- package/schema/json_field.js +2 -2
- package/schema/schema.d.ts +11 -7
- package/schema/schema.js +18 -5
- package/scripts/custom_compiler.js +2 -19
- package/scripts/transform_schema.d.ts +1 -0
- package/scripts/transform_schema.js +288 -0
- package/testutils/builder.d.ts +14 -13
- package/testutils/builder.js +2 -0
- package/testutils/db/test_db.js +9 -9
- package/testutils/fake_data/fake_contact.d.ts +2 -2
- package/testutils/fake_data/fake_contact.js +6 -13
- package/testutils/fake_data/fake_event.d.ts +2 -2
- package/testutils/fake_data/fake_event.js +8 -16
- package/testutils/fake_data/fake_user.d.ts +2 -2
- package/testutils/fake_data/fake_user.js +7 -16
- package/testutils/fake_data/user_query.d.ts +2 -2
- package/tsc/compilerOptions.d.ts +2 -0
- package/tsc/compilerOptions.js +61 -0
package/action/action.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface Builder<T extends Ent> {
|
|
|
14
14
|
build(): Promise<Changeset<T>>;
|
|
15
15
|
operation: WriteOperation;
|
|
16
16
|
editedEnt?(): Promise<T | null>;
|
|
17
|
+
nodeType: string;
|
|
17
18
|
}
|
|
18
19
|
export interface Executor extends Iterable<DataOperation>, Iterator<DataOperation> {
|
|
19
20
|
placeholderID: ID;
|
|
@@ -31,24 +32,24 @@ export interface Changeset<T extends Ent> {
|
|
|
31
32
|
dependencies?: Map<ID, Builder<Ent>>;
|
|
32
33
|
}
|
|
33
34
|
export declare type TriggerReturn = void | Promise<Changeset<Ent> | void | (Changeset<Ent> | void)[]> | Promise<Changeset<Ent>>[];
|
|
34
|
-
export interface Trigger<
|
|
35
|
-
changeset(builder:
|
|
35
|
+
export interface Trigger<TBuilder extends Builder<Ent>, TData extends Data> {
|
|
36
|
+
changeset(builder: TBuilder, input: TData): TriggerReturn;
|
|
36
37
|
}
|
|
37
|
-
export interface Observer<
|
|
38
|
-
observe(builder:
|
|
38
|
+
export interface Observer<TBuilder extends Builder<Ent>, TData extends Data> {
|
|
39
|
+
observe(builder: TBuilder, input: TData): void | Promise<void>;
|
|
39
40
|
}
|
|
40
|
-
export interface Validator<
|
|
41
|
-
validate(builder:
|
|
41
|
+
export interface Validator<TBuilder extends Builder<Ent>, TData extends Data> {
|
|
42
|
+
validate(builder: TBuilder, input: TData): Promise<void> | void;
|
|
42
43
|
}
|
|
43
|
-
export interface Action<
|
|
44
|
+
export interface Action<TEnt extends Ent, TBuilder extends Builder<TEnt>, TData extends Data> {
|
|
44
45
|
readonly viewer: Viewer;
|
|
45
|
-
changeset(): Promise<Changeset<
|
|
46
|
-
builder:
|
|
47
|
-
getPrivacyPolicy(): PrivacyPolicy
|
|
48
|
-
triggers?: Trigger<
|
|
49
|
-
observers?: Observer<
|
|
50
|
-
validators?: Validator<
|
|
51
|
-
getInput():
|
|
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;
|
|
52
53
|
valid(): Promise<boolean>;
|
|
53
54
|
validX(): Promise<void>;
|
|
54
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<
|
|
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>;
|
|
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;
|
|
@@ -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<
|
|
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<
|
|
67
|
+
build(): Promise<EntChangeset<TEnt>>;
|
|
68
68
|
private viewerForEntLoad;
|
|
69
69
|
returnedRow(): Promise<Data | null>;
|
|
70
|
-
editedEnt(): Promise<
|
|
71
|
-
editedEntX(): Promise<
|
|
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;
|
package/action/orchestrator.js
CHANGED
|
@@ -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)(
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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)(
|
|
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)(
|
|
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 = {
|
|
@@ -92,6 +92,12 @@ export interface LoadEntOptions<T extends Ent> extends LoadableEntOptions<T>, Se
|
|
|
92
92
|
export interface LoadCustomEntOptions<T extends Ent> extends SelectBaseDataOptions {
|
|
93
93
|
ent: EntConstructor<T>;
|
|
94
94
|
}
|
|
95
|
+
export interface LoaderInfo {
|
|
96
|
+
tableName: string;
|
|
97
|
+
fields: string[];
|
|
98
|
+
nodeType: string;
|
|
99
|
+
loaderFactory: LoaderFactory<any, Data | null>;
|
|
100
|
+
}
|
|
95
101
|
export interface EditEntOptions<T extends Ent> extends LoadableEntOptions<T>, EditRowOptions {
|
|
96
102
|
}
|
|
97
103
|
declare enum privacyResult {
|
|
@@ -104,17 +110,17 @@ export interface PrivacyResult {
|
|
|
104
110
|
error?: PrivacyError;
|
|
105
111
|
}
|
|
106
112
|
export interface PrivacyError extends Error {
|
|
107
|
-
privacyPolicy: PrivacyPolicy
|
|
113
|
+
privacyPolicy: PrivacyPolicy<Ent>;
|
|
108
114
|
ent?: Ent;
|
|
109
115
|
}
|
|
110
116
|
export declare function Allow(): PrivacyResult;
|
|
111
117
|
export declare function Skip(): PrivacyResult;
|
|
112
118
|
export declare function Deny(): PrivacyResult;
|
|
113
119
|
export declare function DenyWithReason(e: PrivacyError): PrivacyResult;
|
|
114
|
-
export interface PrivacyPolicyRule {
|
|
115
|
-
apply(v: Viewer, ent?:
|
|
120
|
+
export interface PrivacyPolicyRule<TEnt extends Ent = Ent> {
|
|
121
|
+
apply(v: Viewer, ent?: TEnt): Promise<PrivacyResult>;
|
|
116
122
|
}
|
|
117
|
-
export interface PrivacyPolicy {
|
|
118
|
-
rules: PrivacyPolicyRule[];
|
|
123
|
+
export interface PrivacyPolicy<TEnt extends Ent = Ent> {
|
|
124
|
+
rules: PrivacyPolicyRule<TEnt>[];
|
|
119
125
|
}
|
|
120
126
|
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,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.
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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.
|
|
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
|
|
1141
|
+
return loadEntsList(viewer, options, ...ids);
|
|
1137
1142
|
}
|
|
1138
1143
|
exports.loadNodesByEdge = loadNodesByEdge;
|
|
1139
1144
|
async function applyPrivacyPolicyForRow(viewer, options, row) {
|
|
@@ -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;
|
package/imports/index.d.ts
CHANGED
|
@@ -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.
|
|
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
package/parse_schema/parse.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Schema, AssocEdge, AssocEdgeGroup, Action } from "../schema";
|
|
1
|
+
import { Schema, Field, AssocEdge, AssocEdgeGroup, Action } from "../schema";
|
|
2
2
|
import { ActionField } from "../schema/schema";
|
|
3
3
|
declare enum NullableResult {
|
|
4
4
|
CONTENTS = "contents",
|
|
@@ -12,10 +12,11 @@ declare type ProcessedAssocEdge = Omit<AssocEdge, "actionOnlyFields" | "edgeActi
|
|
|
12
12
|
patternName?: string;
|
|
13
13
|
edgeActions?: OutputAction[];
|
|
14
14
|
};
|
|
15
|
-
declare type ProcessedSchema = Omit<Schema, "edges" | "actions" | "edgeGroups"> & {
|
|
15
|
+
declare type ProcessedSchema = Omit<Schema, "edges" | "actions" | "edgeGroups" | "fields"> & {
|
|
16
16
|
actions: OutputAction[];
|
|
17
17
|
assocEdges: ProcessedAssocEdge[];
|
|
18
18
|
assocEdgeGroups: ProcessedAssocEdgeGroup[];
|
|
19
|
+
fields: ProcessedField[];
|
|
19
20
|
};
|
|
20
21
|
declare type ProcessedAssocEdgeGroup = Omit<AssocEdgeGroup, "edgeAction"> & {
|
|
21
22
|
edgeAction?: OutputAction;
|
|
@@ -29,7 +30,15 @@ interface schemasDict {
|
|
|
29
30
|
interface ProcessedPattern {
|
|
30
31
|
name: string;
|
|
31
32
|
assocEdges: ProcessedAssocEdge[];
|
|
33
|
+
fields: ProcessedField[];
|
|
32
34
|
}
|
|
35
|
+
declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate"> & {
|
|
36
|
+
name: string;
|
|
37
|
+
hasDefaultValueOnCreate?: boolean;
|
|
38
|
+
hasDefaultValueOnEdit?: boolean;
|
|
39
|
+
patternName?: string;
|
|
40
|
+
derivedFields?: ProcessedField[];
|
|
41
|
+
};
|
|
33
42
|
interface patternsDict {
|
|
34
43
|
[key: string]: ProcessedPattern;
|
|
35
44
|
}
|
package/parse_schema/parse.js
CHANGED
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseSchema = void 0;
|
|
4
|
-
function processFields(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
function processFields(src, patternName) {
|
|
5
|
+
const ret = [];
|
|
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
|
+
let f = { name, ...field };
|
|
22
|
+
f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
|
|
23
|
+
f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
|
|
9
24
|
if (field.polymorphic) {
|
|
10
25
|
// convert boolean into object
|
|
11
26
|
// we keep boolean as an option to keep API simple
|
|
12
27
|
if (typeof field.polymorphic === "boolean") {
|
|
13
|
-
f
|
|
28
|
+
f.polymorphic = {};
|
|
14
29
|
}
|
|
15
30
|
else {
|
|
16
|
-
f
|
|
31
|
+
f.polymorphic = field.polymorphic;
|
|
17
32
|
}
|
|
18
33
|
}
|
|
34
|
+
else {
|
|
35
|
+
delete f.polymorphic;
|
|
36
|
+
}
|
|
19
37
|
// convert string to object to make API consumed by go simple
|
|
20
38
|
if (f.fieldEdge && f.fieldEdge.inverseEdge) {
|
|
21
39
|
if (typeof f.fieldEdge.inverseEdge === "string") {
|
|
@@ -24,16 +42,25 @@ function processFields(processedSchema, src) {
|
|
|
24
42
|
};
|
|
25
43
|
}
|
|
26
44
|
}
|
|
27
|
-
|
|
45
|
+
if (patternName) {
|
|
46
|
+
f.patternName = patternName;
|
|
47
|
+
}
|
|
48
|
+
if (field.getDerivedFields) {
|
|
49
|
+
f.derivedFields = processFields(field.getDerivedFields(name));
|
|
50
|
+
}
|
|
51
|
+
ret.push(f);
|
|
28
52
|
}
|
|
53
|
+
return ret;
|
|
29
54
|
}
|
|
30
|
-
function processEdges(
|
|
55
|
+
function processEdges(src, patternName) {
|
|
56
|
+
const ret = [];
|
|
31
57
|
for (const edge of src) {
|
|
32
58
|
let edge2 = { ...edge };
|
|
33
59
|
edge2.edgeActions = edge.edgeActions?.map((action) => processAction(action));
|
|
34
60
|
edge2.patternName = patternName;
|
|
35
|
-
|
|
61
|
+
ret.push(edge2);
|
|
36
62
|
}
|
|
63
|
+
return ret;
|
|
37
64
|
}
|
|
38
65
|
function processEdgeGroups(processedSchema, edgeGroups) {
|
|
39
66
|
// array-ify this
|
|
@@ -49,26 +76,26 @@ function processEdgeGroups(processedSchema, edgeGroups) {
|
|
|
49
76
|
}
|
|
50
77
|
}
|
|
51
78
|
function processPattern(patterns, pattern, processedSchema) {
|
|
52
|
-
|
|
53
|
-
|
|
79
|
+
const name = pattern.name;
|
|
80
|
+
const fields = processFields(pattern.fields, pattern.name);
|
|
81
|
+
processedSchema.fields.push(...fields);
|
|
82
|
+
if (pattern.edges) {
|
|
83
|
+
const edges = processEdges(pattern.edges, pattern.name);
|
|
84
|
+
processedSchema.assocEdges.push(...edges);
|
|
85
|
+
}
|
|
54
86
|
if (patterns[name] === undefined) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
processEdges(edges, pattern.edges);
|
|
58
|
-
}
|
|
87
|
+
// intentionally processing separately and not passing pattern.name
|
|
88
|
+
const edges = processEdges(pattern.edges || []);
|
|
59
89
|
patterns[name] = {
|
|
60
90
|
name: pattern.name,
|
|
61
91
|
assocEdges: edges,
|
|
92
|
+
fields: fields,
|
|
62
93
|
};
|
|
63
94
|
}
|
|
64
95
|
else {
|
|
65
96
|
// TODO ideally we want to make sure that different patterns don't have the same name
|
|
66
97
|
// can't do a deepEqual check because function calls and therefore different instances in fields
|
|
67
98
|
}
|
|
68
|
-
processFields(processedSchema, pattern.fields);
|
|
69
|
-
if (pattern.edges) {
|
|
70
|
-
processEdges(processedSchema.assocEdges, pattern.edges, pattern.name);
|
|
71
|
-
}
|
|
72
99
|
}
|
|
73
100
|
var NullableResult;
|
|
74
101
|
(function (NullableResult) {
|
|
@@ -84,6 +111,7 @@ function processAction(action) {
|
|
|
84
111
|
let actionOnlyFields = action.actionOnlyFields.map((f) => {
|
|
85
112
|
let f2 = f;
|
|
86
113
|
if (!f.nullable) {
|
|
114
|
+
delete f2.nullable;
|
|
87
115
|
return f2;
|
|
88
116
|
}
|
|
89
117
|
if (typeof f.nullable === "boolean") {
|
|
@@ -133,9 +161,11 @@ function parseSchema(potentialSchemas) {
|
|
|
133
161
|
processPattern(patterns, pattern, processedSchema);
|
|
134
162
|
}
|
|
135
163
|
}
|
|
136
|
-
processFields(
|
|
164
|
+
const fields = processFields(schema.fields);
|
|
165
|
+
processedSchema.fields.push(...fields);
|
|
137
166
|
if (schema.edges) {
|
|
138
|
-
processEdges(
|
|
167
|
+
const edges = processEdges(schema.edges);
|
|
168
|
+
processedSchema.assocEdges.push(...edges);
|
|
139
169
|
}
|
|
140
170
|
if (schema.edgeGroups) {
|
|
141
171
|
processEdgeGroups(processedSchema, schema.edgeGroups);
|