@beyonk/http 12.0.0 → 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/README.MD CHANGED
@@ -188,9 +188,7 @@ Handlers have a signature with two items:
188
188
  ```js
189
189
  .badData((e, ctx) => {
190
190
  console.error('Bad data', e)
191
- ctx.redirect('/foo/bar')
192
- // or
193
- ctx.error('/foo/bar')
191
+ throw redirect('/foo/bar')
194
192
  })
195
193
  ```
196
194
 
@@ -201,7 +199,7 @@ However, if the `context` object you pass in has a `fetch` function, this is use
201
199
  ```js
202
200
  export async function preload () {
203
201
  await Api
204
- .context(this) // fetch, redirect, error.
202
+ .context({ fetch })
205
203
  .endpoint('foo/bar')
206
204
  ...
207
205
  }
@@ -232,7 +230,7 @@ Names are the same as the local handlers:
232
230
  baseUrl: 'https://example.com/your/api/base',
233
231
  handlers: {
234
232
  paymentRequired(e => {
235
- redirect(307, '/checkout')
233
+ throw redirect(307, '/checkout')
236
234
  })
237
235
  }
238
236
  })
package/package.json CHANGED
@@ -1,24 +1,30 @@
1
1
  {
2
2
  "name": "@beyonk/http",
3
- "version": "12.0.0",
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": "^4.2.0",
17
- "@beyonk/esm": "^4.0.1",
21
+ "@beyonk/eslint-config": "^9.0.3",
18
22
  "@hapi/code": "^5.3.1",
19
- "eslint": "^7.2.0",
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
@@ -1,12 +0,0 @@
1
- function compose (...fns) {
2
- return function () {
3
- var result = fns[0].apply(this, arguments)
4
- var len = fns.length
5
- for (var i = 1; i < len; i++) {
6
- result = fns[i].call(this, result)
7
- }
8
- return result
9
- }
10
- }
11
-
12
- export { compose }
package/lib/api/index.js DELETED
@@ -1,231 +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 { byCode } from '../errors.js'
14
- import { compose } from './_just-compose.js'
15
-
16
- class ApiBase {}
17
- const Behaviours = compose(
18
- AccessDeniedMixin,
19
- ConflictMixin,
20
- DefaultMixin,
21
- ForbiddenMixin,
22
- HandleMixin,
23
- NotFoundMixin,
24
- BadDataMixin,
25
- PaymentRequiredMixin,
26
- PreconditionFailedMixin,
27
- TooManyRequestsMixin,
28
- NotAcceptableMixin,
29
- GoneMixin
30
- )(ApiBase)
31
-
32
- class Api extends Behaviours {
33
- constructor (options) {
34
- super()
35
- this.options = Object.assign({
36
- retry: false,
37
- parseErrors: true,
38
- handlers: {}
39
- }, options)
40
-
41
- this.handlers = {}
42
- this.client = null
43
- this.resetRequest()
44
- }
45
-
46
- resetRequest () {
47
- this.config = {
48
- endpoint: null,
49
- method: 'get',
50
- payload: null,
51
- query: null,
52
- headers: {},
53
- overrides: {}
54
- }
55
- }
56
-
57
- getClient () {
58
- if (this.options.mock) {
59
- console.warn('@beyonk/http: Using mocked http client')
60
- return this.options.mock
61
- }
62
-
63
- if (this.client) {
64
- return this.client
65
- } else if (typeof window !== 'undefined') {
66
- return window.fetch.bind(window)
67
- }
68
-
69
- throw Error("No client provided and can't find one automatically")
70
- }
71
-
72
- async send (fn) {
73
- const endpoint = this.config.endpoint.includes('://') ? this.config.endpoint : `${this.options.baseUrl}/${this.config.endpoint}`
74
- const hasPayload = !!this.config.payload
75
-
76
- const options = Object.assign(
77
- {
78
- method: this.config.method,
79
- cors: true,
80
- credentials: 'include',
81
- headers: Object.assign(
82
- { Accept: 'application/json' },
83
- hasPayload ? { 'Content-Type': 'application/json' } : {},
84
- this.config.headers
85
- )
86
- },
87
- hasPayload ? { body: JSON.stringify(this.config.payload) } : {},
88
- this.config.overrides
89
- )
90
-
91
- const client = this.getClient()
92
- const ep = this.config.query ? `${endpoint}?${this.config.query}` : `${endpoint}`
93
-
94
- let result
95
- try {
96
- result = await this._doQuery(1, client, ep, options)
97
- } catch (e) {
98
- console.log(e)
99
- return this.handle(e, this.ctx)
100
- } finally {
101
- this.resetRequest()
102
- }
103
-
104
- const { json, httpStatus } = result
105
- return fn ? fn(json, httpStatus) : json
106
- }
107
-
108
- _hasContent (response) {
109
- const contentLength = parseInt(response.headers.get('content-length'), 10)
110
-
111
- const isNoContentResponse = response.status === 204
112
- if (isNoContentResponse) {
113
- return false
114
- }
115
-
116
- const headerExists = !isNaN(contentLength)
117
- return !headerExists || contentLength > 0
118
- }
119
-
120
- async _doQuery (attempt, client, endpoint, options) {
121
- const retry = this.options.retry || { attempts: 1 }
122
- try {
123
- const r = await client(endpoint, options)
124
-
125
- if (r.status >= 200 && r.status < 400) {
126
- let json
127
-
128
- if (this._hasContent(r)) {
129
- try {
130
- json = await r.json()
131
- } catch (e) {
132
- console.error('Unable to parse response json', e.message)
133
- }
134
- }
135
-
136
- return { httpStatus: r.status, json }
137
- }
138
-
139
- let content = ''
140
- try {
141
- content = this.options.parseErrors ? await r.json() : await r.text()
142
- } catch (e) {
143
- console.log('Failed to parse error body when asked.')
144
- }
145
-
146
- const ClientError = byCode(r.status)
147
- throw new ClientError(r.statusText, content)
148
- } catch (e) {
149
- if (attempt < retry.attempts && retry.errors.includes(e.code)) {
150
- console.warn(`Got ${e.code} when calling ${endpoint}. Retrying request (${attempt}/${retry.attempts})`)
151
- return this._doQuery(++attempt, client, endpoint, options)
152
- }
153
-
154
- throw e
155
- }
156
- }
157
-
158
- context (ctx) {
159
- if (ctx.fetch) {
160
- this.client = ctx.fetch
161
- }
162
- this.ctx = ctx
163
- return this
164
- }
165
-
166
- override (override) {
167
- this.config.overrides = override
168
- return this
169
- }
170
-
171
- headers (headers) {
172
- this.config.headers = headers
173
- return this
174
- }
175
-
176
- async get (fn) {
177
- this.config.method = 'GET'
178
- return this.send(fn)
179
- }
180
-
181
- async post (fn) {
182
- this.config.method = 'POST'
183
- return this.send(fn)
184
- }
185
-
186
- async patch (fn) {
187
- this.config.method = 'PATCH'
188
- return this.send(fn)
189
- }
190
-
191
- async put (fn) {
192
- this.config.method = 'PUT'
193
- return this.send(fn)
194
- }
195
-
196
- async del (fn) {
197
- this.config.method = 'DELETE'
198
- return this.send(fn)
199
- }
200
-
201
- endpoint (endpoint) {
202
- this.config.endpoint = endpoint
203
- return this
204
- }
205
-
206
- query (query) {
207
- const q = Object.entries(query).reduce((curr, [ k, v ]) => {
208
- if (typeof v === 'undefined') {
209
- return curr
210
- }
211
- if (Array.isArray(v)) {
212
- curr.push(...v.map(n => `${k}=${encodeURIComponent(n)}`))
213
- } else {
214
- curr.push(`${k}=${encodeURIComponent(v)}`)
215
- }
216
- return curr
217
- }, [])
218
-
219
- this.config.query = q.join('&')
220
- return this
221
- }
222
-
223
- payload (payload) {
224
- this.config.payload = payload
225
- return this
226
- }
227
- }
228
-
229
- export {
230
- Api
231
- }