jfexmd 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/.prompt +13 -0
- package/CHANGELOG.md +7 -0
- package/README.MD +649 -0
- package/bin/build-aux.sh +10 -0
- package/bin/build.sh +11 -0
- package/bin/check-node.sh +17 -0
- package/bin/copy-to-publish.sh +8 -0
- package/bin/feature.sh +3 -0
- package/bin/generate-changelog.js +47 -0
- package/bin/publish-auxiliary.sh +2 -0
- package/bin/publish-exmd.sh +2 -0
- package/bin/push.js +30 -0
- package/bin/replace-aux.sh +8 -0
- package/bin/replace-to-test.sh +26 -0
- package/docs/readme.md +7 -0
- package/package.json +61 -0
- package/resource-pack/auxiliary/README.MD +22 -0
- package/resource-pack/auxiliary/package.json +14 -0
- package/resource-pack/readme.md +0 -0
- package/resources/index.d.ts +1 -0
- package/src/api-server/auth-api.js +204 -0
- package/src/api-server/graceful-shutdown.js +95 -0
- package/src/api-server/health.js +57 -0
- package/src/api-server/index.js +553 -0
- package/src/api-server/init-email.js +8 -0
- package/src/api-server/readme.md +4 -0
- package/src/api-server/swagger-data.js +33 -0
- package/src/authorization/auth-controller.js +378 -0
- package/src/authorization/auth-service/query-by-username.js +35 -0
- package/src/authorization/db-ope.js +29 -0
- package/src/authorization/default-user-model.js +63 -0
- package/src/authorization/readme.md +10 -0
- package/src/authorization/util-password.js +33 -0
- package/src/authorization/util-time.js +29 -0
- package/src/authorization/util-token.js +65 -0
- package/src/auxiliary/aux-db-server.js +58 -0
- package/src/auxiliary/index.js +56 -0
- package/src/auxiliary/readme.md +6 -0
- package/src/auxiliary/views-utils.js +46 -0
- package/src/db-server/base-model-fun/add.js +66 -0
- package/src/db-server/base-model-fun/common-fun.js +209 -0
- package/src/db-server/base-model-fun/delete.js +57 -0
- package/src/db-server/base-model-fun/get.js +58 -0
- package/src/db-server/base-model-fun/modify.js +53 -0
- package/src/db-server/base-model-fun/query.js +107 -0
- package/src/db-server/base-model-fun/readme.md +9 -0
- package/src/db-server/base-model.js +64 -0
- package/src/db-server/datasource-registry.js +36 -0
- package/src/db-server/db-Adapter.js +9 -0
- package/src/db-server/db-client-runtime.js +71 -0
- package/src/db-server/db-connect/postgresql-connect.js +13 -0
- package/src/db-server/index.js +73 -0
- package/src/db-server/readme.md +5 -0
- package/src/email/index.js +5 -0
- package/src/email/tencenmail.js +45 -0
- package/src/index.js +192 -0
- package/src/lib/multer/LICENSE +17 -0
- package/src/lib/multer/README.md +333 -0
- package/src/lib/multer/index.js +106 -0
- package/src/lib/multer/lib/counter.js +28 -0
- package/src/lib/multer/lib/file-appender.js +67 -0
- package/src/lib/multer/lib/make-middleware.js +173 -0
- package/src/lib/multer/lib/multer-error.js +31 -0
- package/src/lib/multer/lib/remove-uploaded-files.js +28 -0
- package/src/lib/multer/package.json +95 -0
- package/src/lib/multer/storage/disk.js +66 -0
- package/src/lib/multer/storage/memory.js +21 -0
- package/src/lib/readme.md +0 -0
- package/src/migrate/asyncdb.js +20 -0
- package/src/migrate/build-model.js +75 -0
- package/src/migrate/build-table.js +245 -0
- package/src/migrate/file-handle.js +66 -0
- package/src/migrate/index.js +20 -0
- package/src/migrate/postgresql-migrate.js +102 -0
- package/src/plugin/builtin/request-log-plugin.js +23 -0
- package/src/plugin/plugin-manager.js +111 -0
- package/src/readme.md +13 -0
- package/src/release/changelog.js +56 -0
- package/src/security/auth-middlewares.js +83 -0
- package/src/security/cors.js +53 -0
- package/src/security/helmet-config.js +39 -0
- package/src/upload/init.js +52 -0
- package/src/upload/upload-controller.js +47 -0
- package/src/utils/RequestTypeUtil.js +59 -0
- package/src/utils/cache-utils.js +51 -0
- package/src/utils/config-migration.js +52 -0
- package/src/utils/config-validator.js +48 -0
- package/src/utils/deprecation.js +24 -0
- package/src/utils/json-to-model.js +36 -0
- package/src/utils/logger.js +58 -0
- package/src/utils/md5.js +365 -0
- package/src/utils/metrics.js +42 -0
- package/src/utils/model-util.js +17 -0
- package/src/utils/moment.js +33 -0
- package/src/utils/promise.js +32 -0
- package/src/utils/rate-limit.js +72 -0
- package/src/utils/readme.md +10 -0
- package/src/utils/string-utils.js +17 -0
- package/src/utils/validate-request.js +22 -0
- package/src/vo/HttpStatus.js +80 -0
- package/src/vo/ResultVo.js +24 -0
- package/src/vo/objectToVo.js +53 -0
- package/test/line1.js +8 -0
- package/test/line2.js +8 -0
- package/test/test-lines.js +11 -0
- package/test/timer.js +17 -0
- package/test/v02-engineering.js +71 -0
- package/test/v03-reliability.js +107 -0
- package/test/v04-extensibility.js +165 -0
- package/test/v05-release-quality.js +82 -0
- package/test/v06-observability.js +69 -0
- package/test/v07-operations.js +73 -0
- package/test/v08-security.js +104 -0
- package/webpack.config.js +70 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
var util = require('util')
|
|
2
|
+
|
|
3
|
+
var errorMessages = {
|
|
4
|
+
LIMIT_PART_COUNT: 'Too many parts',
|
|
5
|
+
LIMIT_FILE_SIZE: 'File too large',
|
|
6
|
+
LIMIT_FILE_COUNT: 'Too many files',
|
|
7
|
+
LIMIT_FIELD_KEY: 'Field name too long',
|
|
8
|
+
LIMIT_FIELD_VALUE: 'Field value too long',
|
|
9
|
+
LIMIT_FIELD_COUNT: 'Too many fields',
|
|
10
|
+
// uploadFileDirectorys 模块目录没有配置
|
|
11
|
+
LIMIT_UNEXPECTED_FILE: '',
|
|
12
|
+
MISSING_FIELD_NAME: 'Field name missing'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function MulterError (code, field, opt) {
|
|
16
|
+
let { file } = opt || {}
|
|
17
|
+
Error.captureStackTrace(this, this.constructor)
|
|
18
|
+
this.name = this.constructor.name
|
|
19
|
+
if (code === 'LIMIT_UNEXPECTED_FILE') {
|
|
20
|
+
console.warn('😂你的uploadFileDirectorys配置了啥,文件参数字段就是啥,比如配置file,你就用file: binary😂', )
|
|
21
|
+
this.message = `There is no name [${file.fieldname}] in uploadFileDirectorys!`
|
|
22
|
+
} else {
|
|
23
|
+
this.message = errorMessages[code]
|
|
24
|
+
}
|
|
25
|
+
this.code = code
|
|
26
|
+
if (field) this.field = field
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
util.inherits(MulterError, Error)
|
|
30
|
+
|
|
31
|
+
module.exports = MulterError
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
function removeUploadedFiles (uploadedFiles, remove, cb) {
|
|
2
|
+
var length = uploadedFiles.length
|
|
3
|
+
var errors = []
|
|
4
|
+
|
|
5
|
+
if (length === 0) return cb(null, errors)
|
|
6
|
+
|
|
7
|
+
function handleFile (idx) {
|
|
8
|
+
var file = uploadedFiles[idx]
|
|
9
|
+
|
|
10
|
+
remove(file, function (err) {
|
|
11
|
+
if (err) {
|
|
12
|
+
err.file = file
|
|
13
|
+
err.field = file.fieldname
|
|
14
|
+
errors.push(err)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (idx < length - 1) {
|
|
18
|
+
handleFile(idx + 1)
|
|
19
|
+
} else {
|
|
20
|
+
cb(null, errors)
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
handleFile(0)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = removeUploadedFiles
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_from": "multer",
|
|
3
|
+
"_id": "multer@1.4.5-lts.1",
|
|
4
|
+
"_inBundle": false,
|
|
5
|
+
"_integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==",
|
|
6
|
+
"_location": "/multer",
|
|
7
|
+
"_phantomChildren": {},
|
|
8
|
+
"_requested": {
|
|
9
|
+
"type": "tag",
|
|
10
|
+
"registry": true,
|
|
11
|
+
"raw": "multer",
|
|
12
|
+
"name": "multer",
|
|
13
|
+
"escapedName": "multer",
|
|
14
|
+
"rawSpec": "",
|
|
15
|
+
"saveSpec": null,
|
|
16
|
+
"fetchSpec": "latest"
|
|
17
|
+
},
|
|
18
|
+
"_requiredBy": [
|
|
19
|
+
"#USER",
|
|
20
|
+
"/"
|
|
21
|
+
],
|
|
22
|
+
"_resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
|
|
23
|
+
"_shasum": "803e24ad1984f58edffbc79f56e305aec5cfd1ac",
|
|
24
|
+
"_spec": "multer",
|
|
25
|
+
"_where": "/Users/wujianfei/exmd-project-doing/bServer (compts-doc-backend)",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/expressjs/multer/issues"
|
|
28
|
+
},
|
|
29
|
+
"bundleDependencies": false,
|
|
30
|
+
"contributors": [
|
|
31
|
+
{
|
|
32
|
+
"name": "Hage Yaapa",
|
|
33
|
+
"email": "captain@hacksparrow.com",
|
|
34
|
+
"url": "http://www.hacksparrow.com"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "Jaret Pfluger",
|
|
38
|
+
"email": "https://github.com/jpfluger"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "Linus Unnebäck",
|
|
42
|
+
"email": "linus@folkdatorn.se"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"append-field": "^1.0.0",
|
|
47
|
+
"busboy": "^1.0.0",
|
|
48
|
+
"concat-stream": "^1.5.2",
|
|
49
|
+
"mkdirp": "^0.5.4",
|
|
50
|
+
"object-assign": "^4.1.1",
|
|
51
|
+
"type-is": "^1.6.4",
|
|
52
|
+
"xtend": "^4.0.0"
|
|
53
|
+
},
|
|
54
|
+
"deprecated": false,
|
|
55
|
+
"description": "Middleware for handling `multipart/form-data`.",
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"deep-equal": "^2.0.3",
|
|
58
|
+
"express": "^4.13.1",
|
|
59
|
+
"form-data": "^1.0.0-rc1",
|
|
60
|
+
"fs-temp": "^1.1.2",
|
|
61
|
+
"mocha": "^3.5.3",
|
|
62
|
+
"rimraf": "^2.4.1",
|
|
63
|
+
"standard": "^14.3.3",
|
|
64
|
+
"testdata-w3c-json-form": "^1.0.0"
|
|
65
|
+
},
|
|
66
|
+
"engines": {
|
|
67
|
+
"node": ">= 6.0.0"
|
|
68
|
+
},
|
|
69
|
+
"files": [
|
|
70
|
+
"LICENSE",
|
|
71
|
+
"index.js",
|
|
72
|
+
"storage/",
|
|
73
|
+
"lib/"
|
|
74
|
+
],
|
|
75
|
+
"homepage": "https://github.com/expressjs/multer#readme",
|
|
76
|
+
"keywords": [
|
|
77
|
+
"form",
|
|
78
|
+
"post",
|
|
79
|
+
"multipart",
|
|
80
|
+
"form-data",
|
|
81
|
+
"formdata",
|
|
82
|
+
"express",
|
|
83
|
+
"middleware"
|
|
84
|
+
],
|
|
85
|
+
"license": "MIT",
|
|
86
|
+
"name": "multer",
|
|
87
|
+
"repository": {
|
|
88
|
+
"type": "git",
|
|
89
|
+
"url": "git+https://github.com/expressjs/multer.git"
|
|
90
|
+
},
|
|
91
|
+
"scripts": {
|
|
92
|
+
"test": "standard && mocha"
|
|
93
|
+
},
|
|
94
|
+
"version": "1.4.5-lts.1"
|
|
95
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var fs = require('fs')
|
|
2
|
+
var os = require('os')
|
|
3
|
+
var path = require('path')
|
|
4
|
+
var crypto = require('crypto')
|
|
5
|
+
var mkdirp = require('mkdirp')
|
|
6
|
+
|
|
7
|
+
function getFilename (req, file, cb) {
|
|
8
|
+
crypto.randomBytes(16, function (err, raw) {
|
|
9
|
+
cb(err, err ? undefined : raw.toString('hex'))
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getDestination (req, file, cb) {
|
|
14
|
+
cb(null, os.tmpdir())
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function DiskStorage (opts) {
|
|
18
|
+
this.getFilename = (opts.filename || getFilename)
|
|
19
|
+
|
|
20
|
+
if (typeof opts.destination === 'string') {
|
|
21
|
+
mkdirp.sync(opts.destination)
|
|
22
|
+
this.getDestination = function ($0, $1, cb) { cb(null, opts.destination) }
|
|
23
|
+
} else {
|
|
24
|
+
this.getDestination = (opts.destination || getDestination)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
DiskStorage.prototype._handleFile = function _handleFile (req, file, cb) {
|
|
29
|
+
var that = this
|
|
30
|
+
|
|
31
|
+
that.getDestination(req, file, function (err, destination) {
|
|
32
|
+
if (err) return cb(err)
|
|
33
|
+
|
|
34
|
+
that.getFilename(req, file, function (err, filename) {
|
|
35
|
+
if (err) return cb(err)
|
|
36
|
+
|
|
37
|
+
var finalPath = path.join(destination, filename)
|
|
38
|
+
var outStream = fs.createWriteStream(finalPath)
|
|
39
|
+
|
|
40
|
+
file.stream.pipe(outStream)
|
|
41
|
+
outStream.on('error', cb)
|
|
42
|
+
outStream.on('finish', function () {
|
|
43
|
+
cb(null, {
|
|
44
|
+
destination: destination,
|
|
45
|
+
filename: filename,
|
|
46
|
+
path: finalPath,
|
|
47
|
+
size: outStream.bytesWritten
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
DiskStorage.prototype._removeFile = function _removeFile (req, file, cb) {
|
|
55
|
+
var path = file.path
|
|
56
|
+
|
|
57
|
+
delete file.destination
|
|
58
|
+
delete file.filename
|
|
59
|
+
delete file.path
|
|
60
|
+
|
|
61
|
+
fs.unlink(path, cb)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = function (opts) {
|
|
65
|
+
return new DiskStorage(opts)
|
|
66
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var concat = require('concat-stream')
|
|
2
|
+
|
|
3
|
+
function MemoryStorage (opts) {}
|
|
4
|
+
|
|
5
|
+
MemoryStorage.prototype._handleFile = function _handleFile (req, file, cb) {
|
|
6
|
+
file.stream.pipe(concat({ encoding: 'buffer' }, function (data) {
|
|
7
|
+
cb(null, {
|
|
8
|
+
buffer: data,
|
|
9
|
+
size: data.length
|
|
10
|
+
})
|
|
11
|
+
}))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
MemoryStorage.prototype._removeFile = function _removeFile (req, file, cb) {
|
|
15
|
+
delete file.buffer
|
|
16
|
+
cb(null)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = function (opts) {
|
|
20
|
+
return new MemoryStorage(opts)
|
|
21
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const PostgresqlConnect = require('@src/db-server/db-connect/postgresql-connect')
|
|
2
|
+
const PostgresqlMigrate = require('@src/migrate/postgresql-migrate')
|
|
3
|
+
const BuildTable = require('@src/migrate/build-table')
|
|
4
|
+
/**
|
|
5
|
+
* models生成表
|
|
6
|
+
* @param {*} data 数据库配置对象
|
|
7
|
+
* @param {*} models models配置,项目中的models/index.js中配置各模块
|
|
8
|
+
*/
|
|
9
|
+
function startAsyndb(data, models) {
|
|
10
|
+
PostgresqlConnect(data).then(client => {
|
|
11
|
+
PostgresqlMigrate.getAllTable(client).then(tableInfo => {
|
|
12
|
+
BuildTable(tableInfo, models, client).then(() => {
|
|
13
|
+
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = startAsyndb
|
|
20
|
+
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const FileHandle = require('./file-handle')
|
|
2
|
+
const inquirer = require('inquirer')
|
|
3
|
+
|
|
4
|
+
function buildContent(tablename, list) {
|
|
5
|
+
let str = ''
|
|
6
|
+
str = `const BaseModel = require('../../../exmd') \
|
|
7
|
+
\nconst fieldsMap = { \
|
|
8
|
+
`
|
|
9
|
+
list.forEach((item, key) => {
|
|
10
|
+
str += `${key === 0 ? '\n' : '\n'}\t${item.field}: {\n`
|
|
11
|
+
str += `\t\ttype: '${item.type}', \
|
|
12
|
+
length: ${item.length}, \
|
|
13
|
+
lengthvar: ${item.lengthvar}, \
|
|
14
|
+
\n\t\tnotnull: ${item.notnull}, \
|
|
15
|
+
comment: ${item.comment ? "'" + this.comment + "'" : null}${
|
|
16
|
+
item.isPrimary ? ',' : ''
|
|
17
|
+
} \
|
|
18
|
+
${item.isPrimary ? '\n\t\tisPrimary: ' + item.isPrimary : ''}${
|
|
19
|
+
item.pk_name ? ',' : ''
|
|
20
|
+
} \
|
|
21
|
+
${item.pk_name ? "\n\t\tpk_name: '" + item.pk_name + "'" : ''}
|
|
22
|
+
}${key !== list.length - 1 ? ',' : ''}`
|
|
23
|
+
})
|
|
24
|
+
str += '\n}'
|
|
25
|
+
str += `\n\nfunction ${tablename}() { \
|
|
26
|
+
\n\tconst vm = this \
|
|
27
|
+
\n\tBaseModel.apply(vm, arguments)\n`
|
|
28
|
+
str += `\tvm.fields = fieldsMap\n\tvm.tableName = '${tablename}'\n`
|
|
29
|
+
str += '}\n\n'
|
|
30
|
+
str += `;(function() {\n\tconst TempFun = function(){} \
|
|
31
|
+
\n\tTempFun.prototype = BaseModel.prototype \
|
|
32
|
+
\n\t${tablename}.prototype = new TempFun() \
|
|
33
|
+
\n})() \
|
|
34
|
+
\n\nmodule.exports = ${tablename}
|
|
35
|
+
`
|
|
36
|
+
return str.trim()
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 生成model
|
|
40
|
+
*/
|
|
41
|
+
function buildModel(tableInfo) {
|
|
42
|
+
const path = FileHandle.getModelPath()
|
|
43
|
+
FileHandle.buildDirs(path).then(() => {
|
|
44
|
+
const tablenameList = Object.keys(tableInfo)
|
|
45
|
+
inquirer
|
|
46
|
+
.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'checkbox', // list列表 checkbox复选框
|
|
49
|
+
name: 'type',
|
|
50
|
+
message: '请选择要操作的表,按空格选择,按回车确定选择.',
|
|
51
|
+
choices: [
|
|
52
|
+
...tablenameList.map((item) => {
|
|
53
|
+
return {
|
|
54
|
+
name: item
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
])
|
|
60
|
+
.then((res) => {
|
|
61
|
+
const list = res.type
|
|
62
|
+
for (let i = 0; i < list.length; i++) {
|
|
63
|
+
let tablename = list[i]
|
|
64
|
+
FileHandle.createFile(
|
|
65
|
+
`${path}/${tablename}.js`,
|
|
66
|
+
buildContent(tablename, tableInfo[tablename])
|
|
67
|
+
).then(() => {
|
|
68
|
+
console.info('创建文件:', tablename)
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
exports.buildModel = buildModel
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
const inquirer = require('inquirer')
|
|
2
|
+
|
|
3
|
+
function isNull(notnull) {
|
|
4
|
+
return notnull ? 'NOT NULL' : ''
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 字段处理
|
|
9
|
+
* @param {*} fieldObj
|
|
10
|
+
*/
|
|
11
|
+
function fieldTypeFunKey(field, fieldObj) {
|
|
12
|
+
const { type, length } = fieldObj[field]
|
|
13
|
+
const nullStr = isNull(fieldObj[field].notnull)
|
|
14
|
+
let funKey = {
|
|
15
|
+
uuid: () => {
|
|
16
|
+
return `${field} uuid ${nullStr}`
|
|
17
|
+
},
|
|
18
|
+
varchar: () => {
|
|
19
|
+
return `${field} varchar(${length}) ${nullStr} DEFAULT ''`
|
|
20
|
+
},
|
|
21
|
+
text: () => {
|
|
22
|
+
return `${field} text COLLATE pg_catalog."default" ${nullStr}`
|
|
23
|
+
},
|
|
24
|
+
integer: () => {
|
|
25
|
+
return `${field} integer ${nullStr} DEFAULT 1`
|
|
26
|
+
},
|
|
27
|
+
int4: () => {
|
|
28
|
+
return `${field} integer ${nullStr} DEFAULT 1`
|
|
29
|
+
},
|
|
30
|
+
bigint: () => {
|
|
31
|
+
return `${field} bigint ${nullStr} DEFAULT 1`
|
|
32
|
+
},
|
|
33
|
+
decimal: () => {
|
|
34
|
+
return `${field} decimal ${nullStr} DEFAULT 1`
|
|
35
|
+
},
|
|
36
|
+
numeric: () => {
|
|
37
|
+
return `${field} numeric ${nullStr} DEFAULT 1`
|
|
38
|
+
},
|
|
39
|
+
serial: () => {
|
|
40
|
+
return `${field} serial`
|
|
41
|
+
},
|
|
42
|
+
bigserial: () => {
|
|
43
|
+
return `${field} bigserial`
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return funKey[type]()
|
|
47
|
+
}
|
|
48
|
+
// 主键描述
|
|
49
|
+
function handlePrimaryKey(tablename, field, fieldObj) {
|
|
50
|
+
const isPrimary = fieldObj[field].isPrimary
|
|
51
|
+
if (isPrimary) {
|
|
52
|
+
return `CONSTRAINT ${tablename.toLocaleLowerCase()}_pkey PRIMARY KEY (${field})`
|
|
53
|
+
}
|
|
54
|
+
return ''
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 建表sql
|
|
59
|
+
* @param {*} tablename 表名
|
|
60
|
+
* @param {*} fields 字段对象
|
|
61
|
+
*/
|
|
62
|
+
function createSql(tablename, fields) {
|
|
63
|
+
let str = `
|
|
64
|
+
CREATE TABLE public.${tablename.toLocaleLowerCase()}
|
|
65
|
+
(
|
|
66
|
+
`
|
|
67
|
+
let idx1 = 0
|
|
68
|
+
// 字段描述
|
|
69
|
+
for (let field in fields) {
|
|
70
|
+
const value = fieldTypeFunKey(field, fields)
|
|
71
|
+
if (!value) {
|
|
72
|
+
throw new Error('框架的类型映射没有该类型支持')
|
|
73
|
+
}
|
|
74
|
+
str += (idx1 !== 0 && value ? ',\n\t' : '') + value
|
|
75
|
+
idx1++
|
|
76
|
+
}
|
|
77
|
+
let idx2 = 0
|
|
78
|
+
// 主键描述
|
|
79
|
+
for (let field in fields) {
|
|
80
|
+
const value = handlePrimaryKey(tablename, field, fields)
|
|
81
|
+
str += (value ? ',\n\t' : '') + value
|
|
82
|
+
idx2++
|
|
83
|
+
}
|
|
84
|
+
str += `
|
|
85
|
+
)
|
|
86
|
+
WITH (
|
|
87
|
+
OIDS = FALSE
|
|
88
|
+
)
|
|
89
|
+
TABLESPACE pg_default;
|
|
90
|
+
|
|
91
|
+
ALTER TABLE public.${tablename.toLocaleLowerCase()}
|
|
92
|
+
OWNER to postgres;`
|
|
93
|
+
return str
|
|
94
|
+
}
|
|
95
|
+
let createTableTimer = null
|
|
96
|
+
/**
|
|
97
|
+
* 建表
|
|
98
|
+
* @param {*} sqlList
|
|
99
|
+
* @param {*} idx
|
|
100
|
+
*/
|
|
101
|
+
function createTable(sqlList, idx, client, callback, fcallback) {
|
|
102
|
+
if (idx >= sqlList.length) {
|
|
103
|
+
console.log('全部创建完成')
|
|
104
|
+
// client.end()
|
|
105
|
+
callback && callback(client)
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
client
|
|
109
|
+
.query(sqlList[idx])
|
|
110
|
+
.then(() => {
|
|
111
|
+
idx++
|
|
112
|
+
clearTimeout(createTableTimer)
|
|
113
|
+
createTableTimer = setTimeout(() => {
|
|
114
|
+
createTable(sqlList, idx, client, callback, fcallback)
|
|
115
|
+
}, 500)
|
|
116
|
+
})
|
|
117
|
+
.catch((err) => {
|
|
118
|
+
fcallback && fcallback(err)
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 首字母大写
|
|
123
|
+
*/
|
|
124
|
+
function titleCase(str) {
|
|
125
|
+
return str.slice(0, 1).toUpperCase() + str.slice(1).toLowerCase()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* 表名转换成小驼峰命名方式
|
|
130
|
+
* 比如:wiki_menu 转成 wikiMenu
|
|
131
|
+
*/
|
|
132
|
+
function tableNameToSmallHump(tableName = '', signStr = '_') {
|
|
133
|
+
return tableName
|
|
134
|
+
.split(signStr)
|
|
135
|
+
.map((item, key) => (key === 0 ? item : titleCase(item)))
|
|
136
|
+
.join('')
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 拿到所有的建表sql
|
|
140
|
+
function getAllCreateTableSql(list, models) {
|
|
141
|
+
return new Promise((resolve, reject) => {
|
|
142
|
+
const result = []
|
|
143
|
+
list.forEach((name) => {
|
|
144
|
+
// wiki_menu这样的表名转成wikiMenu, 因为前面代码会从创建的对象中拿取里面的tableName
|
|
145
|
+
let key = tableNameToSmallHump(name)
|
|
146
|
+
const temp = new models[key]()
|
|
147
|
+
const sql = createSql(name, temp.fields)
|
|
148
|
+
result.push(sql)
|
|
149
|
+
})
|
|
150
|
+
resolve(result)
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// 授权
|
|
155
|
+
function grantAllPrivileges(client) {
|
|
156
|
+
let idx = 0
|
|
157
|
+
let loop = (rolenameList) => {
|
|
158
|
+
if (idx >= rolenameList.length) {
|
|
159
|
+
client.end()
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
let username = rolenameList[idx]
|
|
163
|
+
client
|
|
164
|
+
.query(`GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ${username};`)
|
|
165
|
+
.then((res) => {
|
|
166
|
+
idx++
|
|
167
|
+
loop(rolenameList)
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
client.query(`select * from pg_roles;`).then((res) => {
|
|
171
|
+
let rolenameList = (res?.rows || [])
|
|
172
|
+
.map((item) => item.rolname)
|
|
173
|
+
.filter((item) => !(item.indexOf('pg_') === 0 || item === 'postgres'))
|
|
174
|
+
loop(rolenameList)
|
|
175
|
+
}).catch(e => {
|
|
176
|
+
console.error(e)
|
|
177
|
+
client.end()
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* 建表
|
|
183
|
+
* @param {*} tableInfo 表信息
|
|
184
|
+
* @param {*} models model信息
|
|
185
|
+
* @param {*} client 客户端对象
|
|
186
|
+
* @returns
|
|
187
|
+
*/
|
|
188
|
+
function buildTable(tableInfo, models, client) {
|
|
189
|
+
return new Promise((resolve, reject) => {
|
|
190
|
+
const currentModelList = Object.keys(models).map((key) => {
|
|
191
|
+
let obj = new models[key]()
|
|
192
|
+
return obj.tableName
|
|
193
|
+
})
|
|
194
|
+
const currentTableList = Object.keys(tableInfo)
|
|
195
|
+
inquirer
|
|
196
|
+
.prompt([
|
|
197
|
+
{
|
|
198
|
+
type: 'checkbox', // list列表 checkbox复选框
|
|
199
|
+
name: 'type',
|
|
200
|
+
message: '请选择要操作的model,按空格选择,按回车确定选择.',
|
|
201
|
+
choices: [
|
|
202
|
+
...currentModelList
|
|
203
|
+
.filter((item) => {
|
|
204
|
+
const idx = currentTableList.indexOf(item)
|
|
205
|
+
return idx === -1
|
|
206
|
+
})
|
|
207
|
+
.map((item) => {
|
|
208
|
+
return {
|
|
209
|
+
name: item
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
])
|
|
215
|
+
.then((res) => {
|
|
216
|
+
const list = res.type
|
|
217
|
+
getAllCreateTableSql(list, models)
|
|
218
|
+
.then((sqlList) => {
|
|
219
|
+
// 建表
|
|
220
|
+
createTable(
|
|
221
|
+
sqlList,
|
|
222
|
+
0,
|
|
223
|
+
client,
|
|
224
|
+
() => {
|
|
225
|
+
console.info('数据库表创建成功🎁')
|
|
226
|
+
grantAllPrivileges(client)
|
|
227
|
+
// 成功
|
|
228
|
+
resolve()
|
|
229
|
+
},
|
|
230
|
+
(e) => {
|
|
231
|
+
// 失败
|
|
232
|
+
reject(e)
|
|
233
|
+
}
|
|
234
|
+
)
|
|
235
|
+
})
|
|
236
|
+
.catch((e) => {
|
|
237
|
+
reject(e)
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
.catch((e) => {
|
|
241
|
+
reject(e)
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
module.exports = buildTable
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 获得model路径
|
|
6
|
+
*/
|
|
7
|
+
function getModelPath() {
|
|
8
|
+
return `${path.resolve('models')}`
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 创建目录
|
|
12
|
+
*/
|
|
13
|
+
function buildDirs(path) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const exist = fs.existsSync(path)
|
|
16
|
+
if (!exist) {
|
|
17
|
+
fs.mkdir(path, (error) => {
|
|
18
|
+
reject(error)
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
setTimeout(() => {
|
|
22
|
+
resolve()
|
|
23
|
+
}, 500)
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 创建文件
|
|
29
|
+
*/
|
|
30
|
+
function createFile(filepath, content) {
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
if (!fs.existsSync(filepath)) {
|
|
33
|
+
fs.writeFile(filepath, content, (err) => {
|
|
34
|
+
if (err) {
|
|
35
|
+
reject(err)
|
|
36
|
+
} else {
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
resolve()
|
|
39
|
+
}, 500)
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
} else {
|
|
43
|
+
fs.unlink(filepath, (err) => {
|
|
44
|
+
if (err) {
|
|
45
|
+
reject(err)
|
|
46
|
+
} else {
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
fs.writeFile(filepath, content, (err) => {
|
|
49
|
+
if (err) {
|
|
50
|
+
reject(err)
|
|
51
|
+
} else {
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
resolve()
|
|
54
|
+
}, 500)
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
}, 500)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
exports.buildDirs = buildDirs
|
|
65
|
+
exports.createFile = createFile
|
|
66
|
+
exports.getModelPath = getModelPath
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const PostgresqlConnect = require('@src/db-server/db-connect/postgresql-connect')
|
|
2
|
+
const PostgresqlMigrate = require('@src/migrate/postgresql-migrate')
|
|
3
|
+
const BuildModel = require('@src/migrate/build-model')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 数据库生成models
|
|
7
|
+
* @param {*} data 数据库配置对象
|
|
8
|
+
*/
|
|
9
|
+
function migrate(data) {
|
|
10
|
+
PostgresqlConnect(data).then(client => {
|
|
11
|
+
PostgresqlMigrate.getAllTable(client).then(tableInfo => {
|
|
12
|
+
client.end()
|
|
13
|
+
BuildModel.buildModel(tableInfo);
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = migrate
|
|
19
|
+
|
|
20
|
+
|