@snowtop/ent 0.1.0-alpha8 → 0.1.0-alpha80
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 +27 -25
- package/action/executor.d.ts +3 -3
- package/action/executor.js +2 -2
- package/action/experimental_action.d.ts +29 -22
- package/action/experimental_action.js +29 -6
- package/action/orchestrator.d.ts +37 -16
- package/action/orchestrator.js +184 -54
- package/action/privacy.d.ts +2 -2
- package/core/base.d.ts +38 -22
- package/core/clause.d.ts +65 -7
- package/core/clause.js +261 -54
- package/core/config.d.ts +8 -0
- package/core/context.d.ts +5 -3
- package/core/context.js +7 -2
- package/core/convert.d.ts +1 -1
- package/core/db.d.ts +1 -2
- package/core/db.js +1 -1
- package/core/ent.d.ts +76 -24
- package/core/ent.js +459 -143
- package/core/loaders/assoc_count_loader.d.ts +2 -2
- package/core/loaders/assoc_count_loader.js +6 -1
- package/core/loaders/assoc_edge_loader.d.ts +2 -2
- package/core/loaders/loader.js +5 -5
- package/core/loaders/object_loader.d.ts +4 -3
- package/core/loaders/object_loader.js +22 -5
- package/core/loaders/query_loader.d.ts +2 -2
- package/core/loaders/raw_count_loader.d.ts +2 -2
- package/core/logger.d.ts +1 -1
- package/core/logger.js +1 -0
- package/core/privacy.d.ts +26 -25
- package/core/privacy.js +21 -25
- package/core/query/assoc_query.d.ts +6 -6
- package/core/query/custom_query.d.ts +5 -5
- package/core/query/query.d.ts +1 -1
- package/core/query/shared_assoc_test.d.ts +1 -1
- package/core/query/shared_assoc_test.js +17 -5
- package/core/query/shared_test.d.ts +3 -0
- package/core/query/shared_test.js +95 -17
- package/core/viewer.d.ts +3 -3
- package/core/viewer.js +1 -1
- package/graphql/builtins/connection.js +3 -3
- package/graphql/builtins/edge.js +2 -2
- package/graphql/builtins/node.js +1 -1
- package/graphql/graphql.js +8 -2
- package/graphql/query/connection_type.js +6 -6
- package/graphql/query/edge_connection.d.ts +9 -9
- package/graphql/query/page_info.d.ts +1 -1
- package/graphql/query/page_info.js +4 -4
- package/graphql/query/shared_assoc_test.js +2 -2
- package/graphql/scalars/time.d.ts +1 -1
- package/index.d.ts +10 -5
- package/index.js +13 -6
- package/package.json +2 -2
- package/parse_schema/parse.d.ts +14 -2
- package/parse_schema/parse.js +40 -2
- package/schema/base_schema.d.ts +1 -1
- package/schema/base_schema.js +3 -0
- package/schema/field.d.ts +36 -7
- package/schema/field.js +70 -2
- package/schema/index.d.ts +2 -2
- package/schema/json_field.d.ts +13 -1
- package/schema/json_field.js +28 -1
- package/schema/schema.d.ts +61 -10
- package/schema/schema.js +18 -4
- package/schema/struct_field.d.ts +11 -1
- package/schema/struct_field.js +43 -4
- package/scripts/custom_graphql.js +5 -1
- package/scripts/{transform_schema.d.ts → migrate_v0.1.d.ts} +0 -0
- package/scripts/migrate_v0.1.js +36 -0
- package/scripts/read_schema.js +25 -2
- package/testutils/builder.d.ts +31 -21
- package/testutils/builder.js +82 -29
- package/testutils/db/fixture.d.ts +10 -0
- package/testutils/db/fixture.js +26 -0
- package/testutils/db/{test_db.d.ts → temp_db.d.ts} +15 -3
- package/testutils/db/{test_db.js → temp_db.js} +63 -15
- package/testutils/db/value.d.ts +6 -0
- package/testutils/db/value.js +251 -0
- package/testutils/db_time_zone.d.ts +4 -0
- package/testutils/db_time_zone.js +41 -0
- package/testutils/ent-graphql-tests/index.js +19 -12
- package/testutils/fake_data/fake_contact.d.ts +3 -3
- package/testutils/fake_data/fake_contact.js +9 -6
- package/testutils/fake_data/fake_event.d.ts +3 -3
- package/testutils/fake_data/fake_event.js +8 -5
- package/testutils/fake_data/fake_user.d.ts +4 -4
- package/testutils/fake_data/fake_user.js +16 -13
- package/testutils/fake_data/test_helpers.d.ts +2 -2
- package/testutils/fake_data/test_helpers.js +5 -5
- package/testutils/fake_data/user_query.d.ts +2 -2
- package/testutils/fake_log.d.ts +3 -3
- package/testutils/parse_sql.d.ts +6 -0
- package/testutils/parse_sql.js +16 -2
- package/testutils/test_edge_global_schema.d.ts +15 -0
- package/testutils/test_edge_global_schema.js +58 -0
- package/testutils/write.d.ts +2 -2
- package/testutils/write.js +29 -7
- package/tsc/ast.d.ts +44 -0
- package/tsc/ast.js +267 -0
- package/tsc/compilerOptions.d.ts +6 -0
- package/tsc/compilerOptions.js +40 -1
- package/tsc/move_generated.d.ts +1 -0
- package/tsc/move_generated.js +160 -0
- package/tsc/transform.d.ts +21 -0
- package/tsc/transform.js +167 -0
- package/tsc/transform_action.d.ts +22 -0
- package/tsc/transform_action.js +179 -0
- package/tsc/transform_ent.d.ts +17 -0
- package/tsc/transform_ent.js +59 -0
- package/tsc/transform_schema.d.ts +27 -0
- package/tsc/transform_schema.js +379 -0
- package/scripts/transform_schema.js +0 -437
package/schema/struct_field.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StructListType = exports.StructType = exports.StructField = void 0;
|
|
3
|
+
exports.StructTypeAsList = exports.StructListType = exports.StructType = exports.StructField = void 0;
|
|
4
4
|
const field_1 = require("./field");
|
|
5
5
|
const schema_1 = require("./schema");
|
|
6
6
|
const camel_case_1 = require("camel-case");
|
|
@@ -17,11 +17,16 @@ class StructField extends field_1.BaseField {
|
|
|
17
17
|
if (options.jsonNotJSONB) {
|
|
18
18
|
this.type.dbType = schema_1.DBType.JSON;
|
|
19
19
|
}
|
|
20
|
+
if (options?.jsonAsList) {
|
|
21
|
+
this.type.listElemType = {
|
|
22
|
+
dbType: schema_1.DBType.JSONB,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
20
25
|
}
|
|
21
26
|
// right now, we store things in the db in lowerCase format
|
|
22
27
|
// this will lead to issues if field changes.
|
|
23
28
|
// TODO: use storageKey and convert back...
|
|
24
|
-
|
|
29
|
+
formatImpl(obj, nested) {
|
|
25
30
|
if (!(obj instanceof Object)) {
|
|
26
31
|
throw new Error("valid was not called");
|
|
27
32
|
}
|
|
@@ -47,13 +52,23 @@ class StructField extends field_1.BaseField {
|
|
|
47
52
|
ret[dbKey] = val;
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
|
-
// don't json.stringify if nested
|
|
55
|
+
// don't json.stringify if nested or list
|
|
51
56
|
if (nested) {
|
|
52
57
|
return ret;
|
|
53
58
|
}
|
|
54
59
|
return JSON.stringify(ret);
|
|
55
60
|
}
|
|
56
|
-
|
|
61
|
+
format(obj, nested) {
|
|
62
|
+
if (Array.isArray(obj) && this.options.jsonAsList) {
|
|
63
|
+
const ret = obj.map((v) => this.formatImpl(v, true));
|
|
64
|
+
if (nested) {
|
|
65
|
+
return ret;
|
|
66
|
+
}
|
|
67
|
+
return JSON.stringify(ret);
|
|
68
|
+
}
|
|
69
|
+
return this.formatImpl(obj, nested);
|
|
70
|
+
}
|
|
71
|
+
async validImpl(obj) {
|
|
57
72
|
if (!(obj instanceof Object)) {
|
|
58
73
|
return false;
|
|
59
74
|
}
|
|
@@ -89,6 +104,19 @@ class StructField extends field_1.BaseField {
|
|
|
89
104
|
const ret = await Promise.all(promises);
|
|
90
105
|
return ret.every((v) => v);
|
|
91
106
|
}
|
|
107
|
+
async valid(obj) {
|
|
108
|
+
if (this.options.jsonAsList) {
|
|
109
|
+
if (!Array.isArray(obj)) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
const valid = await Promise.all(obj.map((v) => this.validImpl(v)));
|
|
113
|
+
return valid.every((b) => b);
|
|
114
|
+
}
|
|
115
|
+
if (!(obj instanceof Object)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return this.validImpl(obj);
|
|
119
|
+
}
|
|
92
120
|
}
|
|
93
121
|
exports.StructField = StructField;
|
|
94
122
|
function StructType(options) {
|
|
@@ -96,7 +124,18 @@ function StructType(options) {
|
|
|
96
124
|
return Object.assign(result, options);
|
|
97
125
|
}
|
|
98
126
|
exports.StructType = StructType;
|
|
127
|
+
/**
|
|
128
|
+
* @deprecated use StructTypeAsList
|
|
129
|
+
*/
|
|
99
130
|
function StructListType(options) {
|
|
100
131
|
return new field_1.ListField(StructType(options), options);
|
|
101
132
|
}
|
|
102
133
|
exports.StructListType = StructListType;
|
|
134
|
+
function StructTypeAsList(options) {
|
|
135
|
+
let result = new StructField({
|
|
136
|
+
...options,
|
|
137
|
+
jsonAsList: true,
|
|
138
|
+
});
|
|
139
|
+
return Object.assign(result, options);
|
|
140
|
+
}
|
|
141
|
+
exports.StructTypeAsList = StructTypeAsList;
|
|
@@ -235,7 +235,11 @@ async function main() {
|
|
|
235
235
|
// if this list grows too long, need to build this into golang types and passed here
|
|
236
236
|
// TODO foreign non-scalars eventually
|
|
237
237
|
(0, graphql_1.addCustomType)({
|
|
238
|
-
importPath:
|
|
238
|
+
importPath: MODULE_PATH,
|
|
239
|
+
// for go tests...
|
|
240
|
+
// TODO need a flag that only does this for go tests
|
|
241
|
+
// breaks when running locally sometimes...
|
|
242
|
+
secondaryImportPath: "../graphql/scalars/time",
|
|
239
243
|
type: "GraphQLTime",
|
|
240
244
|
});
|
|
241
245
|
(0, graphql_1.addCustomType)({
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const transform_1 = require("../tsc/transform");
|
|
7
|
+
const transform_schema_1 = require("../tsc/transform_schema");
|
|
8
|
+
const transform_ent_1 = require("../tsc/transform_ent");
|
|
9
|
+
const move_generated_1 = require("../tsc/move_generated");
|
|
10
|
+
const transform_action_1 = require("../tsc/transform_action");
|
|
11
|
+
const minimist_1 = __importDefault(require("minimist"));
|
|
12
|
+
const ast_1 = require("../tsc/ast");
|
|
13
|
+
// todo-sqlite
|
|
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
|
|
15
|
+
function main() {
|
|
16
|
+
const customInfo = (0, ast_1.getCustomInfo)();
|
|
17
|
+
const options = (0, minimist_1.default)(process.argv.slice(2));
|
|
18
|
+
// install 0.1.x dependencies
|
|
19
|
+
// maybe provide options to make this easier if someone wants to do this in steps to see what's happening
|
|
20
|
+
if (options.move_generated) {
|
|
21
|
+
(0, move_generated_1.moveGenerated)(customInfo.relativeImports);
|
|
22
|
+
}
|
|
23
|
+
// codegen write-all --disable-custom-graphql
|
|
24
|
+
if (options.transform_schema) {
|
|
25
|
+
(0, transform_1.transform)(new transform_schema_1.TransformSchema(customInfo.relativeImports, options.old_base_class, options.new_schema_class, options.transform_path));
|
|
26
|
+
}
|
|
27
|
+
// codegen write-all --disable-custom-graphql
|
|
28
|
+
if (options.transform_ent) {
|
|
29
|
+
(0, transform_1.transform)(new transform_ent_1.TransformEnt());
|
|
30
|
+
}
|
|
31
|
+
if (options.transform_action) {
|
|
32
|
+
(0, transform_1.transform)(new transform_action_1.TransformAction(customInfo));
|
|
33
|
+
}
|
|
34
|
+
// codegen write-all
|
|
35
|
+
}
|
|
36
|
+
main();
|
package/scripts/read_schema.js
CHANGED
|
@@ -28,26 +28,49 @@ const pascal_case_1 = require("pascal-case");
|
|
|
28
28
|
const minimist_1 = __importDefault(require("minimist"));
|
|
29
29
|
const process_1 = require("process");
|
|
30
30
|
const parse_1 = require("../parse_schema/parse");
|
|
31
|
+
const ast_1 = require("../tsc/ast");
|
|
31
32
|
function main() {
|
|
32
33
|
const options = (0, minimist_1.default)(process.argv.slice(2));
|
|
33
34
|
if (!options.path) {
|
|
34
35
|
throw new Error("path required");
|
|
35
36
|
}
|
|
37
|
+
const customInfo = (0, ast_1.getCustomInfo)();
|
|
38
|
+
const globalSchemaPath = customInfo.globalSchemaPath || "__global__schema.ts";
|
|
39
|
+
let globalSchema;
|
|
36
40
|
const r = /(\w+).ts/;
|
|
41
|
+
// do we still even need this...
|
|
37
42
|
const paths = glob_1.default.sync(path.join(options.path, "*.ts"), {
|
|
38
43
|
ignore: [`\d+_read_schema.ts`],
|
|
39
44
|
});
|
|
40
45
|
let potentialSchemas = {};
|
|
41
46
|
for (const p of paths) {
|
|
42
47
|
const basename = path.basename(p);
|
|
48
|
+
if (basename === globalSchemaPath) {
|
|
49
|
+
globalSchema = require(p).default;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
43
52
|
const match = r.exec(basename);
|
|
44
53
|
if (!match) {
|
|
45
54
|
throw new Error(`non-typescript file ${p} returned by glob`);
|
|
46
55
|
}
|
|
47
|
-
|
|
56
|
+
let schema = match[1];
|
|
57
|
+
// convert foo_schema.ts -> foo
|
|
58
|
+
if (schema.endsWith("_schema")) {
|
|
59
|
+
schema = schema.slice(0, -7);
|
|
60
|
+
}
|
|
61
|
+
let relativePath;
|
|
62
|
+
const index = p.indexOf("src/schema");
|
|
63
|
+
if (index !== -1) {
|
|
64
|
+
relativePath = p.substring(index);
|
|
65
|
+
}
|
|
66
|
+
const s = require(p).default;
|
|
67
|
+
if (relativePath !== undefined) {
|
|
68
|
+
s.schemaPath = relativePath;
|
|
69
|
+
}
|
|
70
|
+
potentialSchemas[(0, pascal_case_1.pascalCase)(schema)] = s;
|
|
48
71
|
}
|
|
49
72
|
// console.log(potentialSchemas);
|
|
50
|
-
const result = (0, parse_1.parseSchema)(potentialSchemas);
|
|
73
|
+
const result = (0, parse_1.parseSchema)(potentialSchemas, globalSchema);
|
|
51
74
|
console.log(JSON.stringify(result));
|
|
52
75
|
}
|
|
53
76
|
try {
|
package/testutils/builder.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { Ent, ID, Viewer, Data, EntConstructor } from "../core/base";
|
|
1
|
+
import { Ent, ID, Viewer, Data, EntConstructor, PrivacyPolicy } from "../core/base";
|
|
2
2
|
import { Orchestrator } from "../action/orchestrator";
|
|
3
3
|
import { Action, Builder, Changeset, WriteOperation, Validator, Trigger, Observer } from "../action";
|
|
4
4
|
import { FieldMap, Schema } from "../schema";
|
|
5
5
|
import { SchemaConfig } from "../schema/base_schema";
|
|
6
|
+
import { FieldInfoMap } from "../schema/schema";
|
|
6
7
|
export declare class User implements Ent {
|
|
7
8
|
viewer: Viewer;
|
|
8
9
|
data: Data;
|
|
9
10
|
id: ID;
|
|
10
11
|
accountID: string;
|
|
11
12
|
nodeType: string;
|
|
12
|
-
|
|
13
|
+
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
13
14
|
firstName: string;
|
|
14
15
|
constructor(viewer: Viewer, data: Data);
|
|
15
16
|
}
|
|
@@ -19,7 +20,7 @@ export declare class Event implements Ent {
|
|
|
19
20
|
id: ID;
|
|
20
21
|
accountID: string;
|
|
21
22
|
nodeType: string;
|
|
22
|
-
|
|
23
|
+
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
23
24
|
constructor(viewer: Viewer, data: Data);
|
|
24
25
|
}
|
|
25
26
|
export declare class Contact implements Ent {
|
|
@@ -28,7 +29,7 @@ export declare class Contact implements Ent {
|
|
|
28
29
|
id: ID;
|
|
29
30
|
accountID: string;
|
|
30
31
|
nodeType: string;
|
|
31
|
-
|
|
32
|
+
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
32
33
|
constructor(viewer: Viewer, data: Data);
|
|
33
34
|
}
|
|
34
35
|
export declare class Group implements Ent {
|
|
@@ -37,7 +38,7 @@ export declare class Group implements Ent {
|
|
|
37
38
|
id: ID;
|
|
38
39
|
accountID: string;
|
|
39
40
|
nodeType: string;
|
|
40
|
-
|
|
41
|
+
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
41
42
|
constructor(viewer: Viewer, data: Data);
|
|
42
43
|
}
|
|
43
44
|
export declare class Message implements Ent {
|
|
@@ -46,7 +47,7 @@ export declare class Message implements Ent {
|
|
|
46
47
|
id: ID;
|
|
47
48
|
accountID: string;
|
|
48
49
|
nodeType: string;
|
|
49
|
-
|
|
50
|
+
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
50
51
|
constructor(viewer: Viewer, data: Data);
|
|
51
52
|
}
|
|
52
53
|
export declare class Address implements Ent {
|
|
@@ -55,7 +56,7 @@ export declare class Address implements Ent {
|
|
|
55
56
|
id: ID;
|
|
56
57
|
accountID: string;
|
|
57
58
|
nodeType: string;
|
|
58
|
-
|
|
59
|
+
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
59
60
|
constructor(viewer: Viewer, data: Data);
|
|
60
61
|
}
|
|
61
62
|
export interface BuilderSchema<T extends Ent> extends Schema {
|
|
@@ -66,18 +67,26 @@ export declare function getBuilderSchemaFromFields<T extends Ent>(fields: FieldM
|
|
|
66
67
|
export declare function getBuilderSchemaTZFromFields<T extends Ent>(fields: FieldMap, ent: EntConstructor<T>): BuilderSchema<T>;
|
|
67
68
|
export declare function getSchemaName(value: BuilderSchema<Ent>): string;
|
|
68
69
|
export declare function getTableName(value: BuilderSchema<Ent>): string;
|
|
69
|
-
export declare
|
|
70
|
+
export declare function getFieldInfo(value: BuilderSchema<Ent>): FieldInfoMap;
|
|
71
|
+
declare type MaybeNull<T extends Ent> = T | null;
|
|
72
|
+
declare type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
|
|
73
|
+
export declare class SimpleBuilder<T extends Ent, TExistingEnt extends TMaybleNullableEnt<T> = MaybeNull<T>> implements Builder<T, Viewer, TExistingEnt> {
|
|
70
74
|
viewer: Viewer;
|
|
71
75
|
private schema;
|
|
72
76
|
operation: WriteOperation;
|
|
73
|
-
existingEnt:
|
|
74
|
-
ent: EntConstructor<T>;
|
|
77
|
+
existingEnt: TExistingEnt;
|
|
78
|
+
ent: EntConstructor<T, Viewer>;
|
|
75
79
|
placeholderID: ID;
|
|
76
|
-
orchestrator: Orchestrator<T, Data>;
|
|
80
|
+
orchestrator: Orchestrator<T, Data, Viewer, TExistingEnt>;
|
|
77
81
|
fields: Map<string, any>;
|
|
78
82
|
nodeType: string;
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
m: Map<string, any>;
|
|
84
|
+
constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation: WriteOperation, existingEnt: TExistingEnt, action?: Action<T, SimpleBuilder<T, TExistingEnt>, Viewer, Data, TExistingEnt> | undefined);
|
|
85
|
+
getInput(): Data;
|
|
86
|
+
updateInput(input: Data): void;
|
|
87
|
+
storeData(k: string, v: any): void;
|
|
88
|
+
getStoredData(k: string): any;
|
|
89
|
+
build(): Promise<Changeset>;
|
|
81
90
|
editedEnt(): Promise<T | null>;
|
|
82
91
|
editedEntX(): Promise<T>;
|
|
83
92
|
save(): Promise<void>;
|
|
@@ -88,20 +97,21 @@ export declare class SimpleBuilder<T extends Ent> implements Builder<T> {
|
|
|
88
97
|
interface viewerEntLoadFunc {
|
|
89
98
|
(data: Data): Viewer | Promise<Viewer>;
|
|
90
99
|
}
|
|
91
|
-
export declare class SimpleAction<T extends Ent> implements Action<T, SimpleBuilder<T>, Data> {
|
|
100
|
+
export declare class SimpleAction<T extends Ent, TExistingEnt extends TMaybleNullableEnt<T> = MaybeNull<T>> implements Action<T, SimpleBuilder<T, TExistingEnt>, Viewer, Data, TExistingEnt> {
|
|
92
101
|
viewer: Viewer;
|
|
93
102
|
private fields;
|
|
94
|
-
builder: SimpleBuilder<T>;
|
|
95
|
-
validators: Validator<SimpleBuilder<T>, Data>[];
|
|
96
|
-
triggers: Trigger<SimpleBuilder<T>, Data>[];
|
|
97
|
-
observers: Observer<SimpleBuilder<T>, Data>[];
|
|
103
|
+
builder: SimpleBuilder<T, TExistingEnt>;
|
|
98
104
|
viewerForEntLoad: viewerEntLoadFunc | undefined;
|
|
99
|
-
constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation
|
|
100
|
-
|
|
105
|
+
constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation: WriteOperation | undefined, existingEnt: TExistingEnt);
|
|
106
|
+
getTriggers(): (Trigger<T, SimpleBuilder<T>> | Array<Trigger<T, SimpleBuilder<T>>>)[];
|
|
107
|
+
getValidators(): Validator<T, SimpleBuilder<T>>[];
|
|
108
|
+
getObservers(): Observer<T, SimpleBuilder<T>>[];
|
|
109
|
+
getPrivacyPolicy(): PrivacyPolicy<Ent<Viewer<Ent<any> | null, ID | null>>, Viewer<Ent<any> | null, ID | null>>;
|
|
101
110
|
getInput(): Data;
|
|
102
|
-
changeset(): Promise<Changeset
|
|
111
|
+
changeset(): Promise<Changeset>;
|
|
103
112
|
valid(): Promise<boolean>;
|
|
104
113
|
validX(): Promise<void>;
|
|
114
|
+
validWithErrors(): Promise<Error[]>;
|
|
105
115
|
save(): Promise<T | null>;
|
|
106
116
|
saveX(): Promise<T>;
|
|
107
117
|
editedEnt(): Promise<T | null>;
|
package/testutils/builder.js
CHANGED
|
@@ -3,7 +3,7 @@ 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
|
-
exports.SimpleAction = exports.SimpleBuilder = exports.getTableName = exports.getSchemaName = exports.getBuilderSchemaTZFromFields = exports.getBuilderSchemaFromFields = exports.getBuilderSchema = exports.Address = exports.Message = exports.Group = exports.Contact = exports.Event = exports.User = void 0;
|
|
6
|
+
exports.SimpleAction = exports.SimpleBuilder = exports.getFieldInfo = exports.getTableName = exports.getSchemaName = exports.getBuilderSchemaTZFromFields = exports.getBuilderSchemaFromFields = exports.getBuilderSchema = exports.Address = exports.Message = exports.Group = exports.Contact = exports.Event = exports.User = void 0;
|
|
7
7
|
const privacy_1 = require("../core/privacy");
|
|
8
8
|
const orchestrator_1 = require("../action/orchestrator");
|
|
9
9
|
const action_1 = require("../action");
|
|
@@ -15,18 +15,21 @@ const loaders_1 = require("../core/loaders");
|
|
|
15
15
|
const convert_1 = require("../core/convert");
|
|
16
16
|
const camel_case_1 = require("camel-case");
|
|
17
17
|
const base_schema_1 = require("../schema/base_schema");
|
|
18
|
+
const schema_2 = require("../schema/schema");
|
|
18
19
|
class User {
|
|
19
20
|
constructor(viewer, data) {
|
|
20
21
|
this.viewer = viewer;
|
|
21
22
|
this.data = data;
|
|
22
23
|
this.accountID = "";
|
|
23
24
|
this.nodeType = "User";
|
|
24
|
-
this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
|
|
25
25
|
this.data.created_at = (0, convert_1.convertDate)(data.created_at);
|
|
26
26
|
this.data.updated_at = (0, convert_1.convertDate)(data.updated_at);
|
|
27
27
|
this.id = data.id;
|
|
28
28
|
this.firstName = data.first_name;
|
|
29
29
|
}
|
|
30
|
+
getPrivacyPolicy() {
|
|
31
|
+
return privacy_1.AlwaysAllowPrivacyPolicy;
|
|
32
|
+
}
|
|
30
33
|
}
|
|
31
34
|
exports.User = User;
|
|
32
35
|
class Event {
|
|
@@ -35,9 +38,11 @@ class Event {
|
|
|
35
38
|
this.data = data;
|
|
36
39
|
this.accountID = "";
|
|
37
40
|
this.nodeType = "Event";
|
|
38
|
-
this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
|
|
39
41
|
this.id = data.id;
|
|
40
42
|
}
|
|
43
|
+
getPrivacyPolicy() {
|
|
44
|
+
return privacy_1.AlwaysAllowPrivacyPolicy;
|
|
45
|
+
}
|
|
41
46
|
}
|
|
42
47
|
exports.Event = Event;
|
|
43
48
|
class Contact {
|
|
@@ -46,11 +51,13 @@ class Contact {
|
|
|
46
51
|
this.data = data;
|
|
47
52
|
this.accountID = "";
|
|
48
53
|
this.nodeType = "Contact";
|
|
49
|
-
this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
|
|
50
54
|
this.data.created_at = (0, convert_1.convertDate)(data.created_at);
|
|
51
55
|
this.data.updated_at = (0, convert_1.convertDate)(data.updated_at);
|
|
52
56
|
this.id = data.id;
|
|
53
57
|
}
|
|
58
|
+
getPrivacyPolicy() {
|
|
59
|
+
return privacy_1.AlwaysAllowPrivacyPolicy;
|
|
60
|
+
}
|
|
54
61
|
}
|
|
55
62
|
exports.Contact = Contact;
|
|
56
63
|
class Group {
|
|
@@ -59,9 +66,11 @@ class Group {
|
|
|
59
66
|
this.data = data;
|
|
60
67
|
this.accountID = "";
|
|
61
68
|
this.nodeType = "Group";
|
|
62
|
-
this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
|
|
63
69
|
this.id = data.id;
|
|
64
70
|
}
|
|
71
|
+
getPrivacyPolicy() {
|
|
72
|
+
return privacy_1.AlwaysAllowPrivacyPolicy;
|
|
73
|
+
}
|
|
65
74
|
}
|
|
66
75
|
exports.Group = Group;
|
|
67
76
|
class Message {
|
|
@@ -70,9 +79,11 @@ class Message {
|
|
|
70
79
|
this.data = data;
|
|
71
80
|
this.accountID = "";
|
|
72
81
|
this.nodeType = "Message";
|
|
73
|
-
this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
|
|
74
82
|
this.id = data.id;
|
|
75
83
|
}
|
|
84
|
+
getPrivacyPolicy() {
|
|
85
|
+
return privacy_1.AlwaysAllowPrivacyPolicy;
|
|
86
|
+
}
|
|
76
87
|
}
|
|
77
88
|
exports.Message = Message;
|
|
78
89
|
class Address {
|
|
@@ -81,9 +92,11 @@ class Address {
|
|
|
81
92
|
this.data = data;
|
|
82
93
|
this.accountID = "";
|
|
83
94
|
this.nodeType = "Address";
|
|
84
|
-
this.privacyPolicy = privacy_1.AlwaysAllowPrivacyPolicy;
|
|
85
95
|
this.id = data.id;
|
|
86
96
|
}
|
|
97
|
+
getPrivacyPolicy() {
|
|
98
|
+
return privacy_1.AlwaysAllowPrivacyPolicy;
|
|
99
|
+
}
|
|
87
100
|
}
|
|
88
101
|
exports.Address = Address;
|
|
89
102
|
function getBuilderSchema(cfg, ent) {
|
|
@@ -118,13 +131,26 @@ exports.getTableName = getTableName;
|
|
|
118
131
|
function randomNum() {
|
|
119
132
|
return Math.random().toString(10).substring(2);
|
|
120
133
|
}
|
|
134
|
+
function getFieldInfo(value) {
|
|
135
|
+
const fields = (0, schema_1.getFields)(value);
|
|
136
|
+
let ret = {};
|
|
137
|
+
for (const [k, f] of fields) {
|
|
138
|
+
ret[k] = {
|
|
139
|
+
dbCol: (0, schema_2.getStorageKey)(f, k),
|
|
140
|
+
inputKey: (0, camel_case_1.camelCase)(k),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return ret;
|
|
144
|
+
}
|
|
145
|
+
exports.getFieldInfo = getFieldInfo;
|
|
121
146
|
// reuses orchestrator and standard things
|
|
122
147
|
class SimpleBuilder {
|
|
123
|
-
constructor(viewer, schema, fields, operation = action_1.WriteOperation.Insert, existingEnt
|
|
148
|
+
constructor(viewer, schema, fields, operation = action_1.WriteOperation.Insert, existingEnt, action) {
|
|
124
149
|
this.viewer = viewer;
|
|
125
150
|
this.schema = schema;
|
|
126
151
|
this.operation = operation;
|
|
127
152
|
this.existingEnt = existingEnt;
|
|
153
|
+
this.m = new Map();
|
|
128
154
|
// create dynamic placeholder
|
|
129
155
|
// TODO: do we need to use this as the node when there's an existingEnt
|
|
130
156
|
// same for generated builders.
|
|
@@ -150,11 +176,13 @@ class SimpleBuilder {
|
|
|
150
176
|
this.ent = schema.ent;
|
|
151
177
|
const tableName = getTableName(schema);
|
|
152
178
|
this.nodeType = (0, camel_case_1.camelCase)(schema.ent.name);
|
|
179
|
+
const fieldInfo = getFieldInfo(schema);
|
|
153
180
|
this.orchestrator = new orchestrator_1.Orchestrator({
|
|
154
181
|
viewer: this.viewer,
|
|
155
182
|
operation: operation,
|
|
156
183
|
tableName: tableName,
|
|
157
184
|
key,
|
|
185
|
+
fieldInfo,
|
|
158
186
|
loaderOptions: {
|
|
159
187
|
loaderFactory: new loaders_1.ObjectLoaderFactory({
|
|
160
188
|
tableName: tableName,
|
|
@@ -164,7 +192,7 @@ class SimpleBuilder {
|
|
|
164
192
|
ent: schema.ent,
|
|
165
193
|
tableName: tableName,
|
|
166
194
|
fields: [],
|
|
167
|
-
fieldPrivacy: (0, schema_1.getFieldsWithPrivacy)(schema),
|
|
195
|
+
fieldPrivacy: (0, schema_1.getFieldsWithPrivacy)(schema, fieldInfo),
|
|
168
196
|
},
|
|
169
197
|
builder: this,
|
|
170
198
|
action: action,
|
|
@@ -177,24 +205,40 @@ class SimpleBuilder {
|
|
|
177
205
|
}
|
|
178
206
|
return m;
|
|
179
207
|
},
|
|
180
|
-
updateInput: (
|
|
181
|
-
const knownFields = (0, schema_1.getFields)(this.schema);
|
|
182
|
-
for (const k in input) {
|
|
183
|
-
if (knownFields.has(k)) {
|
|
184
|
-
this.fields.set(k, input[k]);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
// related to #510. we do camelCase to pass fields in here but fields may be snakeCase and we want that to pass in tests
|
|
188
|
-
// we do camelCase in
|
|
189
|
-
const sc = (0, snake_case_1.snakeCase)(k);
|
|
190
|
-
if (knownFields.has(sc)) {
|
|
191
|
-
this.fields.set(sc, input[k]);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
},
|
|
208
|
+
updateInput: this.updateInput.bind(this),
|
|
196
209
|
});
|
|
197
210
|
}
|
|
211
|
+
getInput() {
|
|
212
|
+
let ret = {};
|
|
213
|
+
for (const [k, v] of this.fields) {
|
|
214
|
+
ret[k] = v;
|
|
215
|
+
}
|
|
216
|
+
return ret;
|
|
217
|
+
}
|
|
218
|
+
updateInput(input) {
|
|
219
|
+
const knownFields = (0, schema_1.getFields)(this.schema);
|
|
220
|
+
for (const k in input) {
|
|
221
|
+
if (knownFields.has(k)) {
|
|
222
|
+
this.fields.set(k, input[k]);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// related to #510. we do camelCase to pass fields in here but fields may be snakeCase and we want that to pass in tests
|
|
226
|
+
// we do camelCase in
|
|
227
|
+
const sc = (0, snake_case_1.snakeCase)(k);
|
|
228
|
+
if (knownFields.has(sc)) {
|
|
229
|
+
this.fields.set(sc, input[k]);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// store data in Builder that can be retrieved by another validator, trigger, observer later in the action
|
|
235
|
+
storeData(k, v) {
|
|
236
|
+
this.m.set(k, v);
|
|
237
|
+
}
|
|
238
|
+
// retrieve data stored in this Builder with key
|
|
239
|
+
getStoredData(k) {
|
|
240
|
+
return this.m.get(k);
|
|
241
|
+
}
|
|
198
242
|
build() {
|
|
199
243
|
return this.orchestrator.build();
|
|
200
244
|
}
|
|
@@ -219,14 +263,20 @@ class SimpleBuilder {
|
|
|
219
263
|
}
|
|
220
264
|
exports.SimpleBuilder = SimpleBuilder;
|
|
221
265
|
class SimpleAction {
|
|
222
|
-
constructor(viewer, schema, fields, operation = action_1.WriteOperation.Insert, existingEnt
|
|
266
|
+
constructor(viewer, schema, fields, operation = action_1.WriteOperation.Insert, existingEnt) {
|
|
223
267
|
this.viewer = viewer;
|
|
224
268
|
this.fields = fields;
|
|
225
|
-
this.validators = [];
|
|
226
|
-
this.triggers = [];
|
|
227
|
-
this.observers = [];
|
|
228
269
|
this.builder = new SimpleBuilder(this.viewer, schema, fields, operation, existingEnt, this);
|
|
229
270
|
}
|
|
271
|
+
getTriggers() {
|
|
272
|
+
return [];
|
|
273
|
+
}
|
|
274
|
+
getValidators() {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
getObservers() {
|
|
278
|
+
return [];
|
|
279
|
+
}
|
|
230
280
|
getPrivacyPolicy() {
|
|
231
281
|
return privacy_1.AlwaysAllowPrivacyPolicy;
|
|
232
282
|
}
|
|
@@ -246,6 +296,9 @@ class SimpleAction {
|
|
|
246
296
|
validX() {
|
|
247
297
|
return this.builder.orchestrator.validX();
|
|
248
298
|
}
|
|
299
|
+
validWithErrors() {
|
|
300
|
+
return this.builder.orchestrator.validWithErrors();
|
|
301
|
+
}
|
|
249
302
|
async save() {
|
|
250
303
|
await (0, action_1.saveBuilder)(this.builder);
|
|
251
304
|
if (this.builder.operation !== action_1.WriteOperation.Delete) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Client } from "pg";
|
|
2
|
+
import { Data } from "../../core/base";
|
|
3
|
+
import { Schema } from "../../schema";
|
|
4
|
+
interface Options {
|
|
5
|
+
overrides?: Data;
|
|
6
|
+
client: Client;
|
|
7
|
+
tableName: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function writeFixture(schema: Schema, opts: Options): Promise<void>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeFixture = void 0;
|
|
4
|
+
const schema_1 = require("../../schema");
|
|
5
|
+
const value_1 = require("./value");
|
|
6
|
+
const ent_1 = require("../../core/ent");
|
|
7
|
+
async function writeFixture(schema, opts) {
|
|
8
|
+
const fields = (0, schema_1.getFields)(schema);
|
|
9
|
+
const d = {};
|
|
10
|
+
for (const [fieldName, field] of fields) {
|
|
11
|
+
const col = (0, schema_1.getStorageKey)(field, fieldName);
|
|
12
|
+
const val = (0, value_1.getDefaultValue)(field, col);
|
|
13
|
+
d[col] = val;
|
|
14
|
+
}
|
|
15
|
+
if (opts.overrides) {
|
|
16
|
+
for (const k in opts.overrides) {
|
|
17
|
+
d[k] = opts.overrides[k];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const q = (0, ent_1.buildInsertQuery)({
|
|
21
|
+
tableName: opts.tableName,
|
|
22
|
+
fields: d,
|
|
23
|
+
});
|
|
24
|
+
await opts.client.query(q[0], q[1]);
|
|
25
|
+
}
|
|
26
|
+
exports.writeFixture = writeFixture;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Client as PGClient } from "pg";
|
|
2
2
|
import { Dialect } from "../../core/db";
|
|
3
3
|
import { Database as SqliteDatabase } from "better-sqlite3";
|
|
4
|
+
import { Field } from "../../schema";
|
|
4
5
|
import { BuilderSchema } from "../builder";
|
|
5
6
|
import { Ent } from "../../core/base";
|
|
6
7
|
interface SchemaItem {
|
|
@@ -12,6 +13,7 @@ interface Column extends SchemaItem {
|
|
|
12
13
|
primaryKey?: boolean;
|
|
13
14
|
unique?: boolean;
|
|
14
15
|
default?: string;
|
|
16
|
+
index?: boolean | indexOptions;
|
|
15
17
|
foreignKey?: {
|
|
16
18
|
table: string;
|
|
17
19
|
col: string;
|
|
@@ -20,21 +22,29 @@ interface Column extends SchemaItem {
|
|
|
20
22
|
interface Constraint extends SchemaItem {
|
|
21
23
|
generate(): string;
|
|
22
24
|
}
|
|
25
|
+
interface Index extends SchemaItem {
|
|
26
|
+
generate(): string;
|
|
27
|
+
}
|
|
23
28
|
export interface CoreConcept {
|
|
24
29
|
name: string;
|
|
25
30
|
create(): string;
|
|
31
|
+
postCreate?(): string[];
|
|
26
32
|
drop(): string;
|
|
27
33
|
}
|
|
28
34
|
export interface Table extends CoreConcept {
|
|
29
35
|
columns: Column[];
|
|
30
36
|
constraints?: Constraint[];
|
|
31
37
|
}
|
|
32
|
-
declare type options = Pick<Column, "nullable" | "primaryKey" | "default" | "foreignKey" | "unique">;
|
|
38
|
+
declare type options = Pick<Column, "nullable" | "primaryKey" | "default" | "foreignKey" | "unique" | "index">;
|
|
33
39
|
export declare function primaryKey(name: string, cols: string[]): Constraint;
|
|
34
40
|
export declare function foreignKey(name: string, cols: string[], fkey: {
|
|
35
41
|
table: string;
|
|
36
42
|
cols: string[];
|
|
37
43
|
}): Constraint;
|
|
44
|
+
interface indexOptions {
|
|
45
|
+
type: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function index(tableName: string, cols: string[], opts?: indexOptions): Index;
|
|
38
48
|
export declare function uniqueIndex(name: string): Constraint;
|
|
39
49
|
export declare function uuid(name: string, opts?: options): Column;
|
|
40
50
|
export declare function text(name: string, opts?: options): Column;
|
|
@@ -72,6 +82,7 @@ export declare class TempDB {
|
|
|
72
82
|
getDialect(): Dialect;
|
|
73
83
|
getTables(): Map<string, CoreConcept>;
|
|
74
84
|
beforeAll(setupConnString?: boolean): Promise<void>;
|
|
85
|
+
createImpl(table: CoreConcept): Promise<void>;
|
|
75
86
|
getSqliteClient(): SqliteDatabase;
|
|
76
87
|
getPostgresClient(): PGClient;
|
|
77
88
|
afterAll(): Promise<void>;
|
|
@@ -81,10 +92,11 @@ export declare class TempDB {
|
|
|
81
92
|
create(...tables: CoreConcept[]): Promise<void>;
|
|
82
93
|
}
|
|
83
94
|
export declare function assoc_edge_config_table(): Table;
|
|
84
|
-
export declare function assoc_edge_table(name: string): Table;
|
|
95
|
+
export declare function assoc_edge_table(name: string, global?: boolean): Table;
|
|
85
96
|
interface sqliteSetupOptions {
|
|
86
97
|
disableDeleteAfterEachTest?: boolean;
|
|
87
98
|
}
|
|
88
|
-
export declare function setupSqlite(connString: string, tables: () => Table[], opts?: sqliteSetupOptions):
|
|
99
|
+
export declare function setupSqlite(connString: string, tables: () => Table[], opts?: sqliteSetupOptions): TempDB;
|
|
89
100
|
export declare function getSchemaTable(schema: BuilderSchema<Ent>, dialect: Dialect): Table;
|
|
101
|
+
export declare function getColumnFromField(fieldName: string, f: Field, dialect: Dialect): Column;
|
|
90
102
|
export {};
|