drizzle-kit 0.9.38 → 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.
- package/.eslintrc +21 -0
- package/LICENSE +674 -0
- package/package.json +17 -16
- package/pnpm-lock.yaml +2209 -0
- package/readme.rst +2 -0
- package/src/cli/commands/migrate.ts +79 -0
- package/src/cli/components-api/index.ts +287 -0
- package/src/cli/enq.ts +41 -0
- package/src/cli/index.ts +14 -0
- package/src/cli/machines/resolveColumnsMachine.ts +173 -0
- package/src/cli/machines/resolveTablesMachine.ts +167 -0
- package/src/cli/utils/formatDataForTable.ts +29 -0
- package/src/cli/utils/valuesForPrompts.ts +35 -0
- package/src/diff.ts +37 -0
- package/src/jsonDiffer.js +197 -115
- package/src/jsonStatements.ts +482 -0
- package/src/migrationPreparator.ts +44 -0
- package/src/serializer/factory.ts +415 -0
- package/src/serializer/index.ts +23 -0
- package/src/simulator.ts +155 -0
- package/src/snapshotsDiffer.ts +267 -0
- package/src/sqlgenerator.ts +323 -0
- package/src/tests/columnsMachine.test.ts +338 -0
- package/src/tests/tablesMachine.test.ts +339 -0
- package/tests/alters/index.test.ts +22 -0
- package/tests/alters/suite1/_patch.yaml +16 -0
- package/tests/alters/suite1/from.ts +16 -0
- package/tests/alters/suite1/to.ts +15 -0
- package/tsconfig.json +7 -0
- package/dev/data/column_rename/with_talbe_rename/new.js +0 -15
- package/dev/data/column_rename/with_talbe_rename/new.js.map +0 -1
- package/dev/data/column_rename/with_talbe_rename/prev.js +0 -15
- package/dev/data/column_rename/with_talbe_rename/prev.js.map +0 -1
- package/dev/data/column_rename/without_table_rename/v1/usersTable.js +0 -15
- package/dev/data/column_rename/without_table_rename/v1/usersTable.js.map +0 -1
- package/dev/data/column_rename/without_table_rename/v2/usersTable.js +0 -15
- package/dev/data/column_rename/without_table_rename/v2/usersTable.js.map +0 -1
- package/dev/data/jobs/from/from.js +0 -22
- package/dev/data/jobs/from/from.js.map +0 -1
- package/dev/data/jobs/to/to.js +0 -23
- package/dev/data/jobs/to/to.js.map +0 -1
- package/dev/data/leha/UsersTable.js +0 -36
- package/dev/data/leha/UsersTable.js.map +0 -1
- package/dev/data/leha/types.js +0 -13
- package/dev/data/leha/types.js.map +0 -1
- package/dev/data/v1/authOtpTable.js +0 -20
- package/dev/data/v1/authOtpTable.js.map +0 -1
- package/dev/data/v1/deletedTable.js +0 -14
- package/dev/data/v1/deletedTable.js.map +0 -1
- package/dev/data/v1/types.js +0 -9
- package/dev/data/v1/types.js.map +0 -1
- package/dev/data/v1/usersTable.js +0 -18
- package/dev/data/v1/usersTable.js.map +0 -1
- package/dev/data/v2/authOtpTable.js +0 -29
- package/dev/data/v2/authOtpTable.js.map +0 -1
- package/dev/data/v2/cityTable.js +0 -15
- package/dev/data/v2/cityTable.js.map +0 -1
- package/dev/data/v2/types.js +0 -13
- package/dev/data/v2/types.js.map +0 -1
- package/dev/data/v2/usersTable.js +0 -21
- package/dev/data/v2/usersTable.js.map +0 -1
- package/dev/data/v3/authOtpTable.js +0 -27
- package/dev/data/v3/authOtpTable.js.map +0 -1
- package/dev/data/v3/cityTable.js +0 -23
- package/dev/data/v3/cityTable.js.map +0 -1
- package/dev/data/v3/types.js +0 -13
- package/dev/data/v3/types.js.map +0 -1
- package/dev/data/v3/usersTable.js +0 -22
- package/dev/data/v3/usersTable.js.map +0 -1
- package/dev/data/v4/multi.js +0 -46
- package/dev/data/v4/multi.js.map +0 -1
- package/dev/diff.js +0 -28
- package/dev/diff.js.map +0 -1
- package/dev/factory.js +0 -78
- package/dev/factory.js.map +0 -1
- package/dev/fstest.js +0 -45
- package/dev/fstest.js.map +0 -1
- package/dev/index.js +0 -16
- package/dev/index.js.map +0 -1
- package/dev/prepare-snapshot.js +0 -19
- package/dev/prepare-snapshot.js.map +0 -1
- package/dev/quokka.js +0 -90
- package/dev/quokka.js.map +0 -1
- package/dev/serialiser.js +0 -30
- package/dev/serialiser.js.map +0 -1
- package/dev/simulate.js +0 -29
- package/dev/simulate.js.map +0 -1
- package/dev/test-build.js +0 -32
- package/dev/test-build.js.map +0 -1
- package/dev/testFactory.js +0 -42
- package/dev/testFactory.js.map +0 -1
- package/dev/testiko.js +0 -57
- package/dev/testiko.js.map +0 -1
- package/dev/yuup.js +0 -36
- package/dev/yuup.js.map +0 -1
- package/index.js +0 -168169
- package/index.js.map +0 -7
- package/jest.config.js +0 -7
- package/jest.config.js.map +0 -1
- package/src/cli/commands/migrate.js +0 -64
- package/src/cli/commands/migrate.js.map +0 -1
- package/src/cli/components-api/index.js +0 -205
- package/src/cli/components-api/index.js.map +0 -1
- package/src/cli/enq.js +0 -38
- package/src/cli/enq.js.map +0 -1
- package/src/cli/index.js +0 -15
- package/src/cli/index.js.map +0 -1
- package/src/cli/machines/resolveColumnsMachine.js +0 -116
- package/src/cli/machines/resolveColumnsMachine.js.map +0 -1
- package/src/cli/machines/resolveTablesMachine.js +0 -114
- package/src/cli/machines/resolveTablesMachine.js.map +0 -1
- package/src/cli/utils/formatDataForTable.js +0 -21
- package/src/cli/utils/formatDataForTable.js.map +0 -1
- package/src/cli/utils/valuesForPrompts.js +0 -38
- package/src/cli/utils/valuesForPrompts.js.map +0 -1
- package/src/diff.js +0 -28
- package/src/diff.js.map +0 -1
- package/src/jsonDiffer.js.map +0 -1
- package/src/jsonStatements.js +0 -197
- package/src/jsonStatements.js.map +0 -1
- package/src/migrationPreparator.js +0 -37
- package/src/migrationPreparator.js.map +0 -1
- package/src/serializer/factory.js +0 -113
- package/src/serializer/factory.js.map +0 -1
- package/src/serializer/index.js +0 -25
- package/src/serializer/index.js.map +0 -1
- package/src/simulator.js +0 -105
- package/src/simulator.js.map +0 -1
- package/src/snapshotsDiffer.js +0 -127
- package/src/snapshotsDiffer.js.map +0 -1
- package/src/sqlgenerator.js +0 -241
- package/src/sqlgenerator.js.map +0 -1
- package/src/tests/columnsMachine.test.js +0 -270
- package/src/tests/columnsMachine.test.js.map +0 -1
- package/src/tests/tablesMachine.test.js +0 -272
- package/src/tests/tablesMachine.test.js.map +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { assign, createMachine, send } from 'xstate';
|
|
2
|
+
import { Named, RenamedObject } from '../components-api';
|
|
3
|
+
|
|
4
|
+
type Event =
|
|
5
|
+
| { type: 'CHOICE_ITEM', itemIndex: number }
|
|
6
|
+
| { type: 'DELETED' }
|
|
7
|
+
| { type: 'RENAMED' }
|
|
8
|
+
| { type: 'CANCEL' }
|
|
9
|
+
| { type: 'CONFIRM' }
|
|
10
|
+
| { type: 'NEXT' }
|
|
11
|
+
| { type: 'CHOICE_NEW_ITEM'; itemIndex: number };
|
|
12
|
+
|
|
13
|
+
interface Context<T extends Named> extends CreateTablesMachineProps<T> {
|
|
14
|
+
missingItemIndex: number,
|
|
15
|
+
newItemIndex: number,
|
|
16
|
+
createdTables: T[];
|
|
17
|
+
renamedTables: RenamedObject<T>[];
|
|
18
|
+
deletedTables: T[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CreateTablesMachineProps<T> {
|
|
22
|
+
missingTables: T[],
|
|
23
|
+
newTables: T[],
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const createResolveTablesMachine = <T extends Named>(props: CreateTablesMachineProps<T>) => (
|
|
27
|
+
createMachine<Context<T>, Event>({
|
|
28
|
+
id: 'resolveTables',
|
|
29
|
+
initial: 'idle',
|
|
30
|
+
context: {
|
|
31
|
+
...props,
|
|
32
|
+
missingItemIndex: 0,
|
|
33
|
+
newItemIndex: 0,
|
|
34
|
+
createdTables: [],
|
|
35
|
+
renamedTables: [],
|
|
36
|
+
deletedTables: [],
|
|
37
|
+
},
|
|
38
|
+
states: {
|
|
39
|
+
idle: {
|
|
40
|
+
entry: send({ type: 'NEXT' }),
|
|
41
|
+
on: {
|
|
42
|
+
NEXT: [
|
|
43
|
+
{
|
|
44
|
+
target: 'done',
|
|
45
|
+
cond: 'isResolved',
|
|
46
|
+
actions: ['resolveRemaining'],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
target: 'table',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
table: {
|
|
55
|
+
on: {
|
|
56
|
+
CHOICE_ITEM: { target: 'action', actions: ['choseItem'] },
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
action: {
|
|
60
|
+
initial: 'actionChoice',
|
|
61
|
+
states: {
|
|
62
|
+
actionChoice: {
|
|
63
|
+
on: { DELETED: '#resolveTables.confirmationDelete', RENAMED: 'rename' },
|
|
64
|
+
},
|
|
65
|
+
rename: {
|
|
66
|
+
on: {
|
|
67
|
+
CHOICE_NEW_ITEM: { target: '#resolveTables.confirmationRename', actions: ['choseNewItem'] },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
confirmationDelete: {
|
|
73
|
+
on: {
|
|
74
|
+
CANCEL: 'action.actionChoice',
|
|
75
|
+
CONFIRM: [
|
|
76
|
+
{ target: 'check', actions: ['delete'] },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
confirmationRename: {
|
|
81
|
+
on: {
|
|
82
|
+
CANCEL: 'action.actionChoice',
|
|
83
|
+
CONFIRM: [
|
|
84
|
+
{ target: 'check', actions: ['rename'] },
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
check: {
|
|
89
|
+
entry: send({ type: 'NEXT' }),
|
|
90
|
+
on: {
|
|
91
|
+
NEXT: [
|
|
92
|
+
{
|
|
93
|
+
target: 'done',
|
|
94
|
+
cond: 'isResolved',
|
|
95
|
+
actions: ['resolveRemaining'],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
target: 'table',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
done: {},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
guards: {
|
|
108
|
+
isResolved: ({ missingTables, newTables }) => !missingTables.length || !newTables.length,
|
|
109
|
+
},
|
|
110
|
+
actions: {
|
|
111
|
+
choseItem: assign({
|
|
112
|
+
missingItemIndex: (context, event) => (event.type === 'CHOICE_ITEM' ? event.itemIndex : 0),
|
|
113
|
+
}),
|
|
114
|
+
|
|
115
|
+
choseNewItem: assign({
|
|
116
|
+
newItemIndex: (context, event) => (event.type === 'CHOICE_NEW_ITEM' ? event.itemIndex : 0),
|
|
117
|
+
}),
|
|
118
|
+
|
|
119
|
+
delete: assign({
|
|
120
|
+
deletedTables: ({
|
|
121
|
+
missingItemIndex,
|
|
122
|
+
deletedTables,
|
|
123
|
+
missingTables,
|
|
124
|
+
}) => [...deletedTables, missingTables[missingItemIndex]],
|
|
125
|
+
missingTables: ({
|
|
126
|
+
missingItemIndex,
|
|
127
|
+
missingTables,
|
|
128
|
+
}) => missingTables.filter((_, index) => index !== missingItemIndex),
|
|
129
|
+
}),
|
|
130
|
+
|
|
131
|
+
rename: assign({
|
|
132
|
+
renamedTables: ({
|
|
133
|
+
missingItemIndex,
|
|
134
|
+
newItemIndex,
|
|
135
|
+
renamedTables,
|
|
136
|
+
newTables,
|
|
137
|
+
missingTables,
|
|
138
|
+
}) => [
|
|
139
|
+
...renamedTables,
|
|
140
|
+
{from: missingTables[missingItemIndex], to: newTables[newItemIndex]},
|
|
141
|
+
],
|
|
142
|
+
missingTables: ({
|
|
143
|
+
missingItemIndex,
|
|
144
|
+
missingTables,
|
|
145
|
+
}) => missingTables.filter((_, index) => index !== missingItemIndex),
|
|
146
|
+
newTables: ({
|
|
147
|
+
newItemIndex,
|
|
148
|
+
newTables,
|
|
149
|
+
}) => newTables.filter((_, index) => index !== newItemIndex),
|
|
150
|
+
}),
|
|
151
|
+
|
|
152
|
+
resolveRemaining: assign({
|
|
153
|
+
createdTables: ({
|
|
154
|
+
newTables,
|
|
155
|
+
createdTables,
|
|
156
|
+
}) => [...createdTables, ...newTables],
|
|
157
|
+
deletedTables: ({
|
|
158
|
+
missingTables,
|
|
159
|
+
deletedTables,
|
|
160
|
+
}) => [...deletedTables, ...missingTables],
|
|
161
|
+
missingTables: (context) => [],
|
|
162
|
+
newTables: (context) => [],
|
|
163
|
+
}),
|
|
164
|
+
}
|
|
165
|
+
}));
|
|
166
|
+
|
|
167
|
+
export default createResolveTablesMachine;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Named, RenamedObject } from '../components-api';
|
|
2
|
+
|
|
3
|
+
const transpose = <T>(matrix: T[][]) => {
|
|
4
|
+
let [row] = matrix
|
|
5
|
+
return row.map((value, column) => matrix.map(row => row[column]))
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default <T extends Named>(
|
|
9
|
+
created: Named[],
|
|
10
|
+
renamed: RenamedObject<T>[],
|
|
11
|
+
deleted: Named[],
|
|
12
|
+
): string[][] => {
|
|
13
|
+
const columns: string[][] = [[],[],[]];
|
|
14
|
+
|
|
15
|
+
columns[0] = created.map(({name}) => name);
|
|
16
|
+
columns[1] = renamed.map(({from, to}) => `${from.name} -> ${to.name}`);
|
|
17
|
+
columns[2] = deleted.map(({name}) => name);
|
|
18
|
+
|
|
19
|
+
const maxColumnLength = Math.max(columns[0].length, columns[1].length, columns[2].length)
|
|
20
|
+
|
|
21
|
+
const filledColumns = columns.map((column) => {
|
|
22
|
+
const columnLength = column.length;
|
|
23
|
+
column.length = maxColumnLength;
|
|
24
|
+
column.fill('', columnLength)
|
|
25
|
+
return column;
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return transpose(filledColumns);
|
|
29
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export enum Action {
|
|
2
|
+
RENAME = 'RENAME',
|
|
3
|
+
DELETE = 'DELETE'
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export enum Confirmation {
|
|
7
|
+
CANCEL = 'CANCEL',
|
|
8
|
+
CONFIRM = 'CONFIRM'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const actions = [
|
|
12
|
+
{
|
|
13
|
+
key: Action.RENAME,
|
|
14
|
+
label: 'Renamed',
|
|
15
|
+
value: Action.RENAME,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
key: Action.DELETE,
|
|
19
|
+
label: 'Deleted',
|
|
20
|
+
value: Action.DELETE,
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
export const confirmations = [
|
|
25
|
+
{
|
|
26
|
+
key: Confirmation.CONFIRM,
|
|
27
|
+
label: 'Yes',
|
|
28
|
+
value: Confirmation.CONFIRM,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: Confirmation.CANCEL,
|
|
32
|
+
label: 'No',
|
|
33
|
+
value: Confirmation.CANCEL,
|
|
34
|
+
},
|
|
35
|
+
];
|
package/src/diff.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import { resolveColumns, resolveTables } from './simulator'
|
|
3
|
+
import {
|
|
4
|
+
applySnapshotsDiff,
|
|
5
|
+
Column,
|
|
6
|
+
ColumnsResolverInput,
|
|
7
|
+
ColumnsResolverOutput,
|
|
8
|
+
Table,
|
|
9
|
+
TablesResolverInput,
|
|
10
|
+
TablesResolverOutput
|
|
11
|
+
} from './snapshotsDiffer'
|
|
12
|
+
|
|
13
|
+
export const dry = {
|
|
14
|
+
version: "1",
|
|
15
|
+
tables: {},
|
|
16
|
+
enums: {}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const simulatedTablesResolver = async (input: TablesResolverInput<Table>): Promise<TablesResolverOutput<Table>> => {
|
|
20
|
+
return resolveTables(input.created, input.deleted)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const simulatedColumnsResolver = async (input: ColumnsResolverInput<Column>): Promise<ColumnsResolverOutput<Column>> => {
|
|
24
|
+
return resolveColumns(input.tableName, input.created, input.deleted)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
// const j3 = JSON.parse(fs.readFileSync('./out/1634215063491.json', 'utf8'))
|
|
30
|
+
const main = async () => {
|
|
31
|
+
const j1 = dry
|
|
32
|
+
// const j1 = JSON.parse(fs.readFileSync('./out/leha1.json', 'utf8'))
|
|
33
|
+
const j2 = JSON.parse(fs.readFileSync('./out/leha2.json', 'utf8'))
|
|
34
|
+
console.log(await applySnapshotsDiff(j1, j2, simulatedTablesResolver, simulatedColumnsResolver))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
main()
|
package/src/jsonDiffer.js
CHANGED
|
@@ -1,87 +1,146 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
'use-strict';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
function diffForRenamedTables(pairs) {
|
|
2
|
+
|
|
3
|
+
import { diff } from 'json-diff'
|
|
4
|
+
|
|
5
|
+
export function diffForRenamedTables(pairs) {
|
|
7
6
|
// raname table1 to name of table2, so we can apply diffs
|
|
8
7
|
const renamed = pairs.map(it => {
|
|
9
|
-
const from = it.from
|
|
10
|
-
const to = it.to
|
|
11
|
-
const newFrom = { ...from, name: to.name }
|
|
12
|
-
return [newFrom, to]
|
|
13
|
-
})
|
|
8
|
+
const from = it.from
|
|
9
|
+
const to = it.to
|
|
10
|
+
const newFrom = { ...from, name: to.name }
|
|
11
|
+
return [newFrom, to]
|
|
12
|
+
})
|
|
13
|
+
|
|
14
14
|
// find any alternations made to a renamed table
|
|
15
15
|
const altered = renamed.map(pair => {
|
|
16
|
-
return diffForRenamedTable(pair[0], pair[1])
|
|
16
|
+
return diffForRenamedTable(pair[0], pair[1])
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
return altered
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function diffForRenamedTable(t1, t2) {
|
|
23
|
+
t1.name = t2.name
|
|
24
|
+
const diffed = diff(t1, t2);
|
|
25
|
+
diffed.name = t2.name
|
|
26
|
+
|
|
27
|
+
return findAlternationsInTable(diffed)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function diffForRenamedColumn(t1, t2) {
|
|
31
|
+
const renamed = { ...t1, name: t2.name }
|
|
32
|
+
const diffed = diff(renamed, t2) || {};
|
|
33
|
+
diffed.name = t2.name
|
|
34
|
+
|
|
35
|
+
return alternationsInColumn(diffed)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const renameNestedObjects = (obj, keyFrom, keyTo) => {
|
|
39
|
+
Object.entries(obj).forEach(([key, value]) => {
|
|
40
|
+
if ((key === keyFrom || (key.includes(keyFrom) && key !== keyFrom)) && 'object' !== typeof value) {
|
|
41
|
+
const newKey = key.replace(keyFrom, keyTo)
|
|
42
|
+
obj[newKey] = value;
|
|
43
|
+
delete obj[key];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if ('object' === typeof value) {
|
|
47
|
+
renameNestedObjects(obj[key], keyFrom, keyTo);
|
|
48
|
+
}
|
|
17
49
|
});
|
|
18
|
-
return altered;
|
|
19
50
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
51
|
+
|
|
52
|
+
const update1to2 = (json) => {
|
|
53
|
+
Object.entries(json).forEach(([key, val]) => {
|
|
54
|
+
if ('object' !== typeof val) return
|
|
55
|
+
|
|
56
|
+
if (val.hasOwnProperty('references')) {
|
|
57
|
+
const ref = val['references']
|
|
58
|
+
const fkName = ref['foreignKeyName']
|
|
59
|
+
const table = ref['table']
|
|
60
|
+
const column = ref['column']
|
|
61
|
+
const onDelete = ref['onDelete']
|
|
62
|
+
const onUpdate = ref['onUpdate']
|
|
63
|
+
const newRef = `${fkName};${table};${column};${onDelete ?? ''};${onUpdate ?? ''}`
|
|
64
|
+
val['references'] = newRef
|
|
65
|
+
} else {
|
|
66
|
+
update1to2(val)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
26
69
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return alternationsInColumn(diffed);
|
|
70
|
+
const migrateSchema = (json) => {
|
|
71
|
+
if (json['version'] === '1') {
|
|
72
|
+
update1to2(json)
|
|
73
|
+
json['version'] = '2'
|
|
74
|
+
}
|
|
33
75
|
}
|
|
34
|
-
|
|
35
|
-
function applyJsonDiff(json1, json2) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
76
|
+
|
|
77
|
+
export function applyJsonDiff(json1, json2) {
|
|
78
|
+
json1 = JSON.parse(JSON.stringify(json1))
|
|
79
|
+
json2 = JSON.parse(JSON.stringify(json2))
|
|
80
|
+
|
|
81
|
+
migrateSchema(json1)
|
|
82
|
+
migrateSchema(json2)
|
|
83
|
+
|
|
84
|
+
//deep copy, needed because of the bug in diff library
|
|
85
|
+
const rawDiff = diff(json1, json2)
|
|
86
|
+
const difference = rawDiff
|
|
87
|
+
|
|
88
|
+
difference.tables = difference.tables ? difference.tables : {}
|
|
89
|
+
difference.enums = difference.enums ? difference.enums : {}
|
|
90
|
+
|
|
91
|
+
renameNestedObjects(difference, 'default', 'defaultValue')
|
|
92
|
+
|
|
93
|
+
const tableEntries = Object.entries(difference.tables)
|
|
40
94
|
const addedTables = tableEntries.filter(it => it[0].includes('__added'))
|
|
41
95
|
.map(it => it[1])
|
|
42
96
|
.map(it => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
54
|
-
});
|
|
97
|
+
return {
|
|
98
|
+
...it, indexes: Object.entries(it.indexes).map(indexEntry => {
|
|
99
|
+
const idx = indexEntry[1]
|
|
100
|
+
const name = idx['name']
|
|
101
|
+
const columns = Object.values(idx['columns']).map(it => it['name'])
|
|
102
|
+
return { name, columns, isUnique: idx['isUnique'] }
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
55
107
|
const deletedTables = tableEntries.filter(it => it[0].includes('__deleted'))
|
|
56
|
-
.map(it => it[1])
|
|
57
|
-
|
|
108
|
+
.map(it => it[1])
|
|
109
|
+
|
|
110
|
+
const enumsEntries = Object.entries(difference.enums)
|
|
111
|
+
|
|
58
112
|
const addedEnums = enumsEntries.filter(it => it[0].includes('__added'))
|
|
59
113
|
.map(it => it[1])
|
|
60
114
|
.map(it => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
115
|
+
// values: { val1: 'val1', val2: 'val2' } => values: ['val1', 'val2']
|
|
116
|
+
const values = Object.entries(it.values).map(ve => ve[1])
|
|
117
|
+
return { name: it.name, values: values }
|
|
118
|
+
})
|
|
119
|
+
|
|
65
120
|
const deletedEnums = enumsEntries.filter(it => it[0].includes('__deleted'))
|
|
66
121
|
.map(it => it[1])
|
|
67
122
|
.map(it => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
123
|
+
// values: { val1: 'val1', val2: 'val2' } => values: ['val1', 'val2']
|
|
124
|
+
const values = Object.entries(it.values).map(ve => ve[1])
|
|
125
|
+
return { name: it.name, values: values }
|
|
126
|
+
})
|
|
127
|
+
|
|
72
128
|
const alteredEnums = enumsEntries.filter(it => !(it[0].includes('__added') || it[0].includes('__deleted')))
|
|
73
129
|
.map(it => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
130
|
+
const vals = it[1].values
|
|
131
|
+
const addedValues = Object.entries(vals).filter(val => val[0].includes('__added')).map(val => val[1])
|
|
132
|
+
const deletedValues = Object.entries(vals).filter(val => val[0].includes('__deleted')).map(val => val[1])
|
|
133
|
+
return { name: it[0], addedValues, deletedValues, }
|
|
134
|
+
})
|
|
135
|
+
|
|
79
136
|
const alteredTables = Object.keys(difference.tables)
|
|
80
137
|
.filter(it => !(it.includes('__added') || it.includes('__deleted')))
|
|
81
138
|
.map(it => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
139
|
+
return { name: it, ...difference.tables[it] }
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const alteredTablesWithColumns = alteredTables.map(table => findAlternationsInTable(table))
|
|
143
|
+
|
|
85
144
|
return {
|
|
86
145
|
addedTables,
|
|
87
146
|
deletedTables,
|
|
@@ -89,90 +148,113 @@ function applyJsonDiff(json1, json2) {
|
|
|
89
148
|
addedEnums,
|
|
90
149
|
deletedEnums,
|
|
91
150
|
alteredEnums,
|
|
92
|
-
}
|
|
151
|
+
}
|
|
93
152
|
}
|
|
94
|
-
|
|
153
|
+
|
|
95
154
|
const findAlternationsInTable = (table) => {
|
|
96
155
|
// map each table to have altered, deleted or renamed columns
|
|
156
|
+
|
|
97
157
|
// in case no columns were altered, but indexes were
|
|
98
158
|
const columns = table.columns;
|
|
159
|
+
|
|
99
160
|
const added = Object.keys(columns).filter(it => it.includes('__added')).map(it => {
|
|
100
|
-
return { ...columns[it] }
|
|
101
|
-
})
|
|
161
|
+
return { ...columns[it] }
|
|
162
|
+
})
|
|
102
163
|
const deleted = Object.keys(columns).filter(it => it.includes('__deleted')).map(it => {
|
|
103
|
-
return { ...columns[it] }
|
|
104
|
-
})
|
|
164
|
+
return { ...columns[it] }
|
|
165
|
+
})
|
|
105
166
|
const altered = Object.keys(columns)
|
|
106
167
|
.filter(it => !(it.includes('__deleted') || it.includes('__added')))
|
|
107
168
|
.map(it => {
|
|
108
|
-
|
|
109
|
-
|
|
169
|
+
return { name: it, ...columns[it] }
|
|
170
|
+
})
|
|
171
|
+
|
|
110
172
|
const deletedIndexes = Object.values(table.indexes__deleted || {}).map(it => {
|
|
111
|
-
const name = it['name']
|
|
112
|
-
const columns = Object.values(it['columns']).map(it => it['name'])
|
|
113
|
-
return { name, columns, isUnique: it['isUnique'] }
|
|
114
|
-
}).concat(
|
|
115
|
-
.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
173
|
+
const name = it['name']
|
|
174
|
+
const columns = Object.values(it['columns']).map(it => it['name'])
|
|
175
|
+
return { name, columns, isUnique: it['isUnique'] }
|
|
176
|
+
}).concat(
|
|
177
|
+
Object.keys(table.indexes || {}).filter(it => it.includes('__deleted'))
|
|
178
|
+
.map(it => {
|
|
179
|
+
const idx = table.indexes[it]
|
|
180
|
+
const name = idx['name']
|
|
181
|
+
const columns = Object.values(idx['columns']).map(it => it['name'])
|
|
182
|
+
return { name, columns, isUnique: idx['isUnique'] }
|
|
183
|
+
})
|
|
184
|
+
);
|
|
185
|
+
|
|
121
186
|
const addedIndexes = Object.values(table.indexes__added || {}).map(it => {
|
|
122
|
-
const name = it['name']
|
|
123
|
-
const columns = Object.values(it['columns']).map(it => it['name'])
|
|
124
|
-
return { name, columns, isUnique: idx['isUnique'] }
|
|
125
|
-
}).concat(
|
|
126
|
-
.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
187
|
+
const name = it['name']
|
|
188
|
+
const columns = Object.values(it['columns']).map(it => it['name'])
|
|
189
|
+
return { name, columns, isUnique: idx['isUnique'] }
|
|
190
|
+
}).concat(
|
|
191
|
+
Object.keys(table.indexes || {}).filter(it => it.includes('__added'))
|
|
192
|
+
.map(it => {
|
|
193
|
+
const idx = table.indexes[it]
|
|
194
|
+
const name = idx['name']
|
|
195
|
+
const columns = Object.values(idx['columns']).map(it => it['name'])
|
|
196
|
+
return { name, columns, isUnique: idx['isUnique'] }
|
|
197
|
+
})
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const mappedAltered = altered.map(it => alternationsInColumn(it))
|
|
201
|
+
|
|
202
|
+
return { name: table.name, deleted, added, altered: mappedAltered, addedIndexes, deletedIndexes }
|
|
203
|
+
}
|
|
204
|
+
|
|
135
205
|
const alternationsInColumn = (column) => {
|
|
136
|
-
const altered = [column]
|
|
206
|
+
const altered = [column]
|
|
137
207
|
const result = altered.map(it => {
|
|
138
208
|
if (typeof it.name !== 'string' && '__old' in it.name) {
|
|
139
209
|
// rename
|
|
140
|
-
return { ...it, name: { type: 'changed', old: it.name.__old, new: it.name.__new } }
|
|
210
|
+
return { ...it, name: { type: 'changed', old: it.name.__old, new: it.name.__new } }
|
|
141
211
|
}
|
|
142
|
-
return it
|
|
212
|
+
return it
|
|
143
213
|
}).map(it => {
|
|
144
214
|
if ('type' in it) {
|
|
145
215
|
// type change
|
|
146
|
-
return { ...it, type: { type: 'changed', old: it.type.__old, new: it.type.__new } }
|
|
216
|
+
return { ...it, type: { type: 'changed', old: it.type.__old, new: it.type.__new } }
|
|
147
217
|
}
|
|
148
|
-
return it
|
|
218
|
+
return it
|
|
149
219
|
}).map(it => {
|
|
150
|
-
if ('
|
|
151
|
-
return { ...it, defaultValue: { type: 'changed', old: it.
|
|
220
|
+
if ('defaultValue' in it) {
|
|
221
|
+
return { ...it, defaultValue: { type: 'changed', old: it.defaultValue.__old, new: it.defaultValue.__new } }
|
|
152
222
|
}
|
|
153
|
-
if ('
|
|
154
|
-
const {
|
|
155
|
-
return { ...others, defaultValue: { type: 'added', value: it.
|
|
223
|
+
if ('defaultValue__added' in it) {
|
|
224
|
+
const { defaultValue__added, ...others } = it
|
|
225
|
+
return { ...others, defaultValue: { type: 'added', value: it.defaultValue__added } }
|
|
156
226
|
}
|
|
157
|
-
if ('
|
|
158
|
-
const {
|
|
159
|
-
return { ...others, defaultValue: { type: 'deleted', value: it.
|
|
227
|
+
if ('defaultValue__deleted' in it) {
|
|
228
|
+
const { defaultValue__deleted, ...others } = it
|
|
229
|
+
return { ...others, defaultValue: { type: 'deleted', value: it.defaultValue__deleted } }
|
|
160
230
|
}
|
|
161
|
-
return it
|
|
231
|
+
return it
|
|
162
232
|
}).map(it => {
|
|
163
233
|
if ('notNull' in it) {
|
|
164
|
-
return { ...it, notNull: { type: 'changed', old: it.notNull.__old, new: it.notNull.__new } }
|
|
234
|
+
return { ...it, notNull: { type: 'changed', old: it.notNull.__old, new: it.notNull.__new } }
|
|
165
235
|
}
|
|
166
236
|
if ('notNull__added' in it) {
|
|
167
|
-
const { notNull__added, ...others } = it
|
|
168
|
-
return { ...others, notNull: { type: 'added', value: it.notNull__added } }
|
|
237
|
+
const { notNull__added, ...others } = it
|
|
238
|
+
return { ...others, notNull: { type: 'added', value: it.notNull__added } }
|
|
169
239
|
}
|
|
170
240
|
if ('notNull__deleted' in it) {
|
|
171
|
-
const { notNull__deleted, ...others } = it
|
|
172
|
-
return { ...others, notNull: { type: 'deleted', value: it.notNull__deleted } }
|
|
241
|
+
const { notNull__deleted, ...others } = it
|
|
242
|
+
return { ...others, notNull: { type: 'deleted', value: it.notNull__deleted } }
|
|
173
243
|
}
|
|
174
|
-
return it
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
|
|
244
|
+
return it
|
|
245
|
+
}).map(it => {
|
|
246
|
+
if ('references' in it) {
|
|
247
|
+
return { ...it, references: { type: 'changed', old: it.references.__old, new: it.references.__new } }
|
|
248
|
+
}
|
|
249
|
+
if ('references__added' in it) {
|
|
250
|
+
const { references__added, ...others } = it
|
|
251
|
+
return { ...others, references: { type: 'added', value: it.references__added } }
|
|
252
|
+
}
|
|
253
|
+
if ('references__deleted' in it) {
|
|
254
|
+
const { references__deleted, ...others } = it
|
|
255
|
+
return { ...others, references: { type: 'deleted', value: it.references__deleted } }
|
|
256
|
+
}
|
|
257
|
+
return it
|
|
258
|
+
})
|
|
259
|
+
return result[0]
|
|
260
|
+
}
|