@snowtop/ent 0.1.0-alpha2 → 0.1.0-alpha3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +8 -2
- package/parse_schema/parse.js +13 -0
- package/schema/field.d.ts +1 -1
- package/schema/field.js +10 -2
- package/schema/index.d.ts +2 -0
- package/schema/index.js +2 -0
- package/schema/schema.d.ts +3 -1
- package/schema/struct_field.d.ts +17 -0
- package/schema/struct_field.js +102 -0
- package/schema/union_field.d.ts +22 -0
- package/schema/union_field.js +61 -0
package/package.json
CHANGED
package/parse_schema/parse.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Schema, Field, AssocEdge, AssocEdgeGroup, Action } from "../schema";
|
|
1
|
+
import { Schema, Field, AssocEdge, AssocEdgeGroup, Action, Type } from "../schema";
|
|
2
2
|
import { ActionField } from "../schema/schema";
|
|
3
3
|
declare enum NullableResult {
|
|
4
4
|
CONTENTS = "contents",
|
|
@@ -32,12 +32,18 @@ interface ProcessedPattern {
|
|
|
32
32
|
assocEdges: ProcessedAssocEdge[];
|
|
33
33
|
fields: ProcessedField[];
|
|
34
34
|
}
|
|
35
|
-
declare type
|
|
35
|
+
declare type ProcessedType = Omit<Type, "subFields" | "listElemType" | "unionFields"> & {
|
|
36
|
+
subFields?: ProcessedField[];
|
|
37
|
+
listElemType?: ProcessedType;
|
|
38
|
+
unionFields?: ProcessedField[];
|
|
39
|
+
};
|
|
40
|
+
declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate" | "type"> & {
|
|
36
41
|
name: string;
|
|
37
42
|
hasDefaultValueOnCreate?: boolean;
|
|
38
43
|
hasDefaultValueOnEdit?: boolean;
|
|
39
44
|
patternName?: string;
|
|
40
45
|
derivedFields?: ProcessedField[];
|
|
46
|
+
type: ProcessedType;
|
|
41
47
|
};
|
|
42
48
|
interface patternsDict {
|
|
43
49
|
[key: string]: ProcessedPattern;
|
package/parse_schema/parse.js
CHANGED
|
@@ -18,6 +18,7 @@ function processFields(src, patternName) {
|
|
|
18
18
|
}
|
|
19
19
|
for (const name in m) {
|
|
20
20
|
const field = m[name];
|
|
21
|
+
//@ts-ignore type and other changed fields with different type in ProcessedField vs Field
|
|
21
22
|
let f = { name, ...field };
|
|
22
23
|
f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
|
|
23
24
|
f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
|
|
@@ -48,6 +49,18 @@ function processFields(src, patternName) {
|
|
|
48
49
|
if (field.getDerivedFields) {
|
|
49
50
|
f.derivedFields = processFields(field.getDerivedFields(name));
|
|
50
51
|
}
|
|
52
|
+
if (field.type.subFields) {
|
|
53
|
+
f.type.subFields = processFields(field.type.subFields);
|
|
54
|
+
}
|
|
55
|
+
if (field.type.unionFields) {
|
|
56
|
+
f.type.unionFields = processFields(field.type.unionFields);
|
|
57
|
+
}
|
|
58
|
+
if (field.type.listElemType &&
|
|
59
|
+
field.type.listElemType.subFields &&
|
|
60
|
+
// check to avoid ts-ignore below. exists just for tsc
|
|
61
|
+
f.type.listElemType) {
|
|
62
|
+
f.type.listElemType.subFields = processFields(field.type.listElemType.subFields);
|
|
63
|
+
}
|
|
51
64
|
ret.push(f);
|
|
52
65
|
}
|
|
53
66
|
return ret;
|
package/schema/field.d.ts
CHANGED
|
@@ -146,7 +146,7 @@ export declare class ListField extends BaseField {
|
|
|
146
146
|
validate(validator: (val: any[]) => boolean): this;
|
|
147
147
|
valid(val: any): Promise<boolean>;
|
|
148
148
|
private postgresVal;
|
|
149
|
-
format(val: any): any;
|
|
149
|
+
format(val: any, nested?: boolean): any;
|
|
150
150
|
minLen(l: number): this;
|
|
151
151
|
maxLen(l: number): this;
|
|
152
152
|
length(l: number): this;
|
package/schema/field.js
CHANGED
|
@@ -597,13 +597,17 @@ class ListField extends BaseField {
|
|
|
597
597
|
}
|
|
598
598
|
return JSON.stringify(val);
|
|
599
599
|
}
|
|
600
|
-
format(val) {
|
|
600
|
+
format(val, nested) {
|
|
601
601
|
if (!Array.isArray(val)) {
|
|
602
602
|
throw new Error(`need an array to format`);
|
|
603
603
|
}
|
|
604
604
|
const elemDBType = this.type.listElemType.dbType;
|
|
605
605
|
const jsonType = elemDBType === "JSON" || elemDBType === "JSONB";
|
|
606
|
-
|
|
606
|
+
// postgres ish doesn't apply when nested
|
|
607
|
+
const postgres = !nested && db_1.default.getDialect() === db_1.Dialect.Postgres;
|
|
608
|
+
if (nested && !this.field.format) {
|
|
609
|
+
return val;
|
|
610
|
+
}
|
|
607
611
|
if (!postgres && !this.field.format) {
|
|
608
612
|
return JSON.stringify(val);
|
|
609
613
|
}
|
|
@@ -629,6 +633,10 @@ class ListField extends BaseField {
|
|
|
629
633
|
if (postgres) {
|
|
630
634
|
return postgresRet + "}";
|
|
631
635
|
}
|
|
636
|
+
// don't JSON.stringify if nested
|
|
637
|
+
if (nested) {
|
|
638
|
+
return ret;
|
|
639
|
+
}
|
|
632
640
|
return JSON.stringify(ret);
|
|
633
641
|
}
|
|
634
642
|
minLen(l) {
|
package/schema/index.d.ts
CHANGED
|
@@ -4,3 +4,5 @@ export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBTy
|
|
|
4
4
|
export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, } from "./base_schema";
|
|
5
5
|
export * from "./field";
|
|
6
6
|
export * from "./json_field";
|
|
7
|
+
export * from "./struct_field";
|
|
8
|
+
export * from "./union_field";
|
package/schema/index.js
CHANGED
|
@@ -26,3 +26,5 @@ Object.defineProperty(exports, "BaseEntSchema", { enumerable: true, get: functio
|
|
|
26
26
|
Object.defineProperty(exports, "BaseEntSchemaWithTZ", { enumerable: true, get: function () { return base_schema_1.BaseEntSchemaWithTZ; } });
|
|
27
27
|
__exportStar(require("./field"), exports);
|
|
28
28
|
__exportStar(require("./json_field"), exports);
|
|
29
|
+
__exportStar(require("./struct_field"), exports);
|
|
30
|
+
__exportStar(require("./union_field"), exports);
|
package/schema/schema.d.ts
CHANGED
|
@@ -97,6 +97,8 @@ export interface Type {
|
|
|
97
97
|
values?: string[];
|
|
98
98
|
enumMap?: EnumMap;
|
|
99
99
|
importType?: ImportType;
|
|
100
|
+
subFields?: FieldMap;
|
|
101
|
+
unionFields?: FieldMap;
|
|
100
102
|
}
|
|
101
103
|
export interface ForeignKey {
|
|
102
104
|
schema: string;
|
|
@@ -149,7 +151,7 @@ export interface PolymorphicOptions {
|
|
|
149
151
|
export interface Field extends FieldOptions {
|
|
150
152
|
type: Type;
|
|
151
153
|
valid?(val: any): Promise<boolean> | boolean;
|
|
152
|
-
format?(val: any): any;
|
|
154
|
+
format?(val: any, nested?: boolean): any;
|
|
153
155
|
logValue(val: any): any;
|
|
154
156
|
}
|
|
155
157
|
export interface SchemaConstructor {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseField, ListField } from "./field";
|
|
2
|
+
import { FieldOptions, Field, Type, FieldMap } from "./schema";
|
|
3
|
+
export interface StructOptions extends FieldOptions {
|
|
4
|
+
tsType: string;
|
|
5
|
+
fields: FieldMap;
|
|
6
|
+
graphQLType?: string;
|
|
7
|
+
jsonNotJSONB?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class StructField extends BaseField implements Field {
|
|
10
|
+
private options;
|
|
11
|
+
type: Type;
|
|
12
|
+
constructor(options: StructOptions);
|
|
13
|
+
format(obj: any, nested?: boolean): string | Object;
|
|
14
|
+
valid(obj: any): Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
export declare function StructType(options: StructOptions): StructField & StructOptions;
|
|
17
|
+
export declare function StructListType(options: StructOptions): ListField;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StructListType = exports.StructType = exports.StructField = void 0;
|
|
4
|
+
const field_1 = require("./field");
|
|
5
|
+
const schema_1 = require("./schema");
|
|
6
|
+
const camel_case_1 = require("camel-case");
|
|
7
|
+
class StructField extends field_1.BaseField {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super();
|
|
10
|
+
this.options = options;
|
|
11
|
+
this.type = {
|
|
12
|
+
dbType: schema_1.DBType.JSONB,
|
|
13
|
+
};
|
|
14
|
+
this.type.subFields = options.fields;
|
|
15
|
+
this.type.type = options.tsType;
|
|
16
|
+
this.type.graphQLType = options.graphQLType || options.tsType;
|
|
17
|
+
if (options.jsonNotJSONB) {
|
|
18
|
+
this.type.dbType = schema_1.DBType.JSON;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// right now, we store things in the db in lowerCase format
|
|
22
|
+
// this will lead to issues if field changes.
|
|
23
|
+
// TODO: use storageKey and convert back...
|
|
24
|
+
format(obj, nested) {
|
|
25
|
+
if (!(obj instanceof Object)) {
|
|
26
|
+
throw new Error("valid was not called");
|
|
27
|
+
}
|
|
28
|
+
let ret = {};
|
|
29
|
+
for (const k in this.options.fields) {
|
|
30
|
+
// TODO more #510
|
|
31
|
+
let dbKey = (0, camel_case_1.camelCase)(k);
|
|
32
|
+
let val = obj[dbKey];
|
|
33
|
+
// for tests with snake_case
|
|
34
|
+
if (val === undefined && obj[k] !== undefined) {
|
|
35
|
+
val = obj[k];
|
|
36
|
+
dbKey = k;
|
|
37
|
+
}
|
|
38
|
+
if (val === undefined) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const field = this.options.fields[k];
|
|
42
|
+
if (field.format) {
|
|
43
|
+
// indicate nested so this isn't JSON stringified
|
|
44
|
+
ret[dbKey] = field.format(val, true);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
ret[dbKey] = val;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// don't json.stringify if nested
|
|
51
|
+
if (nested) {
|
|
52
|
+
return ret;
|
|
53
|
+
}
|
|
54
|
+
return JSON.stringify(ret);
|
|
55
|
+
}
|
|
56
|
+
async valid(obj) {
|
|
57
|
+
if (!(obj instanceof Object)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
let promises = [];
|
|
61
|
+
// TODO probably need to support optional fields...
|
|
62
|
+
let valid = true;
|
|
63
|
+
for (const k in this.options.fields) {
|
|
64
|
+
const field = this.options.fields[k];
|
|
65
|
+
// TODO more #510
|
|
66
|
+
let dbKey = (0, camel_case_1.camelCase)(k);
|
|
67
|
+
let val = obj[dbKey];
|
|
68
|
+
// for tests with snake_case
|
|
69
|
+
if (val === undefined && obj[k] !== undefined) {
|
|
70
|
+
val = obj[k];
|
|
71
|
+
dbKey = k;
|
|
72
|
+
}
|
|
73
|
+
if (val === undefined || val === null) {
|
|
74
|
+
// nullable, nothing to do here
|
|
75
|
+
if (field.nullable) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
valid = false;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (!field.valid) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
promises.push(field.valid(val));
|
|
85
|
+
}
|
|
86
|
+
if (!valid) {
|
|
87
|
+
return valid;
|
|
88
|
+
}
|
|
89
|
+
const ret = await Promise.all(promises);
|
|
90
|
+
return ret.every((v) => v);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.StructField = StructField;
|
|
94
|
+
function StructType(options) {
|
|
95
|
+
let result = new StructField(options);
|
|
96
|
+
return Object.assign(result, options);
|
|
97
|
+
}
|
|
98
|
+
exports.StructType = StructType;
|
|
99
|
+
function StructListType(options) {
|
|
100
|
+
return new field_1.ListField(StructType(options), options);
|
|
101
|
+
}
|
|
102
|
+
exports.StructListType = StructListType;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { StructField } from "./struct_field";
|
|
2
|
+
import { FieldOptions, Type } from "./schema";
|
|
3
|
+
import { BaseField, ListField } from "./field";
|
|
4
|
+
export declare type StructMap = {
|
|
5
|
+
[key: string]: StructField;
|
|
6
|
+
};
|
|
7
|
+
export interface UnionOptions extends FieldOptions {
|
|
8
|
+
tsType: string;
|
|
9
|
+
fields: StructMap;
|
|
10
|
+
graphQLType?: string;
|
|
11
|
+
jsonNotJSONB?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare class UnionField extends BaseField implements FieldOptions {
|
|
14
|
+
private options;
|
|
15
|
+
type: Type;
|
|
16
|
+
m: Map<Object, string>;
|
|
17
|
+
constructor(options: UnionOptions);
|
|
18
|
+
format(obj: any, nested?: boolean): string | Object;
|
|
19
|
+
valid(obj: any): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
export declare function UnionType(options: UnionOptions): UnionField & UnionOptions;
|
|
22
|
+
export declare function UnionListType(options: UnionOptions): ListField;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnionListType = exports.UnionType = exports.UnionField = void 0;
|
|
4
|
+
const schema_1 = require("./schema");
|
|
5
|
+
const field_1 = require("./field");
|
|
6
|
+
class UnionField extends field_1.BaseField {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
super();
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.type = {
|
|
11
|
+
dbType: schema_1.DBType.JSONB,
|
|
12
|
+
};
|
|
13
|
+
this.m = new Map();
|
|
14
|
+
this.type.unionFields = options.fields;
|
|
15
|
+
this.type.type = options.tsType;
|
|
16
|
+
this.type.graphQLType = options.graphQLType || options.tsType;
|
|
17
|
+
// TODO should throw if not nested?
|
|
18
|
+
if (options.jsonNotJSONB) {
|
|
19
|
+
this.type.dbType = schema_1.DBType.JSON;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
format(obj, nested) {
|
|
23
|
+
if (!(obj instanceof Object)) {
|
|
24
|
+
throw new Error("valid was not called");
|
|
25
|
+
}
|
|
26
|
+
for (const k in this.options.fields) {
|
|
27
|
+
const field = this.options.fields[k];
|
|
28
|
+
const fmt = field.format(obj, nested);
|
|
29
|
+
if (fmt !== "{}") {
|
|
30
|
+
return fmt;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// TODO need better logic here
|
|
34
|
+
// maybe add something ignored to the objec that indicates which key?
|
|
35
|
+
// or store in map
|
|
36
|
+
throw new Error(`couldn't format union`);
|
|
37
|
+
}
|
|
38
|
+
async valid(obj) {
|
|
39
|
+
if (!(obj instanceof Object)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
let promises = [];
|
|
43
|
+
for (const k in this.options.fields) {
|
|
44
|
+
const field = this.options.fields[k];
|
|
45
|
+
promises.push(field.valid(obj));
|
|
46
|
+
}
|
|
47
|
+
const ret = await Promise.all(promises);
|
|
48
|
+
// only 1 should be valid
|
|
49
|
+
return ret.filter((v) => v).length === 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.UnionField = UnionField;
|
|
53
|
+
function UnionType(options) {
|
|
54
|
+
let result = new UnionField(options);
|
|
55
|
+
return Object.assign(result, options);
|
|
56
|
+
}
|
|
57
|
+
exports.UnionType = UnionType;
|
|
58
|
+
function UnionListType(options) {
|
|
59
|
+
return new field_1.ListField(UnionType(options), options);
|
|
60
|
+
}
|
|
61
|
+
exports.UnionListType = UnionListType;
|