@snowtop/ent 0.1.0-alpha79 → 0.1.0-alpha81

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.1.0-alpha79",
3
+ "version": "0.1.0-alpha81",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/schema/field.d.ts CHANGED
@@ -165,11 +165,16 @@ export declare class IntegerEnumField extends BaseField implements Field {
165
165
  format(val: any): any;
166
166
  }
167
167
  export declare function IntegerEnumType(options: IntegerEnumOptions): IntegerEnumField;
168
+ interface ListOptions extends FieldOptions {
169
+ disableJSONStringify?: boolean;
170
+ }
168
171
  export declare class ListField extends BaseField {
169
172
  private field;
173
+ private options?;
170
174
  type: Type;
171
175
  private validators;
172
- constructor(field: Field, options?: FieldOptions);
176
+ constructor(field: Field, options?: ListOptions | undefined);
177
+ __getElemField(): Field;
173
178
  validate(validator: (val: any[]) => boolean): this;
174
179
  valid(val: any): Promise<boolean>;
175
180
  private postgresVal;
@@ -180,7 +185,7 @@ export declare class ListField extends BaseField {
180
185
  range(start: any, stop: any): this;
181
186
  }
182
187
  export declare function StringListType(options?: StringOptions): ListField;
183
- export declare function IntListType(options: FieldOptions): ListField;
188
+ export declare function IntListType(options?: FieldOptions): ListField;
184
189
  export declare function IntegerListType(options?: FieldOptions): ListField;
185
190
  export declare function FloatListType(options?: FieldOptions): ListField;
186
191
  export declare function BigIntegerListType(options: FieldOptions): ListField;
package/schema/field.js CHANGED
@@ -22,10 +22,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
22
22
  exports.UUIDListType = exports.IntegerEnumListType = exports.EnumListType = exports.DateListType = exports.TimetzListType = exports.TimeListType = exports.TimestamptzListType = exports.TimestampListType = exports.BooleanListType = exports.BigIntegerListType = exports.FloatListType = exports.IntegerListType = exports.IntListType = exports.StringListType = exports.ListField = exports.IntegerEnumType = exports.IntegerEnumField = exports.EnumType = exports.StringEnumField = exports.EnumField = exports.DateType = exports.DateField = exports.TimetzType = exports.TimeType = exports.TimeField = exports.leftPad = exports.TimestamptzType = exports.TimestampType = exports.TimestampField = exports.StringType = exports.StringField = exports.BooleanType = exports.BooleanField = exports.FloatType = exports.FloatField = exports.BigIntegerType = exports.BigIntegerField = exports.IntegerType = exports.IntegerField = exports.UUIDType = exports.UUIDField = exports.BaseField = void 0;
23
23
  const luxon_1 = require("luxon");
24
24
  const snake_case_1 = require("snake-case");
25
- const db_1 = __importStar(require("../core/db"));
26
- const schema_1 = require("./schema");
27
25
  const util_1 = require("util");
28
26
  const uuid_1 = require("uuid");
27
+ const db_1 = __importStar(require("../core/db"));
28
+ const schema_1 = require("./schema");
29
29
  class BaseField {
30
30
  logValue(val) {
31
31
  if (this.sensitive) {
@@ -608,6 +608,7 @@ class ListField extends BaseField {
608
608
  constructor(field, options) {
609
609
  super();
610
610
  this.field = field;
611
+ this.options = options;
611
612
  this.validators = [];
612
613
  if (field.type.dbType === schema_1.DBType.List) {
613
614
  throw new Error(`nested lists not currently supported`);
@@ -618,6 +619,9 @@ class ListField extends BaseField {
618
619
  };
619
620
  Object.assign(this, options);
620
621
  }
622
+ __getElemField() {
623
+ return this.field;
624
+ }
621
625
  validate(validator) {
622
626
  this.validators.push(validator);
623
627
  return this;
@@ -645,11 +649,12 @@ class ListField extends BaseField {
645
649
  return result;
646
650
  }
647
651
  postgresVal(val, jsonType) {
648
- if (!jsonType) {
652
+ if (!jsonType && val === "") {
649
653
  // support empty strings in list
650
- if (val === "") {
651
- val = '"' + val + '"';
652
- }
654
+ val = '"' + val + '"';
655
+ return val;
656
+ }
657
+ if (this.options?.disableJSONStringify) {
653
658
  return val;
654
659
  }
655
660
  return JSON.stringify(val);
@@ -786,6 +791,9 @@ function IntegerEnumListType(options) {
786
791
  }
787
792
  exports.IntegerEnumListType = IntegerEnumListType;
788
793
  function UUIDListType(options) {
789
- return new ListField(UUIDType(options), options);
794
+ return new ListField(UUIDType(options), {
795
+ ...options,
796
+ disableJSONStringify: true,
797
+ });
790
798
  }
791
799
  exports.UUIDListType = UUIDListType;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StructTypeAsList = exports.StructListType = exports.StructType = exports.StructField = void 0;
4
+ const camel_case_1 = require("camel-case");
4
5
  const field_1 = require("./field");
5
6
  const schema_1 = require("./schema");
6
- const camel_case_1 = require("camel-case");
7
7
  class StructField extends field_1.BaseField {
8
8
  constructor(options) {
9
9
  super();
@@ -26,10 +26,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  const glob_1 = __importDefault(require("glob"));
27
27
  const json5_1 = __importDefault(require("json5"));
28
28
  const minimist_1 = __importDefault(require("minimist"));
29
- const graphql_1 = require("../graphql/graphql");
30
- const readline = __importStar(require("readline"));
31
29
  const path = __importStar(require("path"));
32
30
  const fs = __importStar(require("fs"));
31
+ const graphql_1 = require("../graphql/graphql");
32
+ const readline = __importStar(require("readline"));
33
33
  const imports_1 = require("../imports");
34
34
  const process_1 = require("process");
35
35
  // need to use the GQLCapture from the package so that when we call GQLCapture.enable()
@@ -3,12 +3,12 @@ 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
+ const minimist_1 = __importDefault(require("minimist"));
6
7
  const transform_1 = require("../tsc/transform");
7
8
  const transform_schema_1 = require("../tsc/transform_schema");
8
9
  const transform_ent_1 = require("../tsc/transform_ent");
9
10
  const move_generated_1 = require("../tsc/move_generated");
10
11
  const transform_action_1 = require("../tsc/transform_action");
11
- const minimist_1 = __importDefault(require("minimist"));
12
12
  const ast_1 = require("../tsc/ast");
13
13
  // todo-sqlite
14
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
@@ -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
+ }