orchid-orm 1.5.29 → 1.5.31

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.
Files changed (59) hide show
  1. package/dist/index.d.ts +6 -14
  2. package/dist/index.js +26 -21
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +26 -21
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +12 -22
  7. package/.env.example +0 -1
  8. package/.turbo/turbo-check.log +0 -26
  9. package/.turbo/turbo-test.log +0 -26
  10. package/.turbo/turbo-test:ci.log +0 -26
  11. package/CHANGELOG.md +0 -382
  12. package/coverage/coverage-summary.json +0 -28
  13. package/jest-setup.ts +0 -11
  14. package/rollup.config.js +0 -18
  15. package/src/bin/bin.ts +0 -3
  16. package/src/bin/init.test.ts +0 -810
  17. package/src/bin/init.ts +0 -529
  18. package/src/codegen/appCodeUpdater.test.ts +0 -75
  19. package/src/codegen/appCodeUpdater.ts +0 -53
  20. package/src/codegen/createBaseTableFile.test.ts +0 -53
  21. package/src/codegen/createBaseTableFile.ts +0 -31
  22. package/src/codegen/fileChanges.ts +0 -41
  23. package/src/codegen/testUtils.ts +0 -56
  24. package/src/codegen/tsUtils.ts +0 -180
  25. package/src/codegen/updateMainFile.test.ts +0 -253
  26. package/src/codegen/updateMainFile.ts +0 -210
  27. package/src/codegen/updateTableFile/changeTable.test.ts +0 -804
  28. package/src/codegen/updateTableFile/changeTable.ts +0 -536
  29. package/src/codegen/updateTableFile/createTable.test.ts +0 -139
  30. package/src/codegen/updateTableFile/createTable.ts +0 -51
  31. package/src/codegen/updateTableFile/renameTable.test.ts +0 -124
  32. package/src/codegen/updateTableFile/renameTable.ts +0 -67
  33. package/src/codegen/updateTableFile/updateTableFile.ts +0 -22
  34. package/src/codegen/utils.ts +0 -13
  35. package/src/index.ts +0 -5
  36. package/src/orm.test.ts +0 -92
  37. package/src/orm.ts +0 -98
  38. package/src/relations/belongsTo.test.ts +0 -1122
  39. package/src/relations/belongsTo.ts +0 -352
  40. package/src/relations/hasAndBelongsToMany.test.ts +0 -1335
  41. package/src/relations/hasAndBelongsToMany.ts +0 -472
  42. package/src/relations/hasMany.test.ts +0 -2616
  43. package/src/relations/hasMany.ts +0 -401
  44. package/src/relations/hasOne.test.ts +0 -1701
  45. package/src/relations/hasOne.ts +0 -351
  46. package/src/relations/relations.test.ts +0 -37
  47. package/src/relations/relations.ts +0 -363
  48. package/src/relations/utils.ts +0 -162
  49. package/src/repo.test.ts +0 -200
  50. package/src/repo.ts +0 -119
  51. package/src/table.test.ts +0 -121
  52. package/src/table.ts +0 -184
  53. package/src/test-utils/test-db.ts +0 -32
  54. package/src/test-utils/test-tables.ts +0 -194
  55. package/src/test-utils/test-utils.ts +0 -119
  56. package/src/transaction.test.ts +0 -47
  57. package/src/transaction.ts +0 -27
  58. package/src/utils.ts +0 -9
  59. package/tsconfig.json +0 -14
@@ -1,536 +0,0 @@
1
- import { RakeDbAst } from 'rake-db';
2
- import fs from 'fs/promises';
3
- import { FileChanges } from '../fileChanges';
4
- import { ts } from '../tsUtils';
5
- import { toPascalCase } from '../../utils';
6
- import {
7
- CallExpression,
8
- Expression,
9
- NodeArray,
10
- ObjectLiteralElementLike,
11
- ObjectLiteralExpression,
12
- PropertyAssignment,
13
- Statement,
14
- } from 'typescript';
15
- import {
16
- addCode,
17
- Code,
18
- codeToString,
19
- columnDefaultArgumentToCode,
20
- columnForeignKeysToCode,
21
- columnIndexesToCode,
22
- ColumnType,
23
- ForeignKey,
24
- foreignKeyToCode,
25
- IndexColumnOptions,
26
- indexToCode,
27
- primaryKeyToCode,
28
- quoteObjectKey,
29
- singleQuote,
30
- TableData,
31
- } from 'pqb';
32
- import { UpdateTableFileParams } from './updateTableFile';
33
-
34
- export const changeTable = async ({
35
- ast,
36
- ...params
37
- }: UpdateTableFileParams & { ast: RakeDbAst.ChangeTable }) => {
38
- const tablePath = params.tablePath(ast.name);
39
- const content = await fs.readFile(tablePath, 'utf-8').catch(() => undefined);
40
- if (!content) return;
41
-
42
- const changes = new FileChanges(content);
43
- const statements = ts.getStatements(content);
44
- const className = toPascalCase(ast.name) + 'Table';
45
-
46
- for (const { t, object } of iterateColumnsShapes(statements, className)) {
47
- const context = makeChangeContext(changes, ast, content, object, t);
48
-
49
- prependSpaces(context);
50
- applySchemaChanges(context);
51
- appendTrailingComma(context);
52
- addColumns(context);
53
- addTableData(context);
54
- }
55
-
56
- await fs.writeFile(tablePath, changes.apply());
57
- };
58
-
59
- function* iterateColumnsShapes(
60
- statements: NodeArray<Statement>,
61
- className: string,
62
- ) {
63
- for (const node of ts.class.iterate(statements)) {
64
- if (node.name?.escapedText !== className) continue;
65
-
66
- for (const member of node.members) {
67
- const name = ts.prop.getName(member);
68
- const { initializer: call } = member as unknown as {
69
- initializer?: Expression;
70
- };
71
-
72
- if (name !== 'columns' || !call || !ts.is.call(call)) continue;
73
-
74
- const { expression } = call;
75
- if (
76
- !ts.is.propertyAccess(expression) ||
77
- !ts.is.this(expression.expression) ||
78
- expression.name.escapedText !== 'setColumns'
79
- )
80
- continue;
81
-
82
- const [arg] = call.arguments;
83
- if (!ts.is.arrowFunction(arg)) continue;
84
-
85
- const { parameters, body } = arg;
86
- const param = parameters[0]?.name;
87
- if (!ts.is.identifier(param) || !ts.is.parenthesizedExpression(body))
88
- continue;
89
-
90
- const { expression: object } = body;
91
- if (!ts.is.objectLiteral(object)) continue;
92
-
93
- yield { t: param.escapedText.toString(), object };
94
- }
95
- }
96
- }
97
-
98
- type ChangeContext = {
99
- changes: FileChanges;
100
- props: NodeArray<ObjectLiteralElementLike>;
101
- shape: {
102
- add: Record<string, ColumnType>;
103
- drop: Record<string, true>;
104
- change: Record<string, RakeDbAst.ChangeTableItem.Change>;
105
- };
106
- t: string;
107
- spaces: string;
108
- object: Expression;
109
- drop: TableData;
110
- add: TableData;
111
- };
112
-
113
- const makeChangeContext = (
114
- changes: FileChanges,
115
- ast: RakeDbAst.ChangeTable,
116
- content: string,
117
- object: ObjectLiteralExpression,
118
- t: string,
119
- ): ChangeContext => {
120
- const add: ChangeContext['shape']['add'] = {};
121
- const drop: ChangeContext['shape']['drop'] = {};
122
- const change: ChangeContext['shape']['change'] = {};
123
-
124
- const { properties: props } = object;
125
- const existingColumns = getExistingColumns(props);
126
-
127
- for (const key in ast.shape) {
128
- const item = ast.shape[key];
129
- if (item.type === 'add' && !existingColumns[key]) {
130
- add[key] = item.item;
131
- }
132
-
133
- if (!existingColumns[key]) continue;
134
-
135
- if (item.type === 'drop' && existingColumns[key]) {
136
- drop[key] = true;
137
- } else if (item.type === 'change' && existingColumns[key]) {
138
- change[key] = item;
139
- }
140
- }
141
-
142
- const spaces = ts.spaces.getAtLine(content, object.end);
143
-
144
- const shape = { add, drop, change };
145
- return {
146
- changes,
147
- props,
148
- shape,
149
- spaces,
150
- t,
151
- object,
152
- add: ast.add,
153
- drop: ast.drop,
154
- };
155
- };
156
-
157
- const getExistingColumns = (props: NodeArray<ObjectLiteralElementLike>) => {
158
- const existingColumns: Record<string, true> = {};
159
- props
160
- .map((prop) => ts.is.propertyAssignment(prop) && ts.prop.getName(prop))
161
- .filter((name): name is string => !!name)
162
- .forEach((name) => (existingColumns[name] = true));
163
-
164
- for (const prop of props) {
165
- if (!ts.is.propertyAssignment(prop)) continue;
166
- const name = ts.prop.getName(prop);
167
- if (name) existingColumns[name] = true;
168
- }
169
-
170
- return existingColumns;
171
- };
172
-
173
- const prependSpaces = ({
174
- props,
175
- shape: { add },
176
- changes,
177
- spaces,
178
- }: ChangeContext) => {
179
- if (Object.keys(add).length && props.pos === props.end) {
180
- changes.add(props.pos, `\n${spaces}`);
181
- }
182
- };
183
-
184
- const applySchemaChanges = (context: ChangeContext) => {
185
- const {
186
- props,
187
- shape: { drop: dropColumns, change: changeColumns },
188
- add,
189
- drop,
190
- } = context;
191
-
192
- props.forEach((prop, i) => {
193
- if (ts.is.spreadAssignment(prop)) {
194
- const call = prop.expression;
195
- if (!ts.is.call(call)) return;
196
-
197
- const access = call.expression;
198
- if (!ts.is.propertyAccess(access)) return;
199
-
200
- const name = access.name.escapedText.toString();
201
- if (name === 'primaryKey') {
202
- if (drop.primaryKey || add.primaryKey) {
203
- removeProp(context, prop, i);
204
- }
205
- } else if (name === 'index') {
206
- dropMatchingIndexes(context, prop, i, call, drop.indexes);
207
- } else if (name === 'foreignKey') {
208
- dropMatchingForeignKey(context, prop, i, call, drop.foreignKeys);
209
- }
210
- } else if (ts.is.propertyAssignment(prop)) {
211
- const name = ts.prop.getName(prop);
212
- if (!name) return;
213
-
214
- if (dropColumns[name]) {
215
- removeProp(context, prop, i);
216
- } else {
217
- const changeItem = changeColumns[name];
218
- if (changeItem) {
219
- changeColumn(context, changeItem, prop);
220
- }
221
- }
222
- }
223
- });
224
- };
225
-
226
- const removeProp = (
227
- { props, changes }: ChangeContext,
228
- prop: ObjectLiteralElementLike,
229
- i: number,
230
- ) => {
231
- const end = props[i + 1]?.pos || props.end;
232
- changes.remove(prop.pos, end);
233
- };
234
-
235
- const changeColumn = (
236
- { changes, t, spaces }: ChangeContext,
237
- changeItem: RakeDbAst.ChangeTableItem.Change,
238
- prop: PropertyAssignment,
239
- ) => {
240
- const { from, to } = changeItem;
241
- if (from.type !== to.type && to.column) {
242
- changes.replace(
243
- prop.initializer.pos,
244
- prop.end,
245
- ` ${codeToString(to.column.toCode(t), spaces + ' ', ' ').trim()}`,
246
- );
247
- return;
248
- }
249
-
250
- const items: CallExpression[] = [];
251
- let chain: Expression | undefined = prop.initializer;
252
- while (ts.is.call(chain) && ts.is.propertyAccess(chain.expression)) {
253
- items.push(chain);
254
- chain = chain.expression.expression;
255
- }
256
-
257
- type Key = keyof RakeDbAst.ChangeTableItem.Change['to'];
258
- const propsToChange: Partial<Record<Key, true>> = {};
259
-
260
- for (const key in from) {
261
- if (to[key as Key] !== from[key as Key]) {
262
- propsToChange[key as Key] = true;
263
- }
264
- }
265
-
266
- for (const key in to) {
267
- if (to[key as Key] !== from[key as Key]) {
268
- propsToChange[key as Key] = true;
269
- }
270
- }
271
-
272
- const changedProps: Partial<Record<Key, true>> = {};
273
- const replaced: Record<string, true> = {};
274
- for (const item of items.reverse()) {
275
- if (!ts.is.propertyAccess(item.expression)) continue;
276
-
277
- const { name } = item.expression;
278
- let key = name.escapedText.toString();
279
- if (key === 'index') key = 'indexes';
280
- else if (key === 'foreignKey') key = 'foreignKeys';
281
-
282
- if (!propsToChange[key as Key]) continue;
283
-
284
- let remove = true;
285
- if (!replaced[key]) {
286
- const code = getColumnMethodArgs(to, key as Key);
287
- if (code) {
288
- changes.replace(
289
- item.expression.expression.end,
290
- item.end,
291
- codeToString(code, spaces + ' ', ' ').trim(),
292
- );
293
- replaced[key] = true;
294
- remove = false;
295
- }
296
- }
297
-
298
- if (remove) {
299
- changes.remove(item.expression.expression.end, item.end);
300
- }
301
-
302
- changedProps[key as Key] = true;
303
- }
304
-
305
- let append = '';
306
- for (const key in propsToChange) {
307
- if (changedProps[key as Key]) continue;
308
-
309
- const code = getColumnMethodArgs(to, key as Key);
310
- if (code) {
311
- append += codeToString(code, spaces + ' ', ' ').trim();
312
- }
313
- }
314
-
315
- if (append) {
316
- changes.add(prop.end, append);
317
- }
318
- };
319
-
320
- const appendTrailingComma = ({ props, changes }: ChangeContext) => {
321
- if (!props.hasTrailingComma) {
322
- const last = props[props.length - 1];
323
- if (last) {
324
- changes.add(last.end, ',');
325
- }
326
- }
327
- };
328
-
329
- const addColumns = ({
330
- shape: { add },
331
- changes,
332
- object,
333
- t,
334
- spaces,
335
- }: ChangeContext) => {
336
- const end = object.end - 1;
337
- for (const key in add) {
338
- const code = codeToString(add[key].toCode(t), spaces + ' ', ' ');
339
- changes.add(end, ` ${quoteObjectKey(key)}: ${code.trim()},\n${spaces}`);
340
- }
341
- };
342
-
343
- const addTableData = ({ add, changes, object, t, spaces }: ChangeContext) => {
344
- const end = object.end - 1;
345
- if (add.primaryKey) {
346
- const code = codeToString(
347
- primaryKeyToCode(add.primaryKey, t),
348
- spaces,
349
- ' ',
350
- );
351
- changes.add(end, ` ${code.trim()}\n${spaces}`);
352
- }
353
- for (const item of add.indexes) {
354
- const code = codeToString(indexToCode(item, t), spaces + ' ', ' ');
355
- changes.add(end, ` ${code.trim()}\n${spaces}`);
356
- }
357
- for (const item of add.foreignKeys) {
358
- const code = codeToString(foreignKeyToCode(item, t), spaces + ' ', ' ');
359
- changes.add(end, ` ${code.trim()}\n${spaces}`);
360
- }
361
- };
362
-
363
- const getColumnMethodArgs = (
364
- to: RakeDbAst.ChangeTableItem.Change['to'],
365
- key: keyof RakeDbAst.ChangeTableItem.Change['to'],
366
- ): Code[] | undefined => {
367
- const value = to[key];
368
- if (!value) return;
369
-
370
- if (key === 'indexes') {
371
- return columnIndexesToCode(value as IndexColumnOptions[]);
372
- }
373
-
374
- if (key === 'foreignKeys') {
375
- return columnForeignKeysToCode(value as ForeignKey<string, string[]>[]);
376
- }
377
-
378
- const code = [`.${key}(`];
379
-
380
- if (key === 'collate' || key === 'compression') {
381
- addCode(code, singleQuote(value as string));
382
- } else if (key === 'default') {
383
- addCode(code, columnDefaultArgumentToCode(value));
384
- } else if (key !== 'nullable' && key !== 'primaryKey') {
385
- return;
386
- }
387
-
388
- addCode(code, ')');
389
- return code;
390
- };
391
-
392
- const dropMatchingIndexes = (
393
- context: ChangeContext,
394
- prop: ObjectLiteralElementLike,
395
- i: number,
396
- call: CallExpression,
397
- items: TableData.Index[],
398
- ) => {
399
- if (!items.length) return;
400
-
401
- const [columnsNode, optionsNode] = call.arguments;
402
- const columns: Record<string, string | number>[] = [];
403
- if (ts.is.stringLiteral(columnsNode)) {
404
- columns.push({ column: columnsNode.text });
405
- } else if (ts.is.arrayLiteral(columnsNode)) {
406
- for (const node of columnsNode.elements) {
407
- if (ts.is.stringLiteral(node)) {
408
- columns.push({ column: node.text });
409
- } else if (ts.is.objectLiteral(node)) {
410
- const object = collectObjectFromCode(node);
411
- if (!object) return;
412
- columns.push(object);
413
- }
414
- }
415
- } else {
416
- return;
417
- }
418
-
419
- const options =
420
- (ts.is.objectLiteral(optionsNode) && collectObjectFromCode(optionsNode)) ||
421
- {};
422
-
423
- for (const item of items) {
424
- if (
425
- deepCompare(columns, item.columns) &&
426
- deepCompare(options, item.options)
427
- ) {
428
- removeProp(context, prop, i);
429
- }
430
- }
431
- };
432
-
433
- const dropMatchingForeignKey = (
434
- context: ChangeContext,
435
- prop: ObjectLiteralElementLike,
436
- i: number,
437
- call: CallExpression,
438
- items: TableData.ForeignKey[],
439
- ) => {
440
- if (!items.length) return;
441
-
442
- const { arguments: args } = call;
443
-
444
- const columns = collectStringArrayFromCode(args[0]);
445
- if (!columns) return;
446
-
447
- const fnOrTableNode = args[1];
448
- let fnOrTable: string;
449
- if (ts.is.stringLiteral(fnOrTableNode)) {
450
- fnOrTable = fnOrTableNode.text;
451
- } else if (ts.is.arrowFunction(fnOrTableNode)) {
452
- fnOrTable = context.changes.content
453
- .slice(fnOrTableNode.pos, fnOrTableNode.end)
454
- .replaceAll(/\s/g, '');
455
- } else {
456
- return;
457
- }
458
-
459
- const foreignColumns = collectStringArrayFromCode(args[2]);
460
- if (!foreignColumns) return;
461
-
462
- const options =
463
- (ts.is.objectLiteral(args[3]) && collectObjectFromCode(args[3])) || {};
464
-
465
- for (const item of items) {
466
- const itemOptions = item.options;
467
- delete itemOptions.dropMode;
468
-
469
- if (
470
- deepCompare(columns, item.columns) &&
471
- deepCompare(fnOrTable, item.fnOrTable.toString()) &&
472
- deepCompare(foreignColumns, item.foreignColumns) &&
473
- deepCompare(options, itemOptions)
474
- ) {
475
- removeProp(context, prop, i);
476
- }
477
- }
478
- };
479
-
480
- const collectStringArrayFromCode = (node: Expression) => {
481
- if (!ts.is.arrayLiteral(node)) return;
482
-
483
- const result = node.elements
484
- .filter(ts.is.stringLiteral)
485
- .map((item) => item.text);
486
-
487
- return result.length === node.elements.length ? result : undefined;
488
- };
489
-
490
- const collectObjectFromCode = (node: ObjectLiteralExpression) => {
491
- const object: Record<string, string | number> = {};
492
- for (const prop of node.properties) {
493
- if (!ts.is.propertyAssignment(prop)) return;
494
- const name = ts.prop.getName(prop);
495
- if (!name) return;
496
-
497
- const init = prop.initializer;
498
- if (ts.is.stringLiteral(init)) {
499
- object[name] = init.text;
500
- } else if (ts.is.numericLiteral(init)) {
501
- object[name] = parseFloat(init.text);
502
- } else {
503
- return;
504
- }
505
- }
506
- return object;
507
- };
508
-
509
- const deepCompare = (a: unknown, b: unknown): boolean => {
510
- if (typeof a !== typeof b) return false;
511
- if (a === b) return true;
512
- if (typeof a === 'object') {
513
- if (a === null) return b === null;
514
-
515
- if (Array.isArray(a)) {
516
- if (!Array.isArray(b) || a.length !== b.length) return false;
517
-
518
- return a.every((item, i) => deepCompare(item, b[i]));
519
- }
520
-
521
- for (const key in a) {
522
- if (
523
- !deepCompare(
524
- (a as Record<string, unknown>)[key],
525
- (b as Record<string, unknown>)[key],
526
- )
527
- )
528
- return false;
529
- }
530
-
531
- for (const key in b as Record<string, unknown>) {
532
- if (!(key in a)) return false;
533
- }
534
- }
535
- return true;
536
- };
@@ -1,139 +0,0 @@
1
- import { updateTableFile } from './updateTableFile';
2
- import { asMock, ast, makeTestWritten, tablePath } from '../testUtils';
3
- import path from 'path';
4
- import fs from 'fs/promises';
5
-
6
- jest.mock('fs/promises', () => ({
7
- readFile: jest.fn(),
8
- writeFile: jest.fn(),
9
- mkdir: jest.fn(),
10
- }));
11
-
12
- const baseTablePath = path.resolve('baseTable.ts');
13
- const baseTableName = 'BaseTable';
14
- const params = { baseTablePath, baseTableName, tablePath };
15
-
16
- const testWritten = makeTestWritten(tablePath('some'));
17
-
18
- const template = ({
19
- schema,
20
- columns,
21
- noPrimaryKey,
22
- }: {
23
- schema?: string;
24
- columns: string;
25
- noPrimaryKey?: boolean;
26
- }) => `import { BaseTable } from '../baseTable';
27
-
28
- export class SomeTable extends BaseTable {
29
- ${schema ? `schema = '${schema}';\n ` : ''}table = 'some';${
30
- noPrimaryKey ? '\n noPrimaryKey = true;' : ''
31
- }
32
- columns = this.setColumns((t) => (${columns}));
33
- }
34
- `;
35
-
36
- describe('createTable', () => {
37
- beforeEach(() => {
38
- jest.resetAllMocks();
39
- });
40
-
41
- it('should add table', async () => {
42
- await updateTableFile({
43
- ...params,
44
- ast: {
45
- ...ast.addTable,
46
- schema: 'schema',
47
- shape: {},
48
- },
49
- });
50
-
51
- expect(asMock(fs.mkdir)).toBeCalledWith(path.dirname(tablePath('some')), {
52
- recursive: true,
53
- });
54
-
55
- testWritten(
56
- template({
57
- schema: 'schema',
58
- columns: `{
59
-
60
- }`,
61
- }),
62
- );
63
- });
64
-
65
- it('should add table', async () => {
66
- await updateTableFile({
67
- ...params,
68
- ast: {
69
- ...ast.addTable,
70
- primaryKey: {
71
- columns: ['one', 'two'],
72
- options: { name: 'name' },
73
- },
74
- indexes: [
75
- {
76
- columns: [{ column: 'one' }, { column: 'two' }],
77
- options: { name: 'indexName', unique: true },
78
- },
79
- ],
80
- foreignKeys: [
81
- {
82
- columns: ['one', 'two'],
83
- fnOrTable: 'some',
84
- foreignColumns: ['three', 'four'],
85
- options: { name: 'foreignKeyName' },
86
- },
87
- ],
88
- },
89
- });
90
-
91
- testWritten(
92
- template({
93
- columns: `{
94
- id: t.serial().primaryKey(),
95
- ...t.primaryKey(['one', 'two'], { name: 'name' }),
96
- ...t.index(['one', 'two'], {
97
- name: 'indexName',
98
- unique: true,
99
- }),
100
- ...t.foreignKey(
101
- ['one', 'two'],
102
- 'some',
103
- ['three', 'four'],
104
- {
105
- name: 'foreignKeyName',
106
- },
107
- ),
108
- }`,
109
- }),
110
- );
111
- });
112
-
113
- it('should add noPrimaryKey prop when noPrimaryKey is `ignore` in ast', async () => {
114
- await updateTableFile({
115
- ...params,
116
- ast: { ...ast.addTable, noPrimaryKey: 'ignore' },
117
- });
118
-
119
- testWritten(
120
- template({
121
- noPrimaryKey: true,
122
- columns: `{
123
- id: t.serial().primaryKey(),
124
- }`,
125
- }),
126
- );
127
- });
128
-
129
- it('should create file with wx flag', async () => {
130
- asMock(fs.writeFile).mockRejectedValue(
131
- Object.assign(new Error(), { code: 'EEXIST' }),
132
- );
133
-
134
- await updateTableFile({ ...params, ast: ast.addTable });
135
-
136
- const [, , options] = asMock(fs.writeFile).mock.calls[0];
137
- expect(options).toEqual({ flag: 'wx' });
138
- });
139
- });
@@ -1,51 +0,0 @@
1
- import { RakeDbAst } from 'rake-db';
2
- import { getImportPath } from '../utils';
3
- import { Code, codeToString, columnsShapeToCode, singleQuote } from 'pqb';
4
- import { toPascalCase } from '../../utils';
5
- import fs from 'fs/promises';
6
- import { UpdateTableFileParams } from './updateTableFile';
7
- import path from 'path';
8
-
9
- export const createTable = async ({
10
- ast,
11
- ...params
12
- }: UpdateTableFileParams & { ast: RakeDbAst.Table }) => {
13
- const tablePath = params.tablePath(ast.name);
14
- const baseTablePath = getImportPath(tablePath, params.baseTablePath);
15
-
16
- const props: Code[] = [];
17
-
18
- if (ast.schema) {
19
- props.push(`schema = ${singleQuote(ast.schema)};`);
20
- }
21
-
22
- props.push(`table = ${singleQuote(ast.name)};`);
23
-
24
- if (ast.noPrimaryKey === 'ignore') {
25
- props.push('noPrimaryKey = true;');
26
- }
27
-
28
- props.push(
29
- 'columns = this.setColumns((t) => ({',
30
- columnsShapeToCode(ast.shape, ast, 't'),
31
- '}));',
32
- );
33
-
34
- const code: Code[] = [
35
- `import { ${params.baseTableName} } from '${baseTablePath}';\n`,
36
- `export class ${toPascalCase(ast.name)}Table extends ${
37
- params.baseTableName
38
- } {`,
39
- props,
40
- '}\n',
41
- ];
42
-
43
- await fs.mkdir(path.dirname(tablePath), { recursive: true });
44
- try {
45
- await fs.writeFile(tablePath, codeToString(code, '', ' '), { flag: 'wx' });
46
- } catch (err) {
47
- if ((err as unknown as { code: string }).code !== 'EEXIST') {
48
- throw err;
49
- }
50
- }
51
- };