-
Notifications
You must be signed in to change notification settings - Fork 4
/
api.js
190 lines (151 loc) · 5.88 KB
/
api.js
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/** Atelier REST API wrapper
* http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GSCF_ref#GSCF_C29114
*/
const httpModule = require('http')
const httpsModule = require('https')
module.exports = ( conn ) => {
const { host, port, username, password, path, version, ns, https, compileflags } = conn
const http = https ? httpsModule : httpModule
const auth = `${username}:${password}`
const ok = res => ( res.statusCode === 200 ) || ( res.statusCode === 201 )
// by default cache without license have up to 25 connections
const agent = new http.Agent({ keepAlive: true, maxSockets: 10 })
let cookies = []; //
const updateCookies = res => {
const resp_cookies = res.headers["set-cookie"] || []
if ( !cookies.length ) {
cookies = ( resp_cookies ).map( c => c ) //init session
} else if ( resp_cookies[0] != cookies[0] ){
cookies = ( resp_cookies ).map( c => c ) //update session
}
}
const getHeaders = () => ({ "Cookie": cookies })
// response handler factory
const OnResp = ( cb ) => ( res ) => {
let data = ''
res.on( 'data', chunk => { data += chunk }) //accumulate all chunks
res.on( 'end', () => {
updateCookies( res )
let parsed;
if ( data ) try {
parsed = JSON.parse( data )
} catch ( e ) {
parsed = data
}
if ( !ok( res ) ){
const err = { code: res.statusCode, message: res.statusMessage }
return cb( err, parsed )
}
cb( null, parsed )
})
}
const headServer = ( cb ) => {
const headers = getHeaders()
http.request(
{ method: 'HEAD', host, port, path, auth, agent, headers },
res => updateCookies( res ) || cb( !ok( res ) ) //without payload
)
.on( 'error', cb )
.end()
}
const getServer = ( cb ) => {
const headers = getHeaders()
http.request( { host, port, path, auth, agent, headers }, OnResp( cb ) )
.on( 'error', cb )
.end()
}
const getDocNames = ( opts, cb ) => {
opts = opts || {}
let generated = +opts.generated || 0
let filter = opts.filter || ''
let category = opts.category || '*'
const url = `${path}${version}/${ns}/docnames/${category}?generated=${generated}&filter=${filter}`
const headers = getHeaders()
http.request( { host, port, 'path': encodeURI(url), auth, agent, headers }, OnResp( cb ) )
.on( 'error', cb )
.end()
}
const getDoc = ( doc, cb ) => {
const url = `${path}${version}/${ns}/doc/${doc}`
const headers = getHeaders()
http.request( { host, port, 'path': encodeURI(url), auth, agent, headers }, OnResp( cb ) )
.on( 'error', cb )
.end()
}
const putDoc = ( name, doc, params, cb ) => {
if (typeof name !== "string")
throw new Error(`Document name must be a string (${ name })`);
if (!doc || typeof doc['enc'] === 'undefined' || !doc['content'])
throw new Error(`Invalid document data ${ JSON.stringify(doc) }`);
if (typeof params === "function" || !params) {
cb = params;
params = {};
}
const url = `${path}${version}/${ns}/doc/${name}${
typeof params.ignoreConflict !== 'undefined'
? '?ignoreConflict=' + +params.ignoreConflict
: ''
}`
const body = JSON.stringify(doc)
const headers = Object.assign( {}, getHeaders(), {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body, "utf8")
})
if ( params['If-None-Match'] ) {
headers['If-None-Match'] = params['If-None-Match']
}
const req = http.request( {
method: 'PUT', host, port, path: encodeURI(url), auth, agent, headers
} , cb ? OnResp( cb ) : updateCookies )
if (cb) {
req.on( 'error', cb )
}
req.write( body )
req.end()
}
const compile = ( docNames, cb ) => {
if (typeof docNames === 'string')
docNames = [ docNames ];
if (!(docNames instanceof Array))
throw new Error(`Document names must be an array (${ docNames })`);
const url = `${path}${version}/${ns}/action/compile?flags=${compileflags}`
const body = JSON.stringify(docNames)
const headers = Object.assign( {}, getHeaders(), {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body, "utf8")
})
const req = http.request( {
method: 'POST', host, port, path: encodeURI(url), auth, agent, headers
} , cb ? OnResp( cb ) : updateCookies )
if (cb) req.on( 'error', cb )
req.write( body )
req.end()
}
const deleteDocs = ( docNames, cb ) => {
if (typeof docNames === 'string')
docNames = [ docNames ];
if (!(docNames instanceof Array))
throw new Error(`Document names must be an array (${ docNames })`);
const url = `${path}${version}/${ns}/docs`
const body = JSON.stringify(docNames)
const headers = Object.assign({}, getHeaders(), {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body, "utf8")
})
const req = http.request( {
method: 'DELETE', host, port, path: encodeURI(url), auth, agent, headers
} , cb ? OnResp( cb ) : updateCookies )
if (cb) req.on( 'error', cb )
req.write( JSON.stringify(docNames) )
req.end()
}
return {
compile,
deleteDocs,
getServer,
getDocNames,
getDoc,
headServer,
putDoc
}
}