@zenorm/generate 0.0.1
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 +4 -0
- package/README.md +251 -0
- package/dist/bin/zenorm-generate.d.ts +2 -0
- package/dist/bin/zenorm-generate.js +27 -0
- package/dist/generate.d.ts +2 -0
- package/dist/generate.js +156 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -0
- package/dist/types.d.ts +88 -0
- package/dist/types.js +2 -0
- package/package.json +39 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# ZenORM
|
|
2
|
+
|
|
3
|
+
[ZenWeb](https://www.npmjs.com/package/zenweb) 衍生的核心项目,此项目可以独立使用
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install zenorm mysql-easy-query
|
|
9
|
+
npm install @zenorm/mysql --save-dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 配置
|
|
13
|
+
|
|
14
|
+
在 `package.json` 的 `scripts` 中增加如下代码,用于执行 `dbgen` 命令
|
|
15
|
+
|
|
16
|
+
```json title="package.json"
|
|
17
|
+
{
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dbgen": "zenorm gen .dbgen.json"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
创建文件 `.dbgen.json` 用于生成数据库结构代码时连接到指定数据库
|
|
25
|
+
|
|
26
|
+
*提示:运行时并不使用此配置*
|
|
27
|
+
|
|
28
|
+
```json title=".dbgen.json"
|
|
29
|
+
{
|
|
30
|
+
"host": "localhost",
|
|
31
|
+
"port": 3306,
|
|
32
|
+
"user": "root",
|
|
33
|
+
"password": "",
|
|
34
|
+
"database": "test"
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 演示
|
|
39
|
+
|
|
40
|
+
以下数据库结构为演示用,在数据中创建表结构
|
|
41
|
+
|
|
42
|
+
```sql
|
|
43
|
+
CREATE TABLE `user` (
|
|
44
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
45
|
+
`name` varchar(255) NOT NULL,
|
|
46
|
+
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
47
|
+
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
48
|
+
PRIMARY KEY (`id`)
|
|
49
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
50
|
+
|
|
51
|
+
CREATE TABLE `profile` (
|
|
52
|
+
`id` int(11) NOT NULL,
|
|
53
|
+
`edu` varchar(255) DEFAULT NULL,
|
|
54
|
+
`work` varchar(255) DEFAULT NULL,
|
|
55
|
+
PRIMARY KEY (`id`)
|
|
56
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
57
|
+
|
|
58
|
+
CREATE TABLE `message` (
|
|
59
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
60
|
+
`user_id` int(11) NOT NULL,
|
|
61
|
+
`content` varchar(255) DEFAULT NULL,
|
|
62
|
+
PRIMARY KEY (`id`),
|
|
63
|
+
KEY `fk1` (`user_id`)
|
|
64
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
运行命令开始生成数据库结构代码
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm run dbgen
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 编辑模型关系
|
|
74
|
+
|
|
75
|
+
编辑生成的模型文件 `src/model/user.ts`
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { model, createRepositoryQuery, join, many, data } from 'zenorm';
|
|
79
|
+
import { UserTable } from './_tables';
|
|
80
|
+
import { Profile } from './profile';
|
|
81
|
+
import { Message } from './message';
|
|
82
|
+
|
|
83
|
+
@model({
|
|
84
|
+
pk: 'id',
|
|
85
|
+
table: 'user',
|
|
86
|
+
})
|
|
87
|
+
export default class User extends UserTable {
|
|
88
|
+
static query = createRepositoryQuery<User, number>(User);
|
|
89
|
+
|
|
90
|
+
// 添加以下代码
|
|
91
|
+
|
|
92
|
+
// join 描述支持使用文件名,解决互相依赖问题
|
|
93
|
+
@join(__dirname + '/profile', { type: 'OneToMany', asList: false })
|
|
94
|
+
profile?: Profile;
|
|
95
|
+
|
|
96
|
+
@join(Message)
|
|
97
|
+
messages?: Message[];
|
|
98
|
+
|
|
99
|
+
@many(Message)
|
|
100
|
+
messageList?: Message[];
|
|
101
|
+
|
|
102
|
+
@data
|
|
103
|
+
get age() {
|
|
104
|
+
return this.birthday ? (new Date().getFullYear()) - this.birthday.getFullYear() : undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
set age(v) {
|
|
108
|
+
if (v === undefined) throw new Error('age is undefined');
|
|
109
|
+
const date = new Date();
|
|
110
|
+
date.setFullYear(date.getFullYear() - v, 1, 1);
|
|
111
|
+
this.birthday = date;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
编辑生成的模型文件 `src/model/profile.ts`
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { model, createRepositoryQuery, join } from 'zenorm';
|
|
120
|
+
import { ProfileTable } from './_tables';
|
|
121
|
+
import User from './user';
|
|
122
|
+
|
|
123
|
+
@model({
|
|
124
|
+
pk: 'id',
|
|
125
|
+
table: 'profile',
|
|
126
|
+
})
|
|
127
|
+
export default class Profile extends ProfileTable {
|
|
128
|
+
static query = createRepositoryQuery<Profile, number>(Profile);
|
|
129
|
+
|
|
130
|
+
// 添加以下代码
|
|
131
|
+
|
|
132
|
+
@join(User)
|
|
133
|
+
user?: User;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 初始化数据库访问层
|
|
138
|
+
|
|
139
|
+
创建代码 `src/db.ts`
|
|
140
|
+
|
|
141
|
+
```ts title="src/test.ts"
|
|
142
|
+
import { createPoolCompatible } from 'mysql-easy-query';
|
|
143
|
+
import { Repositories } from './model';
|
|
144
|
+
|
|
145
|
+
// 创建数据库连接池
|
|
146
|
+
export const pool = createPoolCompatible({
|
|
147
|
+
pools: {
|
|
148
|
+
// 主库
|
|
149
|
+
MASTER: {
|
|
150
|
+
host: '10.0.0.1',
|
|
151
|
+
user: 'root',
|
|
152
|
+
database: 'test',
|
|
153
|
+
password: '',
|
|
154
|
+
},
|
|
155
|
+
// 如果需要读写分离,创建命令规则为 SLAVE* 的只读配置
|
|
156
|
+
/*
|
|
157
|
+
SLAVE1: {
|
|
158
|
+
host: '10.0.0.2'
|
|
159
|
+
},
|
|
160
|
+
*/
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// 创建仓库访问层
|
|
165
|
+
export const repositories = new Repositories(pool);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 开始使用
|
|
169
|
+
|
|
170
|
+
#### 常规使用
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { repositories } from './db';
|
|
174
|
+
|
|
175
|
+
const {
|
|
176
|
+
UserRepository,
|
|
177
|
+
MessageRepository,
|
|
178
|
+
} = repositories;
|
|
179
|
+
|
|
180
|
+
async function test() {
|
|
181
|
+
// create
|
|
182
|
+
const id = await UserRepository.create({ name: 'yf' });
|
|
183
|
+
console.log(id); // 1
|
|
184
|
+
|
|
185
|
+
// get and update
|
|
186
|
+
const user = await UserRepository.findByPk(id);
|
|
187
|
+
user.name = 'yefei';
|
|
188
|
+
user.age = 20;
|
|
189
|
+
await UserRepository.save(user);
|
|
190
|
+
|
|
191
|
+
// find all
|
|
192
|
+
const users = await UserRepository.find().all();
|
|
193
|
+
|
|
194
|
+
// find limit
|
|
195
|
+
const users = await UserRepository.find().limit(10).all();
|
|
196
|
+
|
|
197
|
+
// find by where
|
|
198
|
+
const users = await UserRepository.find({ name: { $like: `%y%` } }).all();
|
|
199
|
+
|
|
200
|
+
// get all count
|
|
201
|
+
const count = await UserRepository.count();
|
|
202
|
+
|
|
203
|
+
// page
|
|
204
|
+
const page = await UserRepository.page();
|
|
205
|
+
|
|
206
|
+
// exists
|
|
207
|
+
const exists = await UserRepository.exists({ id: 1 });
|
|
208
|
+
// or
|
|
209
|
+
const exists = await UserRepository.find({ name: 'yf' }).exists();
|
|
210
|
+
|
|
211
|
+
// update
|
|
212
|
+
const updatedCount = await UserRepository.find({ id: 1 }).update({ name: 'yf', age: 11 });
|
|
213
|
+
|
|
214
|
+
// delete
|
|
215
|
+
const user = await UserRepository.findByPk(1);
|
|
216
|
+
const deletedCount = await UserRepository.delete(user);
|
|
217
|
+
|
|
218
|
+
await UserRepository.find({ name: 'aaa' }).delete();
|
|
219
|
+
|
|
220
|
+
// join 预定义
|
|
221
|
+
const user = await UserRepository.find().join("messages").get();
|
|
222
|
+
|
|
223
|
+
// join 模型(未定义的)
|
|
224
|
+
const user = await MessageRepository.find().join(User).all();
|
|
225
|
+
|
|
226
|
+
// many 独立查询功能
|
|
227
|
+
const userList = await UserRepository.find().many("messageList").all();
|
|
228
|
+
|
|
229
|
+
// 指定使用主从库
|
|
230
|
+
await UserRepository.find().of('MASTER').all();
|
|
231
|
+
await UserRepository.find().of('SLAVE*').all();
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### 事物支持
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
import { pool } from './db';
|
|
239
|
+
import { User, Message } from './model';
|
|
240
|
+
|
|
241
|
+
async function test() {
|
|
242
|
+
await pool.transaction(async tx => {
|
|
243
|
+
await User.query(tx).find().update({ some: 'data' });
|
|
244
|
+
await Message.query(tx).find().update({ some: 'data' });
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Related projects
|
|
250
|
+
[mysql-easy-query](https://www.npmjs.com/package/mysql-easy-query)
|
|
251
|
+
[sql-easy-builder](https://www.npmjs.com/package/sql-easy-builder)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const generate_1 = require("../generate");
|
|
6
|
+
function getConfig() {
|
|
7
|
+
const configFile = path.join(process.cwd(), process.argv[3]);
|
|
8
|
+
const config = require(configFile);
|
|
9
|
+
return Object.assign({
|
|
10
|
+
backend: '@zenorm/mysql',
|
|
11
|
+
}, config);
|
|
12
|
+
}
|
|
13
|
+
async function main() {
|
|
14
|
+
const config = await getConfig();
|
|
15
|
+
const call = require(config.backend).default;
|
|
16
|
+
await (0, generate_1.generate)(call()(config), config);
|
|
17
|
+
}
|
|
18
|
+
if (!process.argv[2]) {
|
|
19
|
+
console.log('zenorm-generate config.json');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
main().then(() => process.exit(), e => {
|
|
24
|
+
console.error(e);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
});
|
|
27
|
+
}
|
package/dist/generate.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generate = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const pascal_case_1 = require("pascal-case");
|
|
7
|
+
const snake_case_1 = require("snake-case");
|
|
8
|
+
const zenormName = process.env.ZENORM_NAME || 'zenorm';
|
|
9
|
+
function cwdPath(p) {
|
|
10
|
+
if (p.startsWith('./')) {
|
|
11
|
+
return path.join(process.cwd(), p.slice(2));
|
|
12
|
+
}
|
|
13
|
+
return p;
|
|
14
|
+
}
|
|
15
|
+
function checkFileDir(dir) {
|
|
16
|
+
return fs_1.promises.mkdir(dir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
function fileExists(f) {
|
|
19
|
+
return fs_1.promises.access(f).then(() => true, e => false);
|
|
20
|
+
}
|
|
21
|
+
function datetime() {
|
|
22
|
+
return new Date().toLocaleString();
|
|
23
|
+
}
|
|
24
|
+
async function generate(tables, cfg) {
|
|
25
|
+
console.log('generate models...');
|
|
26
|
+
const config = Object.assign({
|
|
27
|
+
outputDir: './src/model',
|
|
28
|
+
tablesFilename: '_tables',
|
|
29
|
+
repositoriesFilename: '_repositories',
|
|
30
|
+
globalFilename: '_global',
|
|
31
|
+
}, cfg);
|
|
32
|
+
const outputDir = cwdPath(config.outputDir);
|
|
33
|
+
await checkFileDir(outputDir);
|
|
34
|
+
console.log('database:', config.database);
|
|
35
|
+
const remark = [
|
|
36
|
+
'// zenorm 自动生成文件',
|
|
37
|
+
'// 请不要修改此文件,因为此文件在每次重新生成数据库结构时会被覆盖',
|
|
38
|
+
`// create at: ${datetime()}`,
|
|
39
|
+
`// create by: ${process.env.USER || process.env.USERNAME || '-'}@${process.env.COMPUTERNAME || '-'}`,
|
|
40
|
+
`// database: ${config.database}`,
|
|
41
|
+
];
|
|
42
|
+
const structs = [
|
|
43
|
+
...remark,
|
|
44
|
+
`import _Global from './${config.globalFilename}';`,
|
|
45
|
+
'',
|
|
46
|
+
];
|
|
47
|
+
const models = [];
|
|
48
|
+
const filterRegExp = config.filter ? new RegExp(config.filter) : null;
|
|
49
|
+
const includeRegExp = config.include ? new RegExp(config.include) : null;
|
|
50
|
+
for await (const t of tables) {
|
|
51
|
+
const tableName = t.name;
|
|
52
|
+
if ((filterRegExp && filterRegExp.test(tableName))
|
|
53
|
+
|| (includeRegExp && !includeRegExp.test(tableName))) {
|
|
54
|
+
// console.log('table:', tableName, 'ignore');
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const className = (0, pascal_case_1.pascalCase)(tableName);
|
|
58
|
+
const name = (0, snake_case_1.snakeCase)(tableName);
|
|
59
|
+
const outputFilename = path.join(outputDir, name + '.ts');
|
|
60
|
+
console.log('table:', tableName);
|
|
61
|
+
let pk = 'id';
|
|
62
|
+
let pkType = 'number';
|
|
63
|
+
const props = [];
|
|
64
|
+
const columns = [];
|
|
65
|
+
for (const c of t.columns) {
|
|
66
|
+
if (c.pk) {
|
|
67
|
+
pk = c.name;
|
|
68
|
+
pkType = c.type;
|
|
69
|
+
}
|
|
70
|
+
if (c.comment && c.comment.length) {
|
|
71
|
+
props.push(` /**`);
|
|
72
|
+
for (const line of c.comment) {
|
|
73
|
+
props.push(` * ${line}`);
|
|
74
|
+
}
|
|
75
|
+
props.push(` */`);
|
|
76
|
+
}
|
|
77
|
+
props.push(` ${c.name}${c.required ? '!' : '?'}: ${c.type};`);
|
|
78
|
+
columns.push(c.name);
|
|
79
|
+
}
|
|
80
|
+
structs.push(`export class ${className}Table extends _Global {`);
|
|
81
|
+
structs.push(` static columns = ${JSON.stringify(columns)};`);
|
|
82
|
+
structs.push(...props);
|
|
83
|
+
structs.push('}');
|
|
84
|
+
structs.push('');
|
|
85
|
+
if (!await fileExists(outputFilename)) {
|
|
86
|
+
const ts = [
|
|
87
|
+
`import { model } from '${zenormName}';`,
|
|
88
|
+
`import { ${className}Table } from './${config.tablesFilename}';`,
|
|
89
|
+
'',
|
|
90
|
+
`@model({`,
|
|
91
|
+
` pk: '${pk}',`,
|
|
92
|
+
name != tableName ? ` name: '${name}',` : null,
|
|
93
|
+
` table: '${tableName}',`,
|
|
94
|
+
`})`,
|
|
95
|
+
`export default class ${className} extends ${className}Table {`,
|
|
96
|
+
`}`,
|
|
97
|
+
'',
|
|
98
|
+
];
|
|
99
|
+
await fs_1.promises.writeFile(outputFilename, ts.filter(i => i !== null).join('\n'));
|
|
100
|
+
}
|
|
101
|
+
models.push([name, className, pkType]);
|
|
102
|
+
}
|
|
103
|
+
const tablesFilename = path.join(outputDir, config.tablesFilename + '.ts');
|
|
104
|
+
console.log(`write tables file: ${tablesFilename}`);
|
|
105
|
+
await fs_1.promises.writeFile(tablesFilename, structs.join('\n'));
|
|
106
|
+
const repositories = [
|
|
107
|
+
...remark,
|
|
108
|
+
`import { QueryParam, createRepositoryQuery } from '${zenormName}';`,
|
|
109
|
+
...models.map(([name, className]) => `import _${className} from './${name}';`),
|
|
110
|
+
'',
|
|
111
|
+
];
|
|
112
|
+
// static
|
|
113
|
+
models.forEach(([name, className, pkType]) => {
|
|
114
|
+
repositories.push(`export class ${className} extends _${className} {`, ` static query = createRepositoryQuery<${className}, ${pkType}>(${className});`, `}`, '');
|
|
115
|
+
});
|
|
116
|
+
// Repositories
|
|
117
|
+
repositories.push(`export class Repositories {`, ` constructor(private _query: QueryParam) {}`, ...models.map(([name, className]) => ` get ${className}Repository() { return ${className}.query(this._query); }`), `}`, '');
|
|
118
|
+
// 添加 Repositories 到目标模块中
|
|
119
|
+
if (config.declareRepositoriesToModules) {
|
|
120
|
+
for (const mod of config.declareRepositoriesToModules) {
|
|
121
|
+
const _m = mod.split('.');
|
|
122
|
+
repositories.push(`declare module '${_m[0]}' {`);
|
|
123
|
+
repositories.push(` interface ${_m.slice(1, -1).join('.')} {`);
|
|
124
|
+
repositories.push(` ${_m[_m.length - 1]}: Repositories;`);
|
|
125
|
+
repositories.push(` }`);
|
|
126
|
+
repositories.push(`}`);
|
|
127
|
+
repositories.push(``);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const repositoriesFilename = path.join(outputDir, config.repositoriesFilename + '.ts');
|
|
131
|
+
console.log(`write repositories file: ${repositoriesFilename}`);
|
|
132
|
+
await fs_1.promises.writeFile(repositoriesFilename, repositories.join('\n'));
|
|
133
|
+
// 生成 global.ts
|
|
134
|
+
await notExistsPut(path.join(outputDir, config.globalFilename + '.ts'), () => {
|
|
135
|
+
return 'export default class Global {}';
|
|
136
|
+
});
|
|
137
|
+
// 生成 index.ts
|
|
138
|
+
await notExistsPut(path.join(outputDir, 'index.ts'), () => {
|
|
139
|
+
return [
|
|
140
|
+
`export * from './${config.tablesFilename}';`,
|
|
141
|
+
`export * from './${config.repositoriesFilename}';`,
|
|
142
|
+
].join('\n');
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
exports.generate = generate;
|
|
146
|
+
/**
|
|
147
|
+
* 文件不存在则创建并写入内容
|
|
148
|
+
* @param filename
|
|
149
|
+
* @param getContent
|
|
150
|
+
*/
|
|
151
|
+
async function notExistsPut(filename, getContent) {
|
|
152
|
+
if (!await fileExists(filename)) {
|
|
153
|
+
console.log(`write file: ${filename}`);
|
|
154
|
+
await fs_1.promises.writeFile(filename, getContent());
|
|
155
|
+
}
|
|
156
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模型文件生成 - 列描述
|
|
3
|
+
*/
|
|
4
|
+
export interface ColumnDescribe {
|
|
5
|
+
/**
|
|
6
|
+
* 是否为主键
|
|
7
|
+
*/
|
|
8
|
+
pk: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* 列名称
|
|
11
|
+
*/
|
|
12
|
+
name: string;
|
|
13
|
+
/**
|
|
14
|
+
* 列类型,例如 number, string, boolean
|
|
15
|
+
*/
|
|
16
|
+
type: string;
|
|
17
|
+
/**
|
|
18
|
+
* 是否为必须项(非NULL)
|
|
19
|
+
*/
|
|
20
|
+
required: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* 注释信息,一行一条
|
|
23
|
+
*/
|
|
24
|
+
comment: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 模型文件生成 - 表描述
|
|
28
|
+
*/
|
|
29
|
+
export interface TabelDescribe {
|
|
30
|
+
/**
|
|
31
|
+
* 表名称
|
|
32
|
+
*/
|
|
33
|
+
name: string;
|
|
34
|
+
/**
|
|
35
|
+
* 列描述信息
|
|
36
|
+
*/
|
|
37
|
+
columns: ColumnDescribe[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 生成配置
|
|
41
|
+
*/
|
|
42
|
+
export interface GenerateConfig {
|
|
43
|
+
host?: string;
|
|
44
|
+
port?: number;
|
|
45
|
+
user?: string;
|
|
46
|
+
password?: string;
|
|
47
|
+
database?: string;
|
|
48
|
+
/**
|
|
49
|
+
* 代码输出目录
|
|
50
|
+
* @default './src/model'
|
|
51
|
+
*/
|
|
52
|
+
outputDir?: string;
|
|
53
|
+
/**
|
|
54
|
+
* 生成数据库表结构文件名
|
|
55
|
+
* 此文件每次生成都会被重新改写
|
|
56
|
+
* @default '_tables'
|
|
57
|
+
*/
|
|
58
|
+
tablesFilename?: string;
|
|
59
|
+
/**
|
|
60
|
+
* 生成 Repositories 文件名
|
|
61
|
+
* 此文件每次生成都会被重新改写
|
|
62
|
+
* @default '_repositories'
|
|
63
|
+
*/
|
|
64
|
+
repositoriesFilename?: string;
|
|
65
|
+
/**
|
|
66
|
+
* 全局文件名
|
|
67
|
+
* @default '_global'
|
|
68
|
+
*/
|
|
69
|
+
globalFilename?: string;
|
|
70
|
+
/**
|
|
71
|
+
* 是否需将 Repositories 实例定义到目标模块中
|
|
72
|
+
* - 例如: ["@zenweb/core.Core.repositories"]
|
|
73
|
+
* @default undefined
|
|
74
|
+
*/
|
|
75
|
+
declareRepositoriesToModules?: string[];
|
|
76
|
+
/**
|
|
77
|
+
* 表过滤规则正则,默认不处理
|
|
78
|
+
*/
|
|
79
|
+
filter?: string;
|
|
80
|
+
/**
|
|
81
|
+
* 表包含规则正则,默认不处理
|
|
82
|
+
*/
|
|
83
|
+
include?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 数据库表信息生成方法
|
|
87
|
+
*/
|
|
88
|
+
export type GenerateFunction = (config: GenerateConfig) => AsyncGenerator<TabelDescribe>;
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zenorm/generate",
|
|
3
|
+
"description": "Easy ORM, easy query. easy typing! Auto generate typescript declaration.",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"exports": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"repository": "https://github.com/yefei/easy-model",
|
|
8
|
+
"author": "YeFei <316606233@qq.com>",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"bin": {
|
|
11
|
+
"zenorm-generate": "./dist/bin/zenorm-generate.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "rimraf dist && tsc",
|
|
18
|
+
"prepublishOnly": "npm run build",
|
|
19
|
+
"gen": "cross-env ZENORM_NAME=../../src ts-node ./src/bin/zenorm-generate.ts test/config.json"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"mysql",
|
|
23
|
+
"query",
|
|
24
|
+
"model",
|
|
25
|
+
"types",
|
|
26
|
+
"generate",
|
|
27
|
+
"database"
|
|
28
|
+
],
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^12.20.41",
|
|
31
|
+
"@zenorm/mysql": "^1.0.0",
|
|
32
|
+
"cross-env": "^7.0.3",
|
|
33
|
+
"typescript": "^4.9.5"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"pascal-case": "^3.1.2",
|
|
37
|
+
"snake-case": "^3.0.4"
|
|
38
|
+
}
|
|
39
|
+
}
|