@snowtop/ent 0.1.0-alpha53 → 0.1.0-alpha58
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/experimental_action.d.ts +1 -1
- package/action/orchestrator.js +21 -1
- package/core/base.d.ts +1 -1
- package/core/clause.d.ts +36 -7
- package/core/clause.js +133 -32
- package/core/config.d.ts +5 -2
- package/core/ent.d.ts +16 -3
- package/core/ent.js +147 -35
- package/core/loaders/assoc_count_loader.js +6 -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/index.d.ts +5 -5
- package/index.js +7 -6
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +8 -2
- package/parse_schema/parse.js +22 -2
- package/schema/field.js +4 -0
- package/schema/index.d.ts +1 -1
- package/schema/schema.d.ts +16 -0
- package/scripts/custom_graphql.js +2 -0
- package/scripts/read_schema.js +10 -1
- package/testutils/db/{test_db.d.ts → temp_db.d.ts} +15 -3
- package/testutils/db/{test_db.js → temp_db.js} +62 -15
- package/testutils/fake_data/fake_contact.d.ts +1 -1
- package/testutils/fake_data/fake_contact.js +2 -2
- package/testutils/fake_data/fake_event.d.ts +1 -1
- package/testutils/fake_data/fake_event.js +3 -3
- package/testutils/fake_data/fake_user.d.ts +1 -1
- package/testutils/fake_data/fake_user.js +2 -2
- package/testutils/fake_data/test_helpers.d.ts +2 -2
- package/testutils/fake_data/test_helpers.js +5 -5
- package/testutils/parse_sql.js +4 -0
- 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 +3 -3
- package/tsc/ast.d.ts +1 -0
- package/tsc/ast.js +3 -0
package/index.js
CHANGED
|
@@ -25,8 +25,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
26
26
|
};
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.
|
|
29
|
-
exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = void 0;
|
|
28
|
+
exports.DenyIfEdgeDoesNotExistRule = exports.DenyIfViewerOutboundEdgeExistsRule = exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.AllowIfFuncRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedOutRule = exports.DenyIfLoggedInRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = exports.DB = exports.setGlobalSchema = exports.getEdgeTypeInGroup = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadEdges = exports.loadEdgeDatas = exports.loadEdgeData = exports.AssocEdgeData = exports.AssocEdge = exports.DeleteNodeOperation = exports.EdgeOperation = exports.EditNodeOperation = exports.loadRows = exports.loadRow = exports.loadRowX = exports.performRawQuery = exports.loadEntXViaKey = exports.loadEntViaKey = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadEnts = exports.loadEntX = exports.loadCustomEnts = exports.loadCustomData = exports.loadEnt = void 0;
|
|
29
|
+
exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = exports.DenyIfViewerInboundEdgeDoesNotExistRule = void 0;
|
|
30
30
|
__exportStar(require("./core/base"), exports);
|
|
31
31
|
var ent_1 = require("./core/ent");
|
|
32
32
|
Object.defineProperty(exports, "loadEnt", { enumerable: true, get: function () { return ent_1.loadEnt; } });
|
|
@@ -57,6 +57,7 @@ Object.defineProperty(exports, "loadRawEdgeCountX", { enumerable: true, get: fun
|
|
|
57
57
|
Object.defineProperty(exports, "loadEdgeForID2", { enumerable: true, get: function () { return ent_1.loadEdgeForID2; } });
|
|
58
58
|
Object.defineProperty(exports, "loadNodesByEdge", { enumerable: true, get: function () { return ent_1.loadNodesByEdge; } });
|
|
59
59
|
Object.defineProperty(exports, "getEdgeTypeInGroup", { enumerable: true, get: function () { return ent_1.getEdgeTypeInGroup; } });
|
|
60
|
+
Object.defineProperty(exports, "setGlobalSchema", { enumerable: true, get: function () { return ent_1.setGlobalSchema; } });
|
|
60
61
|
const db_1 = __importDefault(require("./core/db"));
|
|
61
62
|
exports.DB = db_1.default;
|
|
62
63
|
__exportStar(require("./core/loaders"), exports);
|
|
@@ -116,10 +117,10 @@ const query = {
|
|
|
116
117
|
LessEq: q.LessEq,
|
|
117
118
|
ArrayEq: q.ArrayEq,
|
|
118
119
|
ArrayNotEq: q.ArrayNotEq,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
PostgresArrayContainsValue: q.PostgresArrayContainsValue,
|
|
121
|
+
PostgresArrayContains: q.PostgresArrayContains,
|
|
122
|
+
PostgresArrayNotContainsValue: q.PostgresArrayNotContainsValue,
|
|
123
|
+
PostgresArrayNotContains: q.PostgresArrayNotContains,
|
|
123
124
|
TsQuery: q.TsQuery,
|
|
124
125
|
PlainToTsQuery: q.PlainToTsQuery,
|
|
125
126
|
PhraseToTsQuery: q.PhraseToTsQuery,
|
package/package.json
CHANGED
package/parse_schema/parse.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema, Field, AssocEdge, AssocEdgeGroup, Action } from "../schema";
|
|
2
|
-
import { ActionField, Type } from "../schema/schema";
|
|
2
|
+
import { ActionField, Type, GlobalSchema } from "../schema/schema";
|
|
3
3
|
declare enum NullableResult {
|
|
4
4
|
CONTENTS = "contents",
|
|
5
5
|
CONTENTS_AND_LIST = "contentsAndList",
|
|
@@ -61,9 +61,15 @@ interface patternsDict {
|
|
|
61
61
|
interface Result {
|
|
62
62
|
schemas: schemasDict;
|
|
63
63
|
patterns: patternsDict;
|
|
64
|
+
globalSchema?: ProcessedGlobalSchema;
|
|
64
65
|
}
|
|
65
66
|
declare type PotentialSchemas = {
|
|
66
67
|
[key: string]: any;
|
|
67
68
|
};
|
|
68
|
-
export declare function parseSchema(potentialSchemas: PotentialSchemas): Result;
|
|
69
|
+
export declare function parseSchema(potentialSchemas: PotentialSchemas, globalSchema?: GlobalSchema): Result;
|
|
70
|
+
interface ProcessedGlobalSchema {
|
|
71
|
+
globalEdges: ProcessedAssocEdge[];
|
|
72
|
+
extraEdgeFields: ProcessedField[];
|
|
73
|
+
initForEdges?: boolean;
|
|
74
|
+
}
|
|
69
75
|
export {};
|
package/parse_schema/parse.js
CHANGED
|
@@ -172,9 +172,13 @@ function processAction(action) {
|
|
|
172
172
|
ret.actionOnlyFields = actionOnlyFields;
|
|
173
173
|
return ret;
|
|
174
174
|
}
|
|
175
|
-
function parseSchema(potentialSchemas) {
|
|
175
|
+
function parseSchema(potentialSchemas, globalSchema) {
|
|
176
176
|
let schemas = {};
|
|
177
177
|
let patterns = {};
|
|
178
|
+
let parsedGlobalSchema;
|
|
179
|
+
if (globalSchema) {
|
|
180
|
+
parsedGlobalSchema = parseGlobalSchema(globalSchema);
|
|
181
|
+
}
|
|
178
182
|
for (const key in potentialSchemas) {
|
|
179
183
|
const value = potentialSchemas[key];
|
|
180
184
|
let schema;
|
|
@@ -234,6 +238,22 @@ function parseSchema(potentialSchemas) {
|
|
|
234
238
|
}
|
|
235
239
|
schemas[key] = processedSchema;
|
|
236
240
|
}
|
|
237
|
-
return { schemas, patterns };
|
|
241
|
+
return { schemas, patterns, globalSchema: parsedGlobalSchema };
|
|
238
242
|
}
|
|
239
243
|
exports.parseSchema = parseSchema;
|
|
244
|
+
function parseGlobalSchema(s) {
|
|
245
|
+
const ret = {
|
|
246
|
+
globalEdges: [],
|
|
247
|
+
extraEdgeFields: [],
|
|
248
|
+
initForEdges: !!s.extraEdgeFields ||
|
|
249
|
+
s.transformEdgeRead !== undefined ||
|
|
250
|
+
s.transformEdgeWrite !== undefined,
|
|
251
|
+
};
|
|
252
|
+
if (s.extraEdgeFields) {
|
|
253
|
+
ret.extraEdgeFields = processFields(s.extraEdgeFields);
|
|
254
|
+
}
|
|
255
|
+
if (s.edges) {
|
|
256
|
+
ret.globalEdges = processEdges(s.edges);
|
|
257
|
+
}
|
|
258
|
+
return ret;
|
|
259
|
+
}
|
package/schema/field.js
CHANGED
|
@@ -25,6 +25,7 @@ const snake_case_1 = require("snake-case");
|
|
|
25
25
|
const db_1 = __importStar(require("../core/db"));
|
|
26
26
|
const schema_1 = require("./schema");
|
|
27
27
|
const util_1 = require("util");
|
|
28
|
+
const uuid_1 = require("uuid");
|
|
28
29
|
class BaseField {
|
|
29
30
|
logValue(val) {
|
|
30
31
|
if (this.sensitive) {
|
|
@@ -92,6 +93,9 @@ class UUIDField extends BaseField {
|
|
|
92
93
|
return val.placeholderID !== undefined;
|
|
93
94
|
}
|
|
94
95
|
async valid(val) {
|
|
96
|
+
if (typeof val === "string" && !(0, uuid_1.validate)(val)) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
95
99
|
if (!this.options?.fieldEdge?.enforceSchema) {
|
|
96
100
|
return true;
|
|
97
101
|
}
|
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, getFieldsWithPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, getTransformedReadClause, getObjectLoaderProperties, } from "./schema";
|
|
3
|
+
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, } from "./schema";
|
|
4
4
|
export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, EntSchema, EntSchemaWithTZ, SchemaConfig, } from "./base_schema";
|
|
5
5
|
export * from "./field";
|
|
6
6
|
export * from "./json_field";
|
package/schema/schema.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Data, Ent, LoaderInfo, PrivacyPolicy, Viewer } from "../core/base";
|
|
2
2
|
import { Builder } from "../action/action";
|
|
3
3
|
import { Clause } from "../core/clause";
|
|
4
|
+
import { AssocEdgeInput } from "../core/ent";
|
|
4
5
|
export declare type FieldMap = {
|
|
5
6
|
[key: string]: Field;
|
|
6
7
|
};
|
|
@@ -11,6 +12,12 @@ interface FieldInfo {
|
|
|
11
12
|
export declare type FieldInfoMap = {
|
|
12
13
|
[key: string]: FieldInfo;
|
|
13
14
|
};
|
|
15
|
+
export interface GlobalSchema {
|
|
16
|
+
edges?: Edge[];
|
|
17
|
+
extraEdgeFields?: FieldMap;
|
|
18
|
+
transformEdgeRead?: () => Clause;
|
|
19
|
+
transformEdgeWrite?: (stmt: EdgeUpdateOperation) => TransformedEdgeUpdateOperation | null;
|
|
20
|
+
}
|
|
14
21
|
export default interface Schema {
|
|
15
22
|
fields: FieldMap | Field[];
|
|
16
23
|
tableName?: string;
|
|
@@ -82,6 +89,14 @@ export declare enum SQLStatementOperation {
|
|
|
82
89
|
Update = "update",
|
|
83
90
|
Delete = "delete"
|
|
84
91
|
}
|
|
92
|
+
export interface EdgeUpdateOperation {
|
|
93
|
+
op: SQLStatementOperation;
|
|
94
|
+
edge: AssocEdgeInput;
|
|
95
|
+
}
|
|
96
|
+
export interface TransformedEdgeUpdateOperation {
|
|
97
|
+
op: SQLStatementOperation;
|
|
98
|
+
data?: Data;
|
|
99
|
+
}
|
|
85
100
|
export interface UpdateOperation<TEnt extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
|
|
86
101
|
op: SQLStatementOperation;
|
|
87
102
|
builder: Builder<TEnt, TViewer>;
|
|
@@ -271,6 +286,7 @@ export interface Index {
|
|
|
271
286
|
columns: string[];
|
|
272
287
|
unique?: boolean;
|
|
273
288
|
fulltext?: FullText;
|
|
289
|
+
indexType?: "gin" | "btree";
|
|
274
290
|
}
|
|
275
291
|
export interface ForeignKeyInfo {
|
|
276
292
|
tableName: string;
|
|
@@ -237,6 +237,8 @@ async function main() {
|
|
|
237
237
|
(0, graphql_1.addCustomType)({
|
|
238
238
|
importPath: MODULE_PATH,
|
|
239
239
|
// for go tests...
|
|
240
|
+
// TODO need a flag that only does this for go tests
|
|
241
|
+
// breaks when running locally sometimes...
|
|
240
242
|
secondaryImportPath: "../graphql/scalars/time",
|
|
241
243
|
type: "GraphQLTime",
|
|
242
244
|
});
|
package/scripts/read_schema.js
CHANGED
|
@@ -28,18 +28,27 @@ 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`);
|
|
@@ -61,7 +70,7 @@ function main() {
|
|
|
61
70
|
potentialSchemas[(0, pascal_case_1.pascalCase)(schema)] = s;
|
|
62
71
|
}
|
|
63
72
|
// console.log(potentialSchemas);
|
|
64
|
-
const result = (0, parse_1.parseSchema)(potentialSchemas);
|
|
73
|
+
const result = (0, parse_1.parseSchema)(potentialSchemas, globalSchema);
|
|
65
74
|
console.log(JSON.stringify(result));
|
|
66
75
|
}
|
|
67
76
|
try {
|
|
@@ -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 {};
|
|
@@ -22,7 +22,7 @@ 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.getSchemaTable = exports.setupSqlite = exports.assoc_edge_table = exports.assoc_edge_config_table = exports.TempDB = exports.enumType = exports.table = exports.boolList = exports.dateList = exports.timetzList = exports.timeList = exports.timestamptzList = exports.timestampList = exports.uuidList = exports.integerList = exports.textList = exports.jsonb = exports.json = exports.float = exports.integer = exports.bool = exports.date = exports.timetz = exports.time = exports.timestamptz = exports.timestamp = exports.enumCol = exports.text = exports.uuid = exports.uniqueIndex = exports.foreignKey = exports.primaryKey = void 0;
|
|
25
|
+
exports.getColumnFromField = exports.getSchemaTable = exports.setupSqlite = exports.assoc_edge_table = exports.assoc_edge_config_table = exports.TempDB = exports.enumType = exports.table = exports.boolList = exports.dateList = exports.timetzList = exports.timeList = exports.timestamptzList = exports.timestampList = exports.uuidList = exports.integerList = exports.textList = exports.jsonb = exports.json = exports.float = exports.integer = exports.bool = exports.date = exports.timetz = exports.time = exports.timestamptz = exports.timestamp = exports.enumCol = exports.text = exports.uuid = exports.uniqueIndex = exports.index = exports.foreignKey = exports.primaryKey = void 0;
|
|
26
26
|
const pg_1 = require("pg");
|
|
27
27
|
const db_1 = __importStar(require("../../core/db"));
|
|
28
28
|
// this should only be used in tests so we expect to be able to import without shenanigans
|
|
@@ -32,6 +32,7 @@ const fs = __importStar(require("fs"));
|
|
|
32
32
|
const schema_1 = require("../../schema");
|
|
33
33
|
const snake_case_1 = require("snake-case");
|
|
34
34
|
const builder_1 = require("../builder");
|
|
35
|
+
const test_edge_global_schema_1 = require("../test_edge_global_schema");
|
|
35
36
|
function primaryKey(name, cols) {
|
|
36
37
|
return {
|
|
37
38
|
name: name,
|
|
@@ -50,6 +51,16 @@ function foreignKey(name, cols, fkey) {
|
|
|
50
51
|
};
|
|
51
52
|
}
|
|
52
53
|
exports.foreignKey = foreignKey;
|
|
54
|
+
function index(tableName, cols, opts) {
|
|
55
|
+
const name = `${tableName}_${cols.join("_")}_idx`;
|
|
56
|
+
return {
|
|
57
|
+
name,
|
|
58
|
+
generate() {
|
|
59
|
+
return `CREATE INDEX ${name} ON ${tableName} USING ${opts?.type || "btree"} (${cols.join(",")});`;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
exports.index = index;
|
|
53
64
|
function uniqueIndex(name) {
|
|
54
65
|
return {
|
|
55
66
|
name: "",
|
|
@@ -248,9 +259,24 @@ exports.boolList = boolList;
|
|
|
248
259
|
function table(name, ...items) {
|
|
249
260
|
let cols = [];
|
|
250
261
|
let constraints = [];
|
|
262
|
+
let indexes = [];
|
|
251
263
|
for (const item of items) {
|
|
252
264
|
if (item.datatype !== undefined) {
|
|
253
265
|
const col = item;
|
|
266
|
+
if (col.index) {
|
|
267
|
+
let opts = {
|
|
268
|
+
type: "btree",
|
|
269
|
+
};
|
|
270
|
+
if (col.index === true) {
|
|
271
|
+
opts = {
|
|
272
|
+
type: "btree",
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
opts = col.index;
|
|
277
|
+
}
|
|
278
|
+
indexes.push(index(name, [col.name], opts));
|
|
279
|
+
}
|
|
254
280
|
// add it as a constraint
|
|
255
281
|
if (col.foreignKey) {
|
|
256
282
|
constraints.push(foreignKey(`${name}_${col.name}_fkey`, [col.name], {
|
|
@@ -288,6 +314,9 @@ function table(name, ...items) {
|
|
|
288
314
|
constraints.forEach((constraint) => schemaStr.push(constraint.generate()));
|
|
289
315
|
return `CREATE TABLE IF NOT EXISTS ${name} (\n ${schemaStr})`;
|
|
290
316
|
},
|
|
317
|
+
postCreate() {
|
|
318
|
+
return indexes.map((index) => index.generate());
|
|
319
|
+
},
|
|
291
320
|
drop() {
|
|
292
321
|
return `DROP TABLE IF EXISTS ${name}`;
|
|
293
322
|
},
|
|
@@ -376,11 +405,24 @@ class TempDB {
|
|
|
376
405
|
this.sqlite = (0, better_sqlite3_1.default)(filePath);
|
|
377
406
|
}
|
|
378
407
|
for (const [_, table] of this.tables) {
|
|
379
|
-
|
|
380
|
-
|
|
408
|
+
await this.createImpl(table);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
async createImpl(table) {
|
|
412
|
+
if (this.dialect == db_1.Dialect.Postgres) {
|
|
413
|
+
await this.dbClient.query(table.create());
|
|
414
|
+
if (table.postCreate) {
|
|
415
|
+
for (const q of table.postCreate()) {
|
|
416
|
+
await this.dbClient.query(q);
|
|
417
|
+
}
|
|
381
418
|
}
|
|
382
|
-
|
|
383
|
-
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
this.sqlite.exec(table.create());
|
|
422
|
+
if (table.postCreate) {
|
|
423
|
+
for (const q of table.postCreate()) {
|
|
424
|
+
this.sqlite.exec(q);
|
|
425
|
+
}
|
|
384
426
|
}
|
|
385
427
|
}
|
|
386
428
|
}
|
|
@@ -431,12 +473,7 @@ class TempDB {
|
|
|
431
473
|
if (this.tables.has(table.name)) {
|
|
432
474
|
throw new Error(`table with name ${table.name} already exists`);
|
|
433
475
|
}
|
|
434
|
-
|
|
435
|
-
await this.dbClient.query(table.create());
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
this.sqlite.exec(table.create());
|
|
439
|
-
}
|
|
476
|
+
await this.createImpl(table);
|
|
440
477
|
this.tables.set(table.name, table);
|
|
441
478
|
}
|
|
442
479
|
}
|
|
@@ -448,18 +485,26 @@ function assoc_edge_config_table() {
|
|
|
448
485
|
text("edge_type", { primaryKey: true }), text("edge_name"), bool("symmetric_edge", { default: "FALSE" }), text("inverse_edge_type", { nullable: true }), text("edge_table"), timestamptz("created_at"), timestamptz("updated_at"));
|
|
449
486
|
}
|
|
450
487
|
exports.assoc_edge_config_table = assoc_edge_config_table;
|
|
451
|
-
|
|
452
|
-
|
|
488
|
+
// if global flag is true, add any column from testEdgeGlobalSchema
|
|
489
|
+
// up to caller to set/clear that as needed
|
|
490
|
+
function assoc_edge_table(name, global) {
|
|
491
|
+
const t = table(name, uuid("id1"), text("id1_type"),
|
|
453
492
|
// same as in assoc_edge_config_table
|
|
454
493
|
text("edge_type"), uuid("id2"), text("id2_type"), timestamptz("time"), text("data", { nullable: true }), primaryKey(`${name}_pkey`, ["id1", "id2", "edge_type"]));
|
|
494
|
+
if (global) {
|
|
495
|
+
for (const k in test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields) {
|
|
496
|
+
const col = getColumnFromField(k, test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields[k], db_1.Dialect.Postgres);
|
|
497
|
+
t.columns.push(col);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return t;
|
|
455
501
|
}
|
|
456
502
|
exports.assoc_edge_table = assoc_edge_table;
|
|
457
503
|
function setupSqlite(connString, tables, opts) {
|
|
458
|
-
let tdb;
|
|
504
|
+
let tdb = new TempDB(db_1.Dialect.SQLite, tables());
|
|
459
505
|
beforeAll(async () => {
|
|
460
506
|
process.env.DB_CONNECTION_STRING = connString;
|
|
461
507
|
(0, config_1.loadConfig)();
|
|
462
|
-
tdb = new TempDB(db_1.Dialect.SQLite, tables());
|
|
463
508
|
await tdb.beforeAll();
|
|
464
509
|
const conn = db_1.default.getInstance().getConnection();
|
|
465
510
|
expect(conn.db.memory).toBe(false);
|
|
@@ -483,6 +528,7 @@ function setupSqlite(connString, tables, opts) {
|
|
|
483
528
|
await tdb.afterAll();
|
|
484
529
|
fs.rmSync(tdb.getSqliteClient().name);
|
|
485
530
|
});
|
|
531
|
+
return tdb;
|
|
486
532
|
}
|
|
487
533
|
exports.setupSqlite = setupSqlite;
|
|
488
534
|
function getSchemaTable(schema, dialect) {
|
|
@@ -549,6 +595,7 @@ function getColumnFromField(fieldName, f, dialect) {
|
|
|
549
595
|
return getColumn(fieldName, f, fn);
|
|
550
596
|
}
|
|
551
597
|
}
|
|
598
|
+
exports.getColumnFromField = getColumnFromField;
|
|
552
599
|
function getColumn(fieldName, f, col) {
|
|
553
600
|
return col(storageKey(fieldName, f), buildOpts(f));
|
|
554
601
|
}
|
|
@@ -16,7 +16,7 @@ export declare class FakeContact implements Ent {
|
|
|
16
16
|
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
17
17
|
constructor(viewer: Viewer, data: Data);
|
|
18
18
|
static getFields(): string[];
|
|
19
|
-
static getTestTable(): import("../db/
|
|
19
|
+
static getTestTable(): import("../db/temp_db").Table;
|
|
20
20
|
static loaderOptions(): LoadEntOptions<FakeContact>;
|
|
21
21
|
static load(v: Viewer, id: ID): Promise<FakeContact | null>;
|
|
22
22
|
static loadX(v: Viewer, id: ID): Promise<FakeContact>;
|
|
@@ -6,7 +6,7 @@ const privacy_1 = require("../../core/privacy");
|
|
|
6
6
|
const builder_1 = require("../builder");
|
|
7
7
|
const schema_1 = require("../../schema");
|
|
8
8
|
const const_1 = require("./const");
|
|
9
|
-
const
|
|
9
|
+
const temp_db_1 = require("../db/temp_db");
|
|
10
10
|
const loaders_1 = require("../../core/loaders");
|
|
11
11
|
const convert_1 = require("../../core/convert");
|
|
12
12
|
const action_1 = require("../../action");
|
|
@@ -40,7 +40,7 @@ class FakeContact {
|
|
|
40
40
|
];
|
|
41
41
|
}
|
|
42
42
|
static getTestTable() {
|
|
43
|
-
return (0,
|
|
43
|
+
return (0, temp_db_1.table)("fake_contacts", (0, temp_db_1.uuid)("id", { primaryKey: true }), (0, temp_db_1.timestamptz)("created_at"), (0, temp_db_1.timestamptz)("updated_at"), (0, temp_db_1.text)("first_name"), (0, temp_db_1.text)("last_name"), (0, temp_db_1.text)("email_address"), (0, temp_db_1.uuid)("user_id"));
|
|
44
44
|
}
|
|
45
45
|
static loaderOptions() {
|
|
46
46
|
return {
|
|
@@ -17,7 +17,7 @@ export declare class FakeEvent implements Ent {
|
|
|
17
17
|
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
18
18
|
constructor(viewer: Viewer, data: Data);
|
|
19
19
|
private static getFields;
|
|
20
|
-
static getTestTable(): import("../db/
|
|
20
|
+
static getTestTable(): import("../db/temp_db").Table;
|
|
21
21
|
static loaderOptions(): LoadEntOptions<FakeEvent>;
|
|
22
22
|
static load(v: Viewer, id: ID): Promise<FakeEvent | null>;
|
|
23
23
|
static loadX(v: Viewer, id: ID): Promise<FakeEvent>;
|
|
@@ -6,7 +6,7 @@ const privacy_1 = require("../../core/privacy");
|
|
|
6
6
|
const builder_1 = require("../builder");
|
|
7
7
|
const schema_1 = require("../../schema");
|
|
8
8
|
const const_1 = require("./const");
|
|
9
|
-
const
|
|
9
|
+
const temp_db_1 = require("../db/temp_db");
|
|
10
10
|
const loaders_1 = require("../../core/loaders");
|
|
11
11
|
const convert_1 = require("../../core/convert");
|
|
12
12
|
const action_1 = require("../../action");
|
|
@@ -42,9 +42,9 @@ class FakeEvent {
|
|
|
42
42
|
];
|
|
43
43
|
}
|
|
44
44
|
static getTestTable() {
|
|
45
|
-
return (0,
|
|
45
|
+
return (0, temp_db_1.table)("fake_events", (0, temp_db_1.uuid)("id", { primaryKey: true }), (0, temp_db_1.timestamptz)("created_at"), (0, temp_db_1.timestamptz)("updated_at"),
|
|
46
46
|
// TODO index:true
|
|
47
|
-
(0,
|
|
47
|
+
(0, temp_db_1.timestamptz)("start_time"), (0, temp_db_1.timestamptz)("end_time", { nullable: true }), (0, temp_db_1.text)("location"), (0, temp_db_1.text)("title"), (0, temp_db_1.text)("description", { nullable: true }), (0, temp_db_1.uuid)("user_id"));
|
|
48
48
|
}
|
|
49
49
|
static loaderOptions() {
|
|
50
50
|
return {
|
|
@@ -26,7 +26,7 @@ export declare class FakeUser implements Ent {
|
|
|
26
26
|
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
27
27
|
constructor(viewer: Viewer, data: Data);
|
|
28
28
|
static getFields(): string[];
|
|
29
|
-
static getTestTable(): import("../db/
|
|
29
|
+
static getTestTable(): import("../db/temp_db").Table;
|
|
30
30
|
static loaderOptions(): LoadEntOptions<FakeUser>;
|
|
31
31
|
static load(v: Viewer, id: ID): Promise<FakeUser | null>;
|
|
32
32
|
static loadX(v: Viewer, id: ID): Promise<FakeUser>;
|
|
@@ -8,7 +8,7 @@ const schema_1 = require("../../schema");
|
|
|
8
8
|
const internal_1 = require("./internal");
|
|
9
9
|
const const_1 = require("./const");
|
|
10
10
|
const viewer_1 = require("../../core/viewer");
|
|
11
|
-
const
|
|
11
|
+
const temp_db_1 = require("../db/temp_db");
|
|
12
12
|
const loaders_1 = require("../../core/loaders");
|
|
13
13
|
const convert_1 = require("../../core/convert");
|
|
14
14
|
const action_1 = require("../../action");
|
|
@@ -74,7 +74,7 @@ class FakeUser {
|
|
|
74
74
|
];
|
|
75
75
|
}
|
|
76
76
|
static getTestTable() {
|
|
77
|
-
return (0,
|
|
77
|
+
return (0, temp_db_1.table)("fake_users", (0, temp_db_1.uuid)("id", { primaryKey: true }), (0, temp_db_1.timestamptz)("created_at"), (0, temp_db_1.timestamptz)("updated_at"), (0, temp_db_1.text)("first_name"), (0, temp_db_1.text)("last_name"), (0, temp_db_1.text)("email_address"), (0, temp_db_1.text)("phone_number"), (0, temp_db_1.text)("password"));
|
|
78
78
|
}
|
|
79
79
|
static loaderOptions() {
|
|
80
80
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Data, Ent } from "../../core/base";
|
|
2
2
|
import { AssocEdge } from "../../core/ent";
|
|
3
|
-
import { TempDB } from "../db/
|
|
3
|
+
import { TempDB } from "../db/temp_db";
|
|
4
4
|
import { FakeUser, UserCreateInput, ContactCreateInput, FakeContact } from ".";
|
|
5
5
|
import { EventCreateInput, FakeEvent } from "./fake_event";
|
|
6
6
|
import { BuilderSchema } from "../builder";
|
|
@@ -20,7 +20,7 @@ export declare function createEdges(): Promise<void>;
|
|
|
20
20
|
export declare function edgeTableNames(): string[];
|
|
21
21
|
export declare function createTestEvent(user: FakeUser, input?: Partial<EventCreateInput>): Promise<FakeEvent>;
|
|
22
22
|
export declare function setupTempDB(): Promise<TempDB>;
|
|
23
|
-
export declare function tempDBTables(): import("../db/
|
|
23
|
+
export declare function tempDBTables(global?: boolean): import("../db/temp_db").Table[];
|
|
24
24
|
interface options {
|
|
25
25
|
howMany: number;
|
|
26
26
|
interval: number;
|
|
@@ -6,7 +6,7 @@ const viewer_1 = require("../../core/viewer");
|
|
|
6
6
|
const ent_1 = require("../../core/ent");
|
|
7
7
|
const snake_case_1 = require("snake-case");
|
|
8
8
|
const write_1 = require("../write");
|
|
9
|
-
const
|
|
9
|
+
const temp_db_1 = require("../db/temp_db");
|
|
10
10
|
const _1 = require(".");
|
|
11
11
|
const fake_event_1 = require("./fake_event");
|
|
12
12
|
const const_1 = require("./const");
|
|
@@ -209,21 +209,21 @@ async function createTestEvent(user, input) {
|
|
|
209
209
|
}
|
|
210
210
|
exports.createTestEvent = createTestEvent;
|
|
211
211
|
async function setupTempDB() {
|
|
212
|
-
const tdb = new
|
|
212
|
+
const tdb = new temp_db_1.TempDB(tempDBTables());
|
|
213
213
|
await tdb.beforeAll();
|
|
214
214
|
// create once
|
|
215
215
|
await createEdges();
|
|
216
216
|
return tdb;
|
|
217
217
|
}
|
|
218
218
|
exports.setupTempDB = setupTempDB;
|
|
219
|
-
function tempDBTables() {
|
|
219
|
+
function tempDBTables(global = false) {
|
|
220
220
|
const tables = [
|
|
221
221
|
_1.FakeUser.getTestTable(),
|
|
222
222
|
_1.FakeContact.getTestTable(),
|
|
223
223
|
fake_event_1.FakeEvent.getTestTable(),
|
|
224
|
-
(0,
|
|
224
|
+
(0, temp_db_1.assoc_edge_config_table)(),
|
|
225
225
|
];
|
|
226
|
-
edgeTableNames().forEach((tableName) => tables.push((0,
|
|
226
|
+
edgeTableNames().forEach((tableName) => tables.push((0, temp_db_1.assoc_edge_table)(tableName, global)));
|
|
227
227
|
return tables;
|
|
228
228
|
}
|
|
229
229
|
exports.tempDBTables = tempDBTables;
|
package/testutils/parse_sql.js
CHANGED
|
@@ -307,6 +307,10 @@ function getOp(where, values) {
|
|
|
307
307
|
return new AndOp([getOp(where.left, values), getOp(where.right, values)]);
|
|
308
308
|
case "OR":
|
|
309
309
|
return new OrOp([getOp(where.left, values), getOp(where.right, values)]);
|
|
310
|
+
case "IS":
|
|
311
|
+
if (where.right?.value === null) {
|
|
312
|
+
return new EqOp(getColumnFromRef(where.left), null);
|
|
313
|
+
}
|
|
310
314
|
default:
|
|
311
315
|
console.log(where);
|
|
312
316
|
throw new Error(`unsupported op ${where.operator}`);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EdgeUpdateOperation, TransformedEdgeUpdateOperation } from "../schema";
|
|
2
|
+
import * as clause from "../core/clause";
|
|
3
|
+
import { AssocEdge } from "../core/ent";
|
|
4
|
+
import { Data } from "../core/base";
|
|
5
|
+
export declare class EdgeWithDeletedAt extends AssocEdge {
|
|
6
|
+
deletedAt: Date | null;
|
|
7
|
+
constructor(data: Data);
|
|
8
|
+
}
|
|
9
|
+
export declare const testEdgeGlobalSchema: {
|
|
10
|
+
extraEdgeFields: {
|
|
11
|
+
deletedAt: import("../schema").TimestampField;
|
|
12
|
+
};
|
|
13
|
+
transformEdgeRead(): clause.Clause;
|
|
14
|
+
transformEdgeWrite(stmt: EdgeUpdateOperation): TransformedEdgeUpdateOperation | null;
|
|
15
|
+
};
|