@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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.1.0-alpha78",
3
+ "version": "0.1.0-alpha80",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
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: FieldOptions): ListField;
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
@@ -618,6 +618,9 @@ class ListField extends BaseField {
618
618
  };
619
619
  Object.assign(this, options);
620
620
  }
621
+ __getElemField() {
622
+ return this.field;
623
+ }
621
624
  validate(validator) {
622
625
  this.validators.push(validator);
623
626
  return this;
@@ -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,6 @@
1
+ import { Field, Schema } from "../../schema";
2
+ interface Info {
3
+ schema: Schema;
4
+ }
5
+ export declare function getDefaultValue(f: Field, col: string, infos?: Map<string, Info>): any;
6
+ export {};
@@ -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,4 @@
1
+ export declare class DBTimeZone {
2
+ private static getVal;
3
+ static getDateOffset(d: Date): Promise<string>;
4
+ }
@@ -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;