miolo-cli 3.0.0-beta.12 → 3.0.0-beta.14
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/dist/miolo-cli.mjs +1 -1
- package/dist/miolo-cli.umd.js +1 -1
- package/package.json +3 -2
- package/src/catcher/index.mjs +75 -0
- package/src/fetcher/fetcher.mjs +214 -0
- package/src/fetcher/index.mjs +7 -0
- package/src/fetcher/utils.mjs +59 -0
- package/src/index.mjs +30 -0
- package/src/socket/index.mjs +6 -0
package/dist/miolo-cli.mjs
CHANGED
package/dist/miolo-cli.umd.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "miolo-cli",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.14",
|
|
4
4
|
"description": "cli utils for miolo",
|
|
5
5
|
"author": "Donato Lorenzo <donato@afialapis.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
|
-
"dist"
|
|
27
|
+
"dist",
|
|
28
|
+
"src"
|
|
28
29
|
],
|
|
29
30
|
"scripts": {
|
|
30
31
|
"reset": "rm -fr package-lock.json npm-lock.yaml dist/* && npm i",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
function init_catcher (catcher_url, fetcher) {
|
|
2
|
+
if (typeof window == "undefined") {
|
|
3
|
+
return
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if (window.miolo_listeners===true) {
|
|
7
|
+
return
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// window.onerror = function(msg, file, line, col, error) {
|
|
11
|
+
// try {
|
|
12
|
+
// const params= {
|
|
13
|
+
// 'error': {
|
|
14
|
+
// msg, file, line, col, error
|
|
15
|
+
// },
|
|
16
|
+
// 'path' : window.location.pathname,
|
|
17
|
+
// 'agent': 'UserAgent' + navigator.userAgent
|
|
18
|
+
// }
|
|
19
|
+
//
|
|
20
|
+
// fetcher.post(catcher_url, params)
|
|
21
|
+
// } catch(e) {
|
|
22
|
+
// console.error(e)
|
|
23
|
+
// }
|
|
24
|
+
// }
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
window.addEventListener("error", (event) => {
|
|
28
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const params= {
|
|
32
|
+
'error': {
|
|
33
|
+
msg: event?.message || 'Client error',
|
|
34
|
+
file: event?.filename,
|
|
35
|
+
line: event?.lineno,
|
|
36
|
+
col: event?.colno,
|
|
37
|
+
error: event?.error
|
|
38
|
+
},
|
|
39
|
+
'path' : window.location.pathname,
|
|
40
|
+
'agent': 'UserAgent' + navigator.userAgent
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fetcher.post(catcher_url, params)
|
|
44
|
+
} catch(e) {
|
|
45
|
+
console.error(e)
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
window.addEventListener("unhandledrejection", (event) => {
|
|
50
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const params= {
|
|
54
|
+
'warning': {
|
|
55
|
+
msg: event?.reason || 'Client Unhandled rejection',
|
|
56
|
+
file: undefined,
|
|
57
|
+
line: undefined,
|
|
58
|
+
col: undefined,
|
|
59
|
+
error: event?.reason
|
|
60
|
+
},
|
|
61
|
+
'path' : window.location.pathname,
|
|
62
|
+
'agent': 'UserAgent' + navigator.userAgent
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
fetcher.post(catcher_url, params)
|
|
66
|
+
} catch(e) {
|
|
67
|
+
console.error(e)
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
window.miolo_listeners = true
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export {init_catcher}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import {omit_nil, trim_left, json_to_query_string, parse_login_cookie} from './utils.mjs'
|
|
2
|
+
|
|
3
|
+
class Fetcher {
|
|
4
|
+
/**
|
|
5
|
+
* @param {*} config {hostname, port, force_hostname, silent_fail: false}
|
|
6
|
+
*/
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config= config
|
|
9
|
+
this.auth = undefined
|
|
10
|
+
this.cookie = undefined
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
set_auth(auth) {
|
|
14
|
+
if (auth) {
|
|
15
|
+
const {username, password}= auth
|
|
16
|
+
this.auth= {username, password}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get_headers() {
|
|
21
|
+
let headers = {}
|
|
22
|
+
|
|
23
|
+
if (this.auth) {
|
|
24
|
+
let {username, password}= this.auth
|
|
25
|
+
username= username || ''
|
|
26
|
+
password= password || ''
|
|
27
|
+
|
|
28
|
+
let sauth
|
|
29
|
+
try {
|
|
30
|
+
sauth= 'Basic ' + Buffer.from(username + ":" + password).toString('base64')
|
|
31
|
+
} catch(_) {
|
|
32
|
+
sauth= 'Basic ' + btoa(username + ":" + password)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
headers['Authorization']= sauth
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (this.cookie) {
|
|
39
|
+
headers['Cookie']= this.cookie
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return headers
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
_prepare_url (url) {
|
|
46
|
+
const endpoint = '/' + trim_left(url, '/')
|
|
47
|
+
|
|
48
|
+
const {hostname, port, force_hostname} = this.config || {}
|
|
49
|
+
if (hostname && force_hostname) {
|
|
50
|
+
return `http://${hostname}:${port}${endpoint}`
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return endpoint
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async _fetch (method, url, params, auth= undefined) {
|
|
57
|
+
this.set_auth(auth)
|
|
58
|
+
|
|
59
|
+
let request = {
|
|
60
|
+
method,
|
|
61
|
+
mode: 'cors',
|
|
62
|
+
credentials: 'include',
|
|
63
|
+
headers: {
|
|
64
|
+
'content-type': 'application/json',
|
|
65
|
+
...this.get_headers() || {}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let wurl = this._prepare_url(url)
|
|
70
|
+
|
|
71
|
+
if (method === 'POST') {
|
|
72
|
+
request.body = JSON.stringify(params || {}, (k, v) => v === undefined ? null : v)
|
|
73
|
+
} else if (method === 'GET') {
|
|
74
|
+
if (params) {
|
|
75
|
+
wurl+= json_to_query_string(params)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const response = await fetch(wurl, request)
|
|
80
|
+
|
|
81
|
+
if (response.redirected) {
|
|
82
|
+
const isBrowser = typeof window == 'object'
|
|
83
|
+
if (isBrowser) {
|
|
84
|
+
// JSDOM does not support navigation, so lets skip it for tests
|
|
85
|
+
const isTest = typeof navigator !== "undefined" &&
|
|
86
|
+
navigator.userAgent.includes("Node.js");
|
|
87
|
+
if (!isTest) {
|
|
88
|
+
window.location.replace(response.url)
|
|
89
|
+
return Promise.resolve(response)
|
|
90
|
+
} else {
|
|
91
|
+
console.error(`Response for ${wurl} is a redirect to ${response.url}. But you are in a test environment, where redirects cannot be done. Unexpected results are coming...`)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (response.headers.get('content-type').indexOf('json') >= 0) {
|
|
97
|
+
const data= await response.json()
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
data,
|
|
101
|
+
status: response.status,
|
|
102
|
+
response
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const data= await response.text()
|
|
107
|
+
return {
|
|
108
|
+
data,
|
|
109
|
+
status: response.status,
|
|
110
|
+
response
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async get(url, params, auth= undefined) {
|
|
116
|
+
/* eslint no-unused-vars:0 */
|
|
117
|
+
try {
|
|
118
|
+
const resp = await this._fetch('GET', url, omit_nil(params), auth)
|
|
119
|
+
return resp
|
|
120
|
+
} catch(e) {
|
|
121
|
+
if (this.config?.silent_fail !== true) {
|
|
122
|
+
console.error(`Error on GET ${url}`)
|
|
123
|
+
console.error(e)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
data: e,
|
|
128
|
+
status: -1,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async post(url, data, auth= undefined) {
|
|
134
|
+
try {
|
|
135
|
+
const resp = await this._fetch('POST', url, data, auth)
|
|
136
|
+
return resp
|
|
137
|
+
} catch(e) {
|
|
138
|
+
if (this.config?.silent_fail !== true) {
|
|
139
|
+
console.error(`Error on POST ${url}`)
|
|
140
|
+
console.error(e)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
data: e,
|
|
145
|
+
status: -1
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async login(url, {username, password}) {
|
|
151
|
+
const res= await this._fetch('POST', url || '/login', {username, password})
|
|
152
|
+
this.cookie= parse_login_cookie(res.response)
|
|
153
|
+
return res
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async logout(url) {
|
|
157
|
+
this.cookie= undefined
|
|
158
|
+
const res= await this._fetch('POST', url || '/logout', {})
|
|
159
|
+
return res
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async read(url, params, auth= undefined) {
|
|
163
|
+
const result = await this.get(`${url}/read`, params, auth)
|
|
164
|
+
return result.data
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async key_list(url, params, auth= undefined) {
|
|
168
|
+
const result = await this.get(`${url}/key_list`, params, auth)
|
|
169
|
+
return result.data
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async name_list(url, params, auth= undefined) {
|
|
173
|
+
const result = await this.key_list(url, params, auth)
|
|
174
|
+
return Object.values(result)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async find(url, id, auth= undefined) {
|
|
178
|
+
const result = await this.get(`${url}/find`, { id: id }, auth)
|
|
179
|
+
return result.data
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async distinct(url, field, params, auth= undefined) {
|
|
183
|
+
const nparams= {
|
|
184
|
+
...params,
|
|
185
|
+
distinct_field: field
|
|
186
|
+
}
|
|
187
|
+
const result = await this.get(`${url}/distinct`, nparams, auth)
|
|
188
|
+
return result.data
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async upsave(url, data, auth= undefined) {
|
|
192
|
+
let result
|
|
193
|
+
if (data.id == undefined) {
|
|
194
|
+
delete data.id
|
|
195
|
+
result= await this.post(`${url}/save`, data, auth)
|
|
196
|
+
} else {
|
|
197
|
+
result= await this.post(`${url}/update`, data, auth)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return result.data
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async remove(url, id, auth= undefined) {
|
|
204
|
+
const data = { id: id }
|
|
205
|
+
const result = await this.post(`${url}/delete`, data, auth)
|
|
206
|
+
return result.data
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
Fetcher.keyList= Fetcher.key_list
|
|
211
|
+
Fetcher.nameList= Fetcher.name_list
|
|
212
|
+
|
|
213
|
+
export { Fetcher }
|
|
214
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform an JSON object to a query string
|
|
3
|
+
*/
|
|
4
|
+
const _parse_value= (value) => {
|
|
5
|
+
try {
|
|
6
|
+
return value.replace(/\+/g, '%2B')
|
|
7
|
+
} catch(e) {
|
|
8
|
+
return value
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function json_to_query_string(obj) {
|
|
13
|
+
if (obj && (Object.keys(obj).length>0)) {
|
|
14
|
+
const uparams = new URLSearchParams()
|
|
15
|
+
for (const key in obj) {
|
|
16
|
+
if (Object.hasOwn(obj, key)) {
|
|
17
|
+
const value = obj[key];
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
value.forEach(item => uparams.append(key, _parse_value(item)))
|
|
20
|
+
} else if (value !== undefined && value !== null) {
|
|
21
|
+
uparams.append(key, _parse_value(value))
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return `?${uparams.toString()}`
|
|
26
|
+
}
|
|
27
|
+
return ''
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function trim_left(str, what) {
|
|
31
|
+
return str.replace(new RegExp(`^${what || '\\s'}+`), '')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
export function omit_nil(obj) {
|
|
36
|
+
if (typeof obj !== 'object') return obj
|
|
37
|
+
return Object.keys(obj).reduce((acc, v) => {
|
|
38
|
+
if (obj[v] !== undefined) acc[v] = obj[v]
|
|
39
|
+
return acc
|
|
40
|
+
}, {})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
export function parse_login_cookie(response) {
|
|
45
|
+
if (typeof window !== 'object') {
|
|
46
|
+
return undefined
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const raw = response.headers.raw()['set-cookie'];
|
|
50
|
+
return raw.map((entry) => {
|
|
51
|
+
const parts = entry.split(';');
|
|
52
|
+
const cookiePart = parts[0];
|
|
53
|
+
return cookiePart;
|
|
54
|
+
}).join(';');
|
|
55
|
+
} catch(e) {
|
|
56
|
+
console.log('[miolo-cli] Could not get the set-cookie after login')
|
|
57
|
+
return undefined
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/index.mjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {init_catcher} from './catcher/index.mjs'
|
|
2
|
+
import {init_fetcher} from './fetcher/index.mjs'
|
|
3
|
+
// import {init_socket} from './socket/index.mjs'
|
|
4
|
+
|
|
5
|
+
function miolo_client(context) {
|
|
6
|
+
|
|
7
|
+
const {config} = context
|
|
8
|
+
|
|
9
|
+
const fetcher = init_fetcher(config)
|
|
10
|
+
|
|
11
|
+
if (config?.catcher_url) {
|
|
12
|
+
init_catcher(config?.catcher_url, fetcher)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// let socket
|
|
16
|
+
// if (config?.socket?.enabled===true) {
|
|
17
|
+
// const domain = config?.socket?.domain
|
|
18
|
+
// const options = config?.socket?.options
|
|
19
|
+
// socket = init_socket(domain, options)
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
const miolo_obj= {
|
|
23
|
+
fetcher,
|
|
24
|
+
//socket
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return miolo_obj
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export {miolo_client}
|