@logux/server 0.13.1 → 0.14.0
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/README.md +3 -23
- package/add-http-pages/index.js +24 -0
- package/base-server/index.d.ts +93 -95
- package/base-server/index.js +78 -70
- package/context/index.d.ts +43 -66
- package/context/index.js +18 -16
- package/create-reporter/index.js +55 -76
- package/human-formatter/index.js +52 -82
- package/index.js +1 -9
- package/options-loader/index.js +46 -14
- package/options-loader/index.test.js +3 -3
- package/options-loader/test.env +2 -0
- package/package.json +11 -20
- package/request/index.d.ts +1 -99
- package/request/index.js +2 -40
- package/server/index.d.ts +24 -37
- package/server/index.js +11 -16
- package/server-client/index.d.ts +0 -15
- package/server-client/index.js +21 -9
- package/test-client/index.d.ts +19 -5
- package/test-server/index.d.ts +20 -10
- package/test-server/index.js +21 -2
- package/bind-backend-proxy/index.js +0 -325
- package/bind-control-server/index.js +0 -137
- package/request/test.test.js +0 -134
- /package/{base-server → add-http-pages}/hello.html +0 -0
package/human-formatter/index.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import { once } from 'node:events'
|
|
2
1
|
import os from 'node:os'
|
|
3
|
-
import {
|
|
4
|
-
import pico from 'picocolors'
|
|
5
|
-
import pino from 'pino'
|
|
6
|
-
import abstractTransport from 'pino-abstract-transport'
|
|
7
|
-
import stripAnsi from 'strip-ansi'
|
|
2
|
+
import { stripVTControlCharacters, styleText } from 'node:util'
|
|
8
3
|
|
|
9
4
|
import { mulberry32, onceXmur3 } from './utils.js'
|
|
10
5
|
|
|
@@ -30,10 +25,11 @@ const PARAMS_BLACKLIST = {
|
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
const LABELS = {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
20: str => label(' DEBUG ', 'white', 'bgWhite', 'black', str),
|
|
29
|
+
30: str => label(' INFO ', 'green', 'bgGreen', 'black', str),
|
|
30
|
+
40: str => label(' WARN ', 'yellow', 'bgYellow', 'black', str),
|
|
31
|
+
50: str => label(' ERROR ', 'red', 'bgRed', 'white', str),
|
|
32
|
+
60: str => label(' FATAL ', 'red', 'bgRed', 'white', str)
|
|
37
33
|
}
|
|
38
34
|
|
|
39
35
|
const COLORS = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan']
|
|
@@ -50,16 +46,16 @@ function formatNow() {
|
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
function rightPag(str, length) {
|
|
53
|
-
let add = length -
|
|
49
|
+
let add = length - stripVTControlCharacters(str).length
|
|
54
50
|
for (let i = 0; i < add; i++) str += ' '
|
|
55
51
|
return str
|
|
56
52
|
}
|
|
57
53
|
|
|
58
|
-
function label(
|
|
59
|
-
let pagged = rightPag(
|
|
60
|
-
let time =
|
|
61
|
-
let highlighted = message.replace(/`([^`]+)`/g,
|
|
62
|
-
return `${pagged}${
|
|
54
|
+
function label(type, color, labelBg, labelText, message) {
|
|
55
|
+
let pagged = rightPag(styleText(labelBg, styleText(labelText, type)), 8)
|
|
56
|
+
let time = styleText('dim', `at ${formatNow()}`)
|
|
57
|
+
let highlighted = message.replace(/`([^`]+)`/g, styleText('yellow', '$1'))
|
|
58
|
+
return `${pagged}${styleText('bold', styleText(color, highlighted))} ${time}`
|
|
63
59
|
}
|
|
64
60
|
|
|
65
61
|
function formatName(key) {
|
|
@@ -88,7 +84,7 @@ function shuffledColors(str) {
|
|
|
88
84
|
return result
|
|
89
85
|
}
|
|
90
86
|
|
|
91
|
-
function splitAndColorize(
|
|
87
|
+
function splitAndColorize(partLength, str) {
|
|
92
88
|
let strBuilder = []
|
|
93
89
|
let colors = shuffledColors(str)
|
|
94
90
|
|
|
@@ -104,58 +100,58 @@ function splitAndColorize(c, partLength, str) {
|
|
|
104
100
|
if (strToColorize.length === 1) {
|
|
105
101
|
color = colors[Math.abs(n - 1) % colors.length]
|
|
106
102
|
}
|
|
107
|
-
strBuilder.push(
|
|
103
|
+
strBuilder.push(styleText(color, strToColorize))
|
|
108
104
|
}
|
|
109
105
|
|
|
110
106
|
return strBuilder.join('')
|
|
111
107
|
}
|
|
112
108
|
|
|
113
|
-
function formatNodeId(
|
|
109
|
+
function formatNodeId(nodeId) {
|
|
114
110
|
let pos = nodeId.lastIndexOf(':')
|
|
115
111
|
if (pos === -1) {
|
|
116
112
|
return nodeId
|
|
117
113
|
} else {
|
|
118
114
|
let s = nodeId.split(':')
|
|
119
|
-
let id =
|
|
120
|
-
let random = splitAndColorize(
|
|
115
|
+
let id = styleText('bold', s[0])
|
|
116
|
+
let random = splitAndColorize(3, s[1])
|
|
121
117
|
return `${id}:${random}`
|
|
122
118
|
}
|
|
123
119
|
}
|
|
124
120
|
|
|
125
|
-
function formatValue(
|
|
121
|
+
function formatValue(value) {
|
|
126
122
|
if (typeof value === 'string') {
|
|
127
|
-
return '"' +
|
|
123
|
+
return '"' + styleText('bold', value) + '"'
|
|
128
124
|
} else if (Array.isArray(value)) {
|
|
129
|
-
return formatArray(
|
|
125
|
+
return formatArray(value)
|
|
130
126
|
} else if (typeof value === 'object' && value) {
|
|
131
|
-
return formatObject(
|
|
127
|
+
return formatObject(value)
|
|
132
128
|
} else {
|
|
133
|
-
return
|
|
129
|
+
return styleText('bold', `${value}`)
|
|
134
130
|
}
|
|
135
131
|
}
|
|
136
132
|
|
|
137
|
-
function formatObject(
|
|
138
|
-
let items = Object.keys(obj).map(k => `${k}: ${formatValue(
|
|
133
|
+
function formatObject(obj) {
|
|
134
|
+
let items = Object.keys(obj).map(k => `${k}: ${formatValue(obj[k])}`)
|
|
139
135
|
return '{ ' + items.join(', ') + ' }'
|
|
140
136
|
}
|
|
141
137
|
|
|
142
|
-
function formatArray(
|
|
143
|
-
let items = array.map(i => formatValue(
|
|
138
|
+
function formatArray(array) {
|
|
139
|
+
let items = array.map(i => formatValue(i))
|
|
144
140
|
return '[' + items.join(', ') + ']'
|
|
145
141
|
}
|
|
146
142
|
|
|
147
|
-
function formatActionId(
|
|
143
|
+
function formatActionId(id) {
|
|
148
144
|
let p = id.split(' ')
|
|
149
145
|
if (p.length === 1) {
|
|
150
146
|
return p
|
|
151
147
|
}
|
|
152
|
-
return
|
|
153
|
-
|
|
154
|
-
p[1]
|
|
155
|
-
)
|
|
148
|
+
return (
|
|
149
|
+
`${styleText('bold', splitAndColorize(4, p[0]))} ` +
|
|
150
|
+
`${formatNodeId(p[1])} ${styleText('bold', p[2])}`
|
|
151
|
+
)
|
|
156
152
|
}
|
|
157
153
|
|
|
158
|
-
function formatParams(
|
|
154
|
+
function formatParams(params, parent) {
|
|
159
155
|
let maxName = params.reduce((max, param) => {
|
|
160
156
|
let name = param[0]
|
|
161
157
|
return name.length > max ? name.length : max
|
|
@@ -169,30 +165,30 @@ function formatParams(c, params, parent) {
|
|
|
169
165
|
let start = PADDING + rightPag(`${name}: `, maxName + 2)
|
|
170
166
|
|
|
171
167
|
if (name === 'Node ID' || (parent === 'Meta' && name === 'server')) {
|
|
172
|
-
return start + formatNodeId(
|
|
168
|
+
return start + formatNodeId(value)
|
|
173
169
|
} else if (
|
|
174
170
|
parent === 'Meta' &&
|
|
175
171
|
(name === 'clients' || name === 'excludeClients')
|
|
176
172
|
) {
|
|
177
|
-
return `${start}[${value.map(v => `"${formatNodeId(
|
|
173
|
+
return `${start}[${value.map(v => `"${formatNodeId(v)}"`).join()}]`
|
|
178
174
|
} else if (name === 'Action ID' || (parent === 'Meta' && name === 'id')) {
|
|
179
|
-
return start + formatActionId(
|
|
175
|
+
return start + formatActionId(value)
|
|
180
176
|
} else if (Array.isArray(value)) {
|
|
181
|
-
return start + formatArray(
|
|
177
|
+
return start + formatArray(value)
|
|
182
178
|
} else if (typeof value === 'object' && value) {
|
|
183
179
|
let nested = Object.keys(value).map(key => [key, value[key]])
|
|
184
180
|
return (
|
|
185
181
|
start +
|
|
186
182
|
NEXT_LINE +
|
|
187
183
|
INDENT +
|
|
188
|
-
formatParams(
|
|
184
|
+
formatParams(nested, name)
|
|
189
185
|
.split(NEXT_LINE)
|
|
190
186
|
.join(NEXT_LINE + INDENT)
|
|
191
187
|
)
|
|
192
188
|
} else if (typeof value === 'string' && parent) {
|
|
193
|
-
return start + '"' +
|
|
189
|
+
return start + '"' + styleText('bold', value) + '"'
|
|
194
190
|
} else {
|
|
195
|
-
return start +
|
|
191
|
+
return start + styleText('bold', `${value}`)
|
|
196
192
|
}
|
|
197
193
|
})
|
|
198
194
|
.join(NEXT_LINE)
|
|
@@ -212,7 +208,7 @@ function splitByLength(string, max) {
|
|
|
212
208
|
return lines.map(i => i.trim())
|
|
213
209
|
}
|
|
214
210
|
|
|
215
|
-
function prettyStackTrace(
|
|
211
|
+
function prettyStackTrace(stack, basepath) {
|
|
216
212
|
return stack
|
|
217
213
|
.split('\n')
|
|
218
214
|
.slice(1)
|
|
@@ -220,24 +216,25 @@ function prettyStackTrace(c, stack, basepath) {
|
|
|
220
216
|
let match = line.match(/\s+at ([^(]+) \(([^)]+)\)/)
|
|
221
217
|
let isSystem = !match || !match[2].startsWith(basepath)
|
|
222
218
|
if (isSystem) {
|
|
223
|
-
return
|
|
219
|
+
return styleText('gray', line.replace(/^\s*/, PADDING))
|
|
224
220
|
} else {
|
|
225
221
|
let func = match[1]
|
|
226
222
|
let relative = match[2].slice(basepath.length)
|
|
227
223
|
let converted = `${PADDING}at ${func} (./${relative})`
|
|
228
224
|
let isDependency = match[2].includes('node_modules')
|
|
229
|
-
return isDependency
|
|
225
|
+
return isDependency
|
|
226
|
+
? styleText('gray', converted)
|
|
227
|
+
: styleText('red', converted)
|
|
230
228
|
}
|
|
231
229
|
})
|
|
232
230
|
.join(NEXT_LINE)
|
|
233
231
|
}
|
|
234
232
|
|
|
235
|
-
function humanFormatter(options) {
|
|
236
|
-
let c = pico.createColors(options.color)
|
|
233
|
+
export default function humanFormatter(options) {
|
|
237
234
|
let basepath = options.basepath
|
|
238
235
|
|
|
239
236
|
return function format(record) {
|
|
240
|
-
let message = [LABELS[record.level](
|
|
237
|
+
let message = [LABELS[record.level](record.msg)]
|
|
241
238
|
let params = Object.keys(record)
|
|
242
239
|
.filter(key => !PARAMS_BLACKLIST[key])
|
|
243
240
|
.map(key => [formatName(key), record[key]])
|
|
@@ -252,53 +249,26 @@ function humanFormatter(options) {
|
|
|
252
249
|
}
|
|
253
250
|
|
|
254
251
|
if (record.err && record.err.stack) {
|
|
255
|
-
message.push(prettyStackTrace(
|
|
252
|
+
message.push(prettyStackTrace(record.err.stack, basepath))
|
|
256
253
|
}
|
|
257
254
|
|
|
258
|
-
message.push(formatParams(
|
|
255
|
+
message.push(formatParams(params))
|
|
259
256
|
|
|
260
257
|
if (record.note) {
|
|
261
258
|
let note = record.note
|
|
262
259
|
if (typeof note === 'string') {
|
|
263
|
-
note = note.replace(/`([^`]+)`/g,
|
|
260
|
+
note = note.replace(/`([^`]+)`/g, styleText('bold', '$1'))
|
|
264
261
|
note = [].concat(
|
|
265
262
|
...note
|
|
266
263
|
.split('\n')
|
|
267
264
|
.map(row => splitByLength(row, 80 - PADDING.length))
|
|
268
265
|
)
|
|
269
266
|
}
|
|
270
|
-
message.push(
|
|
267
|
+
message.push(
|
|
268
|
+
note.map(i => PADDING + styleText('gray', i)).join(NEXT_LINE)
|
|
269
|
+
)
|
|
271
270
|
}
|
|
272
271
|
|
|
273
272
|
return message.filter(i => i !== '').join(NEXT_LINE) + SEPARATOR
|
|
274
273
|
}
|
|
275
274
|
}
|
|
276
|
-
|
|
277
|
-
export default async function (options) {
|
|
278
|
-
let format = humanFormatter(options)
|
|
279
|
-
let destination = pino.destination({
|
|
280
|
-
dest: options.destination || 1,
|
|
281
|
-
sync: options.sync || false
|
|
282
|
-
})
|
|
283
|
-
await once(destination, 'ready')
|
|
284
|
-
let transform = new Transform({
|
|
285
|
-
autoDestroy: true,
|
|
286
|
-
objectMode: true,
|
|
287
|
-
transform(chunk, encoding, callback) {
|
|
288
|
-
callback(null, format(chunk))
|
|
289
|
-
}
|
|
290
|
-
})
|
|
291
|
-
|
|
292
|
-
return abstractTransport(
|
|
293
|
-
source => {
|
|
294
|
-
source.pipe(transform)
|
|
295
|
-
transform.pipe(destination)
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
close(err, cb) {
|
|
299
|
-
transform.end()
|
|
300
|
-
transform.on('close', cb.bind(null, err))
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
)
|
|
304
|
-
}
|
package/index.js
CHANGED
|
@@ -8,15 +8,7 @@ export { ALLOWED_META } from './allowed-meta/index.js'
|
|
|
8
8
|
export { BaseServer, wasNot403 } from './base-server/index.js'
|
|
9
9
|
export { Context } from './context/index.js'
|
|
10
10
|
export { filterMeta } from './filter-meta/index.js'
|
|
11
|
-
export {
|
|
12
|
-
del,
|
|
13
|
-
get,
|
|
14
|
-
patch,
|
|
15
|
-
post,
|
|
16
|
-
put,
|
|
17
|
-
request,
|
|
18
|
-
ResponseError
|
|
19
|
-
} from './request/index.js'
|
|
11
|
+
export { ResponseError } from './request/index.js'
|
|
20
12
|
export { Server } from './server/index.js'
|
|
21
13
|
export { TestClient } from './test-client/index.js'
|
|
22
14
|
export { TestServer } from './test-server/index.js'
|
package/options-loader/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { join } from 'node:path'
|
|
3
|
+
import { styleText } from 'node:util'
|
|
3
4
|
|
|
4
5
|
export function loadOptions(spec, process, env) {
|
|
5
6
|
let rawCliArgs = gatherCliArgs(process.argv)
|
|
@@ -18,7 +19,7 @@ export function loadOptions(spec, process, env) {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
let cliArgs = parseValues(spec, mapArgs(rawCliArgs, namesMap))
|
|
21
|
-
let dotenvArgs =
|
|
22
|
+
let dotenvArgs = loadEnv(env)
|
|
22
23
|
if (dotenvArgs) {
|
|
23
24
|
dotenvArgs = Object.fromEntries(
|
|
24
25
|
Object.entries(dotenvArgs).filter(([key]) =>
|
|
@@ -72,17 +73,38 @@ function parseValues(spec, args) {
|
|
|
72
73
|
parsed[key] = parsingResult[1]
|
|
73
74
|
} else {
|
|
74
75
|
throw Error(
|
|
75
|
-
`Failed to parse ${
|
|
76
|
+
`Failed to parse ${styleText('bold', key)} argument value. \n` +
|
|
76
77
|
parsingResult[0]
|
|
77
|
-
}`
|
|
78
78
|
)
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
return parsed
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function
|
|
85
|
-
|
|
84
|
+
function loadEnv(file) {
|
|
85
|
+
if (!file || !existsSync(file)) {
|
|
86
|
+
file = join(process.cwd(), '.env')
|
|
87
|
+
if (!existsSync(file)) return undefined
|
|
88
|
+
}
|
|
89
|
+
let result = {}
|
|
90
|
+
let lines
|
|
91
|
+
try {
|
|
92
|
+
lines = readFileSync(file, 'utf8').split('\n')
|
|
93
|
+
} catch {
|
|
94
|
+
/* c8 ignore next 2 */
|
|
95
|
+
return undefined
|
|
96
|
+
}
|
|
97
|
+
for (let line of lines) {
|
|
98
|
+
if (line.trim().startsWith('#') || !line.includes('=')) {
|
|
99
|
+
continue
|
|
100
|
+
}
|
|
101
|
+
let [key, ...valueParts] = line.split('=')
|
|
102
|
+
result[key] = valueParts
|
|
103
|
+
.join('=')
|
|
104
|
+
.trim()
|
|
105
|
+
.replace(/(^"|"$|^'|'$)/g, '')
|
|
106
|
+
}
|
|
107
|
+
return result
|
|
86
108
|
}
|
|
87
109
|
|
|
88
110
|
function mapArgs(parsedCliArgs, argsSpec) {
|
|
@@ -106,8 +128,9 @@ function composeHelp(spec, argv) {
|
|
|
106
128
|
let nameColumnLength = Math.max(...options.map(it => it.full.length))
|
|
107
129
|
let envColumnLength = Math.max(...options.map(it => it.env.length))
|
|
108
130
|
|
|
109
|
-
let composeName = name =>
|
|
110
|
-
|
|
131
|
+
let composeName = name =>
|
|
132
|
+
styleText('yellow', name.padEnd(nameColumnLength + 2))
|
|
133
|
+
let composeEnv = env => styleText('cyan', env.padEnd(envColumnLength + 2))
|
|
111
134
|
let composeOptionHelp = option => {
|
|
112
135
|
return (
|
|
113
136
|
composeName(option.full) + composeEnv(option.env) + option.description
|
|
@@ -120,7 +143,7 @@ function composeHelp(spec, argv) {
|
|
|
120
143
|
let lastPart = pathParts[pathParts.length - 1]
|
|
121
144
|
examples = [
|
|
122
145
|
'',
|
|
123
|
-
|
|
146
|
+
styleText('bold', 'Examples:'),
|
|
124
147
|
...spec.examples.map(i => i.replace('$0', lastPart))
|
|
125
148
|
]
|
|
126
149
|
}
|
|
@@ -128,7 +151,7 @@ function composeHelp(spec, argv) {
|
|
|
128
151
|
return [
|
|
129
152
|
'Start Logux Server',
|
|
130
153
|
'',
|
|
131
|
-
|
|
154
|
+
styleText('bold', 'Options:'),
|
|
132
155
|
...options.map(option => composeOptionHelp(option)),
|
|
133
156
|
...examples
|
|
134
157
|
].join('\n')
|
|
@@ -157,7 +180,8 @@ export function oneOf(options, rawValue) {
|
|
|
157
180
|
if (!options.includes(rawValue)) {
|
|
158
181
|
let opt = JSON.stringify(options)
|
|
159
182
|
return [
|
|
160
|
-
`Expected ${
|
|
183
|
+
`Expected ${styleText('green', 'one of ' + opt)}, ` +
|
|
184
|
+
`got ${styleText('red', `${rawValue}`)}`,
|
|
161
185
|
null
|
|
162
186
|
]
|
|
163
187
|
} else {
|
|
@@ -168,7 +192,11 @@ export function oneOf(options, rawValue) {
|
|
|
168
192
|
export function number(rawValue) {
|
|
169
193
|
let parsed = Number.parseInt(rawValue, 10)
|
|
170
194
|
if (Number.isNaN(parsed)) {
|
|
171
|
-
return [
|
|
195
|
+
return [
|
|
196
|
+
`Expected ${styleText('green', 'number')}, ` +
|
|
197
|
+
`got ${styleText('red', `${rawValue}`)}`,
|
|
198
|
+
null
|
|
199
|
+
]
|
|
172
200
|
} else {
|
|
173
201
|
return [null, parsed]
|
|
174
202
|
}
|
|
@@ -176,7 +204,11 @@ export function number(rawValue) {
|
|
|
176
204
|
|
|
177
205
|
export function string(rawValue) {
|
|
178
206
|
if (typeof rawValue !== 'string') {
|
|
179
|
-
return [
|
|
207
|
+
return [
|
|
208
|
+
`Expected ${styleText('green', 'string')}, ` +
|
|
209
|
+
`got ${styleText('red', `${rawValue}`)}`,
|
|
210
|
+
null
|
|
211
|
+
]
|
|
180
212
|
} else {
|
|
181
213
|
return [null, rawValue]
|
|
182
214
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import '../test/force-colors.js'
|
|
2
|
+
|
|
1
3
|
import { resolve } from 'node:path'
|
|
2
4
|
import { describe, expect, it } from 'vitest'
|
|
3
5
|
|
|
@@ -73,9 +75,7 @@ describe('loadOptions', () => {
|
|
|
73
75
|
}
|
|
74
76
|
},
|
|
75
77
|
fakeProcess([], {}),
|
|
76
|
-
|
|
77
|
-
path: resolve(process.cwd(), 'options-loader/test.env')
|
|
78
|
-
}
|
|
78
|
+
resolve(process.cwd(), 'options-loader/test.env')
|
|
79
79
|
)
|
|
80
80
|
|
|
81
81
|
expect(options.port).toEqual(31337)
|
package/options-loader/test.env
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logux/server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Build own Logux server
|
|
3
|
+
"version": "0.14.0",
|
|
4
|
+
"description": "Build own Logux server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"logux",
|
|
7
7
|
"server",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"homepage": "https://logux.org/",
|
|
19
19
|
"repository": "logux/server",
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": "^
|
|
21
|
+
"node": "^20.0.0 || >=22.0.0"
|
|
22
22
|
},
|
|
23
23
|
"type": "module",
|
|
24
24
|
"types": "./index.d.ts",
|
|
@@ -27,23 +27,14 @@
|
|
|
27
27
|
"./package.json": "./package.json"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@logux/actions": "^0.
|
|
31
|
-
"@logux/core": "^0.
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"nanoevents": "^9.0.0",
|
|
38
|
-
"nanoid": "^5.0.7",
|
|
39
|
-
"netmask": "^2.0.2",
|
|
40
|
-
"node-fetch": "^3.3.2",
|
|
41
|
-
"picocolors": "^1.0.1",
|
|
42
|
-
"pino": "9.3.2",
|
|
43
|
-
"pino-abstract-transport": "^1.2.0",
|
|
44
|
-
"semver": "^7.6.3",
|
|
45
|
-
"strip-ansi": "^7.1.0",
|
|
30
|
+
"@logux/actions": "^0.5.0",
|
|
31
|
+
"@logux/core": "^0.10.0",
|
|
32
|
+
"cookie": "^1.0.2",
|
|
33
|
+
"fastq": "^1.19.1",
|
|
34
|
+
"nanoevents": "^9.1.0",
|
|
35
|
+
"nanoid": "^5.1.5",
|
|
36
|
+
"tinyglobby": "^0.2.14",
|
|
46
37
|
"url-pattern": "^1.0.3",
|
|
47
|
-
"ws": "^8.18.
|
|
38
|
+
"ws": "^8.18.3"
|
|
48
39
|
}
|
|
49
40
|
}
|
package/request/index.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import type { RequestInit } from 'node-fetch'
|
|
2
|
-
import type fetch from 'node-fetch'
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
2
|
* Throwing this error in `accessAndProcess` or `accessAndLoad`
|
|
6
3
|
* will deny the action.
|
|
@@ -9,100 +6,5 @@ export class ResponseError extends Error {
|
|
|
9
6
|
name: 'ResponseError'
|
|
10
7
|
statusCode: number
|
|
11
8
|
|
|
12
|
-
constructor(
|
|
13
|
-
statusCode: number,
|
|
14
|
-
url: string,
|
|
15
|
-
opts: RequestInit,
|
|
16
|
-
response: string
|
|
17
|
-
)
|
|
9
|
+
constructor(statusCode: number, url: string)
|
|
18
10
|
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Syntax sugar around `node-fetch`, which throws {@link ResponseError}
|
|
22
|
-
* on non-2xx response.
|
|
23
|
-
*
|
|
24
|
-
* @param url Resource URL.
|
|
25
|
-
* @param opts `fetch()` options.
|
|
26
|
-
* @param fetcher A way to replace `fetch()` for tests.
|
|
27
|
-
*/
|
|
28
|
-
export function request<Body = any>(
|
|
29
|
-
url: string,
|
|
30
|
-
opts?: RequestInit,
|
|
31
|
-
fetcher?: typeof fetch
|
|
32
|
-
): Body
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Syntax sugar for `GET` requests by `node-fetch`, throwing
|
|
36
|
-
* {@link ResponseError} on non-2xx response and parsing JSON response.
|
|
37
|
-
*
|
|
38
|
-
* ```js
|
|
39
|
-
* import { get } from '@logux/server'
|
|
40
|
-
*
|
|
41
|
-
* let user = get(url)
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* @param url Resource URL.
|
|
45
|
-
* @param opts `fetch()` options.
|
|
46
|
-
* @param fetcher A way to replace `fetch()` for tests.
|
|
47
|
-
*/
|
|
48
|
-
export function get<Body = any>(
|
|
49
|
-
url: string,
|
|
50
|
-
opts?: Omit<RequestInit, 'method'>,
|
|
51
|
-
fetcher?: typeof fetch
|
|
52
|
-
): Body
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Syntax sugar for `POST` requests by `node-fetch`, throwing
|
|
56
|
-
* {@link ResponseError} on non-2xx response.
|
|
57
|
-
*
|
|
58
|
-
* @param url Resource URL.
|
|
59
|
-
* @param opts `fetch()` options.
|
|
60
|
-
* @param fetcher A way to replace `fetch()` for tests.
|
|
61
|
-
*/
|
|
62
|
-
export function post<Body = any>(
|
|
63
|
-
url: string,
|
|
64
|
-
opts?: Omit<RequestInit, 'method'>,
|
|
65
|
-
fetcher?: typeof fetch
|
|
66
|
-
): Body
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Syntax sugar for `PUT` requests by `node-fetch`, throwing
|
|
70
|
-
* {@link ResponseError} on non-2xx response and parsing JSON response.
|
|
71
|
-
*
|
|
72
|
-
* @param url Resource URL.
|
|
73
|
-
* @param opts `fetch()` options.
|
|
74
|
-
* @param fetcher A way to replace `fetch()` for tests.
|
|
75
|
-
*/
|
|
76
|
-
export function put<Body = any>(
|
|
77
|
-
url: string,
|
|
78
|
-
opts?: Omit<RequestInit, 'method'>,
|
|
79
|
-
fetcher?: typeof fetch
|
|
80
|
-
): Body
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Syntax sugar for `PATCH` requests by `node-fetch`, throwing
|
|
84
|
-
* {@link ResponseError} on non-2xx response and parsing JSON response.
|
|
85
|
-
*
|
|
86
|
-
* @param url Resource URL.
|
|
87
|
-
* @param opts `fetch()` options.
|
|
88
|
-
* @param fetcher A way to replace `fetch()` for tests.
|
|
89
|
-
*/
|
|
90
|
-
export function patch<Body = any>(
|
|
91
|
-
url: string,
|
|
92
|
-
opts?: Omit<RequestInit, 'method'>,
|
|
93
|
-
fetcher?: typeof fetch
|
|
94
|
-
): Body
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Syntax sugar for `DELETE` requests by `node-fetch`, throwing
|
|
98
|
-
* {@link ResponseError} on non-2xx response and parsing JSON response.
|
|
99
|
-
*
|
|
100
|
-
* @param url Resource URL.
|
|
101
|
-
* @param opts `fetch()` options.
|
|
102
|
-
* @param fetcher A way to replace `fetch()` for tests.
|
|
103
|
-
*/
|
|
104
|
-
export function del<Body = any>(
|
|
105
|
-
url: string,
|
|
106
|
-
opts?: Omit<RequestInit, 'method'>,
|
|
107
|
-
fetcher?: typeof fetch
|
|
108
|
-
): Body
|
package/request/index.js
CHANGED
|
@@ -1,45 +1,7 @@
|
|
|
1
|
-
import fetch from 'node-fetch'
|
|
2
|
-
|
|
3
|
-
function argsToString(url, opts, response) {
|
|
4
|
-
let { method, ...other } = opts
|
|
5
|
-
return `${method || 'GET'} ${url} ${JSON.stringify(other)} ${response}`
|
|
6
|
-
}
|
|
7
|
-
|
|
8
1
|
export class ResponseError extends Error {
|
|
9
|
-
constructor(statusCode, url
|
|
10
|
-
super(`${statusCode} response on ${
|
|
2
|
+
constructor(statusCode, url) {
|
|
3
|
+
super(`${statusCode} response on ${url}`)
|
|
11
4
|
this.name = 'ResponseError'
|
|
12
5
|
this.statusCode = statusCode
|
|
13
6
|
}
|
|
14
7
|
}
|
|
15
|
-
|
|
16
|
-
export async function request(url, opts = {}, fetcher = fetch) {
|
|
17
|
-
let response = await fetcher(url, opts)
|
|
18
|
-
if (response.status === 204) {
|
|
19
|
-
return undefined
|
|
20
|
-
} else if (response.status >= 200 && response.status <= 299) {
|
|
21
|
-
return response.json()
|
|
22
|
-
} else {
|
|
23
|
-
throw new ResponseError(response.status, url, opts, await response.text())
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function get(url, opts = {}, fetcher = fetch) {
|
|
28
|
-
return request(url, { ...opts, method: 'GET' }, fetcher)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function post(url, opts = {}, fetcher = fetch) {
|
|
32
|
-
return request(url, { ...opts, method: 'POST' }, fetcher)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function put(url, opts = {}, fetcher = fetch) {
|
|
36
|
-
return request(url, { ...opts, method: 'PUT' }, fetcher)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function patch(url, opts = {}, fetcher = fetch) {
|
|
40
|
-
return request(url, { ...opts, method: 'PATCH' }, fetcher)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function del(url, opts = {}, fetcher = fetch) {
|
|
44
|
-
return request(url, { ...opts, method: 'DELETE' }, fetcher)
|
|
45
|
-
}
|