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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * miolo-cli v3.0.0-beta.12
2
+ * miolo-cli v3.0.0-beta.14
3
3
  *
4
4
  * https://www.afialapis.com/os/miolo
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * miolo-cli v3.0.0-beta.12
2
+ * miolo-cli v3.0.0-beta.14
3
3
  *
4
4
  * https://www.afialapis.com/os/miolo
5
5
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "miolo-cli",
3
- "version": "3.0.0-beta.12",
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,7 @@
1
+ import {Fetcher} from './fetcher.mjs'
2
+
3
+
4
+ export function init_fetcher(config) {
5
+ const fetcher= new Fetcher(config)
6
+ return fetcher
7
+ }
@@ -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}
@@ -0,0 +1,6 @@
1
+ import { io } from "socket.io-client";
2
+
3
+ export function init_socket(domain, options) {
4
+ const socket = io(domain, options)
5
+ return socket
6
+ }