@centralping/ergo 0.1.0-beta.1 → 0.1.0-beta.2
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 +14 -15
- package/http/accepts.js +1 -2
- package/http/authorization.js +1 -2
- package/http/body.js +1 -2
- package/http/cache-control.js +1 -2
- package/http/compress.js +1 -2
- package/http/cookie.js +1 -2
- package/http/cors.js +1 -2
- package/http/csrf.js +1 -2
- package/http/handler.js +1 -2
- package/http/index.js +37 -4
- package/http/json-api-query.js +1 -2
- package/http/logger.js +1 -2
- package/http/main.js +2 -3
- package/http/precondition.js +1 -2
- package/http/prefer.js +1 -2
- package/http/rate-limit.js +1 -2
- package/http/security-headers.js +1 -2
- package/http/send.js +1 -2
- package/http/timeout.js +1 -2
- package/http/url.js +1 -2
- package/http/validate.js +1 -2
- package/lib/accepts.js +1 -2
- package/lib/attach-instance.js +0 -1
- package/lib/authorization.js +1 -2
- package/lib/body/multiparse.js +1 -2
- package/lib/body/multipart/headers.js +1 -2
- package/lib/body/writer.js +1 -2
- package/lib/cookie/cookie.js +1 -2
- package/lib/cookie/index.js +0 -1
- package/lib/cookie/jar.js +16 -12
- package/lib/cookie/parse.js +1 -2
- package/lib/cors.js +1 -2
- package/lib/csrf.js +1 -2
- package/lib/from-connect.js +2 -3
- package/lib/json-api-query/index.js +0 -1
- package/lib/json-api-query/validate.js +1 -2
- package/lib/link.js +1 -2
- package/lib/prefer.js +1 -2
- package/lib/query.js +1 -2
- package/lib/rate-limit.js +1 -2
- package/lib/sanitize-quoted-string.js +0 -1
- package/lib/security-headers.js +1 -2
- package/lib/validate.js +1 -2
- package/lib/vary.js +0 -1
- package/package.json +2 -2
- package/types/http/precondition.d.ts +1 -2
- package/types/lib/attach-instance.d.ts +0 -1
- package/types/lib/cookie/jar.d.ts +4 -0
- package/types/lib/from-connect.d.ts +2 -3
- package/types/lib/prefer.d.ts +1 -2
- package/types/lib/rate-limit.d.ts +1 -2
- package/types/lib/sanitize-quoted-string.d.ts +0 -1
- package/types/lib/vary.d.ts +0 -1
- package/types/utils/compose.d.ts +1 -2
- package/types/utils/iterables/range.d.ts +1 -2
- package/utils/attempt.js +1 -2
- package/utils/buffers/index.js +0 -1
- package/utils/buffers/match.js +1 -2
- package/utils/buffers/split.js +1 -2
- package/utils/compose-with.js +1 -2
- package/utils/compose.js +1 -2
- package/utils/flat-array.js +1 -2
- package/utils/get.js +1 -2
- package/utils/http-errors.js +1 -2
- package/utils/iterables/buffer-split.js +1 -2
- package/utils/iterables/chain.js +1 -2
- package/utils/iterables/exec-all.js +1 -2
- package/utils/iterables/filter.js +1 -2
- package/utils/iterables/for-each.js +1 -2
- package/utils/iterables/from-stream.js +1 -2
- package/utils/iterables/index.js +0 -1
- package/utils/iterables/map.js +1 -2
- package/utils/iterables/range.js +1 -2
- package/utils/iterables/reduce.js +1 -2
- package/utils/iterables/take.js +1 -2
- package/utils/observables/buffer-split.js +0 -1
- package/utils/observables/chain.js +0 -1
- package/utils/observables/index.js +0 -1
- package/utils/observables/map.js +0 -1
- package/utils/observables/take.js +0 -1
- package/utils/pick.js +1 -2
- package/utils/set.js +1 -2
- package/utils/streams/index.js +0 -1
- package/utils/streams/meter.js +1 -2
- package/utils/streams/tee.js +1 -2
- package/utils/type.js +1 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<picture>
|
|
3
|
-
<source media="(prefers-color-scheme: dark)" srcset="assets/logo-wordmark-dark.svg">
|
|
4
|
-
<source media="(prefers-color-scheme: light)" srcset="assets/logo-wordmark-light.svg">
|
|
5
|
-
<img alt="ergo" src="assets/logo-wordmark-light.svg" width="240">
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/CentralPing/ergo/main/assets/logo-wordmark-dark.svg">
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/CentralPing/ergo/main/assets/logo-wordmark-light.svg">
|
|
5
|
+
<img alt="ergo" src="https://raw.githubusercontent.com/CentralPing/ergo/main/assets/logo-wordmark-light.svg" width="240">
|
|
6
6
|
</picture>
|
|
7
7
|
</p>
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
[](https://www.npmjs.com/package/@centralping/ergo)
|
|
12
12
|
[](https://scorecard.dev/viewer/?uri=github.com/CentralPing/ergo)
|
|
13
13
|
[](https://nodejs.org)
|
|
14
|
-
[](LICENSE)
|
|
14
|
+
[](https://github.com/CentralPing/ergo/blob/main/LICENSE)
|
|
15
15
|
|
|
16
16
|
A **Fast Fail** REST API toolkit for Node.js. _ergo_ (error or go) provides composable, stream-native middleware organized around the principle that a server should fail as early as possible -- before doing any expensive work -- through four ordered stages: **Negotiation, Authorization, Validation, and Execution**. Every behavior is backed by an IETF RFC or industry standard, not invented conventions.
|
|
17
17
|
|
|
@@ -57,20 +57,19 @@ Requires **Node.js >= 22**.
|
|
|
57
57
|
|
|
58
58
|
```js
|
|
59
59
|
import {createServer} from 'node:http';
|
|
60
|
-
import {compose, handler, logger, cors, authorization, body
|
|
60
|
+
import {compose, handler, logger, cors, authorization, body} from '@centralping/ergo';
|
|
61
61
|
|
|
62
62
|
const pipeline = compose(
|
|
63
|
-
[logger(),
|
|
64
|
-
[cors(),
|
|
63
|
+
[logger(), 'log'],
|
|
64
|
+
[cors(), 'cors'],
|
|
65
65
|
[authorization({strategies: [{type: 'Bearer', authorizer: (_, token) =>
|
|
66
66
|
token === 'my-token' ? {authorized: true, info: {uid: 1}} : {}
|
|
67
|
-
}]}),
|
|
68
|
-
[body(),
|
|
69
|
-
(req, res,
|
|
70
|
-
send()
|
|
67
|
+
}]}), 'auth'],
|
|
68
|
+
[body(), 'body'],
|
|
69
|
+
(req, res, acc) => ({response: {body: {user: acc.auth, data: acc.body.parsed}}})
|
|
71
70
|
);
|
|
72
71
|
|
|
73
|
-
createServer(handler(pipeline
|
|
72
|
+
createServer(handler(pipeline)).listen(3000);
|
|
74
73
|
```
|
|
75
74
|
|
|
76
75
|
## Middleware Overview
|
|
@@ -96,7 +95,7 @@ createServer(handler(pipeline, send())).listen(3000);
|
|
|
96
95
|
| `cacheControl()` | Cache-Control header management | [RFC 9111](https://www.rfc-editor.org/rfc/rfc9111) |
|
|
97
96
|
| `jsonApiQuery()` | JSON:API query parameter validation | [JSON:API](https://jsonapi.org/) |
|
|
98
97
|
|
|
99
|
-
See the [full API reference](https://centralping.github.io/
|
|
98
|
+
See the [full API reference](https://centralping.github.io/packages/ergo/) for detailed options and examples.
|
|
100
99
|
|
|
101
100
|
## Standards Compliance
|
|
102
101
|
|
|
@@ -120,8 +119,8 @@ See the [full API reference](https://centralping.github.io/api/ergo/) for detail
|
|
|
120
119
|
## Documentation
|
|
121
120
|
|
|
122
121
|
- [Getting Started](https://centralping.github.io/getting-started/)
|
|
123
|
-
- [API Reference](https://centralping.github.io/
|
|
124
|
-
- [
|
|
122
|
+
- [API Reference](https://centralping.github.io/packages/ergo/)
|
|
123
|
+
- [Fast Fail Pipeline](https://centralping.github.io/concepts/fast-fail/)
|
|
125
124
|
- [Benchmarks](https://centralping.github.io/benchmarks/)
|
|
126
125
|
|
|
127
126
|
## Development
|
package/http/accepts.js
CHANGED
|
@@ -10,13 +10,12 @@
|
|
|
10
10
|
* Fast Fail pipeline.
|
|
11
11
|
*
|
|
12
12
|
* @module http/accepts
|
|
13
|
-
* @version 0.1.0
|
|
14
13
|
* @since 0.1.0
|
|
15
14
|
* @requires ../lib/accepts.js
|
|
16
15
|
* @requires ../utils/http-errors.js
|
|
17
16
|
*
|
|
18
17
|
* @example
|
|
19
|
-
* import {compose, accepts} from 'ergo';
|
|
18
|
+
* import {compose, accepts} from '@centralping/ergo';
|
|
20
19
|
*
|
|
21
20
|
* const pipeline = compose(
|
|
22
21
|
* [accepts({types: ['application/json']}), 'accepts'],
|
package/http/authorization.js
CHANGED
|
@@ -10,13 +10,12 @@
|
|
|
10
10
|
* response header (RFC 7235).
|
|
11
11
|
*
|
|
12
12
|
* @module http/authorization
|
|
13
|
-
* @version 0.1.0
|
|
14
13
|
* @since 0.1.0
|
|
15
14
|
* @requires ../lib/authorization.js
|
|
16
15
|
* @requires ../utils/http-errors.js
|
|
17
16
|
*
|
|
18
17
|
* @example
|
|
19
|
-
* import {compose, authorization} from 'ergo';
|
|
18
|
+
* import {compose, authorization} from '@centralping/ergo';
|
|
20
19
|
*
|
|
21
20
|
* const pipeline = compose(
|
|
22
21
|
* [authorization({
|
package/http/body.js
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
* 3-stream pipeline for reduced per-request overhead.
|
|
18
18
|
*
|
|
19
19
|
* @module http/body
|
|
20
|
-
* @version 0.1.0
|
|
21
20
|
* @since 0.1.0
|
|
22
21
|
* @requires node:stream
|
|
23
22
|
* @requires node:zlib
|
|
@@ -29,7 +28,7 @@
|
|
|
29
28
|
* @requires ../utils/http-errors.js
|
|
30
29
|
*
|
|
31
30
|
* @example
|
|
32
|
-
* import {compose, body} from 'ergo';
|
|
31
|
+
* import {compose, body} from '@centralping/ergo';
|
|
33
32
|
*
|
|
34
33
|
* const pipeline = compose(
|
|
35
34
|
* [body({limit: 2 * 1024 * 1024}), 'body'],
|
package/http/cache-control.js
CHANGED
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
* a raw directive string or structured options that are assembled into a directive.
|
|
7
7
|
*
|
|
8
8
|
* @module http/cache-control
|
|
9
|
-
* @version 0.1.0
|
|
10
9
|
* @since 0.1.0
|
|
11
10
|
*
|
|
12
11
|
* @example
|
|
13
|
-
* import {compose, cacheControl} from 'ergo';
|
|
12
|
+
* import {compose, cacheControl} from '@centralping/ergo';
|
|
14
13
|
*
|
|
15
14
|
* // String shorthand
|
|
16
15
|
* const pipeline = compose(
|
package/http/compress.js
CHANGED
|
@@ -13,13 +13,12 @@
|
|
|
13
13
|
* - Bodies below the configurable `threshold` byte count (default 1 KiB)
|
|
14
14
|
*
|
|
15
15
|
* @module http/compress
|
|
16
|
-
* @version 0.1.0
|
|
17
16
|
* @since 0.1.0
|
|
18
17
|
* @requires node:zlib
|
|
19
18
|
* @requires negotiator
|
|
20
19
|
*
|
|
21
20
|
* @example
|
|
22
|
-
* import {compose, compress} from 'ergo';
|
|
21
|
+
* import {compose, compress} from '@centralping/ergo';
|
|
23
22
|
*
|
|
24
23
|
* const pipeline = compose(
|
|
25
24
|
* compress({threshold: 1024, encodings: ['br', 'gzip', 'deflate']}),
|
package/http/cookie.js
CHANGED
|
@@ -12,12 +12,11 @@
|
|
|
12
12
|
* and other cookie-based workflows.
|
|
13
13
|
*
|
|
14
14
|
* @module http/cookie
|
|
15
|
-
* @version 0.1.0
|
|
16
15
|
* @since 0.1.0
|
|
17
16
|
* @requires ../lib/cookie/index.js
|
|
18
17
|
*
|
|
19
18
|
* @example
|
|
20
|
-
* import {compose, cookie} from 'ergo';
|
|
19
|
+
* import {compose, cookie} from '@centralping/ergo';
|
|
21
20
|
*
|
|
22
21
|
* const pipeline = compose(
|
|
23
22
|
* [cookie(), 'cookies'],
|
package/http/cors.js
CHANGED
|
@@ -10,13 +10,12 @@
|
|
|
10
10
|
* Pre-flight `OPTIONS` requests should be handled at the router level using `ergo-router`.
|
|
11
11
|
*
|
|
12
12
|
* @module http/cors
|
|
13
|
-
* @version 0.1.0
|
|
14
13
|
* @since 0.1.0
|
|
15
14
|
* @requires ../lib/cors.js
|
|
16
15
|
* @requires ../utils/http-errors.js
|
|
17
16
|
*
|
|
18
17
|
* @example
|
|
19
|
-
* import {compose, cors} from 'ergo';
|
|
18
|
+
* import {compose, cors} from '@centralping/ergo';
|
|
20
19
|
*
|
|
21
20
|
* const pipeline = compose(
|
|
22
21
|
* [cors({
|
package/http/csrf.js
CHANGED
|
@@ -11,13 +11,12 @@
|
|
|
11
11
|
* The CSRF UUID is stored in a separate cookie so the token can be regenerated independently.
|
|
12
12
|
*
|
|
13
13
|
* @module http/csrf
|
|
14
|
-
* @version 0.1.0
|
|
15
14
|
* @since 0.1.0
|
|
16
15
|
* @requires ../lib/csrf.js
|
|
17
16
|
* @requires ../utils/http-errors.js
|
|
18
17
|
*
|
|
19
18
|
* @example
|
|
20
|
-
* import {compose, cookie, csrf} from 'ergo';
|
|
19
|
+
* import {compose, cookie, csrf} from '@centralping/ergo';
|
|
21
20
|
*
|
|
22
21
|
* const csrfMiddleware = csrf({secret: process.env.CSRF_SECRET});
|
|
23
22
|
*
|
package/http/handler.js
CHANGED
|
@@ -13,11 +13,10 @@
|
|
|
13
13
|
* compose middleware directly without the router.
|
|
14
14
|
*
|
|
15
15
|
* @module http/handler
|
|
16
|
-
* @version 0.2.0
|
|
17
16
|
* @since 0.1.0
|
|
18
17
|
*
|
|
19
18
|
* @example
|
|
20
|
-
* import {handler, compose,
|
|
19
|
+
* import {handler, compose, logger, authorization, body} from '@centralping/ergo';
|
|
21
20
|
*
|
|
22
21
|
* const pipeline = compose(
|
|
23
22
|
* [logger(), 'log'],
|
package/http/index.js
CHANGED
|
@@ -1,13 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
2
|
+
* @fileoverview Fast Fail REST API toolkit for Node.js.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Composable middleware organized into four ordered pipeline stages — a failure
|
|
5
|
+
* at any stage immediately returns a standards-compliant error response so no
|
|
6
|
+
* downstream work is wasted:
|
|
7
|
+
*
|
|
8
|
+
* | Stage | Middleware | Purpose |
|
|
9
|
+
* | --- | --- | --- |
|
|
10
|
+
* | **Negotiation** | {@link logger}, {@link cors}, {@link accepts}, {@link cookie}, {@link url} | Parse/inspect request headers and URL |
|
|
11
|
+
* | **Authorization** | {@link authorization}, {@link csrf} | Authenticate and verify request integrity |
|
|
12
|
+
* | **Validation** | {@link body}, {@link jsonApiQuery}, {@link validate} | Parse and validate the request body |
|
|
13
|
+
* | **Execution** | {@link timeout}, {@link compress}, {@link handler}, {@link send} | Run the handler and serialize the response |
|
|
14
|
+
*
|
|
15
|
+
* Cross-cutting middleware available at any stage:
|
|
16
|
+
* {@link cacheControl}, {@link prefer}, {@link precondition},
|
|
17
|
+
* {@link rateLimit}, {@link securityHeaders}
|
|
18
|
+
*
|
|
19
|
+
* **Composition utilities:** {@link compose}, {@link createResponseAcc},
|
|
20
|
+
* {@link mergeResponse}, {@link httpErrors}, {@link fromConnect}
|
|
6
21
|
*
|
|
7
22
|
* @module @centralping/ergo
|
|
8
|
-
* @version 0.1.0-beta.1
|
|
9
23
|
* @since 0.1.0
|
|
10
24
|
* @requires ./main.js
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* import {compose, handler, logger, cors, accepts, authorization,
|
|
28
|
+
* body, send} from '@centralping/ergo';
|
|
29
|
+
*
|
|
30
|
+
* const pipeline = compose(
|
|
31
|
+
* [logger(), 'log'],
|
|
32
|
+
* [cors(), 'cors'],
|
|
33
|
+
* [accepts({types: ['application/json']}), 'accepts'],
|
|
34
|
+
* [authorization({strategies: [...]}), 'auth'],
|
|
35
|
+
* [body(), 'body'],
|
|
36
|
+
* (req, res, acc) => ({response: {body: acc.body.parsed}}),
|
|
37
|
+
* );
|
|
38
|
+
*
|
|
39
|
+
* const server = http.createServer(handler(pipeline));
|
|
40
|
+
*
|
|
41
|
+
* @see {@link https://centralping.github.io/concepts/fast-fail/ Fast Fail Pipeline}
|
|
42
|
+
* @see {@link https://centralping.github.io/concepts/security/ Security}
|
|
43
|
+
* @see {@link https://centralping.github.io/concepts/standards/ Standards Compliance}
|
|
11
44
|
*/
|
|
12
45
|
|
|
13
46
|
export * from './main.js';
|
package/http/json-api-query.js
CHANGED
|
@@ -11,13 +11,12 @@
|
|
|
11
11
|
* Must be placed after `url()` in the pipeline so that `acc.url` is populated.
|
|
12
12
|
*
|
|
13
13
|
* @module http/json-api-query
|
|
14
|
-
* @version 0.1.0
|
|
15
14
|
* @since 0.1.0
|
|
16
15
|
* @requires ../lib/json-api-query/index.js
|
|
17
16
|
* @requires ../utils/http-errors.js
|
|
18
17
|
*
|
|
19
18
|
* @example
|
|
20
|
-
* import {compose, url, jsonApiQuery} from 'ergo';
|
|
19
|
+
* import {compose, url, jsonApiQuery} from '@centralping/ergo';
|
|
21
20
|
*
|
|
22
21
|
* const pipeline = compose(
|
|
23
22
|
* [url(), 'url'],
|
package/http/logger.js
CHANGED
|
@@ -23,13 +23,12 @@
|
|
|
23
23
|
* accidental secret leakage.
|
|
24
24
|
*
|
|
25
25
|
* @module http/logger
|
|
26
|
-
* @version 0.1.0
|
|
27
26
|
* @since 0.1.0
|
|
28
27
|
* @requires node:os
|
|
29
28
|
* @requires node:crypto
|
|
30
29
|
*
|
|
31
30
|
* @example
|
|
32
|
-
* import {compose, logger} from 'ergo';
|
|
31
|
+
* import {compose, logger} from '@centralping/ergo';
|
|
33
32
|
*
|
|
34
33
|
* const pipeline = compose(
|
|
35
34
|
* [logger(), 'log'],
|
package/http/main.js
CHANGED
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
* accumulated under named keys in `domainAcc`; response properties merge
|
|
15
15
|
* into `responseAcc`. `send()` is called post-pipeline by `handler()`.
|
|
16
16
|
*
|
|
17
|
-
* @module ergo
|
|
18
|
-
* @version 0.1.0
|
|
17
|
+
* @module @centralping/ergo
|
|
19
18
|
* @since 0.1.0
|
|
20
19
|
* @requires ./handler.js
|
|
21
20
|
* @requires ./accepts.js
|
|
@@ -42,7 +41,7 @@
|
|
|
42
41
|
*
|
|
43
42
|
* @example
|
|
44
43
|
* import {compose, handler, logger, cors, authorization, accepts,
|
|
45
|
-
* cookie, url, body} from 'ergo';
|
|
44
|
+
* cookie, url, body} from '@centralping/ergo';
|
|
46
45
|
*
|
|
47
46
|
* const pipeline = compose(
|
|
48
47
|
* // Stage 1: Negotiation
|
package/http/precondition.js
CHANGED
|
@@ -10,11 +10,10 @@
|
|
|
10
10
|
* inspection that short-circuits before authorization, body parsing, or execution.
|
|
11
11
|
*
|
|
12
12
|
* @module http/precondition
|
|
13
|
-
* @version 0.1.0
|
|
14
13
|
* @since 0.1.0
|
|
15
14
|
*
|
|
16
15
|
* @example
|
|
17
|
-
* import {compose, precondition} from 'ergo';
|
|
16
|
+
* import {compose, precondition} from '@centralping/ergo';
|
|
18
17
|
*
|
|
19
18
|
* // Enforce on all requests (method scoping handled by pipeline builder)
|
|
20
19
|
* const pipeline = compose(
|
package/http/prefer.js
CHANGED
|
@@ -8,12 +8,11 @@
|
|
|
8
8
|
* Placed in Stage 1 (Negotiation) — cheap header parse with no I/O.
|
|
9
9
|
*
|
|
10
10
|
* @module http/prefer
|
|
11
|
-
* @version 0.1.0
|
|
12
11
|
* @since 0.1.0
|
|
13
12
|
* @requires ../lib/prefer.js
|
|
14
13
|
*
|
|
15
14
|
* @example
|
|
16
|
-
* import {compose, prefer} from 'ergo';
|
|
15
|
+
* import {compose, prefer} from '@centralping/ergo';
|
|
17
16
|
*
|
|
18
17
|
* const pipeline = compose(
|
|
19
18
|
* [prefer(), 'prefer'],
|
package/http/rate-limit.js
CHANGED
|
@@ -10,12 +10,11 @@
|
|
|
10
10
|
* or execution.
|
|
11
11
|
*
|
|
12
12
|
* @module http/rate-limit
|
|
13
|
-
* @version 0.1.0
|
|
14
13
|
* @since 0.1.0
|
|
15
14
|
* @requires ../lib/rate-limit.js
|
|
16
15
|
*
|
|
17
16
|
* @example
|
|
18
|
-
* import {compose, rateLimit} from 'ergo';
|
|
17
|
+
* import {compose, rateLimit} from '@centralping/ergo';
|
|
19
18
|
*
|
|
20
19
|
* const pipeline = compose(
|
|
21
20
|
* [rateLimit({max: 100, windowMs: 60000}), 'rateLimit'],
|
package/http/security-headers.js
CHANGED
|
@@ -8,12 +8,11 @@
|
|
|
8
8
|
* Delegates tuple construction to `lib/security-headers.js` (the shared primitive).
|
|
9
9
|
*
|
|
10
10
|
* @module http/security-headers
|
|
11
|
-
* @version 0.1.0
|
|
12
11
|
* @since 0.1.0
|
|
13
12
|
* @requires ../lib/security-headers.js
|
|
14
13
|
*
|
|
15
14
|
* @example
|
|
16
|
-
* import {compose, securityHeaders} from 'ergo';
|
|
15
|
+
* import {compose, securityHeaders} from '@centralping/ergo';
|
|
17
16
|
*
|
|
18
17
|
* // Use defaults
|
|
19
18
|
* const pipeline = compose(
|
package/http/send.js
CHANGED
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
* - Optional response envelope for 2xx Object bodies
|
|
30
30
|
*
|
|
31
31
|
* @module http/send
|
|
32
|
-
* @version 0.2.0
|
|
33
32
|
* @since 0.1.0
|
|
34
33
|
* @requires node:stream
|
|
35
34
|
* @requires node:http
|
|
@@ -38,7 +37,7 @@
|
|
|
38
37
|
* @requires ../lib/vary.js
|
|
39
38
|
*
|
|
40
39
|
* @example
|
|
41
|
-
* import {send, createResponseAcc} from 'ergo';
|
|
40
|
+
* import {send, createResponseAcc} from '@centralping/ergo';
|
|
42
41
|
*
|
|
43
42
|
* const writer = send({etag: true});
|
|
44
43
|
* // After pipeline completes:
|
package/http/timeout.js
CHANGED
|
@@ -12,11 +12,10 @@
|
|
|
12
12
|
* can be GC'd.
|
|
13
13
|
*
|
|
14
14
|
* @module http/timeout
|
|
15
|
-
* @version 0.2.0
|
|
16
15
|
* @since 0.1.0
|
|
17
16
|
*
|
|
18
17
|
* @example
|
|
19
|
-
* import {compose, timeout} from 'ergo';
|
|
18
|
+
* import {compose, timeout} from '@centralping/ergo';
|
|
20
19
|
*
|
|
21
20
|
* const pipeline = compose(
|
|
22
21
|
* [timeout({ms: 10000, statusCode: 504}), 'timeout'],
|
package/http/url.js
CHANGED
|
@@ -11,12 +11,11 @@
|
|
|
11
11
|
* - `search` is the raw query string including the `?` prefix, or `undefined`
|
|
12
12
|
*
|
|
13
13
|
* @module http/url
|
|
14
|
-
* @version 0.1.0
|
|
15
14
|
* @since 0.1.0
|
|
16
15
|
* @requires ../lib/query.js
|
|
17
16
|
*
|
|
18
17
|
* @example
|
|
19
|
-
* import {compose, url} from 'ergo';
|
|
18
|
+
* import {compose, url} from '@centralping/ergo';
|
|
20
19
|
*
|
|
21
20
|
* const pipeline = compose(
|
|
22
21
|
* [url(), 'url'],
|
package/http/validate.js
CHANGED
|
@@ -9,12 +9,11 @@
|
|
|
9
9
|
* are populated before validation runs.
|
|
10
10
|
*
|
|
11
11
|
* @module http/validate
|
|
12
|
-
* @version 0.1.0
|
|
13
12
|
* @since 0.1.0
|
|
14
13
|
* @requires ../lib/validate.js
|
|
15
14
|
*
|
|
16
15
|
* @example
|
|
17
|
-
* import {compose, body, url, validate} from 'ergo';
|
|
16
|
+
* import {compose, body, url, validate} from '@centralping/ergo';
|
|
18
17
|
*
|
|
19
18
|
* const pipeline = compose(
|
|
20
19
|
* [body(), 'body'],
|
package/lib/accepts.js
CHANGED
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
* as the pure-logic backing implementation.
|
|
7
7
|
*
|
|
8
8
|
* @module lib/accepts
|
|
9
|
-
* @version 0.1.0
|
|
10
9
|
* @since 0.1.0
|
|
11
10
|
* @requires negotiator
|
|
12
11
|
* @requires ../utils/flat-array.js
|
|
13
12
|
*
|
|
14
13
|
* @example
|
|
15
|
-
* import accepts from 'ergo/lib/accepts';
|
|
14
|
+
* import accepts from '@centralping/ergo/lib/accepts';
|
|
16
15
|
*
|
|
17
16
|
* const negotiate = accepts({types: ['application/json', 'text/html']});
|
|
18
17
|
* const result = negotiate({'accept': 'text/html,application/json;q=0.9'});
|
package/lib/attach-instance.js
CHANGED
package/lib/authorization.js
CHANGED
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
* 401 for known schemes (with a `WWW-Authenticate` challenge) or 403 for unrecognized schemes.
|
|
12
12
|
*
|
|
13
13
|
* @module lib/authorization
|
|
14
|
-
* @version 0.1.0
|
|
15
14
|
* @since 0.1.0
|
|
16
15
|
*
|
|
17
16
|
* @example
|
|
18
|
-
* import authorize from 'ergo/lib/authorization';
|
|
17
|
+
* import authorize from '@centralping/ergo/lib/authorization';
|
|
19
18
|
*
|
|
20
19
|
* const authorizer = authorize([{
|
|
21
20
|
* type: 'Bearer',
|
package/lib/body/multiparse.js
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
* `Content-Disposition`, `Content-Type`, `Content-Transfer-Encoding`.
|
|
13
13
|
*
|
|
14
14
|
* @module lib/body/multiparse
|
|
15
|
-
* @version 0.1.0
|
|
16
15
|
* @since 0.1.0
|
|
17
16
|
* @requires ./multipart/headers.js
|
|
18
17
|
* @requires ../../utils/iterables/buffer-split.js
|
|
@@ -21,7 +20,7 @@
|
|
|
21
20
|
* @see {@link https://www.rfc-editor.org/rfc/rfc7578}
|
|
22
21
|
*
|
|
23
22
|
* @example
|
|
24
|
-
* import multiparse from 'ergo/lib/body/multiparse';
|
|
23
|
+
* import multiparse from '@centralping/ergo/lib/body/multiparse';
|
|
25
24
|
*
|
|
26
25
|
* const parts = multiparse(rawBodyBuffer, 'boundary-string');
|
|
27
26
|
* // parts => [{headers: {...}, name: 'file', filename: 'upload.txt', body: Buffer}]
|
|
@@ -11,14 +11,13 @@
|
|
|
11
11
|
* - `content-transfer-encoding` (deprecated but present in legacy clients)
|
|
12
12
|
*
|
|
13
13
|
* @module lib/body/multipart/headers
|
|
14
|
-
* @version 0.1.0
|
|
15
14
|
* @since 0.1.0
|
|
16
15
|
* @requires ../../../utils/iterables/exec-all.js
|
|
17
16
|
*
|
|
18
17
|
* @see {@link https://www.rfc-editor.org/rfc/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data}
|
|
19
18
|
*
|
|
20
19
|
* @example
|
|
21
|
-
* import parseHeaders from 'ergo/lib/body/multipart/headers';
|
|
20
|
+
* import parseHeaders from '@centralping/ergo/lib/body/multipart/headers';
|
|
22
21
|
*
|
|
23
22
|
* parseHeaders(['Content-Disposition: form-data; name="field1"']);
|
|
24
23
|
* // => {'content-disposition': {type: 'form-data', parameters: {name: 'field1'}}}
|
package/lib/body/writer.js
CHANGED
|
@@ -8,13 +8,12 @@
|
|
|
8
8
|
* `pipeline(req, meter, decompressor, writer())`
|
|
9
9
|
*
|
|
10
10
|
* @module lib/body/writer
|
|
11
|
-
* @version 0.1.0
|
|
12
11
|
* @since 0.1.0
|
|
13
12
|
* @requires node:stream
|
|
14
13
|
*
|
|
15
14
|
* @example
|
|
16
15
|
* import {pipeline} from 'node:stream';
|
|
17
|
-
* import writer from 'ergo/lib/body/writer';
|
|
16
|
+
* import writer from '@centralping/ergo/lib/body/writer';
|
|
18
17
|
*
|
|
19
18
|
* const w = writer();
|
|
20
19
|
* pipeline(readable, w, err => {
|
package/lib/cookie/cookie.js
CHANGED
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
* immediately by defaulting `maxAge` to 0.
|
|
10
10
|
*
|
|
11
11
|
* @module lib/cookie/cookie
|
|
12
|
-
* @version 0.1.0
|
|
13
12
|
* @since 0.1.0
|
|
14
13
|
*
|
|
15
14
|
* @example
|
|
16
|
-
* import bake from 'ergo/lib/cookie/cookie';
|
|
15
|
+
* import bake from '@centralping/ergo/lib/cookie/cookie';
|
|
17
16
|
*
|
|
18
17
|
* const c = bake('session', 'abc123', {maxAge: 3600, sameSite: 'Lax'});
|
|
19
18
|
* c.toHeader(); // 'session=abc123; Path=/; Max-Age=3600; SameSite=Lax; Secure; HttpOnly'
|
package/lib/cookie/index.js
CHANGED
package/lib/cookie/jar.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Creates a cookie jar with dual-storage semantics for per-request cookie management.
|
|
5
5
|
*
|
|
6
6
|
* **Incoming cookies** (from the `Cookie` header) are parsed as raw `name: value` strings
|
|
7
|
-
* and stored as own properties
|
|
7
|
+
* and stored as own properties. Per RFC 6265 §5.4, the browser sends
|
|
8
8
|
* only `name=value` pairs — no directives. Access them directly: `jar.session`.
|
|
9
9
|
*
|
|
10
10
|
* **Outgoing cookies** (created via `set()`) are full cookie objects with directives,
|
|
@@ -19,14 +19,13 @@
|
|
|
19
19
|
* - `toHeader()` — serializes outgoing cookies to `Set-Cookie` header strings
|
|
20
20
|
*
|
|
21
21
|
* @module lib/cookie/jar
|
|
22
|
-
* @version 0.1.0
|
|
23
22
|
* @since 0.1.0
|
|
24
23
|
* @requires ./cookie.js
|
|
25
24
|
* @requires ../../utils/iterables/index.js
|
|
26
25
|
*
|
|
27
26
|
* @example
|
|
28
|
-
* import jar from 'ergo/lib/cookie/jar';
|
|
29
|
-
* import parse from 'ergo/lib/cookie/parse';
|
|
27
|
+
* import jar from '@centralping/ergo/lib/cookie/jar';
|
|
28
|
+
* import parse from '@centralping/ergo/lib/cookie/parse';
|
|
30
29
|
*
|
|
31
30
|
* const cookies = jar(parse('session=abc123; lang=en'));
|
|
32
31
|
* cookies.session; // => 'abc123' (incoming, own property)
|
|
@@ -91,16 +90,21 @@ const clay = Object.create(
|
|
|
91
90
|
/**
|
|
92
91
|
* Creates a cookie jar pre-populated from a parsed cookie object.
|
|
93
92
|
*
|
|
93
|
+
* Incoming cookie names that collide with jar prototype methods or own properties
|
|
94
|
+
* (`set`, `get`, `clear`, `toHeader`, `isJar`, `size`, `jar`) are silently dropped
|
|
95
|
+
* to prevent `TypeError` from strict-mode assignment to non-writable properties.
|
|
96
|
+
*
|
|
94
97
|
* @param {object} [cookies={}] - Initial cookie values (from `parse()`)
|
|
95
98
|
* @returns {object} - Cookie jar with `get`, `set`, `clear`, `toHeader`, `size` members
|
|
96
99
|
*/
|
|
97
100
|
function jar(cookies = {}) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
const instance = Object.create(clay, {jar: {value: new Map()}});
|
|
102
|
+
|
|
103
|
+
for (const key of Object.keys(cookies)) {
|
|
104
|
+
if (!(key in instance)) {
|
|
105
|
+
instance[key] = cookies[key];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return instance;
|
|
106
110
|
}
|
package/lib/cookie/parse.js
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
* to protect against header-stuffing attacks.
|
|
11
11
|
*
|
|
12
12
|
* @module lib/cookie/parse
|
|
13
|
-
* @version 0.1.0
|
|
14
13
|
* @since 0.1.0
|
|
15
14
|
* @requires ../../utils/iterables/index.js
|
|
16
15
|
*
|
|
@@ -18,7 +17,7 @@
|
|
|
18
17
|
* @see {@link https://www.rfc-editor.org/rfc/rfc2109 RFC 2109 - HTTP State Management Mechanism (obsoleted)}
|
|
19
18
|
*
|
|
20
19
|
* @example
|
|
21
|
-
* import parse from 'ergo/lib/cookie/parse';
|
|
20
|
+
* import parse from '@centralping/ergo/lib/cookie/parse';
|
|
22
21
|
*
|
|
23
22
|
* parse('session=abc123; user=alice');
|
|
24
23
|
* // => {session: 'abc123', user: 'alice'}
|
package/lib/cors.js
CHANGED
|
@@ -15,13 +15,12 @@
|
|
|
15
15
|
* @see {@link https://www.w3.org/TR/2014/REC-cors-20140116/}
|
|
16
16
|
*
|
|
17
17
|
* @module lib/cors
|
|
18
|
-
* @version 0.1.0
|
|
19
18
|
* @since 0.1.0
|
|
20
19
|
* @requires ../utils/type.js
|
|
21
20
|
* @requires ../utils/flat-array.js
|
|
22
21
|
*
|
|
23
22
|
* @example
|
|
24
|
-
* import cors from 'ergo/lib/cors';
|
|
23
|
+
* import cors from '@centralping/ergo/lib/cors';
|
|
25
24
|
*
|
|
26
25
|
* const corsValidator = cors({
|
|
27
26
|
* origins: ['https://app.example.com'],
|
package/lib/csrf.js
CHANGED
|
@@ -9,13 +9,12 @@
|
|
|
9
9
|
* can be reissued without changing the UUID.
|
|
10
10
|
*
|
|
11
11
|
* @module lib/csrf
|
|
12
|
-
* @version 0.1.0
|
|
13
12
|
* @since 0.1.0
|
|
14
13
|
* @requires node:crypto
|
|
15
14
|
* @requires ../utils/type.js
|
|
16
15
|
*
|
|
17
16
|
* @example
|
|
18
|
-
* import {issue, verify} from 'ergo/lib/csrf';
|
|
17
|
+
* import {issue, verify} from '@centralping/ergo/lib/csrf';
|
|
19
18
|
*
|
|
20
19
|
* const {token, uuid} = issue('my-secret');
|
|
21
20
|
* // token => 'base64-encoded-hmac'
|