/
sftp.ts
144 lines (124 loc) · 3.76 KB
/
sftp.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import * as fse from 'fs-extra'
// import * as fs from 'fs'
import path from 'path'
import SftpClient from 'ssh2-sftp-client'
import NodeSsh from 'node-ssh'
import normalizePath from 'normalize-path'
import Model from '../../model'
type sftpConnectConfig = {
host: string;
port: number;
type?: string;
username: string;
password?: string;
privateKey?: string | Buffer;
}
export default class SftpDeploy extends Model {
// connect: SftpClient
constructor(appInstance: any) {
super(appInstance)
// this.connect = new SftpClient()
console.log('instance sftp deploy')
}
async remoteDetect() {
const result = {
success: true,
message: '',
}
const client = new SftpClient()
const { setting } = this.db
const connectConfig: sftpConnectConfig = {
host: setting.server,
port: Number(setting.port),
username: setting.username,
}
if (setting.privateKey) {
try {
connectConfig.privateKey = fse.readFileSync(setting.privateKey)
} catch (e) {
console.error('SFTP Test Remote Error: ', e.message)
result.success = false
result.message = e.message
return result
}
} else {
connectConfig.password = setting.password
}
const testFilename = 'gridea.txt'
const localTestFilePath = normalizePath(path.join(this.appDir, testFilename))
const remoteTestFilePath = normalizePath(path.join(setting.remotePath, testFilename))
try {
await client.connect(connectConfig)
await client.list('/')
try {
fse.writeFileSync(localTestFilePath, 'This is gridea test file. you can delete it.')
await client.put(localTestFilePath, remoteTestFilePath)
await client.delete(remoteTestFilePath)
} catch (e) {
console.error('SFTP Test Remote Error: ', e.message)
result.success = false
result.message = e.message
} finally {
if (fse.existsSync(localTestFilePath)) {
fse.unlinkSync(localTestFilePath)
}
}
} catch (e) {
console.error('SFTP Test Remote Error: ', e.message)
result.success = false
result.message = e.message
} finally {
await client.end()
}
return result
}
async publish() {
const result = {
success: true,
message: '',
}
const client = new NodeSsh()
const { setting } = this.db
const connectConfig: sftpConnectConfig = {
host: setting.server,
port: Number(setting.port),
type: 'sftp',
username: setting.username,
}
// node-ssh: privateKey is path string.
if (setting.privateKey) {
connectConfig.privateKey = setting.privateKey
} else {
connectConfig.password = setting.password
}
const localPath = normalizePath(path.join(this.appDir, 'output'))
const remotePath = normalizePath(path.join(setting.remotePath))
try {
await client.connect(connectConfig)
try {
await client.exec(`rm -rf ${remotePath}`)
await client.mkdir(remotePath)
const res = await client.putDirectory(localPath, remotePath, {
recursive: true,
concurrency: 10,
validate: function (itemPath: string) {
const baseName = path.basename(itemPath)
return baseName.substr(0, 1) !== '.' // do not allow dot files
&& baseName !== 'node_modules' // do not allow node_modules
},
})
} catch (e) {
console.error('SFTP Publish Error: ', e.message)
result.success = false
result.message = e.message
}
} catch (e) {
console.error('SFTP Publish Error: ', e.message)
result.success = false
result.message = e.message
} finally {
await client.dispose()
}
return result
}
}