drizzle-kit 0.9.40 → 0.9.41

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 (136) hide show
  1. package/.eslintrc +21 -0
  2. package/LICENSE +674 -0
  3. package/package.json +17 -16
  4. package/pnpm-lock.yaml +2209 -0
  5. package/readme.rst +2 -0
  6. package/src/cli/commands/migrate.ts +79 -0
  7. package/src/cli/components-api/index.ts +287 -0
  8. package/src/cli/enq.ts +41 -0
  9. package/src/cli/index.ts +14 -0
  10. package/src/cli/machines/resolveColumnsMachine.ts +173 -0
  11. package/src/cli/machines/resolveTablesMachine.ts +167 -0
  12. package/src/cli/utils/formatDataForTable.ts +29 -0
  13. package/src/cli/utils/valuesForPrompts.ts +35 -0
  14. package/src/diff.ts +37 -0
  15. package/src/jsonDiffer.js +197 -115
  16. package/src/jsonStatements.ts +482 -0
  17. package/src/migrationPreparator.ts +44 -0
  18. package/src/serializer/factory.ts +415 -0
  19. package/src/serializer/index.ts +23 -0
  20. package/src/simulator.ts +155 -0
  21. package/src/snapshotsDiffer.ts +267 -0
  22. package/src/sqlgenerator.ts +323 -0
  23. package/src/tests/columnsMachine.test.ts +338 -0
  24. package/src/tests/tablesMachine.test.ts +339 -0
  25. package/tests/alters/index.test.ts +22 -0
  26. package/tests/alters/suite1/_patch.yaml +16 -0
  27. package/tests/alters/suite1/from.ts +16 -0
  28. package/tests/alters/suite1/to.ts +15 -0
  29. package/tsconfig.json +7 -0
  30. package/dev/data/column_rename/with_talbe_rename/new.js +0 -15
  31. package/dev/data/column_rename/with_talbe_rename/new.js.map +0 -1
  32. package/dev/data/column_rename/with_talbe_rename/prev.js +0 -15
  33. package/dev/data/column_rename/with_talbe_rename/prev.js.map +0 -1
  34. package/dev/data/column_rename/without_table_rename/v1/usersTable.js +0 -15
  35. package/dev/data/column_rename/without_table_rename/v1/usersTable.js.map +0 -1
  36. package/dev/data/column_rename/without_table_rename/v2/usersTable.js +0 -15
  37. package/dev/data/column_rename/without_table_rename/v2/usersTable.js.map +0 -1
  38. package/dev/data/jobs/from/from.js +0 -22
  39. package/dev/data/jobs/from/from.js.map +0 -1
  40. package/dev/data/jobs/to/to.js +0 -23
  41. package/dev/data/jobs/to/to.js.map +0 -1
  42. package/dev/data/leha/UsersTable.js +0 -36
  43. package/dev/data/leha/UsersTable.js.map +0 -1
  44. package/dev/data/leha/types.js +0 -13
  45. package/dev/data/leha/types.js.map +0 -1
  46. package/dev/data/v1/authOtpTable.js +0 -20
  47. package/dev/data/v1/authOtpTable.js.map +0 -1
  48. package/dev/data/v1/deletedTable.js +0 -14
  49. package/dev/data/v1/deletedTable.js.map +0 -1
  50. package/dev/data/v1/types.js +0 -9
  51. package/dev/data/v1/types.js.map +0 -1
  52. package/dev/data/v1/usersTable.js +0 -18
  53. package/dev/data/v1/usersTable.js.map +0 -1
  54. package/dev/data/v2/authOtpTable.js +0 -29
  55. package/dev/data/v2/authOtpTable.js.map +0 -1
  56. package/dev/data/v2/cityTable.js +0 -15
  57. package/dev/data/v2/cityTable.js.map +0 -1
  58. package/dev/data/v2/types.js +0 -13
  59. package/dev/data/v2/types.js.map +0 -1
  60. package/dev/data/v2/usersTable.js +0 -21
  61. package/dev/data/v2/usersTable.js.map +0 -1
  62. package/dev/data/v3/authOtpTable.js +0 -27
  63. package/dev/data/v3/authOtpTable.js.map +0 -1
  64. package/dev/data/v3/cityTable.js +0 -23
  65. package/dev/data/v3/cityTable.js.map +0 -1
  66. package/dev/data/v3/types.js +0 -13
  67. package/dev/data/v3/types.js.map +0 -1
  68. package/dev/data/v3/usersTable.js +0 -22
  69. package/dev/data/v3/usersTable.js.map +0 -1
  70. package/dev/data/v4/multi.js +0 -46
  71. package/dev/data/v4/multi.js.map +0 -1
  72. package/dev/diff.js +0 -28
  73. package/dev/diff.js.map +0 -1
  74. package/dev/factory.js +0 -78
  75. package/dev/factory.js.map +0 -1
  76. package/dev/fstest.js +0 -45
  77. package/dev/fstest.js.map +0 -1
  78. package/dev/index.js +0 -16
  79. package/dev/index.js.map +0 -1
  80. package/dev/prepare-snapshot.js +0 -19
  81. package/dev/prepare-snapshot.js.map +0 -1
  82. package/dev/quokka.js +0 -90
  83. package/dev/quokka.js.map +0 -1
  84. package/dev/serialiser.js +0 -30
  85. package/dev/serialiser.js.map +0 -1
  86. package/dev/simulate.js +0 -29
  87. package/dev/simulate.js.map +0 -1
  88. package/dev/test-build.js +0 -32
  89. package/dev/test-build.js.map +0 -1
  90. package/dev/testFactory.js +0 -42
  91. package/dev/testFactory.js.map +0 -1
  92. package/dev/testiko.js +0 -57
  93. package/dev/testiko.js.map +0 -1
  94. package/dev/yuup.js +0 -36
  95. package/dev/yuup.js.map +0 -1
  96. package/index.js +0 -168169
  97. package/index.js.map +0 -7
  98. package/jest.config.js +0 -7
  99. package/jest.config.js.map +0 -1
  100. package/src/cli/commands/migrate.js +0 -64
  101. package/src/cli/commands/migrate.js.map +0 -1
  102. package/src/cli/components-api/index.js +0 -205
  103. package/src/cli/components-api/index.js.map +0 -1
  104. package/src/cli/enq.js +0 -38
  105. package/src/cli/enq.js.map +0 -1
  106. package/src/cli/index.js +0 -15
  107. package/src/cli/index.js.map +0 -1
  108. package/src/cli/machines/resolveColumnsMachine.js +0 -116
  109. package/src/cli/machines/resolveColumnsMachine.js.map +0 -1
  110. package/src/cli/machines/resolveTablesMachine.js +0 -114
  111. package/src/cli/machines/resolveTablesMachine.js.map +0 -1
  112. package/src/cli/utils/formatDataForTable.js +0 -21
  113. package/src/cli/utils/formatDataForTable.js.map +0 -1
  114. package/src/cli/utils/valuesForPrompts.js +0 -38
  115. package/src/cli/utils/valuesForPrompts.js.map +0 -1
  116. package/src/diff.js +0 -28
  117. package/src/diff.js.map +0 -1
  118. package/src/jsonDiffer.js.map +0 -1
  119. package/src/jsonStatements.js +0 -197
  120. package/src/jsonStatements.js.map +0 -1
  121. package/src/migrationPreparator.js +0 -37
  122. package/src/migrationPreparator.js.map +0 -1
  123. package/src/serializer/factory.js +0 -113
  124. package/src/serializer/factory.js.map +0 -1
  125. package/src/serializer/index.js +0 -25
  126. package/src/serializer/index.js.map +0 -1
  127. package/src/simulator.js +0 -105
  128. package/src/simulator.js.map +0 -1
  129. package/src/snapshotsDiffer.js +0 -127
  130. package/src/snapshotsDiffer.js.map +0 -1
  131. package/src/sqlgenerator.js +0 -241
  132. package/src/sqlgenerator.js.map +0 -1
  133. package/src/tests/columnsMachine.test.js +0 -270
  134. package/src/tests/columnsMachine.test.js.map +0 -1
  135. package/src/tests/tablesMachine.test.js +0 -272
  136. package/src/tests/tablesMachine.test.js.map +0 -1
@@ -0,0 +1,415 @@
1
+ import ts from "typescript";
2
+ import fs from "fs";
3
+ const printer: ts.Printer = ts.createPrinter();
4
+
5
+ const prepareFabricFile = (folder: string, fileName?: string) => {
6
+ const staticImports = [
7
+ ts.createImportDeclaration(
8
+ undefined,
9
+ undefined,
10
+ ts.createImportClause(
11
+ undefined,
12
+ ts.createNamespaceImport(ts.createIdentifier('drizzle'))
13
+ ),
14
+ ts.createStringLiteral('drizzle-orm')
15
+ ),
16
+ ts.createImportDeclaration(
17
+ undefined,
18
+ undefined,
19
+ ts.createImportClause(
20
+ ts.createIdentifier('Session'),
21
+ undefined
22
+ ),
23
+ ts.createStringLiteral('drizzle-orm/db/session')
24
+ ),
25
+ ts.createImportDeclaration(
26
+ undefined,
27
+ undefined,
28
+ ts.createImportClause(
29
+ ts.createIdentifier('MigrationSerializer'),
30
+ undefined
31
+ ),
32
+ ts.createStringLiteral('drizzle-orm/serializer/serializer')
33
+ ),
34
+ ts.createImportDeclaration(
35
+ undefined,
36
+ undefined,
37
+ ts.createImportClause(ts.createIdentifier("Enum"), undefined),
38
+ ts.createStringLiteral("drizzle-orm/types/type"),
39
+ ),
40
+ ts.createImportDeclaration(
41
+ undefined,
42
+ undefined,
43
+ ts.createImportClause(
44
+ undefined,
45
+ ts.createNamespaceImport(ts.createIdentifier('pg'))
46
+ ),
47
+ ts.createStringLiteral('pg')
48
+ ),
49
+ ];
50
+
51
+ const dynamicImports = [];
52
+ const filenames = fileName ? [fileName!!] : fs.readdirSync(folder);
53
+ for (let i = 0; i < filenames.length; i++) {
54
+ const filename = filenames[i];
55
+
56
+ const importPath = `${folder}/${filename.split(".")[0]}`;
57
+ dynamicImports.push(ts.createImportDeclaration(
58
+ undefined,
59
+ undefined,
60
+ ts.createImportClause(
61
+ undefined,
62
+ ts.createNamespaceImport(ts.createIdentifier(`i${i}`)),
63
+ ),
64
+ ts.createStringLiteral(importPath),
65
+ ));
66
+ }
67
+
68
+ const variablesStatements = [
69
+ ts.createVariableStatement(
70
+ undefined,
71
+ ts.createVariableDeclarationList(
72
+ [
73
+ ts.createVariableDeclaration(
74
+ ts.createIdentifier("db"),
75
+ undefined,
76
+ ts.createNew(ts.createIdentifier("drizzle.DB"), undefined, [
77
+ ts.createNew(ts.createIdentifier("Session"), undefined, [ts.createNew(ts.createPropertyAccess(
78
+ ts.createIdentifier('pg'),
79
+ ts.createIdentifier('Pool')
80
+ ), undefined, [])]),
81
+ ]),
82
+ ),
83
+ ],
84
+ ts.NodeFlags.Const,
85
+ ),
86
+ ),
87
+ ts.createVariableStatement(
88
+ undefined,
89
+ ts.createVariableDeclarationList(
90
+ [
91
+ ts.createVariableDeclaration(
92
+ ts.createIdentifier("serializer"),
93
+ undefined,
94
+ ts.createNew(ts.createIdentifier("MigrationSerializer"), undefined, []),
95
+ ),
96
+ ],
97
+ ts.NodeFlags.Const,
98
+ ),
99
+ ),
100
+ ];
101
+
102
+ const blockStatements = [];
103
+
104
+ // const tables: AbstractTable<any> = []
105
+ blockStatements.push(ts.createVariableStatement(
106
+ undefined,
107
+ ts.createVariableDeclarationList(
108
+ [
109
+ ts.createVariableDeclaration(
110
+ ts.createIdentifier('tables'),
111
+ ts.createArrayTypeNode(
112
+ ts.createTypeReferenceNode(
113
+ ts.createQualifiedName(
114
+ ts.createIdentifier('drizzle'),
115
+ ts.createIdentifier('AbstractTable')
116
+ ),
117
+ [ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
118
+ )
119
+ ),
120
+ ts.createArrayLiteral([], false)
121
+ ),
122
+ ],
123
+ ts.NodeFlags.Const,
124
+ ),
125
+ ));
126
+
127
+ // const enums: Enum<any>[] = []
128
+ blockStatements.push(ts.createVariableStatement(
129
+ undefined,
130
+ ts.createVariableDeclarationList(
131
+ [
132
+ ts.createVariableDeclaration(
133
+ ts.createIdentifier('enums'),
134
+ ts.createArrayTypeNode(
135
+ ts.createTypeReferenceNode(
136
+ ts.createIdentifier('Enum'),
137
+ [ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
138
+ )
139
+ ),
140
+ ts.createArrayLiteral([], false)
141
+ )
142
+ ],
143
+ ts.NodeFlags.Const
144
+ ),
145
+ ));
146
+
147
+ for (let i = 0; i < filenames.length; i++) {
148
+ // const t1 = (new i1.default(db) as unknown as AbstractTable<any>);
149
+ // tables.push(t1)
150
+
151
+ // const i1values = Object.values(i1)
152
+ const valuesDeclaration = ts.createVariableStatement(
153
+ undefined,
154
+ ts.createVariableDeclarationList(
155
+ [
156
+ ts.createVariableDeclaration(
157
+ ts.createIdentifier(`i${i}values`),
158
+ undefined,
159
+ ts.createCall(
160
+ ts.createPropertyAccess(
161
+ ts.createIdentifier('Object'),
162
+ ts.createIdentifier('values')
163
+ ),
164
+ undefined,
165
+ [ts.createIdentifier('i' + i)]
166
+ )
167
+ )
168
+ ],
169
+ ts.NodeFlags.Const
170
+ )
171
+ )
172
+ blockStatements.push(valuesDeclaration)
173
+
174
+ // i1values.forEach((t) => {
175
+ // if (t instanceof Enum) {
176
+ // enums.push(t);
177
+ // return
178
+ // }
179
+
180
+ // if (typeof t === 'function' && t.prototype && t.prototype.constructor) {
181
+ // const instance = new t(db)
182
+
183
+ // if (instance instanceof AbstractTable) {
184
+ // tables.push(instance as unknown as AbstractTable<any>)
185
+ // }
186
+ // }
187
+ // });
188
+ const iterationWithTypeChecks = ts.createExpressionStatement(
189
+ ts.createCall(
190
+ ts.createPropertyAccess(
191
+ ts.createIdentifier(`i${i}values`),
192
+ ts.createIdentifier('forEach')
193
+ ),
194
+ undefined,
195
+ [
196
+ ts.createArrowFunction(
197
+ undefined,
198
+ undefined,
199
+ [
200
+ ts.createParameter(
201
+ undefined,
202
+ undefined,
203
+ undefined,
204
+ ts.createIdentifier('t'),
205
+ undefined,
206
+ undefined,
207
+ undefined
208
+ )
209
+ ],
210
+ undefined,
211
+ ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
212
+ ts.createBlock(
213
+ [
214
+ ts.createIf(
215
+ ts.createBinary(
216
+ ts.createIdentifier('t'),
217
+ ts.SyntaxKind.InstanceOfKeyword,
218
+ ts.createIdentifier('Enum')
219
+ ),
220
+ ts.createBlock(
221
+ [
222
+ ts.createExpressionStatement(
223
+ ts.createCall(
224
+ ts.createPropertyAccess(
225
+ ts.createIdentifier('enums'),
226
+ ts.createIdentifier('push')
227
+ ),
228
+ undefined,
229
+ [ts.createIdentifier('t')]
230
+ )
231
+ ),
232
+ ts.createReturn(undefined)
233
+ ],
234
+ true
235
+ ),
236
+ undefined
237
+ ),
238
+ ts.createIf(
239
+ ts.createBinary(
240
+ ts.createBinary(
241
+ ts.createBinary(
242
+ ts.createTypeOf(ts.createIdentifier('t')),
243
+ ts.createToken(
244
+ ts.SyntaxKind.EqualsEqualsEqualsToken
245
+ ),
246
+ ts.createStringLiteral('function')
247
+ ),
248
+ ts.createToken(
249
+ ts.SyntaxKind.AmpersandAmpersandToken
250
+ ),
251
+ ts.createPropertyAccess(
252
+ ts.createIdentifier('t'),
253
+ ts.createIdentifier('prototype')
254
+ )
255
+ ),
256
+ ts.createToken(
257
+ ts.SyntaxKind.AmpersandAmpersandToken
258
+ ),
259
+ ts.createPropertyAccess(
260
+ ts.createPropertyAccess(
261
+ ts.createIdentifier('t'),
262
+ ts.createIdentifier('prototype')
263
+ ),
264
+ ts.createIdentifier('constructor')
265
+ )
266
+ ),
267
+ ts.createBlock(
268
+ [
269
+ ts.createVariableStatement(
270
+ undefined,
271
+ ts.createVariableDeclarationList(
272
+ [
273
+ ts.createVariableDeclaration(
274
+ ts.createIdentifier('instance'),
275
+ undefined,
276
+ ts.createNew(
277
+ ts.createIdentifier('t'),
278
+ undefined,
279
+ [ts.createIdentifier('db')]
280
+ )
281
+ )
282
+ ],
283
+ ts.NodeFlags.Const
284
+ )
285
+ ),
286
+ ts.createIf(
287
+ ts.createBinary(
288
+ ts.createIdentifier('instance'),
289
+ ts.SyntaxKind.InstanceOfKeyword,
290
+ ts.createIdentifier('drizzle.AbstractTable')
291
+ ),
292
+ ts.createBlock(
293
+ [
294
+ ts.createExpressionStatement(
295
+ ts.createCall(
296
+ ts.createPropertyAccess(
297
+ ts.createIdentifier('tables'),
298
+ ts.createIdentifier('push')
299
+ ),
300
+ undefined,
301
+ [
302
+ ts.createAsExpression(
303
+ ts.createAsExpression(
304
+ ts.createIdentifier(
305
+ 'instance'
306
+ ),
307
+ ts.createKeywordTypeNode(
308
+ ts.SyntaxKind.UnknownKeyword
309
+ )
310
+ ),
311
+ ts.createTypeReferenceNode(
312
+ ts.createQualifiedName(
313
+ ts.createIdentifier('drizzle'),
314
+ ts.createIdentifier('AbstractTable')
315
+ ),
316
+ [
317
+ ts.createKeywordTypeNode(
318
+ ts.SyntaxKind.AnyKeyword
319
+ )
320
+ ]
321
+ )
322
+ )
323
+ ]
324
+ )
325
+ )
326
+ ],
327
+ true
328
+ ),
329
+ undefined
330
+ )
331
+ ],
332
+ true
333
+ ),
334
+ undefined
335
+ )
336
+ ],
337
+ true
338
+ )
339
+ )
340
+ ]
341
+ )
342
+ )
343
+ blockStatements.push(iterationWithTypeChecks)
344
+ }
345
+
346
+ // return serializer.generate(tables, enums)
347
+ blockStatements.push(
348
+ ts.createReturn(
349
+ ts.createCall(
350
+ ts.createPropertyAccess(
351
+ ts.createIdentifier("serializer"),
352
+ ts.createIdentifier("generate"),
353
+ ),
354
+ undefined,
355
+ [
356
+ ts.createIdentifier("tables"),
357
+ ts.createIdentifier("enums"),
358
+ ],
359
+ ),
360
+ ),
361
+ );
362
+
363
+ const funcStatement = [
364
+ ts.createVariableStatement(
365
+ undefined,
366
+ ts.createVariableDeclarationList(
367
+ [
368
+ ts.createVariableDeclaration(
369
+ ts.createIdentifier("testFun"),
370
+ undefined,
371
+ ts.createArrowFunction(
372
+ undefined,
373
+ undefined,
374
+ [],
375
+ undefined,
376
+ ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
377
+ // function body
378
+ ts.createBlock(
379
+ blockStatements,
380
+ true,
381
+ ),
382
+ ),
383
+ ),
384
+ ],
385
+ ts.NodeFlags.Const,
386
+ ),
387
+ ),
388
+ ];
389
+ const invocationStatement = [
390
+ ts.createExpressionStatement(
391
+ ts.createCall(ts.createIdentifier("testFun"), undefined, []),
392
+ ),
393
+ ];
394
+
395
+ const outFile: ts.SourceFile = ts.createSourceFile(
396
+ "outfile.ts",
397
+ "",
398
+ ts.ScriptTarget.ES2015,
399
+ true,
400
+ ts.ScriptKind.TS,
401
+ );
402
+
403
+ const source = [];
404
+ source.push(...staticImports);
405
+ source.push(...dynamicImports);
406
+ source.push(...variablesStatements);
407
+ source.push(...funcStatement);
408
+ source.push(...invocationStatement);
409
+
410
+ const newFile = ts.factory.updateSourceFile(outFile, source);
411
+
412
+ return printer.printFile(newFile);
413
+ };
414
+
415
+ export default prepareFabricFile;
@@ -0,0 +1,23 @@
1
+ import fs from "fs";
2
+ import { StringDecoder } from "string_decoder";
3
+ import prepareFabricFile from "./factory";
4
+ const esbuild = require("esbuild");
5
+
6
+ const serialize = (path: string, fileName?: string): string => {
7
+ const decoder = new StringDecoder();
8
+ const preparedFarbic = prepareFabricFile(path, fileName)
9
+
10
+ fs.writeFileSync("__out.ts", preparedFarbic, "utf-8");
11
+ const result = esbuild.buildSync({
12
+ entryPoints: ["__out.ts"],
13
+ bundle: true,
14
+ platform: "node",
15
+ write: false,
16
+ external: ["pg-native"],
17
+ });
18
+
19
+ fs.unlinkSync("__out.ts");
20
+ return eval(decoder.write(result.outputFiles[0].contents));
21
+ };
22
+
23
+ export default serialize;
@@ -0,0 +1,155 @@
1
+ declare global {
2
+ interface Array<T> {
3
+ exactlyOne(): T;
4
+ }
5
+ }
6
+
7
+ Array.prototype.exactlyOne = function () {
8
+ if (this.length !== 1) {
9
+ return undefined
10
+ }
11
+ return this[0]
12
+ }
13
+
14
+ interface TablesHandler<T extends Named> {
15
+ can(added: T[], removed: T[]): boolean
16
+ handle(added: T[], removed: T[]): { created: T[], deleted: T[], renamed: { from: T, to: T }[] }
17
+ }
18
+
19
+ interface ColumnsHandler<T extends Named> {
20
+ can(tableName: string, added: T[], removed: T[]): boolean
21
+ handle(tableName: string, added: T[], removed: T[]): { tableName: string, created: T[], deleted: T[], renamed: { from: T, to: T }[] }
22
+ }
23
+
24
+ class DryRun<T extends Named> implements TablesHandler<T> {
25
+ can(added: T[], removed: T[]): boolean {
26
+ return added.length === 0 && removed.length === 0
27
+ }
28
+ handle(added: T[], _: T[]): { created: T[]; deleted: T[]; renamed: { from: T; to: T; }[]; } {
29
+ return { created: added, deleted: [], renamed: [] }
30
+ }
31
+ }
32
+
33
+ // class Fallback implements Handler {
34
+ // can(_: Table[], __: Table[]): boolean {
35
+ // return true
36
+ // }
37
+ // handle(added: Table[], _: Table[]): { created: Table[]; deleted: Table[]; renamed: { from: Table; to: Table; }[]; } {
38
+ // return { created: added, deleted: , renamed: [] }
39
+ // }
40
+ // }
41
+
42
+ class Case1<T extends Named> implements TablesHandler<T> {
43
+ can(_: T[], removed: T[]): boolean {
44
+ return removed.length === 1 && removed[0].name === 'citiess'
45
+ }
46
+
47
+ handle(added: T[], removed: T[]): { created: T[]; deleted: T[]; renamed: { from: T; to: T; }[]; } {
48
+ return { created: added, deleted: removed, renamed: [] }
49
+ }
50
+ }
51
+ class Case2<T extends Named> implements TablesHandler<T> {
52
+ // authOtp, deleted, users -> authOtp renamed, cities added, deleted deleted
53
+ can(_: T[], removed: T[]): boolean {
54
+ return removed.length === 3 && removed[0].name === 'auth_otp'
55
+ }
56
+
57
+ handle(added: T[], removed: T[]): { created: T[]; deleted: T[]; renamed: { from: T; to: T; }[]; } {
58
+ return { created: added.slice(1), deleted: removed.slice(1), renamed: [{ from: removed[0], to: added[0] }] }
59
+ }
60
+ }
61
+
62
+ type Named = { name: string }
63
+
64
+ const handlers: TablesHandler<any>[] = []
65
+ handlers.push(new Case1())
66
+ handlers.push(new Case2())
67
+ handlers.push(new DryRun())
68
+
69
+ export const resolveTables = <T extends Named>(added: T[], removed: T[]) => {
70
+ const handler = handlers.filter(it => {
71
+ return it.can(added, removed)
72
+ }).exactlyOne()
73
+
74
+ if (!handler) {
75
+ console.log('added', added.map(it => it.name).join())
76
+ console.log('removed', removed.map(it => it.name).join())
77
+ throw new Error("No handler");
78
+ }
79
+
80
+ console.log(`Simluated by ${handler.constructor.name}`)
81
+ return handler.handle(added, removed)
82
+ }
83
+ class LehaColumnsHandler<T extends Named> implements ColumnsHandler<T> {
84
+ can(tableName: string, _: T[], __: T[]): boolean {
85
+ return tableName === 'users'
86
+ }
87
+
88
+ handle(
89
+ tableName: string,
90
+ added: T[],
91
+ removed: T[]
92
+ ): { tableName: string; created: T[]; deleted: T[]; renamed: { from: T; to: T }[] } {
93
+ return { tableName, created: [], deleted: [], renamed: [{from: removed[0], to: added[0]}] }
94
+ }
95
+ }
96
+
97
+ class DryRunColumnsHandler<T extends Named> implements ColumnsHandler<T> {
98
+ can(tableName: string, _: T[], __: T[]): boolean {
99
+ return true
100
+ }
101
+
102
+ handle(
103
+ tableName: string,
104
+ added: T[],
105
+ removed: T[]
106
+ ): { tableName: string; created: T[]; deleted: T[]; renamed: { from: T; to: T }[] } {
107
+ return { tableName, created: added, deleted: removed, renamed: [] }
108
+ }
109
+ }
110
+
111
+
112
+ class V1V2AuthOtpColumnsHandler<T extends Named> implements ColumnsHandler<T> {
113
+ can(tableName: string, _: T[], __: T[]): boolean {
114
+ return tableName === 'auth_otp'
115
+ }
116
+
117
+ handle(
118
+ tableName: string,
119
+ added: T[],
120
+ removed: T[]
121
+ ): { tableName: string; created: T[]; deleted: T[]; renamed: { from: T; to: T }[] } {
122
+ const phonePrev = removed.filter((it) => it.name === 'phone')[0];
123
+ const phoneNew = added.filter((it) => it.name === 'phone1')[0];
124
+
125
+ const newAdded = added.filter((it => it.name !== 'phone1'))
126
+ const newRemoved = removed.filter((it => it.name !== 'phone'))
127
+
128
+ return { tableName, created: newAdded, deleted: newRemoved, renamed: [{ from: phonePrev, to: phoneNew }] }
129
+ }
130
+
131
+ // handle(tableName:string, added: T[], _: T[]): { created: T[]; deleted: T[]; renamed: { from: T; to: T; }[]; } {
132
+ // return { created: added, deleted: [], renamed: [] }
133
+ // }
134
+ }
135
+
136
+ const columnsHandlers: ColumnsHandler<any>[] = []
137
+ columnsHandlers.push(new V1V2AuthOtpColumnsHandler())
138
+ columnsHandlers.push(new LehaColumnsHandler())
139
+ columnsHandlers.push(new DryRunColumnsHandler())
140
+
141
+ export const resolveColumns = <T extends Named>(tableName: string, added: T[], removed: T[]) => {
142
+ const handler = columnsHandlers.filter(it => {
143
+ return it.can(tableName, added, removed)
144
+ })[0]
145
+
146
+ if (!handler) {
147
+ console.log('added', added.map(it => it.name).join())
148
+ console.log('removed', removed.map(it => it.name).join())
149
+ throw new Error("No columns handler for table: " + tableName);
150
+ }
151
+
152
+ console.log(`${tableName} columns simluated by ${handler.constructor.name}`)
153
+ return handler.handle(tableName, added, removed)
154
+ }
155
+