@snowtop/ent 0.1.0-alpha78 → 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/core/clause.js +14 -2
- package/package.json +1 -1
- package/schema/field.d.ts +2 -1
- package/schema/field.js +3 -0
- package/testutils/db/fixture.d.ts +10 -0
- package/testutils/db/fixture.js +26 -0
- 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/core/clause.js
CHANGED
|
@@ -184,9 +184,9 @@ class postgresArrayOperator {
|
|
|
184
184
|
}
|
|
185
185
|
logValues() {
|
|
186
186
|
if (isSensitive(this.value)) {
|
|
187
|
-
return [this.value.logValue()];
|
|
187
|
+
return [`{${this.value.logValue()}}`];
|
|
188
188
|
}
|
|
189
|
-
return [this.value];
|
|
189
|
+
return [`{${this.value}}`];
|
|
190
190
|
}
|
|
191
191
|
instanceKey() {
|
|
192
192
|
if (this.not) {
|
|
@@ -211,6 +211,18 @@ class postgresArrayOperatorList extends postgresArrayOperator {
|
|
|
211
211
|
.join(", ")}}`,
|
|
212
212
|
];
|
|
213
213
|
}
|
|
214
|
+
logValues() {
|
|
215
|
+
return [
|
|
216
|
+
`{${this.value
|
|
217
|
+
.map((v) => {
|
|
218
|
+
if (isSensitive(v)) {
|
|
219
|
+
return v.logValue();
|
|
220
|
+
}
|
|
221
|
+
return v;
|
|
222
|
+
})
|
|
223
|
+
.join(", ")}}`,
|
|
224
|
+
];
|
|
225
|
+
}
|
|
214
226
|
}
|
|
215
227
|
class inClause {
|
|
216
228
|
constructor(col, value, type = "uuid") {
|
package/package.json
CHANGED
package/schema/field.d.ts
CHANGED
|
@@ -170,6 +170,7 @@ export declare class ListField extends BaseField {
|
|
|
170
170
|
type: Type;
|
|
171
171
|
private validators;
|
|
172
172
|
constructor(field: Field, options?: FieldOptions);
|
|
173
|
+
__getElemField(): Field;
|
|
173
174
|
validate(validator: (val: any[]) => boolean): this;
|
|
174
175
|
valid(val: any): Promise<boolean>;
|
|
175
176
|
private postgresVal;
|
|
@@ -180,7 +181,7 @@ export declare class ListField extends BaseField {
|
|
|
180
181
|
range(start: any, stop: any): this;
|
|
181
182
|
}
|
|
182
183
|
export declare function StringListType(options?: StringOptions): ListField;
|
|
183
|
-
export declare function IntListType(options
|
|
184
|
+
export declare function IntListType(options?: FieldOptions): ListField;
|
|
184
185
|
export declare function IntegerListType(options?: FieldOptions): ListField;
|
|
185
186
|
export declare function FloatListType(options?: FieldOptions): ListField;
|
|
186
187
|
export declare function BigIntegerListType(options: FieldOptions): ListField;
|
package/schema/field.js
CHANGED
|
@@ -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;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultValue = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const schema_1 = require("../../schema");
|
|
6
|
+
const schema_2 = require("../../schema");
|
|
7
|
+
function random() {
|
|
8
|
+
return Math.random().toString(16).substring(2);
|
|
9
|
+
}
|
|
10
|
+
function randomEmail(domain) {
|
|
11
|
+
domain = domain || "email.com";
|
|
12
|
+
return `test+${random()}@${domain}`;
|
|
13
|
+
}
|
|
14
|
+
function randomPhoneNumber() {
|
|
15
|
+
return `+1${Math.random().toString(10).substring(2, 11)}`;
|
|
16
|
+
}
|
|
17
|
+
function coinFlip() {
|
|
18
|
+
return Math.floor(Math.random() * 10) >= 5;
|
|
19
|
+
}
|
|
20
|
+
function specialType(typ, col) {
|
|
21
|
+
let list = m.get(typ.dbType);
|
|
22
|
+
if (list?.length) {
|
|
23
|
+
for (const l of list) {
|
|
24
|
+
let regex = [];
|
|
25
|
+
if (Array.isArray(l.regex)) {
|
|
26
|
+
regex = l.regex;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
regex = [l.regex];
|
|
30
|
+
}
|
|
31
|
+
for (const r of regex) {
|
|
32
|
+
if (r.test(col)) {
|
|
33
|
+
return l.newValue();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
function getDefaultValue(f, col, infos) {
|
|
41
|
+
if (f.defaultValueOnCreate) {
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
return f.defaultValueOnCreate();
|
|
44
|
+
}
|
|
45
|
+
// half the time, return null for nullable
|
|
46
|
+
if (f.nullable && coinFlip()) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const specialVal = specialType(f.type, col);
|
|
50
|
+
if (specialVal !== undefined) {
|
|
51
|
+
return specialVal;
|
|
52
|
+
}
|
|
53
|
+
return getValueForType(f.type, f, infos);
|
|
54
|
+
}
|
|
55
|
+
exports.getDefaultValue = getDefaultValue;
|
|
56
|
+
function getValueForType(typ, f, infos) {
|
|
57
|
+
switch (typ.dbType) {
|
|
58
|
+
case schema_1.DBType.UUID:
|
|
59
|
+
return (0, uuid_1.v4)();
|
|
60
|
+
case schema_1.DBType.Boolean:
|
|
61
|
+
return coinFlip();
|
|
62
|
+
case schema_1.DBType.Date:
|
|
63
|
+
return (0, schema_2.DateType)().format(new Date());
|
|
64
|
+
case schema_1.DBType.Time:
|
|
65
|
+
return (0, schema_2.TimeType)().format(new Date());
|
|
66
|
+
case schema_1.DBType.Timetz:
|
|
67
|
+
return (0, schema_2.TimetzType)().format(new Date());
|
|
68
|
+
case schema_1.DBType.Timestamp:
|
|
69
|
+
return (0, schema_2.TimestampType)().format(new Date());
|
|
70
|
+
case schema_1.DBType.Timestamptz:
|
|
71
|
+
return (0, schema_2.TimestamptzType)().format(new Date());
|
|
72
|
+
case schema_1.DBType.String:
|
|
73
|
+
return random();
|
|
74
|
+
case schema_1.DBType.Int:
|
|
75
|
+
return Math.floor(Math.random() * 100000000);
|
|
76
|
+
case schema_1.DBType.Float:
|
|
77
|
+
return Math.random() * 100000000;
|
|
78
|
+
case schema_1.DBType.Enum:
|
|
79
|
+
case schema_1.DBType.StringEnum:
|
|
80
|
+
if (typ.values) {
|
|
81
|
+
const idx = Math.floor(Math.random() * typ.values.length);
|
|
82
|
+
return typ.values[idx];
|
|
83
|
+
}
|
|
84
|
+
if (typ.enumMap) {
|
|
85
|
+
const vals = Object.values(typ.enumMap);
|
|
86
|
+
const idx = Math.floor(Math.random() * vals.length);
|
|
87
|
+
return vals[idx];
|
|
88
|
+
}
|
|
89
|
+
if (f.foreignKey) {
|
|
90
|
+
const schema = f.foreignKey.schema;
|
|
91
|
+
const col = f.foreignKey.column;
|
|
92
|
+
if (!infos) {
|
|
93
|
+
throw new Error(`infos required for enum with foreignKey`);
|
|
94
|
+
}
|
|
95
|
+
const info = infos.get(schema);
|
|
96
|
+
if (!info) {
|
|
97
|
+
throw new Error(`couldn't load data for schema ${schema}`);
|
|
98
|
+
}
|
|
99
|
+
if (!info.schema.dbRows) {
|
|
100
|
+
throw new Error(`no dbRows for schema ${schema}`);
|
|
101
|
+
}
|
|
102
|
+
const idx = Math.floor(Math.random() * info.schema.dbRows.length);
|
|
103
|
+
return info.schema.dbRows[idx][col];
|
|
104
|
+
}
|
|
105
|
+
throw new Error("TODO: enum without values not currently supported");
|
|
106
|
+
case schema_1.DBType.IntEnum:
|
|
107
|
+
const vals = Object.values(typ.intEnumMap);
|
|
108
|
+
const idx = Math.floor(Math.random() * vals.length);
|
|
109
|
+
return vals[idx];
|
|
110
|
+
case schema_1.DBType.BigInt:
|
|
111
|
+
return BigInt(Math.floor(Math.random() * 100000000));
|
|
112
|
+
case schema_1.DBType.JSONB:
|
|
113
|
+
// type as list
|
|
114
|
+
if (typ.listElemType?.dbType === schema_1.DBType.JSONB) {
|
|
115
|
+
const values = [];
|
|
116
|
+
for (let i = 0; i < 10; i++) {
|
|
117
|
+
values.push(getValueForType(typ.listElemType, f, infos));
|
|
118
|
+
}
|
|
119
|
+
if (!f.format) {
|
|
120
|
+
throw new Error("invalid format");
|
|
121
|
+
}
|
|
122
|
+
return f.format(values);
|
|
123
|
+
}
|
|
124
|
+
return (0, schema_2.JSONBType)().format({});
|
|
125
|
+
case schema_1.DBType.JSON:
|
|
126
|
+
return (0, schema_2.JSONType)().format({});
|
|
127
|
+
case schema_1.DBType.List:
|
|
128
|
+
// just do 10
|
|
129
|
+
const values = [];
|
|
130
|
+
for (let i = 0; i < 10; i++) {
|
|
131
|
+
values.push(getValueForType(f.type.listElemType, f.__getElemField(), infos));
|
|
132
|
+
}
|
|
133
|
+
if (!f.format) {
|
|
134
|
+
throw new Error("invalid format");
|
|
135
|
+
}
|
|
136
|
+
return f.format(values);
|
|
137
|
+
default:
|
|
138
|
+
throw new Error(`unsupported type ${typ.dbType}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const emailType = {
|
|
142
|
+
dbType: schema_1.DBType.String,
|
|
143
|
+
newValue: () => {
|
|
144
|
+
return (0, schema_2.StringType)().format(randomEmail().toLowerCase());
|
|
145
|
+
},
|
|
146
|
+
regex: /^email(_address)|_email$/,
|
|
147
|
+
};
|
|
148
|
+
const pdt = (0, schema_2.StringType)();
|
|
149
|
+
const phoneType = {
|
|
150
|
+
dbType: schema_1.DBType.String,
|
|
151
|
+
newValue: () => {
|
|
152
|
+
return randomPhoneNumber();
|
|
153
|
+
},
|
|
154
|
+
regex: /^phone(_number)?|_phone$|_phone_number$/,
|
|
155
|
+
};
|
|
156
|
+
const passwordType = {
|
|
157
|
+
dbType: schema_1.DBType.String,
|
|
158
|
+
newValue: () => {
|
|
159
|
+
// we don't use password type because when we're generating so many rows, it's too slow...
|
|
160
|
+
return random();
|
|
161
|
+
},
|
|
162
|
+
regex: /^password/,
|
|
163
|
+
};
|
|
164
|
+
const firstNames = [
|
|
165
|
+
"Daenerys",
|
|
166
|
+
"Jon",
|
|
167
|
+
"Arya",
|
|
168
|
+
"Sansa",
|
|
169
|
+
"Eddard",
|
|
170
|
+
"Khal",
|
|
171
|
+
"Robb",
|
|
172
|
+
"Joffrey",
|
|
173
|
+
"Ramsay",
|
|
174
|
+
"Cersei",
|
|
175
|
+
"Bolton",
|
|
176
|
+
"Oberyn",
|
|
177
|
+
"Jojen",
|
|
178
|
+
"Petyr",
|
|
179
|
+
"Brienne",
|
|
180
|
+
"Ygritte",
|
|
181
|
+
"Missandei",
|
|
182
|
+
"Shae",
|
|
183
|
+
"Sandor",
|
|
184
|
+
"Theon",
|
|
185
|
+
"Catelyn",
|
|
186
|
+
"Gilly",
|
|
187
|
+
"Samwell",
|
|
188
|
+
"Jaime",
|
|
189
|
+
"Stannis",
|
|
190
|
+
"Tyene",
|
|
191
|
+
"Obara",
|
|
192
|
+
"Nymeria",
|
|
193
|
+
"Elia",
|
|
194
|
+
"Ellaria",
|
|
195
|
+
"Myrcella",
|
|
196
|
+
"Hodor",
|
|
197
|
+
"Osha",
|
|
198
|
+
"Meera",
|
|
199
|
+
"Davos",
|
|
200
|
+
"Gendry",
|
|
201
|
+
];
|
|
202
|
+
const lastNames = [
|
|
203
|
+
"Stark",
|
|
204
|
+
"Targaryen",
|
|
205
|
+
"Lannister",
|
|
206
|
+
"Drogo",
|
|
207
|
+
"Baratheon",
|
|
208
|
+
"Reed",
|
|
209
|
+
"Martell",
|
|
210
|
+
"Tyrell",
|
|
211
|
+
"Clegane",
|
|
212
|
+
"Baelish",
|
|
213
|
+
"Greyjoy",
|
|
214
|
+
"Tarly",
|
|
215
|
+
"Sand",
|
|
216
|
+
"Snow",
|
|
217
|
+
"Bolton",
|
|
218
|
+
"Frey",
|
|
219
|
+
"Tarth",
|
|
220
|
+
"Payne",
|
|
221
|
+
"Seaworth",
|
|
222
|
+
];
|
|
223
|
+
const firstNameType = {
|
|
224
|
+
dbType: schema_1.DBType.String,
|
|
225
|
+
newValue: () => {
|
|
226
|
+
let idx = Math.floor(firstNames.length * Math.random());
|
|
227
|
+
return firstNames[idx];
|
|
228
|
+
},
|
|
229
|
+
regex: /^first_?(name)?/,
|
|
230
|
+
};
|
|
231
|
+
const lastNameType = {
|
|
232
|
+
dbType: schema_1.DBType.String,
|
|
233
|
+
newValue: () => {
|
|
234
|
+
let idx = Math.floor(lastNames.length * Math.random());
|
|
235
|
+
return lastNames[idx];
|
|
236
|
+
},
|
|
237
|
+
regex: /^last_?(name)?/,
|
|
238
|
+
};
|
|
239
|
+
let types = [
|
|
240
|
+
phoneType,
|
|
241
|
+
emailType,
|
|
242
|
+
passwordType,
|
|
243
|
+
firstNameType,
|
|
244
|
+
lastNameType,
|
|
245
|
+
];
|
|
246
|
+
let m = new Map();
|
|
247
|
+
for (const type of types) {
|
|
248
|
+
let list = m.get(type.dbType) || [];
|
|
249
|
+
list.push(type);
|
|
250
|
+
m.set(type.dbType, list);
|
|
251
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
exports.DBTimeZone = void 0;
|
|
7
|
+
const luxon_1 = require("luxon");
|
|
8
|
+
const schema_1 = require("../schema");
|
|
9
|
+
const db_1 = __importDefault(require("../core/db"));
|
|
10
|
+
let dbCurrentZone = undefined;
|
|
11
|
+
class DBTimeZone {
|
|
12
|
+
static async getVal() {
|
|
13
|
+
if (dbCurrentZone !== undefined) {
|
|
14
|
+
return dbCurrentZone;
|
|
15
|
+
}
|
|
16
|
+
const r = await db_1.default.getInstance()
|
|
17
|
+
.getPool()
|
|
18
|
+
.query("SELECT current_setting('TIMEZONE');");
|
|
19
|
+
if (r.rows.length) {
|
|
20
|
+
dbCurrentZone = r.rows[0].current_setting;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
dbCurrentZone = null;
|
|
24
|
+
}
|
|
25
|
+
return dbCurrentZone;
|
|
26
|
+
}
|
|
27
|
+
static async getDateOffset(d) {
|
|
28
|
+
let zone = await DBTimeZone.getVal();
|
|
29
|
+
let dt = luxon_1.DateTime.fromJSDate(d);
|
|
30
|
+
if (zone) {
|
|
31
|
+
dt = dt.setZone(zone);
|
|
32
|
+
}
|
|
33
|
+
// use
|
|
34
|
+
const val = (0, schema_1.leftPad)(dt.get("offset") / 60);
|
|
35
|
+
if (val == "00") {
|
|
36
|
+
return "+00";
|
|
37
|
+
}
|
|
38
|
+
return val;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.DBTimeZone = DBTimeZone;
|