orchid-orm 1.4.19 → 1.4.21
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/CHANGELOG.md +10 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +998 -86
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1021 -84
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/{appCodeUpdater → codegen}/appCodeUpdater.test.ts +33 -9
- package/src/{appCodeUpdater → codegen}/appCodeUpdater.ts +16 -4
- package/src/codegen/createBaseTableFile.test.ts +58 -0
- package/src/codegen/createBaseTableFile.ts +36 -0
- package/src/{appCodeUpdater → codegen}/fileChanges.ts +0 -0
- package/src/{appCodeUpdater → codegen}/testUtils.ts +0 -0
- package/src/{appCodeUpdater → codegen}/tsUtils.ts +0 -0
- package/src/{appCodeUpdater → codegen}/updateMainFile.test.ts +34 -15
- package/src/{appCodeUpdater → codegen}/updateMainFile.ts +57 -11
- package/src/{appCodeUpdater → codegen}/updateTableFile/changeTable.test.ts +1 -0
- package/src/{appCodeUpdater → codegen}/updateTableFile/changeTable.ts +0 -0
- package/src/{appCodeUpdater → codegen}/updateTableFile/createTable.test.ts +11 -3
- package/src/{appCodeUpdater → codegen}/updateTableFile/createTable.ts +3 -1
- package/src/{appCodeUpdater → codegen}/updateTableFile/renameTable.test.ts +1 -0
- package/src/{appCodeUpdater → codegen}/updateTableFile/renameTable.ts +0 -0
- package/src/{appCodeUpdater → codegen}/updateTableFile/updateTableFile.ts +0 -0
- package/src/{appCodeUpdater → codegen}/utils.ts +0 -0
- package/src/index.ts +1 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orchid-orm",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.21",
|
|
4
4
|
"description": "Postgres ORM",
|
|
5
5
|
"homepage": "https://orchid-orm.netlify.app/guide/orm-setup-and-overview.html",
|
|
6
6
|
"repository": {
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
"author": "Roman Kushyn",
|
|
32
32
|
"license": "ISC",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"pqb": "0.8.
|
|
34
|
+
"pqb": "0.8.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@swc/core": "^1.3.19",
|
|
38
38
|
"rollup": "^2.79.0",
|
|
39
39
|
"rollup-plugin-dts": "^4.2.2",
|
|
40
40
|
"rollup-plugin-esbuild": "^4.10.1",
|
|
41
|
-
"orchid-orm-schema-to-zod": "0.2.
|
|
41
|
+
"orchid-orm-schema-to-zod": "0.2.4",
|
|
42
42
|
"@swc/jest": "^0.2.21",
|
|
43
43
|
"@types/jest": "^28.1.2",
|
|
44
44
|
"@types/node": "^18.0.1",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"rimraf": "^3.0.2",
|
|
51
51
|
"tslib": "^2.4.0",
|
|
52
52
|
"typescript": "^4.7.4",
|
|
53
|
-
"rake-db": "2.2.
|
|
53
|
+
"rake-db": "2.2.4"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"typescript": "*"
|
|
@@ -3,6 +3,7 @@ import { asMock, ast } from './testUtils';
|
|
|
3
3
|
import { updateMainFile } from './updateMainFile';
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { updateTableFile } from './updateTableFile/updateTableFile';
|
|
6
|
+
import { createBaseTableFile } from './createBaseTableFile';
|
|
6
7
|
|
|
7
8
|
jest.mock('./updateMainFile', () => ({
|
|
8
9
|
updateMainFile: jest.fn(),
|
|
@@ -12,18 +13,24 @@ jest.mock('./updateTableFile/updateTableFile', () => ({
|
|
|
12
13
|
updateTableFile: jest.fn(),
|
|
13
14
|
}));
|
|
14
15
|
|
|
16
|
+
jest.mock('./createBaseTableFile', () => ({
|
|
17
|
+
createBaseTableFile: jest.fn(() => Promise.resolve()),
|
|
18
|
+
}));
|
|
19
|
+
|
|
15
20
|
describe('appCodeUpdater', () => {
|
|
16
|
-
|
|
17
|
-
const params = {
|
|
18
|
-
tablePath: (table: string) => `tables/${table}.ts`,
|
|
19
|
-
baseTablePath: 'baseTable.ts',
|
|
20
|
-
baseTableName: 'BaseTable',
|
|
21
|
-
mainFilePath: 'db.ts',
|
|
22
|
-
};
|
|
21
|
+
beforeEach(jest.clearAllMocks);
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
const params = {
|
|
24
|
+
tablePath: (table: string) => `tables/${table}.ts`,
|
|
25
|
+
baseTablePath: 'baseTable.ts',
|
|
26
|
+
baseTableName: 'BaseTable',
|
|
27
|
+
mainFilePath: 'db.ts',
|
|
28
|
+
};
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
const fn = appCodeUpdater(params);
|
|
31
|
+
|
|
32
|
+
it('should call table and file updaters with proper arguments', async () => {
|
|
33
|
+
await fn({ ast: ast.addTable, options: {}, cache: {} });
|
|
27
34
|
|
|
28
35
|
const mainFilePath = path.resolve(params.mainFilePath);
|
|
29
36
|
const tablePath = path.resolve(params.tablePath('table'));
|
|
@@ -38,5 +45,22 @@ describe('appCodeUpdater', () => {
|
|
|
38
45
|
expect(table.baseTablePath).toBe(params.baseTablePath);
|
|
39
46
|
expect(table.baseTableName).toBe(params.baseTableName);
|
|
40
47
|
expect(table.mainFilePath).toBe(mainFilePath);
|
|
48
|
+
|
|
49
|
+
const [base] = asMock(createBaseTableFile).mock.calls[0];
|
|
50
|
+
expect(base.baseTablePath).toBe(params.baseTablePath);
|
|
51
|
+
expect(base.baseTableName).toBe(params.baseTableName);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should call createBaseTable only on first call', async () => {
|
|
55
|
+
const cache = {};
|
|
56
|
+
expect(createBaseTableFile).not.toBeCalled();
|
|
57
|
+
|
|
58
|
+
await fn({ ast: ast.addTable, options: {}, cache });
|
|
59
|
+
|
|
60
|
+
expect(createBaseTableFile).toBeCalledTimes(1);
|
|
61
|
+
|
|
62
|
+
await fn({ ast: ast.addTable, options: {}, cache });
|
|
63
|
+
|
|
64
|
+
expect(createBaseTableFile).toBeCalledTimes(1);
|
|
41
65
|
});
|
|
42
66
|
});
|
|
@@ -2,6 +2,7 @@ import { AppCodeUpdater } from 'rake-db';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { updateMainFile } from './updateMainFile';
|
|
4
4
|
import { updateTableFile } from './updateTableFile/updateTableFile';
|
|
5
|
+
import { createBaseTableFile } from './createBaseTableFile';
|
|
5
6
|
|
|
6
7
|
export class AppCodeUpdaterError extends Error {}
|
|
7
8
|
|
|
@@ -21,10 +22,21 @@ export const appCodeUpdater = (
|
|
|
21
22
|
mainFilePath: path.resolve(config.mainFilePath),
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
return async (ast) => {
|
|
25
|
-
|
|
26
|
-
updateMainFile(params.mainFilePath, params.tablePath, ast),
|
|
25
|
+
return async ({ ast, options, cache: cacheObject }) => {
|
|
26
|
+
const promises: Promise<void>[] = [
|
|
27
|
+
updateMainFile(params.mainFilePath, params.tablePath, ast, options),
|
|
27
28
|
updateTableFile({ ...params, ast }),
|
|
28
|
-
]
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const cache = cacheObject as { createdBaseTable?: true };
|
|
32
|
+
if (!cache.createdBaseTable) {
|
|
33
|
+
promises.push(
|
|
34
|
+
createBaseTableFile(params).then(() => {
|
|
35
|
+
cache.createdBaseTable = true;
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await Promise.all(promises);
|
|
29
41
|
};
|
|
30
42
|
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { createBaseTableFile } from './createBaseTableFile';
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import { asMock } from './testUtils';
|
|
5
|
+
|
|
6
|
+
jest.mock('fs/promises', () => ({
|
|
7
|
+
mkdir: jest.fn(),
|
|
8
|
+
writeFile: jest.fn(),
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
const params = {
|
|
12
|
+
baseTablePath: path.resolve('baseTable.ts'),
|
|
13
|
+
baseTableName: 'CustomName',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe('createBaseTableFile', () => {
|
|
17
|
+
it('should call mkdir with recursive option', async () => {
|
|
18
|
+
asMock(fs.writeFile).mockResolvedValue(null);
|
|
19
|
+
|
|
20
|
+
await createBaseTableFile(params);
|
|
21
|
+
|
|
22
|
+
expect(fs.mkdir).toBeCalledWith(path.dirname(params.baseTablePath), {
|
|
23
|
+
recursive: true,
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should write file with wx flag to not overwrite', async () => {
|
|
28
|
+
asMock(fs.writeFile).mockRejectedValueOnce(
|
|
29
|
+
Object.assign(new Error(), { code: 'EEXIST' }),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
await createBaseTableFile(params);
|
|
33
|
+
|
|
34
|
+
expect(asMock(fs.writeFile)).toBeCalledWith(
|
|
35
|
+
params.baseTablePath,
|
|
36
|
+
`import { createBaseTable } from 'orchid-orm';
|
|
37
|
+
import { columnTypes } from 'pqb';
|
|
38
|
+
|
|
39
|
+
export const ${params.baseTableName} = createBaseTable({
|
|
40
|
+
columnTypes: {
|
|
41
|
+
...columnTypes,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
`,
|
|
45
|
+
{
|
|
46
|
+
flag: 'wx',
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should throw if error is not EEXIST', async () => {
|
|
52
|
+
asMock(fs.writeFile).mockRejectedValueOnce(
|
|
53
|
+
Object.assign(new Error('custom'), { code: 'other' }),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
await expect(() => createBaseTableFile(params)).rejects.toThrow('custom');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AppCodeUpdaterConfig } from './appCodeUpdater';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
type CreateBaseTableFileParams = Pick<
|
|
6
|
+
AppCodeUpdaterConfig,
|
|
7
|
+
'baseTablePath' | 'baseTableName'
|
|
8
|
+
>;
|
|
9
|
+
|
|
10
|
+
export const createBaseTableFile = async ({
|
|
11
|
+
baseTableName,
|
|
12
|
+
baseTablePath,
|
|
13
|
+
}: CreateBaseTableFileParams) => {
|
|
14
|
+
await fs.mkdir(path.dirname(baseTablePath), { recursive: true });
|
|
15
|
+
|
|
16
|
+
await fs
|
|
17
|
+
.writeFile(
|
|
18
|
+
baseTablePath,
|
|
19
|
+
`import { createBaseTable } from 'orchid-orm';
|
|
20
|
+
import { columnTypes } from 'pqb';
|
|
21
|
+
|
|
22
|
+
export const ${baseTableName} = createBaseTable({
|
|
23
|
+
columnTypes: {
|
|
24
|
+
...columnTypes,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
`,
|
|
28
|
+
{
|
|
29
|
+
flag: 'wx',
|
|
30
|
+
},
|
|
31
|
+
)
|
|
32
|
+
.catch((err) => {
|
|
33
|
+
if (err.code === 'EEXIST') return;
|
|
34
|
+
throw err;
|
|
35
|
+
});
|
|
36
|
+
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -6,25 +6,44 @@ import { asMock, ast, makeTestWritten, tablePath } from './testUtils';
|
|
|
6
6
|
jest.mock('fs/promises', () => ({
|
|
7
7
|
readFile: jest.fn(),
|
|
8
8
|
writeFile: jest.fn(),
|
|
9
|
+
mkdir: jest.fn(),
|
|
9
10
|
}));
|
|
10
11
|
|
|
11
12
|
const mainFilePath = path.resolve('db.ts');
|
|
12
13
|
const testWritten = makeTestWritten(mainFilePath);
|
|
14
|
+
const options = { databaseURL: 'url' };
|
|
13
15
|
|
|
14
16
|
describe('updateMainFile', () => {
|
|
15
17
|
beforeEach(() => {
|
|
16
18
|
jest.resetAllMocks();
|
|
17
19
|
});
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
describe('add table', () => {
|
|
22
|
+
it('should create file if not exist and add a table', async () => {
|
|
23
|
+
asMock(fs.readFile).mockRejectedValue(
|
|
24
|
+
Object.assign(new Error(), { code: 'ENOENT' }),
|
|
25
|
+
);
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
await updateMainFile(mainFilePath, tablePath, ast.addTable, options);
|
|
28
|
+
|
|
29
|
+
expect(asMock(fs.mkdir)).toBeCalledWith(path.dirname(mainFilePath), {
|
|
30
|
+
recursive: true,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
testWritten(`import { orchidORM } from 'orchid-orm';
|
|
34
|
+
import { Table } from './tables/table';
|
|
35
|
+
|
|
36
|
+
export const db = orchidORM(
|
|
37
|
+
{
|
|
38
|
+
databaseURL: 'url',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
table: Table,
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
`);
|
|
45
|
+
});
|
|
26
46
|
|
|
27
|
-
describe('add table', () => {
|
|
28
47
|
it('should add table', async () => {
|
|
29
48
|
asMock(fs.readFile).mockResolvedValue(`
|
|
30
49
|
import { orchidORM } from 'orchid-orm';
|
|
@@ -32,7 +51,7 @@ import { orchidORM } from 'orchid-orm';
|
|
|
32
51
|
export const db = orchidORM({}, {});
|
|
33
52
|
`);
|
|
34
53
|
|
|
35
|
-
await updateMainFile(mainFilePath, tablePath, ast.addTable);
|
|
54
|
+
await updateMainFile(mainFilePath, tablePath, ast.addTable, options);
|
|
36
55
|
|
|
37
56
|
testWritten(`
|
|
38
57
|
import { orchidORM } from 'orchid-orm';
|
|
@@ -51,7 +70,7 @@ import { orchidORM as custom } from 'orchid-orm';
|
|
|
51
70
|
export const db = custom({}, {});
|
|
52
71
|
`);
|
|
53
72
|
|
|
54
|
-
await updateMainFile(mainFilePath, tablePath, ast.addTable);
|
|
73
|
+
await updateMainFile(mainFilePath, tablePath, ast.addTable, options);
|
|
55
74
|
|
|
56
75
|
testWritten(`
|
|
57
76
|
import { orchidORM as custom } from 'orchid-orm';
|
|
@@ -73,7 +92,7 @@ export const db = orchidORM({}, {
|
|
|
73
92
|
});
|
|
74
93
|
`);
|
|
75
94
|
|
|
76
|
-
await updateMainFile(mainFilePath, tablePath, ast.addTable);
|
|
95
|
+
await updateMainFile(mainFilePath, tablePath, ast.addTable, options);
|
|
77
96
|
|
|
78
97
|
testWritten(`
|
|
79
98
|
import { orchidORM } from 'orchid-orm';
|
|
@@ -97,7 +116,7 @@ export const db = orchidORM({}, {
|
|
|
97
116
|
});
|
|
98
117
|
`);
|
|
99
118
|
|
|
100
|
-
await updateMainFile(mainFilePath, tablePath, ast.addTable);
|
|
119
|
+
await updateMainFile(mainFilePath, tablePath, ast.addTable, options);
|
|
101
120
|
|
|
102
121
|
testWritten(`
|
|
103
122
|
import { orchidORM } from 'orchid-orm';
|
|
@@ -123,7 +142,7 @@ export const db = orchidORM({}, {
|
|
|
123
142
|
});
|
|
124
143
|
`);
|
|
125
144
|
|
|
126
|
-
await updateMainFile(mainFilePath, tablePath, ast.dropTable);
|
|
145
|
+
await updateMainFile(mainFilePath, tablePath, ast.dropTable, options);
|
|
127
146
|
|
|
128
147
|
testWritten(`
|
|
129
148
|
import { orchidORM } from 'orchid-orm';
|
|
@@ -143,7 +162,7 @@ export const db = orchidORM({}, {
|
|
|
143
162
|
});
|
|
144
163
|
`);
|
|
145
164
|
|
|
146
|
-
await updateMainFile(mainFilePath, tablePath, ast.dropTable);
|
|
165
|
+
await updateMainFile(mainFilePath, tablePath, ast.dropTable, options);
|
|
147
166
|
|
|
148
167
|
testWritten(`
|
|
149
168
|
import { orchidORM } from 'orchid-orm';
|
|
@@ -163,7 +182,7 @@ export const db = orchidORM({}, {
|
|
|
163
182
|
});
|
|
164
183
|
`);
|
|
165
184
|
|
|
166
|
-
await updateMainFile(mainFilePath, tablePath, ast.dropTable);
|
|
185
|
+
await updateMainFile(mainFilePath, tablePath, ast.dropTable, options);
|
|
167
186
|
|
|
168
187
|
testWritten(`
|
|
169
188
|
import { orchidORM } from 'orchid-orm';
|
|
@@ -187,7 +206,7 @@ export const db = orchidORM({}, {
|
|
|
187
206
|
});
|
|
188
207
|
`);
|
|
189
208
|
|
|
190
|
-
await updateMainFile(mainFilePath, tablePath, ast.dropTable);
|
|
209
|
+
await updateMainFile(mainFilePath, tablePath, ast.dropTable, options);
|
|
191
210
|
|
|
192
211
|
testWritten(`
|
|
193
212
|
import { orchidORM } from 'orchid-orm';
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { RakeDbAst } from 'rake-db';
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
3
4
|
import { NodeArray, ObjectLiteralExpression, Statement } from 'typescript';
|
|
4
5
|
import { toCamelCase, toPascalCase } from '../utils';
|
|
5
6
|
import { AppCodeUpdaterError } from './appCodeUpdater';
|
|
6
7
|
import { FileChanges } from './fileChanges';
|
|
7
8
|
import { ts } from './tsUtils';
|
|
8
9
|
import { getImportPath } from './utils';
|
|
10
|
+
import { AdapterOptions, singleQuote } from 'pqb';
|
|
9
11
|
|
|
10
12
|
type Context = {
|
|
11
|
-
|
|
13
|
+
filePath: string;
|
|
12
14
|
tablePath: (name: string) => string;
|
|
13
15
|
statements: NodeArray<Statement>;
|
|
14
16
|
object: ObjectLiteralExpression;
|
|
@@ -19,12 +21,48 @@ type Context = {
|
|
|
19
21
|
const libraryName = 'orchid-orm';
|
|
20
22
|
const importKey = 'orchidORM';
|
|
21
23
|
|
|
24
|
+
const newFile = (
|
|
25
|
+
options: AdapterOptions,
|
|
26
|
+
) => `import { orchidORM } from 'orchid-orm';
|
|
27
|
+
|
|
28
|
+
export const db = orchidORM(
|
|
29
|
+
{
|
|
30
|
+
${optionsToString(options)}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
const optionsToString = (options: AdapterOptions) => {
|
|
38
|
+
const lines: string[] = [];
|
|
39
|
+
for (const key in options) {
|
|
40
|
+
const value = options[key as keyof AdapterOptions];
|
|
41
|
+
if (typeof value !== 'object' && typeof value !== 'function') {
|
|
42
|
+
lines.push(
|
|
43
|
+
`${key}: ${typeof value === 'string' ? singleQuote(value) : value},`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return lines.join('\n ');
|
|
48
|
+
};
|
|
49
|
+
|
|
22
50
|
export const updateMainFile = async (
|
|
23
|
-
|
|
51
|
+
filePath: string,
|
|
24
52
|
tablePath: (name: string) => string,
|
|
25
53
|
ast: RakeDbAst,
|
|
54
|
+
options: AdapterOptions,
|
|
26
55
|
) => {
|
|
27
|
-
const
|
|
56
|
+
const result = await fs.readFile(filePath, 'utf-8').then(
|
|
57
|
+
(content) => ({ error: undefined, content }),
|
|
58
|
+
(error) => {
|
|
59
|
+
return { error, content: undefined };
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
if (result.error && result.error.code !== 'ENOENT') throw result.error;
|
|
64
|
+
const content = result.content || newFile(options);
|
|
65
|
+
|
|
28
66
|
const statements = ts.getStatements(content);
|
|
29
67
|
|
|
30
68
|
const importName = ts.import.getStatementsImportedName(
|
|
@@ -46,7 +84,7 @@ export const updateMainFile = async (
|
|
|
46
84
|
const spaces = ts.spaces.getAtLine(content, object.end);
|
|
47
85
|
|
|
48
86
|
const context: Context = {
|
|
49
|
-
|
|
87
|
+
filePath,
|
|
50
88
|
tablePath,
|
|
51
89
|
statements,
|
|
52
90
|
object,
|
|
@@ -54,20 +92,28 @@ export const updateMainFile = async (
|
|
|
54
92
|
spaces,
|
|
55
93
|
};
|
|
56
94
|
|
|
95
|
+
let write: string | undefined;
|
|
57
96
|
if (ast.type === 'table') {
|
|
58
97
|
if (ast.action === 'create') {
|
|
59
|
-
|
|
98
|
+
write = createTable(context, ast);
|
|
60
99
|
} else {
|
|
61
|
-
|
|
100
|
+
write = dropTable(context, ast);
|
|
62
101
|
}
|
|
63
102
|
}
|
|
64
|
-
|
|
65
103
|
// rename table is not handled because renaming of the class and the file is better to be done by the editor,
|
|
66
104
|
// editor can scan all project files, rename import path and imported class name
|
|
105
|
+
|
|
106
|
+
if (write) {
|
|
107
|
+
if (result.error) {
|
|
108
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await fs.writeFile(filePath, write);
|
|
112
|
+
}
|
|
67
113
|
};
|
|
68
114
|
|
|
69
115
|
const createTable = (
|
|
70
|
-
{
|
|
116
|
+
{ filePath, tablePath, statements, object, content, spaces }: Context,
|
|
71
117
|
ast: RakeDbAst.Table,
|
|
72
118
|
) => {
|
|
73
119
|
const key = toCamelCase(ast.name);
|
|
@@ -75,7 +121,7 @@ const createTable = (
|
|
|
75
121
|
|
|
76
122
|
const changes = new FileChanges(content);
|
|
77
123
|
|
|
78
|
-
const importPath = getImportPath(
|
|
124
|
+
const importPath = getImportPath(filePath, tablePath(ast.name));
|
|
79
125
|
const importPos = ts.import.getEndPos(statements);
|
|
80
126
|
changes.add(
|
|
81
127
|
importPos,
|
|
@@ -95,12 +141,12 @@ const createTable = (
|
|
|
95
141
|
};
|
|
96
142
|
|
|
97
143
|
const dropTable = (
|
|
98
|
-
{
|
|
144
|
+
{ filePath, tablePath, statements, object, content }: Context,
|
|
99
145
|
ast: RakeDbAst.Table,
|
|
100
146
|
) => {
|
|
101
147
|
const changes = new FileChanges(content);
|
|
102
148
|
|
|
103
|
-
const importPath = getImportPath(
|
|
149
|
+
const importPath = getImportPath(filePath, tablePath(ast.name));
|
|
104
150
|
const tableClassName = toPascalCase(ast.name);
|
|
105
151
|
const importNames: string[] = [];
|
|
106
152
|
for (const node of ts.import.iterateWithSource(statements, importPath)) {
|
|
File without changes
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { updateTableFile } from './updateTableFile';
|
|
2
|
-
import { ast, makeTestWritten, tablePath } from '../testUtils';
|
|
2
|
+
import { asMock, ast, makeTestWritten, tablePath } from '../testUtils';
|
|
3
3
|
import path from 'path';
|
|
4
|
+
import fs from 'fs/promises';
|
|
4
5
|
|
|
5
6
|
jest.mock('fs/promises', () => ({
|
|
6
7
|
readFile: jest.fn(),
|
|
7
8
|
writeFile: jest.fn(),
|
|
9
|
+
mkdir: jest.fn(),
|
|
8
10
|
}));
|
|
9
11
|
|
|
10
12
|
const baseTablePath = path.resolve('baseTable.ts');
|
|
@@ -44,6 +46,10 @@ describe('createTable', () => {
|
|
|
44
46
|
},
|
|
45
47
|
});
|
|
46
48
|
|
|
49
|
+
expect(asMock(fs.mkdir)).toBeCalledWith(path.dirname(tablePath('table')), {
|
|
50
|
+
recursive: true,
|
|
51
|
+
});
|
|
52
|
+
|
|
47
53
|
testWritten(`import { BaseTable } from '../baseTable';
|
|
48
54
|
|
|
49
55
|
export class Table extends BaseTable {
|
|
@@ -64,7 +70,8 @@ export class Table extends BaseTable {
|
|
|
64
70
|
},
|
|
65
71
|
),
|
|
66
72
|
}));
|
|
67
|
-
}
|
|
73
|
+
}
|
|
74
|
+
`);
|
|
68
75
|
});
|
|
69
76
|
|
|
70
77
|
it('should add noPrimaryKey prop when noPrimaryKey is `ignore` in ast', async () => {
|
|
@@ -81,6 +88,7 @@ export class Table extends BaseTable {
|
|
|
81
88
|
columns = this.setColumns((t) => ({
|
|
82
89
|
id: t.serial().primaryKey(),
|
|
83
90
|
}));
|
|
84
|
-
}
|
|
91
|
+
}
|
|
92
|
+
`);
|
|
85
93
|
});
|
|
86
94
|
});
|
|
@@ -4,6 +4,7 @@ import { Code, codeToString, columnsShapeToCode, singleQuote } from 'pqb';
|
|
|
4
4
|
import { toPascalCase } from '../../utils';
|
|
5
5
|
import fs from 'fs/promises';
|
|
6
6
|
import { UpdateTableFileParams } from './updateTableFile';
|
|
7
|
+
import path from 'path';
|
|
7
8
|
|
|
8
9
|
export const createTable = async ({
|
|
9
10
|
ast,
|
|
@@ -27,8 +28,9 @@ export const createTable = async ({
|
|
|
27
28
|
`import { ${params.baseTableName} } from '${baseTablePath}';\n`,
|
|
28
29
|
`export class ${toPascalCase(ast.name)} extends ${params.baseTableName} {`,
|
|
29
30
|
props,
|
|
30
|
-
'}',
|
|
31
|
+
'}\n',
|
|
31
32
|
];
|
|
32
33
|
|
|
34
|
+
await fs.mkdir(path.dirname(tablePath), { recursive: true });
|
|
33
35
|
await fs.writeFile(tablePath, codeToString(code, '', ' '));
|
|
34
36
|
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|