@snowtop/ent 0.1.0-alpha → 0.1.0-alpha1
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/orchestrator.js +11 -11
- package/imports/index.d.ts +0 -1
- package/imports/index.js +3 -36
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +2 -0
- package/parse_schema/parse.js +10 -2
- package/schema/base_schema.js +15 -15
- package/schema/field.d.ts +24 -24
- package/schema/field.js +31 -30
- 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 +6 -4
- package/schema/schema.js +5 -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/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/tsc/compilerOptions.d.ts +2 -0
- package/tsc/compilerOptions.js +61 -0
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/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
|
@@ -33,9 +33,11 @@ interface ProcessedPattern {
|
|
|
33
33
|
fields: ProcessedField[];
|
|
34
34
|
}
|
|
35
35
|
declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate"> & {
|
|
36
|
+
name: string;
|
|
36
37
|
hasDefaultValueOnCreate?: boolean;
|
|
37
38
|
hasDefaultValueOnEdit?: boolean;
|
|
38
39
|
patternName?: string;
|
|
40
|
+
derivedFields?: ProcessedField[];
|
|
39
41
|
};
|
|
40
42
|
interface patternsDict {
|
|
41
43
|
[key: string]: ProcessedPattern;
|
package/parse_schema/parse.js
CHANGED
|
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseSchema = void 0;
|
|
4
4
|
function processFields(src, patternName) {
|
|
5
5
|
const ret = [];
|
|
6
|
-
for (const
|
|
7
|
-
|
|
6
|
+
for (const name in src) {
|
|
7
|
+
const field = src[name];
|
|
8
|
+
let f = { name, ...field };
|
|
8
9
|
f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
|
|
9
10
|
f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
|
|
10
11
|
if (field.polymorphic) {
|
|
@@ -17,6 +18,9 @@ function processFields(src, patternName) {
|
|
|
17
18
|
f.polymorphic = field.polymorphic;
|
|
18
19
|
}
|
|
19
20
|
}
|
|
21
|
+
else {
|
|
22
|
+
delete f.polymorphic;
|
|
23
|
+
}
|
|
20
24
|
// convert string to object to make API consumed by go simple
|
|
21
25
|
if (f.fieldEdge && f.fieldEdge.inverseEdge) {
|
|
22
26
|
if (typeof f.fieldEdge.inverseEdge === "string") {
|
|
@@ -28,6 +32,9 @@ function processFields(src, patternName) {
|
|
|
28
32
|
if (patternName) {
|
|
29
33
|
f.patternName = patternName;
|
|
30
34
|
}
|
|
35
|
+
if (field.getDerivedFields) {
|
|
36
|
+
f.derivedFields = processFields(field.getDerivedFields(name));
|
|
37
|
+
}
|
|
31
38
|
ret.push(f);
|
|
32
39
|
}
|
|
33
40
|
return ret;
|
|
@@ -91,6 +98,7 @@ function processAction(action) {
|
|
|
91
98
|
let actionOnlyFields = action.actionOnlyFields.map((f) => {
|
|
92
99
|
let f2 = f;
|
|
93
100
|
if (!f.nullable) {
|
|
101
|
+
delete f2.nullable;
|
|
94
102
|
return f2;
|
|
95
103
|
}
|
|
96
104
|
if (typeof f.nullable === "boolean") {
|
package/schema/base_schema.js
CHANGED
|
@@ -3,17 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BaseEntSchemaWithTZ = exports.BaseEntSchema = exports.Node = exports.Timestamps = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
5
|
const field_1 = require("./field");
|
|
6
|
-
let tsFields =
|
|
7
|
-
(0, field_1.TimestampType)({
|
|
8
|
-
name: "createdAt",
|
|
6
|
+
let tsFields = {
|
|
7
|
+
createdAt: (0, field_1.TimestampType)({
|
|
9
8
|
hideFromGraphQL: true,
|
|
10
9
|
disableUserEditable: true,
|
|
11
10
|
defaultValueOnCreate: () => {
|
|
12
11
|
return new Date();
|
|
13
12
|
},
|
|
14
13
|
}),
|
|
15
|
-
(0, field_1.TimestampType)({
|
|
16
|
-
name: "updatedAt",
|
|
14
|
+
updatedAt: (0, field_1.TimestampType)({
|
|
17
15
|
hideFromGraphQL: true,
|
|
18
16
|
disableUserEditable: true,
|
|
19
17
|
defaultValueOnCreate: () => {
|
|
@@ -23,25 +21,28 @@ let tsFields = [
|
|
|
23
21
|
return new Date();
|
|
24
22
|
},
|
|
25
23
|
}),
|
|
26
|
-
|
|
24
|
+
};
|
|
27
25
|
// Timestamps is a Pattern that adds a createdAt and updatedAt timestamp fields to the ent
|
|
28
26
|
exports.Timestamps = {
|
|
29
27
|
name: "timestamps",
|
|
30
28
|
fields: tsFields,
|
|
31
29
|
};
|
|
32
30
|
let nodeField = (0, field_1.UUIDType)({
|
|
33
|
-
name: "ID",
|
|
34
31
|
primaryKey: true,
|
|
35
32
|
disableUserEditable: true,
|
|
36
33
|
defaultValueOnCreate: () => {
|
|
37
34
|
return (0, uuid_1.v4)();
|
|
38
35
|
},
|
|
39
36
|
});
|
|
40
|
-
let nodeFields =
|
|
41
|
-
|
|
42
|
-
nodeField,
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
let nodeFields = {
|
|
38
|
+
// inconsistent naming :(
|
|
39
|
+
ID: nodeField,
|
|
40
|
+
...tsFields,
|
|
41
|
+
};
|
|
42
|
+
let nodeFieldsWithTZ = {
|
|
43
|
+
// inconsistent naming :(
|
|
44
|
+
ID: nodeField,
|
|
45
|
+
createdAt: (0, field_1.TimestampType)({
|
|
45
46
|
hideFromGraphQL: true,
|
|
46
47
|
disableUserEditable: true,
|
|
47
48
|
defaultValueOnCreate: () => {
|
|
@@ -49,8 +50,7 @@ let nodeFieldsWithTZ = [
|
|
|
49
50
|
},
|
|
50
51
|
withTimezone: true,
|
|
51
52
|
}),
|
|
52
|
-
(0, field_1.TimestampType)({
|
|
53
|
-
name: "updatedAt",
|
|
53
|
+
updatedAt: (0, field_1.TimestampType)({
|
|
54
54
|
hideFromGraphQL: true,
|
|
55
55
|
disableUserEditable: true,
|
|
56
56
|
defaultValueOnCreate: () => {
|
|
@@ -61,7 +61,7 @@ let nodeFieldsWithTZ = [
|
|
|
61
61
|
},
|
|
62
62
|
withTimezone: true,
|
|
63
63
|
}),
|
|
64
|
-
|
|
64
|
+
};
|
|
65
65
|
// Node is a Pattern that adds 3 fields to the ent: (id, createdAt, and updatedAt timestamps)
|
|
66
66
|
exports.Node = {
|
|
67
67
|
name: "node",
|
package/schema/field.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Field, FieldOptions, ForeignKey, PolymorphicOptions, Type } from "./schema";
|
|
1
|
+
import { Field, FieldMap, FieldOptions, ForeignKey, PolymorphicOptions, Type } from "./schema";
|
|
2
2
|
export declare abstract class BaseField {
|
|
3
3
|
name: string;
|
|
4
4
|
nullable?: boolean;
|
|
@@ -12,18 +12,18 @@ export declare abstract class BaseField {
|
|
|
12
12
|
index?: boolean;
|
|
13
13
|
foreignKey?: ForeignKey;
|
|
14
14
|
polymorphic?: boolean | PolymorphicOptions;
|
|
15
|
-
derivedFields?: Field[];
|
|
16
15
|
derivedWhenEmbedded?: boolean;
|
|
17
16
|
logValue(val: any): any;
|
|
18
17
|
}
|
|
19
18
|
export declare class UUIDField extends BaseField implements Field {
|
|
20
|
-
private options
|
|
19
|
+
private options?;
|
|
21
20
|
type: Type;
|
|
22
|
-
constructor(options
|
|
21
|
+
constructor(options?: FieldOptions | undefined);
|
|
22
|
+
getDerivedFields(fieldName: string): FieldMap;
|
|
23
23
|
private isBuilder;
|
|
24
24
|
valid(val: any): Promise<boolean>;
|
|
25
25
|
}
|
|
26
|
-
export declare function UUIDType(options
|
|
26
|
+
export declare function UUIDType(options?: FieldOptions): UUIDField;
|
|
27
27
|
export interface IntegerOptions extends FieldOptions {
|
|
28
28
|
min?: number;
|
|
29
29
|
max?: number;
|
|
@@ -40,7 +40,7 @@ export declare class IntegerField extends BaseField implements Field {
|
|
|
40
40
|
valid(val: any): boolean;
|
|
41
41
|
validate(validator: (str: number) => boolean): this;
|
|
42
42
|
}
|
|
43
|
-
export declare function IntegerType(options
|
|
43
|
+
export declare function IntegerType(options?: IntegerOptions): IntegerField;
|
|
44
44
|
export declare class BigIntegerField extends BaseField implements Field {
|
|
45
45
|
type: Type;
|
|
46
46
|
}
|
|
@@ -48,11 +48,11 @@ export declare function BigIntegerType(options: FieldOptions): BigIntegerField;
|
|
|
48
48
|
export declare class FloatField extends BaseField implements Field {
|
|
49
49
|
type: Type;
|
|
50
50
|
}
|
|
51
|
-
export declare function FloatType(options
|
|
51
|
+
export declare function FloatType(options?: FieldOptions): FloatField;
|
|
52
52
|
export declare class BooleanField extends BaseField implements Field {
|
|
53
53
|
type: Type;
|
|
54
54
|
}
|
|
55
|
-
export declare function BooleanType(options
|
|
55
|
+
export declare function BooleanType(options?: FieldOptions): BooleanField;
|
|
56
56
|
export interface StringOptions extends FieldOptions {
|
|
57
57
|
minLen?: number;
|
|
58
58
|
maxLen?: number;
|
|
@@ -88,7 +88,7 @@ export declare class StringField extends BaseField implements Field {
|
|
|
88
88
|
trimLeft(): this;
|
|
89
89
|
trimRight(): this;
|
|
90
90
|
}
|
|
91
|
-
export declare function StringType(options
|
|
91
|
+
export declare function StringType(options?: StringOptions): StringField;
|
|
92
92
|
export interface TimestampOptions extends FieldOptions {
|
|
93
93
|
withTimezone?: boolean;
|
|
94
94
|
}
|
|
@@ -98,8 +98,8 @@ export declare class TimestampField extends BaseField implements Field {
|
|
|
98
98
|
constructor(options: TimestampOptions);
|
|
99
99
|
format(val: Date): any;
|
|
100
100
|
}
|
|
101
|
-
export declare function TimestampType(options
|
|
102
|
-
export declare function TimestamptzType(options
|
|
101
|
+
export declare function TimestampType(options?: TimestampOptions): TimestampField;
|
|
102
|
+
export declare function TimestamptzType(options?: FieldOptions): TimestampField;
|
|
103
103
|
export interface TimeOptions extends FieldOptions {
|
|
104
104
|
withTimezone?: boolean;
|
|
105
105
|
precision?: number;
|
|
@@ -108,16 +108,16 @@ export declare const leftPad: (val: number) => string;
|
|
|
108
108
|
export declare class TimeField extends BaseField implements Field {
|
|
109
109
|
type: Type;
|
|
110
110
|
withTimezone?: boolean;
|
|
111
|
-
constructor(options
|
|
111
|
+
constructor(options?: TimeOptions);
|
|
112
112
|
format(val: any): any;
|
|
113
113
|
}
|
|
114
|
-
export declare function TimeType(options
|
|
115
|
-
export declare function TimetzType(options
|
|
114
|
+
export declare function TimeType(options?: TimeOptions): TimeField;
|
|
115
|
+
export declare function TimetzType(options?: FieldOptions): TimeField;
|
|
116
116
|
export declare class DateField extends BaseField implements Field {
|
|
117
117
|
type: Type;
|
|
118
118
|
format(val: any): any;
|
|
119
119
|
}
|
|
120
|
-
export declare function DateType(options
|
|
120
|
+
export declare function DateType(options?: FieldOptions): DateField;
|
|
121
121
|
declare type EnumMap = {
|
|
122
122
|
[key: string]: string;
|
|
123
123
|
};
|
|
@@ -142,7 +142,7 @@ export declare class ListField extends BaseField {
|
|
|
142
142
|
private field;
|
|
143
143
|
type: Type;
|
|
144
144
|
private validators;
|
|
145
|
-
constructor(field: Field, options
|
|
145
|
+
constructor(field: Field, options?: FieldOptions);
|
|
146
146
|
validate(validator: (val: any[]) => boolean): this;
|
|
147
147
|
valid(val: any): Promise<boolean>;
|
|
148
148
|
private postgresVal;
|
|
@@ -152,17 +152,17 @@ export declare class ListField extends BaseField {
|
|
|
152
152
|
length(l: number): this;
|
|
153
153
|
range(start: any, stop: any): this;
|
|
154
154
|
}
|
|
155
|
-
export declare function StringListType(options
|
|
155
|
+
export declare function StringListType(options?: StringOptions): ListField;
|
|
156
156
|
export declare function IntListType(options: FieldOptions): ListField;
|
|
157
|
-
export declare function IntegerListType(options
|
|
158
|
-
export declare function FloatListType(options
|
|
157
|
+
export declare function IntegerListType(options?: FieldOptions): ListField;
|
|
158
|
+
export declare function FloatListType(options?: FieldOptions): ListField;
|
|
159
159
|
export declare function BigIntegerListType(options: FieldOptions): ListField;
|
|
160
|
-
export declare function BooleanListType(options
|
|
160
|
+
export declare function BooleanListType(options?: FieldOptions): ListField;
|
|
161
161
|
export declare function TimestampListType(options: TimestampOptions): ListField;
|
|
162
|
-
export declare function TimestamptzListType(options
|
|
163
|
-
export declare function TimeListType(options
|
|
162
|
+
export declare function TimestamptzListType(options?: TimestampOptions): ListField;
|
|
163
|
+
export declare function TimeListType(options?: TimeOptions): ListField;
|
|
164
164
|
export declare function TimetzListType(options: TimeOptions): ListField;
|
|
165
|
-
export declare function DateListType(options
|
|
165
|
+
export declare function DateListType(options?: FieldOptions): ListField;
|
|
166
166
|
export declare function EnumListType(options: EnumOptions): ListField;
|
|
167
|
-
export declare function UUIDListType(options
|
|
167
|
+
export declare function UUIDListType(options?: FieldOptions): ListField;
|
|
168
168
|
export {};
|
package/schema/field.js
CHANGED
|
@@ -40,19 +40,25 @@ class UUIDField extends BaseField {
|
|
|
40
40
|
super();
|
|
41
41
|
this.options = options;
|
|
42
42
|
this.type = { dbType: schema_1.DBType.UUID };
|
|
43
|
-
|
|
43
|
+
if (options?.fieldEdge?.enforceSchema &&
|
|
44
|
+
!options.fieldEdge.getLoaderInfoFromSchema) {
|
|
45
|
+
throw new Error(`cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
getDerivedFields(fieldName) {
|
|
49
|
+
const polymorphic = this.options?.polymorphic;
|
|
44
50
|
if (polymorphic) {
|
|
45
51
|
let name = "";
|
|
46
|
-
if (
|
|
47
|
-
let idx =
|
|
48
|
-
name =
|
|
52
|
+
if (fieldName.endsWith("_id")) {
|
|
53
|
+
let idx = fieldName.indexOf("_id");
|
|
54
|
+
name = fieldName.substring(0, idx) + "_type";
|
|
49
55
|
}
|
|
50
|
-
else if (
|
|
51
|
-
let idx =
|
|
52
|
-
name =
|
|
56
|
+
else if (fieldName.endsWith("ID")) {
|
|
57
|
+
let idx = fieldName.indexOf("ID");
|
|
58
|
+
name = fieldName.substring(0, idx) + "Type";
|
|
53
59
|
}
|
|
54
60
|
else {
|
|
55
|
-
throw new Error(`unsupported id polymorhpic type ${
|
|
61
|
+
throw new Error(`unsupported id polymorhpic type ${fieldName}`);
|
|
56
62
|
}
|
|
57
63
|
// polymorphic field automatically hidden from GraphQL
|
|
58
64
|
// can be made visible with custom fields if user wants to change this behavior
|
|
@@ -60,38 +66,33 @@ class UUIDField extends BaseField {
|
|
|
60
66
|
// intentionally not made private as it doesn't seem like it needs to be hidden
|
|
61
67
|
if (typeof polymorphic === "object" && polymorphic.types) {
|
|
62
68
|
// an enum with types validated here
|
|
63
|
-
|
|
64
|
-
EnumType({
|
|
65
|
-
name,
|
|
69
|
+
return {
|
|
70
|
+
[name]: EnumType({
|
|
66
71
|
values: polymorphic.types,
|
|
67
72
|
hideFromGraphQL: true,
|
|
68
73
|
derivedWhenEmbedded: true,
|
|
69
|
-
nullable: options
|
|
74
|
+
nullable: this.options?.nullable,
|
|
70
75
|
}),
|
|
71
|
-
|
|
76
|
+
};
|
|
72
77
|
}
|
|
73
78
|
else {
|
|
74
79
|
// just a string field...
|
|
75
|
-
|
|
76
|
-
StringType({
|
|
77
|
-
name,
|
|
80
|
+
return {
|
|
81
|
+
[name]: StringType({
|
|
78
82
|
hideFromGraphQL: true,
|
|
79
83
|
derivedWhenEmbedded: true,
|
|
80
|
-
nullable: options
|
|
84
|
+
nullable: this.options?.nullable,
|
|
81
85
|
}),
|
|
82
|
-
|
|
86
|
+
};
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
|
-
|
|
86
|
-
!options.fieldEdge.getLoaderInfoFromSchema) {
|
|
87
|
-
throw new Error(`cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`);
|
|
88
|
-
}
|
|
89
|
+
return {};
|
|
89
90
|
}
|
|
90
91
|
isBuilder(val) {
|
|
91
92
|
return val.placeholderID !== undefined;
|
|
92
93
|
}
|
|
93
94
|
async valid(val) {
|
|
94
|
-
if (!this.options
|
|
95
|
+
if (!this.options?.fieldEdge?.enforceSchema) {
|
|
95
96
|
return true;
|
|
96
97
|
}
|
|
97
98
|
const getLoaderInfo = this.options.fieldEdge.getLoaderInfoFromSchema;
|
|
@@ -119,7 +120,7 @@ class IntegerField extends BaseField {
|
|
|
119
120
|
super();
|
|
120
121
|
this.type = { dbType: schema_1.DBType.Int };
|
|
121
122
|
this.validators = [];
|
|
122
|
-
this.options = {
|
|
123
|
+
this.options = {};
|
|
123
124
|
// for legacy callers
|
|
124
125
|
this.handleOptions(options || this.options);
|
|
125
126
|
}
|
|
@@ -206,9 +207,9 @@ class StringField extends BaseField {
|
|
|
206
207
|
this.type = { dbType: schema_1.DBType.String };
|
|
207
208
|
this.validators = [];
|
|
208
209
|
this.formatters = [];
|
|
209
|
-
this.options = {
|
|
210
|
+
this.options = {};
|
|
210
211
|
// for legacy callers
|
|
211
|
-
this.handleOptions(options || {
|
|
212
|
+
this.handleOptions(options || {});
|
|
212
213
|
}
|
|
213
214
|
getOptions() {
|
|
214
215
|
return this.options;
|
|
@@ -347,7 +348,7 @@ class TimestampField extends BaseField {
|
|
|
347
348
|
}
|
|
348
349
|
exports.TimestampField = TimestampField;
|
|
349
350
|
function TimestampType(options) {
|
|
350
|
-
let result = new TimestampField(options);
|
|
351
|
+
let result = new TimestampField({ ...options });
|
|
351
352
|
return Object.assign(result, options);
|
|
352
353
|
}
|
|
353
354
|
exports.TimestampType = TimestampType;
|
|
@@ -374,7 +375,7 @@ class TimeField extends BaseField {
|
|
|
374
375
|
constructor(options) {
|
|
375
376
|
super();
|
|
376
377
|
this.type = { dbType: schema_1.DBType.Time };
|
|
377
|
-
if (options
|
|
378
|
+
if (options?.withTimezone) {
|
|
378
379
|
this.type = {
|
|
379
380
|
dbType: schema_1.DBType.Timetz,
|
|
380
381
|
};
|
|
@@ -451,8 +452,8 @@ class EnumField extends BaseField {
|
|
|
451
452
|
dbType: options.createEnumType ? schema_1.DBType.Enum : schema_1.DBType.StringEnum,
|
|
452
453
|
values: options.values,
|
|
453
454
|
enumMap: options.map,
|
|
454
|
-
type: options.tsType
|
|
455
|
-
graphQLType: options.graphQLType
|
|
455
|
+
type: options.tsType,
|
|
456
|
+
graphQLType: options.graphQLType,
|
|
456
457
|
};
|
|
457
458
|
if (!options.foreignKey) {
|
|
458
459
|
if (!options.values && !options.map) {
|
package/schema/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Schema from "./schema";
|
|
2
2
|
export { Schema };
|
|
3
|
-
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, ActionOperation, Action, EdgeAction, NoFields, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, } from "./schema";
|
|
3
|
+
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, } from "./schema";
|
|
4
4
|
export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, } from "./base_schema";
|
|
5
5
|
export * from "./field";
|
|
6
6
|
export * from "./json_field";
|
package/schema/json_field.d.ts
CHANGED
|
@@ -5,13 +5,13 @@ export interface JSONOptions extends FieldOptions {
|
|
|
5
5
|
importType?: ImportType;
|
|
6
6
|
}
|
|
7
7
|
export declare class JSONField extends BaseField implements Field {
|
|
8
|
-
private options
|
|
8
|
+
private options?;
|
|
9
9
|
type: Type;
|
|
10
|
-
constructor(jsonb: boolean, options
|
|
10
|
+
constructor(jsonb: boolean, options?: JSONOptions | undefined);
|
|
11
11
|
format(val: any): string;
|
|
12
12
|
valid(val: any): boolean;
|
|
13
13
|
}
|
|
14
|
-
export declare function JSONType(options
|
|
15
|
-
export declare function JSONBType(options
|
|
16
|
-
export declare function JSONBListType(options
|
|
17
|
-
export declare function JSONListType(options
|
|
14
|
+
export declare function JSONType(options?: JSONOptions): JSONField;
|
|
15
|
+
export declare function JSONBType(options?: JSONOptions): JSONField;
|
|
16
|
+
export declare function JSONBListType(options?: JSONOptions): ListField;
|
|
17
|
+
export declare function JSONListType(options?: JSONOptions): ListField;
|
package/schema/json_field.js
CHANGED
|
@@ -13,7 +13,7 @@ class JSONField extends field_1.BaseField {
|
|
|
13
13
|
if (jsonb) {
|
|
14
14
|
this.type.dbType = schema_1.DBType.JSONB;
|
|
15
15
|
}
|
|
16
|
-
if (options
|
|
16
|
+
if (options?.importType) {
|
|
17
17
|
this.type.importType = options.importType;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -21,7 +21,7 @@ class JSONField extends field_1.BaseField {
|
|
|
21
21
|
return JSON.stringify(val);
|
|
22
22
|
}
|
|
23
23
|
valid(val) {
|
|
24
|
-
if (this.options
|
|
24
|
+
if (this.options?.validator) {
|
|
25
25
|
return this.options.validator(val);
|
|
26
26
|
}
|
|
27
27
|
return true;
|
package/schema/schema.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Data, Ent, LoaderInfo } from "../core/base";
|
|
2
2
|
import { Builder } from "../action/action";
|
|
3
|
+
export declare type FieldMap = {
|
|
4
|
+
[key: string]: Field;
|
|
5
|
+
};
|
|
3
6
|
export default interface Schema {
|
|
4
|
-
fields:
|
|
7
|
+
fields: FieldMap;
|
|
5
8
|
tableName?: string;
|
|
6
9
|
patterns?: Pattern[];
|
|
7
10
|
edges?: Edge[];
|
|
@@ -57,7 +60,7 @@ export interface AssocEdgeGroup {
|
|
|
57
60
|
export declare type Edge = AssocEdge;
|
|
58
61
|
export interface Pattern {
|
|
59
62
|
name: string;
|
|
60
|
-
fields:
|
|
63
|
+
fields: FieldMap;
|
|
61
64
|
edges?: Edge[];
|
|
62
65
|
}
|
|
63
66
|
export declare enum DBType {
|
|
@@ -117,7 +120,6 @@ export interface FieldEdge {
|
|
|
117
120
|
disableBuilderType?: boolean;
|
|
118
121
|
}
|
|
119
122
|
export interface FieldOptions {
|
|
120
|
-
name: string;
|
|
121
123
|
nullable?: boolean;
|
|
122
124
|
storageKey?: string;
|
|
123
125
|
serverDefault?: any;
|
|
@@ -136,7 +138,7 @@ export interface FieldOptions {
|
|
|
136
138
|
defaultValueOnEdit?(builder: Builder<Ent>, input: Data): any;
|
|
137
139
|
derivedWhenEmbedded?: boolean;
|
|
138
140
|
polymorphic?: boolean | PolymorphicOptions;
|
|
139
|
-
|
|
141
|
+
getDerivedFields?(name: string): FieldMap;
|
|
140
142
|
}
|
|
141
143
|
export interface PolymorphicOptions {
|
|
142
144
|
types?: string[];
|
package/schema/schema.js
CHANGED
|
@@ -37,12 +37,12 @@ function getFields(value) {
|
|
|
37
37
|
schema = new value();
|
|
38
38
|
}
|
|
39
39
|
function addFields(fields) {
|
|
40
|
-
for (const
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
addFields(
|
|
40
|
+
for (const name in fields) {
|
|
41
|
+
const field = fields[name];
|
|
42
|
+
if (field.getDerivedFields !== undefined) {
|
|
43
|
+
addFields(field.getDerivedFields(name));
|
|
44
44
|
}
|
|
45
|
-
m.set(
|
|
45
|
+
m.set(name, field);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
let m = new Map();
|
|
@@ -25,9 +25,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
const typescript_1 = __importDefault(require("typescript"));
|
|
27
27
|
const path = __importStar(require("path"));
|
|
28
|
-
const fs = __importStar(require("fs"));
|
|
29
|
-
const json5_1 = __importDefault(require("json5"));
|
|
30
28
|
const glob_1 = __importDefault(require("glob"));
|
|
29
|
+
const compilerOptions_1 = require("../tsc/compilerOptions");
|
|
31
30
|
// TODO this should probably be its own package but for now it's here
|
|
32
31
|
class Compiler {
|
|
33
32
|
constructor(sourceFiles, moduleSearchLocations) {
|
|
@@ -35,7 +34,7 @@ class Compiler {
|
|
|
35
34
|
this.moduleSearchLocations = moduleSearchLocations;
|
|
36
35
|
this.regexMap = new Map();
|
|
37
36
|
this.resolvers = [];
|
|
38
|
-
this.options =
|
|
37
|
+
this.options = (0, compilerOptions_1.readCompilerOptions)(".");
|
|
39
38
|
if (this.options.paths) {
|
|
40
39
|
for (let key in this.options.paths) {
|
|
41
40
|
if (key === "*") {
|
|
@@ -105,22 +104,6 @@ class Compiler {
|
|
|
105
104
|
}
|
|
106
105
|
return undefined;
|
|
107
106
|
}
|
|
108
|
-
readCompilerOptions() {
|
|
109
|
-
let json = {};
|
|
110
|
-
try {
|
|
111
|
-
json = json5_1.default.parse(fs.readFileSync("./tsconfig.json", {
|
|
112
|
-
encoding: "utf8",
|
|
113
|
-
}));
|
|
114
|
-
}
|
|
115
|
-
catch (e) {
|
|
116
|
-
console.error("couldn't read tsconfig.json file");
|
|
117
|
-
}
|
|
118
|
-
let options = json["compilerOptions"] || {};
|
|
119
|
-
if (options.moduleResolution === "node") {
|
|
120
|
-
options.moduleResolution = typescript_1.default.ModuleResolutionKind.NodeJs;
|
|
121
|
-
}
|
|
122
|
-
return options;
|
|
123
|
-
}
|
|
124
107
|
createCompilerHost() {
|
|
125
108
|
return {
|
|
126
109
|
getSourceFile: this.getSourceFile,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
const glob_1 = require("glob");
|
|
26
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
27
|
+
const fs = __importStar(require("fs"));
|
|
28
|
+
const compilerOptions_1 = require("../tsc/compilerOptions");
|
|
29
|
+
const child_process_1 = require("child_process");
|
|
30
|
+
function getTarget(target) {
|
|
31
|
+
switch (target.toLowerCase()) {
|
|
32
|
+
case "es2015":
|
|
33
|
+
return typescript_1.default.ScriptTarget.ES2015;
|
|
34
|
+
case "es2016":
|
|
35
|
+
return typescript_1.default.ScriptTarget.ES2016;
|
|
36
|
+
case "es2017":
|
|
37
|
+
return typescript_1.default.ScriptTarget.ES2017;
|
|
38
|
+
case "es2018":
|
|
39
|
+
return typescript_1.default.ScriptTarget.ES2018;
|
|
40
|
+
case "es2019":
|
|
41
|
+
return typescript_1.default.ScriptTarget.ES2019;
|
|
42
|
+
case "es2020":
|
|
43
|
+
return typescript_1.default.ScriptTarget.ES2020;
|
|
44
|
+
case "es2021":
|
|
45
|
+
return typescript_1.default.ScriptTarget.ES2021;
|
|
46
|
+
case "es3":
|
|
47
|
+
return typescript_1.default.ScriptTarget.ES3;
|
|
48
|
+
case "es5":
|
|
49
|
+
return typescript_1.default.ScriptTarget.ES5;
|
|
50
|
+
case "esnext":
|
|
51
|
+
return typescript_1.default.ScriptTarget.ESNext;
|
|
52
|
+
default:
|
|
53
|
+
return typescript_1.default.ScriptTarget.ESNext;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function main() {
|
|
57
|
+
// this assumes this is being run from root of directory
|
|
58
|
+
const options = (0, compilerOptions_1.readCompilerOptions)(".");
|
|
59
|
+
let files = glob_1.glob.sync("src/schema/*.ts");
|
|
60
|
+
const target = options.target
|
|
61
|
+
? // @ts-ignore
|
|
62
|
+
getTarget(options.target)
|
|
63
|
+
: typescript_1.default.ScriptTarget.ESNext;
|
|
64
|
+
// filter to only event.ts e.g. for comments and whitespace...
|
|
65
|
+
// files = files.filter((f) => f.endsWith("event.ts"));
|
|
66
|
+
files.forEach((file) => {
|
|
67
|
+
// assume valid file since we do glob above
|
|
68
|
+
const idx = file.lastIndexOf(".ts");
|
|
69
|
+
const writeFile = file.substring(0, idx) + "2" + ".ts";
|
|
70
|
+
let contents = fs.readFileSync(file).toString();
|
|
71
|
+
// go through the file and print everything back if not starting immediately after other position
|
|
72
|
+
const sourceFile = typescript_1.default.createSourceFile(file, contents, target, false, typescript_1.default.ScriptKind.TS);
|
|
73
|
+
const nodes = [];
|
|
74
|
+
let updateImport = false;
|
|
75
|
+
const f = {
|
|
76
|
+
trackNode: function (tni) {
|
|
77
|
+
nodes.push({
|
|
78
|
+
node: tni.node,
|
|
79
|
+
importNode: tni.node && typescript_1.default.isImportDeclaration(tni.node),
|
|
80
|
+
rawString: tni.rawString,
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
flagUpdateImport() {
|
|
84
|
+
updateImport = true;
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
if (!traverse(contents, sourceFile, f)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
let newContents = "";
|
|
91
|
+
for (const node of nodes) {
|
|
92
|
+
if (updateImport && node.importNode) {
|
|
93
|
+
const importNode = node.node;
|
|
94
|
+
const transformedImport = transformImport(importNode, sourceFile);
|
|
95
|
+
if (transformedImport) {
|
|
96
|
+
newContents += transformedImport;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (node.node) {
|
|
101
|
+
newContents += node.node.getFullText(sourceFile);
|
|
102
|
+
}
|
|
103
|
+
else if (node.rawString) {
|
|
104
|
+
newContents += node.rawString;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
console.error("invalid node");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// console.debug(newContents);
|
|
111
|
+
// ideally there's a flag that indicates if we write
|
|
112
|
+
fs.writeFileSync(writeFile, newContents);
|
|
113
|
+
});
|
|
114
|
+
(0, child_process_1.execSync)("prettier src/schema/*.ts --write");
|
|
115
|
+
}
|
|
116
|
+
function traverse(fileContents, sourceFile, f) {
|
|
117
|
+
let traversed = false;
|
|
118
|
+
typescript_1.default.forEachChild(sourceFile, function (node) {
|
|
119
|
+
if (typescript_1.default.isClassDeclaration(node)) {
|
|
120
|
+
traversed = true;
|
|
121
|
+
// TODO address implicit schema doesn't work here...
|
|
122
|
+
// console.debug(sourceFile.fileName, node.kind);
|
|
123
|
+
if (traverseClass(fileContents, sourceFile, node, f)) {
|
|
124
|
+
f.flagUpdateImport();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
f.trackNode({ node });
|
|
129
|
+
});
|
|
130
|
+
return traversed;
|
|
131
|
+
}
|
|
132
|
+
// TODO need to replace class field member, print that and see what happens
|
|
133
|
+
function traverseClass(fileContents, sourceFile, node, f) {
|
|
134
|
+
let updated = false;
|
|
135
|
+
// beginning of class...
|
|
136
|
+
// including comment
|
|
137
|
+
let klassContents = fileContents.substring(node.getFullStart(), node.members[0].getFullStart());
|
|
138
|
+
for (let member of node.members) {
|
|
139
|
+
if (!isFieldElement(member, sourceFile)) {
|
|
140
|
+
klassContents += member.getFullText(sourceFile);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
// intentionally doesn't parse decorators since we don't need it
|
|
144
|
+
let fieldMap = "";
|
|
145
|
+
// fieldMapComment...
|
|
146
|
+
const comment = getPreText(fileContents, member, sourceFile);
|
|
147
|
+
if (comment) {
|
|
148
|
+
fieldMap += comment;
|
|
149
|
+
}
|
|
150
|
+
updated = true;
|
|
151
|
+
// need to change to fields: FieldMap = {code: StringType()};
|
|
152
|
+
const property = member;
|
|
153
|
+
const initializer = property.initializer;
|
|
154
|
+
fieldMap += "fields: FieldMap = {";
|
|
155
|
+
for (const element of initializer.elements) {
|
|
156
|
+
const parsed = parseFieldElement(element, sourceFile, fileContents);
|
|
157
|
+
if (parsed === null) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
const { callEx, name, nameComment, properties } = parsed;
|
|
161
|
+
let property = "";
|
|
162
|
+
const fieldComment = getPreText(fileContents, element, sourceFile).trim();
|
|
163
|
+
if (fieldComment) {
|
|
164
|
+
property += "\n" + fieldComment + "\n";
|
|
165
|
+
}
|
|
166
|
+
if (nameComment) {
|
|
167
|
+
property += nameComment + "\n";
|
|
168
|
+
}
|
|
169
|
+
// e.g. UUIDType, StringType etc
|
|
170
|
+
let call = callEx.expression.getText(sourceFile);
|
|
171
|
+
let fnCall = "";
|
|
172
|
+
if (properties.length) {
|
|
173
|
+
fnCall = `{${properties.join(",")}}`;
|
|
174
|
+
}
|
|
175
|
+
property += `${name}:${call}(${fnCall}),`;
|
|
176
|
+
fieldMap += property;
|
|
177
|
+
}
|
|
178
|
+
fieldMap += "}";
|
|
179
|
+
klassContents += fieldMap;
|
|
180
|
+
}
|
|
181
|
+
klassContents += "\n}";
|
|
182
|
+
// console.debug(klassContents);
|
|
183
|
+
if (!updated) {
|
|
184
|
+
return updated;
|
|
185
|
+
}
|
|
186
|
+
f.trackNode({ rawString: klassContents });
|
|
187
|
+
return updated;
|
|
188
|
+
}
|
|
189
|
+
function isFieldElement(member, sourceFile) {
|
|
190
|
+
if (member.kind !== typescript_1.default.SyntaxKind.PropertyDeclaration) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
const property = member;
|
|
194
|
+
const token = property.name;
|
|
195
|
+
if (token.escapedText !== "fields") {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
const propertytype = property.type?.getText(sourceFile);
|
|
199
|
+
if (propertytype !== "Field[]") {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
if (property.initializer?.kind !== typescript_1.default.SyntaxKind.ArrayLiteralExpression) {
|
|
203
|
+
console.error("invalid array type");
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
function parseFieldElement(element, sourceFile, fileContents) {
|
|
209
|
+
if (element.kind !== typescript_1.default.SyntaxKind.CallExpression) {
|
|
210
|
+
console.error("skipped non-call expression");
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
let callEx = element;
|
|
214
|
+
if (callEx.arguments.length !== 1) {
|
|
215
|
+
console.error("callExpression with arguments not of length 1");
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
let arg = callEx.arguments[0];
|
|
219
|
+
if (arg.kind !== typescript_1.default.SyntaxKind.ObjectLiteralExpression) {
|
|
220
|
+
console.error("not objectLiteralExpression");
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
let expr = arg;
|
|
224
|
+
let name = "";
|
|
225
|
+
let propertyComment;
|
|
226
|
+
let properties = [];
|
|
227
|
+
for (const p of expr.properties) {
|
|
228
|
+
const p2 = p;
|
|
229
|
+
// found name property
|
|
230
|
+
if (p2.name.escapedText === "name") {
|
|
231
|
+
name = p2.initializer.getText(sourceFile);
|
|
232
|
+
// check for any comment associated with name: "fooo"
|
|
233
|
+
propertyComment = getPreText(fileContents, p, sourceFile).trim();
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
properties.push(p.getFullText(sourceFile));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (!name) {
|
|
240
|
+
console.error(`couldn't find name property`);
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
// remove quotes
|
|
244
|
+
name = name.slice(1, -1);
|
|
245
|
+
return {
|
|
246
|
+
callEx,
|
|
247
|
+
name,
|
|
248
|
+
properties,
|
|
249
|
+
nameComment: propertyComment,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function transformImport(importNode, sourceFile) {
|
|
253
|
+
// remove quotes too
|
|
254
|
+
const text = importNode.moduleSpecifier.getText(sourceFile).slice(1, -1);
|
|
255
|
+
if (text !== "@snowtop/ent" &&
|
|
256
|
+
text !== "@snowtop/ent/schema" &&
|
|
257
|
+
text !== "@snowtop/ent/schema/") {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const importText = importNode.importClause?.getText(sourceFile) || "";
|
|
261
|
+
const start = importText.indexOf("{");
|
|
262
|
+
const end = importText.lastIndexOf("}");
|
|
263
|
+
if (start === -1 || end === -1) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const imports = importText
|
|
267
|
+
.substring(start + 1, end)
|
|
268
|
+
// .trim()
|
|
269
|
+
.split(",");
|
|
270
|
+
for (let i = 0; i < imports.length; i++) {
|
|
271
|
+
const imp = imports[i].trim();
|
|
272
|
+
if (imp === "Field") {
|
|
273
|
+
imports[i] = "FieldMap";
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// TODO better to update node instead of doing this but this works for now
|
|
277
|
+
return ("import " +
|
|
278
|
+
importText.substring(0, start + 1) +
|
|
279
|
+
imports.join(", ") +
|
|
280
|
+
importText.substring(end) +
|
|
281
|
+
' from "' +
|
|
282
|
+
text +
|
|
283
|
+
'"');
|
|
284
|
+
}
|
|
285
|
+
function getPreText(fileContents, node, sourceFile) {
|
|
286
|
+
return fileContents.substring(node.getFullStart(), node.getStart(sourceFile));
|
|
287
|
+
}
|
|
288
|
+
Promise.resolve(main());
|
package/testutils/db/test_db.js
CHANGED
|
@@ -479,8 +479,8 @@ exports.setupSqlite = setupSqlite;
|
|
|
479
479
|
function getSchemaTable(schema, dialect) {
|
|
480
480
|
const fields = (0, schema_1.getFields)(schema);
|
|
481
481
|
const columns = [];
|
|
482
|
-
for (const [
|
|
483
|
-
columns.push(getColumnFromField(field, dialect));
|
|
482
|
+
for (const [fieldName, field] of fields) {
|
|
483
|
+
columns.push(getColumnFromField(fieldName, field, dialect));
|
|
484
484
|
}
|
|
485
485
|
return table((0, builder_1.getTableName)(schema), ...columns);
|
|
486
486
|
}
|
|
@@ -520,7 +520,7 @@ function getColumnForDbType(t, dialect) {
|
|
|
520
520
|
return undefined;
|
|
521
521
|
}
|
|
522
522
|
}
|
|
523
|
-
function getColumnFromField(f, dialect) {
|
|
523
|
+
function getColumnFromField(fieldName, f, dialect) {
|
|
524
524
|
switch (f.type.dbType) {
|
|
525
525
|
case schema_1.DBType.List:
|
|
526
526
|
const elemType = f.type.listElemType;
|
|
@@ -531,17 +531,17 @@ function getColumnFromField(f, dialect) {
|
|
|
531
531
|
if (elemFn === undefined) {
|
|
532
532
|
throw new Error(`unsupported type for ${elemType}`);
|
|
533
533
|
}
|
|
534
|
-
return list(storageKey(f), elemFn("ignore"), buildOpts(f));
|
|
534
|
+
return list(storageKey(fieldName, f), elemFn("ignore"), buildOpts(f));
|
|
535
535
|
default:
|
|
536
536
|
const fn = getColumnForDbType(f.type.dbType, dialect);
|
|
537
537
|
if (fn === undefined) {
|
|
538
538
|
throw new Error(`unsupported type ${f.type.dbType}`);
|
|
539
539
|
}
|
|
540
|
-
return getColumn(f, fn);
|
|
540
|
+
return getColumn(fieldName, f, fn);
|
|
541
541
|
}
|
|
542
542
|
}
|
|
543
|
-
function getColumn(f, col) {
|
|
544
|
-
return col(storageKey(f), buildOpts(f));
|
|
543
|
+
function getColumn(fieldName, f, col) {
|
|
544
|
+
return col(storageKey(fieldName, f), buildOpts(f));
|
|
545
545
|
}
|
|
546
546
|
function buildOpts(f) {
|
|
547
547
|
let ret = {};
|
|
@@ -560,11 +560,11 @@ function buildOpts(f) {
|
|
|
560
560
|
}
|
|
561
561
|
return ret;
|
|
562
562
|
}
|
|
563
|
-
function storageKey(f) {
|
|
563
|
+
function storageKey(fieldName, f) {
|
|
564
564
|
if (f.storageKey) {
|
|
565
565
|
return f.storageKey;
|
|
566
566
|
}
|
|
567
|
-
return (0, snake_case_1.snakeCase)(
|
|
567
|
+
return (0, snake_case_1.snakeCase)(fieldName);
|
|
568
568
|
}
|
|
569
569
|
function isSyncClient(client) {
|
|
570
570
|
return client.execSync !== undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ID, Ent, Viewer, Data, LoadEntOptions, PrivacyPolicy } from "../../core/base";
|
|
2
2
|
import { BuilderSchema, SimpleBuilder } from "../builder";
|
|
3
|
-
import {
|
|
3
|
+
import { BaseEntSchema, FieldMap } from "../../schema";
|
|
4
4
|
import { NodeType } from "./const";
|
|
5
5
|
import { ObjectLoaderFactory } from "../../core/loaders";
|
|
6
6
|
export declare class FakeContact implements Ent {
|
|
@@ -24,7 +24,7 @@ export declare class FakeContact implements Ent {
|
|
|
24
24
|
}
|
|
25
25
|
export declare class FakeContactSchema extends BaseEntSchema implements BuilderSchema<FakeContact> {
|
|
26
26
|
ent: typeof FakeContact;
|
|
27
|
-
fields:
|
|
27
|
+
fields: FieldMap;
|
|
28
28
|
}
|
|
29
29
|
export interface ContactCreateInput {
|
|
30
30
|
firstName: string;
|
|
@@ -63,21 +63,14 @@ class FakeContactSchema extends schema_1.BaseEntSchema {
|
|
|
63
63
|
constructor() {
|
|
64
64
|
super(...arguments);
|
|
65
65
|
this.ent = FakeContact;
|
|
66
|
-
this.fields =
|
|
67
|
-
(0, schema_1.StringType)(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
(0, schema_1.
|
|
71
|
-
name: "lastName",
|
|
72
|
-
}),
|
|
73
|
-
(0, schema_1.StringType)({
|
|
74
|
-
name: "emailAddress",
|
|
75
|
-
}),
|
|
76
|
-
(0, schema_1.UUIDType)({
|
|
77
|
-
name: "userID",
|
|
66
|
+
this.fields = {
|
|
67
|
+
firstName: (0, schema_1.StringType)(),
|
|
68
|
+
lastName: (0, schema_1.StringType)(),
|
|
69
|
+
emailAddress: (0, schema_1.StringType)(),
|
|
70
|
+
userID: (0, schema_1.UUIDType)({
|
|
78
71
|
foreignKey: { schema: "User", column: "ID" },
|
|
79
72
|
}),
|
|
80
|
-
|
|
73
|
+
};
|
|
81
74
|
}
|
|
82
75
|
}
|
|
83
76
|
exports.FakeContactSchema = FakeContactSchema;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ID, Ent, Viewer, Data, LoadEntOptions, PrivacyPolicy } from "../../core/base";
|
|
2
2
|
import { BuilderSchema, SimpleBuilder } from "../builder";
|
|
3
|
-
import {
|
|
3
|
+
import { BaseEntSchema, FieldMap } from "../../schema";
|
|
4
4
|
import { NodeType } from "./const";
|
|
5
5
|
export declare class FakeEvent implements Ent {
|
|
6
6
|
viewer: Viewer;
|
|
@@ -25,7 +25,7 @@ export declare class FakeEvent implements Ent {
|
|
|
25
25
|
}
|
|
26
26
|
export declare class FakeEventSchema extends BaseEntSchema implements BuilderSchema<FakeEvent> {
|
|
27
27
|
ent: typeof FakeEvent;
|
|
28
|
-
fields:
|
|
28
|
+
fields: FieldMap;
|
|
29
29
|
}
|
|
30
30
|
export interface EventCreateInput {
|
|
31
31
|
startTime: Date;
|
|
@@ -67,30 +67,22 @@ class FakeEventSchema extends schema_1.BaseEntSchema {
|
|
|
67
67
|
constructor() {
|
|
68
68
|
super(...arguments);
|
|
69
69
|
this.ent = FakeEvent;
|
|
70
|
-
this.fields =
|
|
71
|
-
(0, schema_1.TimestampType)({
|
|
72
|
-
name: "startTime",
|
|
70
|
+
this.fields = {
|
|
71
|
+
startTime: (0, schema_1.TimestampType)({
|
|
73
72
|
index: true,
|
|
74
73
|
}),
|
|
75
|
-
(0, schema_1.TimestampType)({
|
|
76
|
-
name: "endTime",
|
|
74
|
+
endTime: (0, schema_1.TimestampType)({
|
|
77
75
|
nullable: true,
|
|
78
76
|
}),
|
|
79
|
-
(0, schema_1.StringType)(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
(0, schema_1.StringType)({
|
|
83
|
-
name: "location",
|
|
84
|
-
}),
|
|
85
|
-
(0, schema_1.StringType)({
|
|
86
|
-
name: "description",
|
|
77
|
+
title: (0, schema_1.StringType)(),
|
|
78
|
+
location: (0, schema_1.StringType)(),
|
|
79
|
+
description: (0, schema_1.StringType)({
|
|
87
80
|
nullable: true,
|
|
88
81
|
}),
|
|
89
|
-
(0, schema_1.UUIDType)({
|
|
90
|
-
name: "userID",
|
|
82
|
+
userID: (0, schema_1.UUIDType)({
|
|
91
83
|
foreignKey: { schema: "User", column: "ID" },
|
|
92
84
|
}),
|
|
93
|
-
|
|
85
|
+
};
|
|
94
86
|
}
|
|
95
87
|
}
|
|
96
88
|
exports.FakeEventSchema = FakeEventSchema;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ID, Ent, Viewer, Data, LoadEntOptions, PrivacyPolicy } from "../../core/base";
|
|
2
2
|
import { BuilderSchema, SimpleAction } from "../builder";
|
|
3
|
-
import {
|
|
3
|
+
import { BaseEntSchema, FieldMap } from "../../schema";
|
|
4
4
|
import { NodeType } from "./const";
|
|
5
5
|
import { IDViewer, IDViewerOptions } from "../../core/viewer";
|
|
6
6
|
import { ObjectLoaderFactory } from "../../core/loaders";
|
|
@@ -34,7 +34,7 @@ export declare class FakeUser implements Ent {
|
|
|
34
34
|
}
|
|
35
35
|
export declare class FakeUserSchema extends BaseEntSchema implements BuilderSchema<FakeUser> {
|
|
36
36
|
ent: typeof FakeUser;
|
|
37
|
-
fields:
|
|
37
|
+
fields: FieldMap;
|
|
38
38
|
}
|
|
39
39
|
export interface UserCreateInput {
|
|
40
40
|
firstName: string;
|
|
@@ -93,24 +93,15 @@ class FakeUserSchema extends schema_1.BaseEntSchema {
|
|
|
93
93
|
constructor() {
|
|
94
94
|
super(...arguments);
|
|
95
95
|
this.ent = FakeUser;
|
|
96
|
-
this.fields =
|
|
97
|
-
(0, schema_1.StringType)(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
(0, schema_1.StringType)(
|
|
101
|
-
|
|
102
|
-
}),
|
|
103
|
-
(0, schema_1.StringType)({
|
|
104
|
-
name: "emailAddress",
|
|
105
|
-
}),
|
|
106
|
-
(0, schema_1.StringType)({
|
|
107
|
-
name: "phoneNumber",
|
|
108
|
-
}),
|
|
109
|
-
(0, schema_1.StringType)({
|
|
110
|
-
name: "password",
|
|
96
|
+
this.fields = {
|
|
97
|
+
firstName: (0, schema_1.StringType)(),
|
|
98
|
+
lastName: (0, schema_1.StringType)(),
|
|
99
|
+
emailAddress: (0, schema_1.StringType)(),
|
|
100
|
+
phoneNumber: (0, schema_1.StringType)(),
|
|
101
|
+
password: (0, schema_1.StringType)({
|
|
111
102
|
nullable: true,
|
|
112
103
|
}),
|
|
113
|
-
|
|
104
|
+
};
|
|
114
105
|
}
|
|
115
106
|
}
|
|
116
107
|
exports.FakeUserSchema = FakeUserSchema;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.readCompilerOptions = void 0;
|
|
26
|
+
const fs = __importStar(require("fs"));
|
|
27
|
+
const json5_1 = __importDefault(require("json5"));
|
|
28
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
29
|
+
const path = __importStar(require("path"));
|
|
30
|
+
function findTSConfigFile(filePath) {
|
|
31
|
+
while (filePath != "/") {
|
|
32
|
+
let configPath = `${filePath}/tsconfig.json`;
|
|
33
|
+
if (fs.existsSync(configPath)) {
|
|
34
|
+
return configPath;
|
|
35
|
+
}
|
|
36
|
+
filePath = path.join(filePath, "..");
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function readCompilerOptions(filePath) {
|
|
41
|
+
let configPath = findTSConfigFile(filePath);
|
|
42
|
+
if (!configPath) {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
let json = {};
|
|
46
|
+
try {
|
|
47
|
+
json = json5_1.default.parse(fs.readFileSync(configPath, {
|
|
48
|
+
encoding: "utf8",
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
console.error("couldn't read tsconfig.json file");
|
|
53
|
+
}
|
|
54
|
+
let options = json["compilerOptions"] || {};
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
if (options.moduleResolution === "node") {
|
|
57
|
+
options.moduleResolution = typescript_1.default.ModuleResolutionKind.NodeJs;
|
|
58
|
+
}
|
|
59
|
+
return options;
|
|
60
|
+
}
|
|
61
|
+
exports.readCompilerOptions = readCompilerOptions;
|