@snowtop/ent 0.1.0-alpha80 → 0.1.0-alpha85
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 +10 -7
- package/action/action.js +2 -6
- package/action/orchestrator.d.ts +1 -0
- package/action/orchestrator.js +23 -0
- package/core/base.d.ts +5 -0
- package/core/base.js +7 -1
- package/package.json +1 -1
- package/schema/field.d.ts +10 -3
- package/schema/field.js +57 -10
- package/schema/schema.d.ts +1 -0
- package/schema/struct_field.js +1 -1
- package/scripts/custom_graphql.js +2 -2
- package/scripts/migrate_v0.1.js +1 -1
- package/testutils/builder.js +2 -1
package/action/action.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { Ent, EntConstructor, Viewer, ID, Data, PrivacyPolicy, Context } from "../core/base";
|
|
1
|
+
import { Ent, EntConstructor, Viewer, ID, Data, PrivacyPolicy, Context, WriteOperation } from "../core/base";
|
|
2
2
|
import { DataOperation, AssocEdgeInputOptions } from "../core/ent";
|
|
3
3
|
import { Queryer } from "../core/db";
|
|
4
4
|
import { TransformedUpdateOperation, UpdateOperation } from "../schema";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Edit = "edit",
|
|
8
|
-
Delete = "delete"
|
|
9
|
-
}
|
|
5
|
+
import { FieldInfoMap } from "../schema/schema";
|
|
6
|
+
export { WriteOperation };
|
|
10
7
|
declare type MaybeNull<T extends Ent> = T | null;
|
|
11
8
|
declare type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
|
|
9
|
+
interface BuilderOrchestrator {
|
|
10
|
+
__getOptions(): {
|
|
11
|
+
fieldInfo: FieldInfoMap;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
12
14
|
export interface Builder<TEnt extends Ent<TViewer>, TViewer extends Viewer = Viewer, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
|
|
13
15
|
existingEnt: TExistingEnt;
|
|
14
16
|
ent: EntConstructor<TEnt, TViewer>;
|
|
@@ -18,6 +20,8 @@ export interface Builder<TEnt extends Ent<TViewer>, TViewer extends Viewer = Vie
|
|
|
18
20
|
operation: WriteOperation;
|
|
19
21
|
editedEnt?(): Promise<TEnt | null>;
|
|
20
22
|
nodeType: string;
|
|
23
|
+
getInput(): Data;
|
|
24
|
+
orchestrator: BuilderOrchestrator;
|
|
21
25
|
}
|
|
22
26
|
export interface Executor extends Iterable<DataOperation>, Iterator<DataOperation> {
|
|
23
27
|
placeholderID: ID;
|
|
@@ -66,4 +70,3 @@ interface Orchestrator {
|
|
|
66
70
|
viewer: Viewer;
|
|
67
71
|
}
|
|
68
72
|
export declare function setEdgeTypeInGroup<T extends string>(orchestrator: Orchestrator, inputEnumValue: string, id1: ID, id2: ID, nodeType: string, m: Map<T, string>): Promise<void>;
|
|
69
|
-
export {};
|
package/action/action.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setEdgeTypeInGroup = exports.saveBuilderX = exports.saveBuilder = exports.WriteOperation = void 0;
|
|
4
|
+
const base_1 = require("../core/base");
|
|
5
|
+
Object.defineProperty(exports, "WriteOperation", { enumerable: true, get: function () { return base_1.WriteOperation; } });
|
|
4
6
|
const ent_1 = require("../core/ent");
|
|
5
7
|
const logger_1 = require("../core/logger");
|
|
6
|
-
var WriteOperation;
|
|
7
|
-
(function (WriteOperation) {
|
|
8
|
-
WriteOperation["Insert"] = "insert";
|
|
9
|
-
WriteOperation["Edit"] = "edit";
|
|
10
|
-
WriteOperation["Delete"] = "delete";
|
|
11
|
-
})(WriteOperation = exports.WriteOperation || (exports.WriteOperation = {}));
|
|
12
8
|
async function saveBuilder(builder) {
|
|
13
9
|
await saveBuilderImpl(builder, false);
|
|
14
10
|
}
|
package/action/orchestrator.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ export declare class Orchestrator<TEnt extends Ent<TViewer>, TInput extends Data
|
|
|
49
49
|
private disableTransformations;
|
|
50
50
|
private memoizedGetFields;
|
|
51
51
|
constructor(options: OrchestratorOptions<TEnt, TInput, TViewer, TExistingEnt>);
|
|
52
|
+
__getOptions(): OrchestratorOptions<any, any, any, any>;
|
|
52
53
|
private addEdge;
|
|
53
54
|
setDisableTransformations(val: boolean): void;
|
|
54
55
|
addInboundEdge<T2 extends Ent>(id1: ID | Builder<T2, any>, edgeType: string, nodeType: string, options?: AssocEdgeInputOptions): void;
|
package/action/orchestrator.js
CHANGED
|
@@ -88,6 +88,10 @@ class Orchestrator {
|
|
|
88
88
|
this.existingEnt = this.options.builder.existingEnt;
|
|
89
89
|
this.memoizedGetFields = (0, memoizee_1.default)(this.getFieldsInfo.bind(this));
|
|
90
90
|
}
|
|
91
|
+
// don't type this because we don't care
|
|
92
|
+
__getOptions() {
|
|
93
|
+
return this.options;
|
|
94
|
+
}
|
|
91
95
|
addEdge(edge, op) {
|
|
92
96
|
this.edgeSet.add(edge.edgeType);
|
|
93
97
|
let m1 = this.edges.get(edge.edgeType) || new Map();
|
|
@@ -607,8 +611,12 @@ class Orchestrator {
|
|
|
607
611
|
// build up data to be saved...
|
|
608
612
|
let data = {};
|
|
609
613
|
let logValues = {};
|
|
614
|
+
let needsFullDataChecks = [];
|
|
610
615
|
for (const [fieldName, field] of schemaFields) {
|
|
611
616
|
let value = editedFields.get(fieldName);
|
|
617
|
+
if (field.validateWithFullData) {
|
|
618
|
+
needsFullDataChecks.push(fieldName);
|
|
619
|
+
}
|
|
612
620
|
if (value === undefined && op === action_1.WriteOperation.Insert) {
|
|
613
621
|
// null allowed
|
|
614
622
|
value = this.defaultFieldsByFieldName[fieldName];
|
|
@@ -626,6 +634,21 @@ class Orchestrator {
|
|
|
626
634
|
logValues[dbKey] = field.logValue(value);
|
|
627
635
|
}
|
|
628
636
|
}
|
|
637
|
+
for (const fieldName of needsFullDataChecks) {
|
|
638
|
+
const field = schemaFields.get(fieldName);
|
|
639
|
+
let value = editedFields.get(fieldName);
|
|
640
|
+
// @ts-ignore...
|
|
641
|
+
// type hackery because it's hard
|
|
642
|
+
const v = await field.validateWithFullData(value, this.options.builder);
|
|
643
|
+
if (!v) {
|
|
644
|
+
if (value === undefined) {
|
|
645
|
+
errors.push(new Error(`field ${fieldName} set to undefined when it can't be nullable`));
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
errors.push(new Error(`field ${fieldName} set to null when it can't be nullable`));
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
629
652
|
// we ignored default values while editing.
|
|
630
653
|
// if we're editing and there's data, add default values
|
|
631
654
|
if (op === action_1.WriteOperation.Edit && this.hasData(data)) {
|
package/core/base.d.ts
CHANGED
|
@@ -143,4 +143,9 @@ export interface PrivacyPolicyRule<TEnt extends Ent = Ent, TViewer = Viewer> {
|
|
|
143
143
|
export interface PrivacyPolicy<TEnt extends Ent = Ent, TViewer = Viewer> {
|
|
144
144
|
rules: PrivacyPolicyRule<TEnt, TViewer>[];
|
|
145
145
|
}
|
|
146
|
+
export declare enum WriteOperation {
|
|
147
|
+
Insert = "insert",
|
|
148
|
+
Edit = "edit",
|
|
149
|
+
Delete = "delete"
|
|
150
|
+
}
|
|
146
151
|
export {};
|
package/core/base.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DenyWithReason = exports.Deny = exports.Skip = exports.Allow = void 0;
|
|
3
|
+
exports.WriteOperation = exports.DenyWithReason = exports.Deny = exports.Skip = exports.Allow = void 0;
|
|
4
4
|
// Privacy
|
|
5
5
|
var privacyResult;
|
|
6
6
|
(function (privacyResult) {
|
|
@@ -53,3 +53,9 @@ function DenyWithReason(e) {
|
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
exports.DenyWithReason = DenyWithReason;
|
|
56
|
+
var WriteOperation;
|
|
57
|
+
(function (WriteOperation) {
|
|
58
|
+
WriteOperation["Insert"] = "insert";
|
|
59
|
+
WriteOperation["Edit"] = "edit";
|
|
60
|
+
WriteOperation["Delete"] = "delete";
|
|
61
|
+
})(WriteOperation = exports.WriteOperation || (exports.WriteOperation = {}));
|
package/package.json
CHANGED
package/schema/field.d.ts
CHANGED
|
@@ -131,8 +131,6 @@ export interface EnumOptions extends FieldOptions {
|
|
|
131
131
|
graphQLType?: string;
|
|
132
132
|
createEnumType?: boolean;
|
|
133
133
|
}
|
|
134
|
-
export interface StringEnumOptions extends EnumOptions {
|
|
135
|
-
}
|
|
136
134
|
/**
|
|
137
135
|
* @deprecated Use StringEnumField
|
|
138
136
|
*/
|
|
@@ -147,6 +145,11 @@ export declare class EnumField extends BaseField implements Field {
|
|
|
147
145
|
}
|
|
148
146
|
export declare class StringEnumField extends EnumField {
|
|
149
147
|
}
|
|
148
|
+
export interface PolymorphicStringEnumOptions extends EnumOptions {
|
|
149
|
+
parentFieldToValidate: string;
|
|
150
|
+
}
|
|
151
|
+
export interface StringEnumOptions extends EnumOptions {
|
|
152
|
+
}
|
|
150
153
|
export declare function EnumType(options: StringEnumOptions): EnumField;
|
|
151
154
|
declare type IntEnumMap = {
|
|
152
155
|
[key: string]: number;
|
|
@@ -165,11 +168,15 @@ export declare class IntegerEnumField extends BaseField implements Field {
|
|
|
165
168
|
format(val: any): any;
|
|
166
169
|
}
|
|
167
170
|
export declare function IntegerEnumType(options: IntegerEnumOptions): IntegerEnumField;
|
|
171
|
+
interface ListOptions extends FieldOptions {
|
|
172
|
+
disableJSONStringify?: boolean;
|
|
173
|
+
}
|
|
168
174
|
export declare class ListField extends BaseField {
|
|
169
175
|
private field;
|
|
176
|
+
private options?;
|
|
170
177
|
type: Type;
|
|
171
178
|
private validators;
|
|
172
|
-
constructor(field: Field, options?:
|
|
179
|
+
constructor(field: Field, options?: ListOptions | undefined);
|
|
173
180
|
__getElemField(): Field;
|
|
174
181
|
validate(validator: (val: any[]) => boolean): this;
|
|
175
182
|
valid(val: any): Promise<boolean>;
|
package/schema/field.js
CHANGED
|
@@ -22,10 +22,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
22
22
|
exports.UUIDListType = exports.IntegerEnumListType = exports.EnumListType = exports.DateListType = exports.TimetzListType = exports.TimeListType = exports.TimestamptzListType = exports.TimestampListType = exports.BooleanListType = exports.BigIntegerListType = exports.FloatListType = exports.IntegerListType = exports.IntListType = exports.StringListType = exports.ListField = exports.IntegerEnumType = exports.IntegerEnumField = exports.EnumType = exports.StringEnumField = exports.EnumField = exports.DateType = exports.DateField = exports.TimetzType = exports.TimeType = exports.TimeField = exports.leftPad = exports.TimestamptzType = exports.TimestampType = exports.TimestampField = exports.StringType = exports.StringField = exports.BooleanType = exports.BooleanField = exports.FloatType = exports.FloatField = exports.BigIntegerType = exports.BigIntegerField = exports.IntegerType = exports.IntegerField = exports.UUIDType = exports.UUIDField = exports.BaseField = void 0;
|
|
23
23
|
const luxon_1 = require("luxon");
|
|
24
24
|
const snake_case_1 = require("snake-case");
|
|
25
|
-
const db_1 = __importStar(require("../core/db"));
|
|
26
|
-
const schema_1 = require("./schema");
|
|
27
25
|
const util_1 = require("util");
|
|
28
26
|
const uuid_1 = require("uuid");
|
|
27
|
+
const base_1 = require("../core/base");
|
|
28
|
+
const db_1 = __importStar(require("../core/db"));
|
|
29
|
+
const schema_1 = require("./schema");
|
|
29
30
|
class BaseField {
|
|
30
31
|
logValue(val) {
|
|
31
32
|
if (this.sensitive) {
|
|
@@ -68,21 +69,22 @@ class UUIDField extends BaseField {
|
|
|
68
69
|
if (typeof polymorphic === "object" && polymorphic.types) {
|
|
69
70
|
// an enum with types validated here
|
|
70
71
|
return {
|
|
71
|
-
[name]:
|
|
72
|
+
[name]: PolymorphicStringEnumType({
|
|
72
73
|
values: polymorphic.types,
|
|
73
74
|
hideFromGraphQL: true,
|
|
74
75
|
derivedWhenEmbedded: true,
|
|
75
76
|
nullable: this.options?.nullable,
|
|
77
|
+
parentFieldToValidate: fieldName,
|
|
76
78
|
}),
|
|
77
79
|
};
|
|
78
80
|
}
|
|
79
81
|
else {
|
|
80
|
-
// just a string field...
|
|
81
82
|
return {
|
|
82
|
-
[name]:
|
|
83
|
+
[name]: PolymorphicStringType({
|
|
83
84
|
hideFromGraphQL: true,
|
|
84
85
|
derivedWhenEmbedded: true,
|
|
85
86
|
nullable: this.options?.nullable,
|
|
87
|
+
parentFieldToValidate: fieldName,
|
|
86
88
|
}),
|
|
87
89
|
};
|
|
88
90
|
}
|
|
@@ -311,6 +313,33 @@ class StringField extends BaseField {
|
|
|
311
313
|
}
|
|
312
314
|
}
|
|
313
315
|
exports.StringField = StringField;
|
|
316
|
+
function validatePolymorphicTypeWithFullData(val, b, field) {
|
|
317
|
+
const input = b.getInput();
|
|
318
|
+
const inputKey = b.orchestrator.__getOptions().fieldInfo[field].inputKey;
|
|
319
|
+
const v = input[inputKey];
|
|
320
|
+
if (val === null) {
|
|
321
|
+
// if this is being set to null, ok if v is also null
|
|
322
|
+
return v === null;
|
|
323
|
+
}
|
|
324
|
+
// if this is not being set, ok if v is not being set
|
|
325
|
+
if (val === undefined && b.operation === base_1.WriteOperation.Insert) {
|
|
326
|
+
return v === undefined;
|
|
327
|
+
}
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
class PolymorphicStringField extends StringField {
|
|
331
|
+
constructor(opts) {
|
|
332
|
+
super(opts);
|
|
333
|
+
this.opts = opts;
|
|
334
|
+
}
|
|
335
|
+
validateWithFullData(val, b) {
|
|
336
|
+
return validatePolymorphicTypeWithFullData(val, b, this.opts.parentFieldToValidate);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function PolymorphicStringType(opts) {
|
|
340
|
+
let result = new PolymorphicStringField(opts);
|
|
341
|
+
return Object.assign(result, opts);
|
|
342
|
+
}
|
|
314
343
|
function StringType(options) {
|
|
315
344
|
let result = new StringField(options);
|
|
316
345
|
const options2 = { ...options };
|
|
@@ -556,6 +585,19 @@ exports.EnumField = EnumField;
|
|
|
556
585
|
class StringEnumField extends EnumField {
|
|
557
586
|
}
|
|
558
587
|
exports.StringEnumField = StringEnumField;
|
|
588
|
+
class PolymorphicStringEnumField extends StringEnumField {
|
|
589
|
+
constructor(opts) {
|
|
590
|
+
super(opts);
|
|
591
|
+
this.opts = opts;
|
|
592
|
+
}
|
|
593
|
+
validateWithFullData(val, b) {
|
|
594
|
+
return validatePolymorphicTypeWithFullData(val, b, this.opts.parentFieldToValidate);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
function PolymorphicStringEnumType(options) {
|
|
598
|
+
let result = new PolymorphicStringEnumField(options);
|
|
599
|
+
return Object.assign(result, options);
|
|
600
|
+
}
|
|
559
601
|
function EnumType(options) {
|
|
560
602
|
let result = new StringEnumField(options);
|
|
561
603
|
return Object.assign(result, options);
|
|
@@ -608,6 +650,7 @@ class ListField extends BaseField {
|
|
|
608
650
|
constructor(field, options) {
|
|
609
651
|
super();
|
|
610
652
|
this.field = field;
|
|
653
|
+
this.options = options;
|
|
611
654
|
this.validators = [];
|
|
612
655
|
if (field.type.dbType === schema_1.DBType.List) {
|
|
613
656
|
throw new Error(`nested lists not currently supported`);
|
|
@@ -648,11 +691,12 @@ class ListField extends BaseField {
|
|
|
648
691
|
return result;
|
|
649
692
|
}
|
|
650
693
|
postgresVal(val, jsonType) {
|
|
651
|
-
if (!jsonType) {
|
|
694
|
+
if (!jsonType && val === "") {
|
|
652
695
|
// support empty strings in list
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
696
|
+
val = '"' + val + '"';
|
|
697
|
+
return val;
|
|
698
|
+
}
|
|
699
|
+
if (this.options?.disableJSONStringify) {
|
|
656
700
|
return val;
|
|
657
701
|
}
|
|
658
702
|
return JSON.stringify(val);
|
|
@@ -789,6 +833,9 @@ function IntegerEnumListType(options) {
|
|
|
789
833
|
}
|
|
790
834
|
exports.IntegerEnumListType = IntegerEnumListType;
|
|
791
835
|
function UUIDListType(options) {
|
|
792
|
-
return new ListField(UUIDType(options),
|
|
836
|
+
return new ListField(UUIDType(options), {
|
|
837
|
+
...options,
|
|
838
|
+
disableJSONStringify: true,
|
|
839
|
+
});
|
|
793
840
|
}
|
|
794
841
|
exports.UUIDListType = UUIDListType;
|
package/schema/schema.d.ts
CHANGED
|
@@ -217,6 +217,7 @@ export interface PolymorphicOptions {
|
|
|
217
217
|
export interface Field extends FieldOptions {
|
|
218
218
|
type: Type;
|
|
219
219
|
valid?(val: any): Promise<boolean> | boolean;
|
|
220
|
+
validateWithFullData?(val: any, builder: Builder<any>): boolean | Promise<boolean>;
|
|
220
221
|
format?(val: any, nested?: boolean): any;
|
|
221
222
|
logValue(val: any): any;
|
|
222
223
|
}
|
package/schema/struct_field.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StructTypeAsList = exports.StructListType = exports.StructType = exports.StructField = void 0;
|
|
4
|
+
const camel_case_1 = require("camel-case");
|
|
4
5
|
const field_1 = require("./field");
|
|
5
6
|
const schema_1 = require("./schema");
|
|
6
|
-
const camel_case_1 = require("camel-case");
|
|
7
7
|
class StructField extends field_1.BaseField {
|
|
8
8
|
constructor(options) {
|
|
9
9
|
super();
|
|
@@ -26,10 +26,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
const glob_1 = __importDefault(require("glob"));
|
|
27
27
|
const json5_1 = __importDefault(require("json5"));
|
|
28
28
|
const minimist_1 = __importDefault(require("minimist"));
|
|
29
|
-
const graphql_1 = require("../graphql/graphql");
|
|
30
|
-
const readline = __importStar(require("readline"));
|
|
31
29
|
const path = __importStar(require("path"));
|
|
32
30
|
const fs = __importStar(require("fs"));
|
|
31
|
+
const graphql_1 = require("../graphql/graphql");
|
|
32
|
+
const readline = __importStar(require("readline"));
|
|
33
33
|
const imports_1 = require("../imports");
|
|
34
34
|
const process_1 = require("process");
|
|
35
35
|
// need to use the GQLCapture from the package so that when we call GQLCapture.enable()
|
package/scripts/migrate_v0.1.js
CHANGED
|
@@ -3,12 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const minimist_1 = __importDefault(require("minimist"));
|
|
6
7
|
const transform_1 = require("../tsc/transform");
|
|
7
8
|
const transform_schema_1 = require("../tsc/transform_schema");
|
|
8
9
|
const transform_ent_1 = require("../tsc/transform_ent");
|
|
9
10
|
const move_generated_1 = require("../tsc/move_generated");
|
|
10
11
|
const transform_action_1 = require("../tsc/transform_action");
|
|
11
|
-
const minimist_1 = __importDefault(require("minimist"));
|
|
12
12
|
const ast_1 = require("../tsc/ast");
|
|
13
13
|
// todo-sqlite
|
|
14
14
|
// ts-node-script --swc --project ./tsconfig.json -r tsconfig-paths/register ../../ts/src/scripts/migrate_v0.1.ts --transform_schema --old_base_class BaseEntTodoSchema --new_schema_class TodoEntSchema --transform_path src/schema/patterns/base
|
package/testutils/builder.js
CHANGED
|
@@ -137,7 +137,8 @@ function getFieldInfo(value) {
|
|
|
137
137
|
for (const [k, f] of fields) {
|
|
138
138
|
ret[k] = {
|
|
139
139
|
dbCol: (0, schema_2.getStorageKey)(f, k),
|
|
140
|
-
|
|
140
|
+
// in tests (anything using SimpleBuilder), make it be the same as the fieldName
|
|
141
|
+
inputKey: k,
|
|
141
142
|
};
|
|
142
143
|
}
|
|
143
144
|
return ret;
|