@beyonk/http 12.0.1 → 12.1.1
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/package.json +18 -12
- package/.github/workflows/publish.yml +0 -60
- package/lib/api/_just-compose.js +0 -12
- package/lib/api/index.js +0 -233
- package/lib/api/index.spec.js +0 -954
- package/lib/entrypoint.js +0 -19
- package/lib/error-handlers/access-denied.js +0 -12
- package/lib/error-handlers/bad-data.js +0 -12
- package/lib/error-handlers/conflict.js +0 -12
- package/lib/error-handlers/default.js +0 -8
- package/lib/error-handlers/expectation-failed.js +0 -12
- package/lib/error-handlers/forbidden.js +0 -12
- package/lib/error-handlers/gone.js +0 -12
- package/lib/error-handlers/handle.js +0 -25
- package/lib/error-handlers/not-acceptable.js +0 -12
- package/lib/error-handlers/not-found.js +0 -12
- package/lib/error-handlers/payment-required.js +0 -12
- package/lib/error-handlers/precondition-failed.js +0 -12
- package/lib/error-handlers/too-many-requests.js +0 -12
- package/lib/errors.js +0 -73
package/package.json
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beyonk/http",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.1.1",
|
|
4
4
|
"description": "An isomorphic http client for Svelte apps",
|
|
5
|
-
"main": "lib/entrypoint.js",
|
|
6
|
-
"module": "lib/entrypoint.js",
|
|
7
5
|
"type": "module",
|
|
8
|
-
"directories": {
|
|
9
|
-
"lib": "lib"
|
|
10
|
-
},
|
|
11
6
|
"repository": {
|
|
12
7
|
"type": "git",
|
|
13
8
|
"url": "https://github.com/beyonk-adventures/http.git"
|
|
14
9
|
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
15
20
|
"devDependencies": {
|
|
16
|
-
"@beyonk/eslint-config": "^
|
|
17
|
-
"@beyonk/esm": "^4.0.1",
|
|
21
|
+
"@beyonk/eslint-config": "^9.0.3",
|
|
18
22
|
"@hapi/code": "^5.3.1",
|
|
19
|
-
"eslint": "^
|
|
23
|
+
"eslint": "^9.29.0",
|
|
20
24
|
"mocha": "^9.0.2",
|
|
21
|
-
"sinon": "^7.5.0"
|
|
25
|
+
"sinon": "^7.5.0",
|
|
26
|
+
"tsup": "^8.4.0",
|
|
27
|
+
"typescript": "^5.8.3"
|
|
22
28
|
},
|
|
23
29
|
"eslintConfig": {
|
|
24
30
|
"extends": "@beyonk",
|
|
@@ -45,9 +51,9 @@
|
|
|
45
51
|
"volta": {
|
|
46
52
|
"node": "18.15.0"
|
|
47
53
|
},
|
|
48
|
-
"packageManager": "pnpm@8.0.0",
|
|
49
54
|
"scripts": {
|
|
50
55
|
"test": "mocha './!(node_modules)/**/**.+(spec).js'",
|
|
51
|
-
"lint": "eslint lib --ext .js"
|
|
56
|
+
"lint": "eslint lib --ext .js",
|
|
57
|
+
"build": "tsup"
|
|
52
58
|
}
|
|
53
59
|
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
name: publish
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- '*'
|
|
7
|
-
tags:
|
|
8
|
-
- 'v*'
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
build:
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v3
|
|
15
|
-
with:
|
|
16
|
-
ref: master
|
|
17
|
-
|
|
18
|
-
- uses: volta-cli/action@v4
|
|
19
|
-
|
|
20
|
-
- name: Cache pnpm modules
|
|
21
|
-
uses: actions/cache@v2
|
|
22
|
-
with:
|
|
23
|
-
path: ~/.pnpm-store
|
|
24
|
-
key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
25
|
-
restore-keys: |
|
|
26
|
-
${{ runner.os }}-
|
|
27
|
-
|
|
28
|
-
- uses: pnpm/action-setup@v2.2.4
|
|
29
|
-
with:
|
|
30
|
-
run_install: true
|
|
31
|
-
|
|
32
|
-
- run: pnpm lint
|
|
33
|
-
|
|
34
|
-
publish-npm:
|
|
35
|
-
if: startsWith(github.ref, 'refs/tags/v')
|
|
36
|
-
needs: build
|
|
37
|
-
runs-on: ubuntu-latest
|
|
38
|
-
steps:
|
|
39
|
-
- uses: actions/checkout@v3
|
|
40
|
-
with:
|
|
41
|
-
ref: master
|
|
42
|
-
|
|
43
|
-
- uses: volta-cli/action@v4
|
|
44
|
-
|
|
45
|
-
- name: Authorize NPM
|
|
46
|
-
run: npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}
|
|
47
|
-
|
|
48
|
-
- name: Cache pnpm modules
|
|
49
|
-
uses: actions/cache@v2
|
|
50
|
-
with:
|
|
51
|
-
path: ~/.pnpm-store
|
|
52
|
-
key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
53
|
-
restore-keys: |
|
|
54
|
-
${{ runner.os }}-
|
|
55
|
-
|
|
56
|
-
- uses: pnpm/action-setup@v2.2.4
|
|
57
|
-
with:
|
|
58
|
-
run_install: true
|
|
59
|
-
|
|
60
|
-
- run: pnpm publish
|
package/lib/api/_just-compose.js
DELETED
package/lib/api/index.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import { AccessDeniedMixin } from '../error-handlers/access-denied.js'
|
|
2
|
-
import { ConflictMixin } from '../error-handlers/conflict.js'
|
|
3
|
-
import { DefaultMixin } from '../error-handlers/default.js'
|
|
4
|
-
import { ForbiddenMixin } from '../error-handlers/forbidden.js'
|
|
5
|
-
import { HandleMixin } from '../error-handlers/handle.js'
|
|
6
|
-
import { NotFoundMixin } from '../error-handlers/not-found.js'
|
|
7
|
-
import { BadDataMixin } from '../error-handlers/bad-data.js'
|
|
8
|
-
import { PaymentRequiredMixin } from '../error-handlers/payment-required.js'
|
|
9
|
-
import { PreconditionFailedMixin } from '../error-handlers/precondition-failed.js'
|
|
10
|
-
import { TooManyRequestsMixin } from '../error-handlers/too-many-requests.js'
|
|
11
|
-
import { NotAcceptableMixin } from '../error-handlers/not-acceptable.js'
|
|
12
|
-
import { GoneMixin } from '../error-handlers/gone.js'
|
|
13
|
-
import { ExpectationFailedMixin } from '../error-handlers/expectation-failed.js'
|
|
14
|
-
import { byCode } from '../errors.js'
|
|
15
|
-
import { compose } from './_just-compose.js'
|
|
16
|
-
|
|
17
|
-
class ApiBase {}
|
|
18
|
-
const Behaviours = compose(
|
|
19
|
-
AccessDeniedMixin,
|
|
20
|
-
ConflictMixin,
|
|
21
|
-
DefaultMixin,
|
|
22
|
-
ForbiddenMixin,
|
|
23
|
-
HandleMixin,
|
|
24
|
-
NotFoundMixin,
|
|
25
|
-
BadDataMixin,
|
|
26
|
-
PaymentRequiredMixin,
|
|
27
|
-
PreconditionFailedMixin,
|
|
28
|
-
TooManyRequestsMixin,
|
|
29
|
-
NotAcceptableMixin,
|
|
30
|
-
GoneMixin,
|
|
31
|
-
ExpectationFailedMixin
|
|
32
|
-
)(ApiBase)
|
|
33
|
-
|
|
34
|
-
class Api extends Behaviours {
|
|
35
|
-
constructor (options) {
|
|
36
|
-
super()
|
|
37
|
-
this.options = Object.assign({
|
|
38
|
-
retry: false,
|
|
39
|
-
parseErrors: true,
|
|
40
|
-
handlers: {}
|
|
41
|
-
}, options)
|
|
42
|
-
|
|
43
|
-
this.handlers = {}
|
|
44
|
-
this.client = null
|
|
45
|
-
this.resetRequest()
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
resetRequest () {
|
|
49
|
-
this.config = {
|
|
50
|
-
endpoint: null,
|
|
51
|
-
method: 'get',
|
|
52
|
-
payload: null,
|
|
53
|
-
query: null,
|
|
54
|
-
headers: {},
|
|
55
|
-
overrides: {}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
getClient () {
|
|
60
|
-
if (this.options.mock) {
|
|
61
|
-
console.warn('@beyonk/http: Using mocked http client')
|
|
62
|
-
return this.options.mock
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (this.client) {
|
|
66
|
-
return this.client
|
|
67
|
-
} else if (typeof window !== 'undefined') {
|
|
68
|
-
return window.fetch.bind(window)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
throw Error("No client provided and can't find one automatically")
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async send (fn) {
|
|
75
|
-
const endpoint = this.config.endpoint.includes('://') ? this.config.endpoint : `${this.options.baseUrl}/${this.config.endpoint}`
|
|
76
|
-
const hasPayload = !!this.config.payload
|
|
77
|
-
|
|
78
|
-
const options = Object.assign(
|
|
79
|
-
{
|
|
80
|
-
method: this.config.method,
|
|
81
|
-
cors: true,
|
|
82
|
-
credentials: 'include',
|
|
83
|
-
headers: Object.assign(
|
|
84
|
-
{ Accept: 'application/json' },
|
|
85
|
-
hasPayload ? { 'Content-Type': 'application/json' } : {},
|
|
86
|
-
this.config.headers
|
|
87
|
-
)
|
|
88
|
-
},
|
|
89
|
-
hasPayload ? { body: JSON.stringify(this.config.payload) } : {},
|
|
90
|
-
this.config.overrides
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
const client = this.getClient()
|
|
94
|
-
const ep = this.config.query ? `${endpoint}?${this.config.query}` : `${endpoint}`
|
|
95
|
-
|
|
96
|
-
let result
|
|
97
|
-
try {
|
|
98
|
-
result = await this._doQuery(1, client, ep, options)
|
|
99
|
-
} catch (e) {
|
|
100
|
-
console.log(e)
|
|
101
|
-
return this.handle(e, this.ctx)
|
|
102
|
-
} finally {
|
|
103
|
-
this.resetRequest()
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const { json, httpStatus } = result
|
|
107
|
-
return fn ? fn(json, httpStatus) : json
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
_hasContent (response) {
|
|
111
|
-
const contentLength = parseInt(response.headers.get('content-length'), 10)
|
|
112
|
-
|
|
113
|
-
const isNoContentResponse = response.status === 204
|
|
114
|
-
if (isNoContentResponse) {
|
|
115
|
-
return false
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const headerExists = !isNaN(contentLength)
|
|
119
|
-
return !headerExists || contentLength > 0
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async _doQuery (attempt, client, endpoint, options) {
|
|
123
|
-
const retry = this.options.retry || { attempts: 1 }
|
|
124
|
-
try {
|
|
125
|
-
const r = await client(endpoint, options)
|
|
126
|
-
|
|
127
|
-
if (r.status >= 200 && r.status < 400) {
|
|
128
|
-
let json
|
|
129
|
-
|
|
130
|
-
if (this._hasContent(r)) {
|
|
131
|
-
try {
|
|
132
|
-
json = await r.json()
|
|
133
|
-
} catch (e) {
|
|
134
|
-
console.error('Unable to parse response json', e.message)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return { httpStatus: r.status, json }
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
let content = ''
|
|
142
|
-
try {
|
|
143
|
-
content = this.options.parseErrors ? await r.json() : await r.text()
|
|
144
|
-
} catch (e) {
|
|
145
|
-
console.log('Failed to parse error body when asked.')
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const ClientError = byCode(r.status)
|
|
149
|
-
throw new ClientError(r.statusText, content)
|
|
150
|
-
} catch (e) {
|
|
151
|
-
if (attempt < retry.attempts && retry.errors.includes(e.code)) {
|
|
152
|
-
console.warn(`Got ${e.code} when calling ${endpoint}. Retrying request (${attempt}/${retry.attempts})`)
|
|
153
|
-
return this._doQuery(++attempt, client, endpoint, options)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
throw e
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
context (ctx) {
|
|
161
|
-
if (ctx.fetch) {
|
|
162
|
-
this.client = ctx.fetch
|
|
163
|
-
}
|
|
164
|
-
this.ctx = ctx
|
|
165
|
-
return this
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
override (override) {
|
|
169
|
-
this.config.overrides = override
|
|
170
|
-
return this
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
headers (headers) {
|
|
174
|
-
this.config.headers = headers
|
|
175
|
-
return this
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async get (fn) {
|
|
179
|
-
this.config.method = 'GET'
|
|
180
|
-
return this.send(fn)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async post (fn) {
|
|
184
|
-
this.config.method = 'POST'
|
|
185
|
-
return this.send(fn)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async patch (fn) {
|
|
189
|
-
this.config.method = 'PATCH'
|
|
190
|
-
return this.send(fn)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async put (fn) {
|
|
194
|
-
this.config.method = 'PUT'
|
|
195
|
-
return this.send(fn)
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async del (fn) {
|
|
199
|
-
this.config.method = 'DELETE'
|
|
200
|
-
return this.send(fn)
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
endpoint (endpoint) {
|
|
204
|
-
this.config.endpoint = endpoint
|
|
205
|
-
return this
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
query (query) {
|
|
209
|
-
const q = Object.entries(query).reduce((curr, [ k, v ]) => {
|
|
210
|
-
if (typeof v === 'undefined') {
|
|
211
|
-
return curr
|
|
212
|
-
}
|
|
213
|
-
if (Array.isArray(v)) {
|
|
214
|
-
curr.push(...v.map(n => `${k}=${encodeURIComponent(n)}`))
|
|
215
|
-
} else {
|
|
216
|
-
curr.push(`${k}=${encodeURIComponent(v)}`)
|
|
217
|
-
}
|
|
218
|
-
return curr
|
|
219
|
-
}, [])
|
|
220
|
-
|
|
221
|
-
this.config.query = q.join('&')
|
|
222
|
-
return this
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
payload (payload) {
|
|
226
|
-
this.config.payload = payload
|
|
227
|
-
return this
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
export {
|
|
232
|
-
Api
|
|
233
|
-
}
|