@fedify/vocab-runtime 2.4.0-pr.934.40 → 2.4.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/deno.json +4 -2
- package/dist/{tests/docloader-Xi61Le8w.mjs → contexts-BK1CqBR5.cjs} +164 -269
- package/dist/{tests/docloader-BFedvemb.cjs → contexts-DPuJ4UYL.js} +160 -288
- package/dist/{docloader-DnUMWHaJ.d.cts → docloader-CYwqh5Df.d.cts} +68 -2
- package/dist/{docloader-xRGn1azD.d.ts → docloader-CYwqh5Df.d.ts} +68 -2
- package/dist/internal/jsonld-cache.cjs +70 -1
- package/dist/internal/jsonld-cache.d.cts +35 -2
- package/dist/internal/jsonld-cache.d.ts +35 -2
- package/dist/internal/jsonld-cache.js +67 -2
- package/dist/internal/portable-dereference.cjs +721 -0
- package/dist/internal/portable-dereference.d.cts +349 -0
- package/dist/internal/portable-dereference.d.ts +349 -0
- package/dist/internal/portable-dereference.js +702 -0
- package/dist/internal/signed-representation.cjs +378 -0
- package/dist/internal/signed-representation.d.cts +144 -0
- package/dist/internal/signed-representation.d.ts +144 -0
- package/dist/internal/signed-representation.js +371 -0
- package/dist/jsonld.cjs +2 -2
- package/dist/mod.cjs +715 -4523
- package/dist/mod.d.cts +406 -6
- package/dist/mod.d.ts +406 -7
- package/dist/mod.js +694 -4518
- package/dist/portable-DqtfLy_1.d.cts +160 -0
- package/dist/portable-DtWsu2yU.d.ts +160 -0
- package/dist/tests/body-CYiu9CO-.mjs +130 -0
- package/dist/tests/body-CkEwROsn.cjs +153 -0
- package/dist/tests/body.test.cjs +89 -0
- package/dist/tests/body.test.d.cts +1 -0
- package/dist/tests/body.test.d.mts +1 -0
- package/dist/tests/body.test.mjs +90 -0
- package/dist/tests/contexts-CIKsin4e.mjs +4512 -0
- package/dist/tests/contexts-DizzBjz4.cjs +4523 -0
- package/dist/tests/decimal.test.cjs +8 -7
- package/dist/tests/decimal.test.mjs +8 -6
- package/dist/tests/digest-3FeH2Y-Q.cjs +176 -0
- package/dist/tests/digest-COC7xDiQ.mjs +141 -0
- package/dist/tests/digest.test.cjs +102 -0
- package/dist/tests/digest.test.d.cts +1 -0
- package/dist/tests/digest.test.d.mts +1 -0
- package/dist/tests/digest.test.mjs +103 -0
- package/dist/tests/docloader-C3YFl6y4.cjs +396 -0
- package/dist/tests/docloader-CvmS4sVq.mjs +373 -0
- package/dist/tests/docloader.test.cjs +692 -39
- package/dist/tests/docloader.test.mjs +686 -34
- package/dist/tests/internal/multicodec.test.cjs +2 -3
- package/dist/tests/internal/multicodec.test.mjs +2 -2
- package/dist/tests/internal/portable-dereference.test.cjs +172 -0
- package/dist/tests/internal/portable-dereference.test.d.cts +1 -0
- package/dist/tests/internal/portable-dereference.test.d.mts +1 -0
- package/dist/tests/internal/portable-dereference.test.mjs +173 -0
- package/dist/tests/jsonld-cache-BPQmOZWD.mjs +342 -0
- package/dist/tests/jsonld-cache-C07AyNOY.cjs +397 -0
- package/dist/tests/jsonld-cache.test.cjs +101 -298
- package/dist/tests/jsonld-cache.test.mjs +94 -289
- package/dist/tests/{key-_wXwomh_.cjs → key-C-AYkdJJ.cjs} +11 -4
- package/dist/tests/{key-CDGDH_vC.mjs → key-C2Db_TAJ.mjs} +11 -3
- package/dist/tests/key.test.cjs +6 -5
- package/dist/tests/key.test.mjs +6 -4
- package/dist/tests/langstr.test.cjs +4 -4
- package/dist/tests/langstr.test.mjs +2 -2
- package/dist/tests/link.test.cjs +2 -3
- package/dist/tests/link.test.mjs +2 -2
- package/dist/tests/multibase/multibase.test.cjs +8 -9
- package/dist/tests/multibase/multibase.test.mjs +6 -6
- package/dist/tests/{multibase-Bz_UUDtL.cjs → multibase-B5Mea7Ip.cjs} +19 -2
- package/dist/tests/{multibase-B4bvakyA.mjs → multibase-BPnF_L4e.mjs} +12 -1
- package/dist/tests/portable-dereference-BNXtgg5U.cjs +278 -0
- package/dist/tests/portable-dereference-DRE5bz-l.mjs +249 -0
- package/dist/tests/portable-media-BLKllU56.cjs +153 -0
- package/dist/tests/portable-media-DRSGBORB.mjs +148 -0
- package/dist/tests/portable-media.test.cjs +222 -0
- package/dist/tests/portable-media.test.d.cts +1 -0
- package/dist/tests/portable-media.test.d.mts +1 -0
- package/dist/tests/portable-media.test.mjs +223 -0
- package/dist/tests/portable-workers.test.cjs +36 -0
- package/dist/tests/portable-workers.test.d.cts +2 -0
- package/dist/tests/portable-workers.test.d.mts +2 -0
- package/dist/tests/portable-workers.test.mjs +35 -0
- package/dist/tests/{request-cCPgOxYG.cjs → request-8vPWtV1-.cjs} +10 -4
- package/dist/tests/{request-BOS-hNaf.mjs → request-DRaOaTqD.mjs} +8 -2
- package/dist/tests/request.test.cjs +7 -4
- package/dist/tests/request.test.mjs +5 -2
- package/dist/tests/signed-representation.test.cjs +588 -0
- package/dist/tests/signed-representation.test.d.cts +1 -0
- package/dist/tests/signed-representation.test.d.mts +1 -0
- package/dist/tests/signed-representation.test.mjs +589 -0
- package/dist/tests/temporal.test.cjs +1 -2
- package/dist/tests/temporal.test.mjs +1 -1
- package/dist/tests/url-BNakuZ8k.cjs +998 -0
- package/dist/tests/url-DMxmp7ZG.mjs +859 -0
- package/dist/tests/url.test.cjs +503 -3
- package/dist/tests/url.test.mjs +503 -2
- package/dist/url-DrGTR8yv.cjs +993 -0
- package/dist/url-Dzyp-NsC.js +860 -0
- package/package.json +27 -4
- package/scripts/test-bun.mjs +17 -0
- package/src/body.test.ts +125 -0
- package/src/body.ts +152 -0
- package/src/contexts/cid-v1.json +114 -0
- package/src/contexts/fep-22cd.json +21 -0
- package/src/contexts/fep-ef61.json +10 -0
- package/src/contexts/miscellany.json +17 -0
- package/src/contexts/security-data-integrity-v1.json +0 -4
- package/src/contexts.ts +40 -0
- package/src/digest.test.ts +220 -0
- package/src/digest.ts +229 -0
- package/src/docloader.test.ts +918 -27
- package/src/docloader.ts +322 -105
- package/src/internal/jsonld-cache.ts +97 -1
- package/src/internal/portable-dereference.test.ts +254 -0
- package/src/internal/portable-dereference.ts +1000 -0
- package/src/internal/signed-representation.ts +565 -0
- package/src/jsonld-cache.test.ts +89 -0
- package/src/key.test.ts +9 -0
- package/src/key.ts +11 -1
- package/src/mod.ts +30 -0
- package/src/multibase/multibase.test.ts +5 -5
- package/src/portable-media.test.ts +293 -0
- package/src/portable-media.ts +264 -0
- package/src/portable-workers.test.ts +81 -0
- package/src/portable.ts +180 -0
- package/src/preprocessor.ts +7 -0
- package/src/request.test.ts +10 -1
- package/src/request.ts +9 -1
- package/src/signed-representation.test.ts +338 -0
- package/src/url.test.ts +844 -1
- package/src/url.ts +717 -17
- package/tsdown.config.ts +2 -0
- package/dist/tests/url-BvjYQdxL.cjs +0 -456
- package/dist/tests/url-a2D8NAgh.mjs +0 -378
- package/dist/url-Ck3dGEwH.cjs +0 -457
- package/dist/url-m1YxGNZ0.js +0 -379
- /package/dist/{chunk-M78iaK0I.cjs → rolldown-runtime-B7lfambq.cjs} +0 -0
- /package/dist/tests/{langstr-CbAxaeEZ.cjs → langstr-C4Fl80ae.cjs} +0 -0
- /package/dist/tests/{langstr-Di5AvKpB.mjs → langstr-CQ26J_L7.mjs} +0 -0
- /package/dist/tests/{link-NUUWCdnK.mjs → link-Cevmc87v.mjs} +0 -0
- /package/dist/tests/{link-FguCydMA.cjs → link-DlKm8bEr.cjs} +0 -0
- /package/dist/tests/{multicodec-CxGVGa91.cjs → multicodec-CLRPeW4N.cjs} +0 -0
- /package/dist/tests/{multicodec-CyFp54fI.mjs → multicodec-CRIj_05H.mjs} +0 -0
- /package/dist/tests/{chunk-C2EiDwsr.cjs → rolldown-runtime-emK7D4bc.cjs} +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { n as DocumentLoader } from "./docloader-CYwqh5Df.cjs";
|
|
3
|
+
import { TracerProvider } from "@opentelemetry/api";
|
|
4
|
+
|
|
5
|
+
//#region src/portable.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Options passed to a {@link PortableObjectVerifier}.
|
|
8
|
+
* @since 2.4.0
|
|
9
|
+
*/
|
|
10
|
+
interface PortableObjectVerifierOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The document loader for fetching remote documents, such as verification
|
|
13
|
+
* methods that are not `did:key` URLs.
|
|
14
|
+
*/
|
|
15
|
+
readonly documentLoader?: DocumentLoader;
|
|
16
|
+
/**
|
|
17
|
+
* The document loader for fetching remote JSON-LD contexts. During
|
|
18
|
+
* gateway dereferencing, this loader returns the same context documents
|
|
19
|
+
* that the vocabulary parser sees.
|
|
20
|
+
*/
|
|
21
|
+
readonly contextLoader?: DocumentLoader;
|
|
22
|
+
/**
|
|
23
|
+
* The OpenTelemetry tracer provider.
|
|
24
|
+
*/
|
|
25
|
+
readonly tracerProvider?: TracerProvider;
|
|
26
|
+
/**
|
|
27
|
+
* The URL the document was finally retrieved from, i.e., the `documentUrl`
|
|
28
|
+
* of the document loader's result, which may differ from the requested URL
|
|
29
|
+
* after redirects. Trust decisions such as the [FEP-ef61] gateway trust
|
|
30
|
+
* policy for unsecured collections depend on it, so custom document loaders
|
|
31
|
+
* must report it truthfully.
|
|
32
|
+
*
|
|
33
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
34
|
+
* @since 2.4.0
|
|
35
|
+
*/
|
|
36
|
+
readonly documentUrl?: URL;
|
|
37
|
+
/**
|
|
38
|
+
* The gateways that the caller explicitly passed to the accessor through
|
|
39
|
+
* its `gateways` option, in order. It is `undefined` if the caller did not
|
|
40
|
+
* pass the option, and can be empty.
|
|
41
|
+
* @since 2.4.0
|
|
42
|
+
*/
|
|
43
|
+
readonly gateways?: readonly URL[];
|
|
44
|
+
/**
|
|
45
|
+
* The gateways inferred from the reference, in order, when the caller did
|
|
46
|
+
* not pass the `gateways` option: the `@gateway` location hints of
|
|
47
|
+
* a portable IRI, the gateway named by an FEP-ef61 compatible identifier,
|
|
48
|
+
* or the WebFinger server of a portable actor. They only tell where the
|
|
49
|
+
* document and related objects might be retrieved, and must not be
|
|
50
|
+
* trusted to act for the portable object's DID.
|
|
51
|
+
* @since 2.4.0
|
|
52
|
+
*/
|
|
53
|
+
readonly gatewayHints?: readonly URL[];
|
|
54
|
+
/**
|
|
55
|
+
* The object whose property referred to the document, if the document was
|
|
56
|
+
* dereferenced through a property accessor.
|
|
57
|
+
* @since 2.4.0
|
|
58
|
+
*/
|
|
59
|
+
readonly referrer?: PortableObjectReferrer;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* An object whose property referred to a portable object being verified.
|
|
63
|
+
* Referrers form a chain: {@link PortableObjectReferrer.referrer} is the
|
|
64
|
+
* object through which this referrer itself was obtained, and so on.
|
|
65
|
+
* @since 2.4.0
|
|
66
|
+
*/
|
|
67
|
+
interface PortableObjectReferrer {
|
|
68
|
+
/**
|
|
69
|
+
* The referring vocabulary object.
|
|
70
|
+
*/
|
|
71
|
+
readonly object: unknown;
|
|
72
|
+
/**
|
|
73
|
+
* The `@id` of the referring object, if any.
|
|
74
|
+
*/
|
|
75
|
+
readonly id: URL | null;
|
|
76
|
+
/**
|
|
77
|
+
* The expanded URI of the property through which the referring object
|
|
78
|
+
* referred to the next object in the chain, e.g.,
|
|
79
|
+
* `https://www.w3.org/ns/activitystreams#outbox`.
|
|
80
|
+
*/
|
|
81
|
+
readonly property: string;
|
|
82
|
+
/**
|
|
83
|
+
* How the referring object itself was accepted by a
|
|
84
|
+
* {@link PortableObjectVerifier} when it was dereferenced through gateways:
|
|
85
|
+
*
|
|
86
|
+
* - `"verified"`: accepted as verified, e.g., with a valid integrity proof.
|
|
87
|
+
* - `"unsecured"`: accepted without an integrity proof, e.g., as an
|
|
88
|
+
* unsecured collection served by a trusted gateway.
|
|
89
|
+
*
|
|
90
|
+
* It is `undefined` if the referring object was not dereferenced through
|
|
91
|
+
* gateways, e.g., if it was embedded in another object or constructed by
|
|
92
|
+
* the application.
|
|
93
|
+
*/
|
|
94
|
+
readonly acceptance?: "verified" | "unsecured";
|
|
95
|
+
/**
|
|
96
|
+
* The opaque collection context that a {@link PortableObjectVerifier}
|
|
97
|
+
* attached to the referring object when it accepted it. See
|
|
98
|
+
* {@link PortableObjectVerification}.
|
|
99
|
+
*/
|
|
100
|
+
readonly collectionContext?: unknown;
|
|
101
|
+
/**
|
|
102
|
+
* The referrer of the referring object, if any.
|
|
103
|
+
*/
|
|
104
|
+
readonly referrer?: PortableObjectReferrer;
|
|
105
|
+
/**
|
|
106
|
+
* Whether the chain was cut off here because it was too long. If `true`,
|
|
107
|
+
* the referring object may have a referrer which is not included.
|
|
108
|
+
*/
|
|
109
|
+
readonly truncated?: boolean;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The result of a {@link PortableObjectVerifier}.
|
|
113
|
+
* @since 2.4.0
|
|
114
|
+
*/
|
|
115
|
+
type PortableObjectVerification = {
|
|
116
|
+
/** Whether the document is accepted. */readonly verified: false;
|
|
117
|
+
} | {
|
|
118
|
+
/** Whether the document is accepted. */readonly verified: true;
|
|
119
|
+
/**
|
|
120
|
+
* Whether the document was accepted without an integrity proof, e.g., as
|
|
121
|
+
* an unsecured [FEP-ef61] collection served by a gateway that its owner
|
|
122
|
+
* lists. Objects embedded in such a document are not trusted because of
|
|
123
|
+
* their origin; property accessors dereference and verify them one by
|
|
124
|
+
* one instead.
|
|
125
|
+
*
|
|
126
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
127
|
+
*/
|
|
128
|
+
readonly unsecured?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* An opaque value that the verifier wants to receive again as
|
|
131
|
+
* {@link PortableObjectReferrer.collectionContext} when objects referred
|
|
132
|
+
* to by this document, such as collection pages, are verified.
|
|
133
|
+
*/
|
|
134
|
+
readonly collectionContext?: unknown;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* A function that applies the [FEP-ef61] trust policy to a portable object
|
|
138
|
+
* fetched through a gateway.
|
|
139
|
+
*
|
|
140
|
+
* It receives the fetched JSON-LD document as is, and resolves to an object
|
|
141
|
+
* whose `verified` property tells whether the document is acceptable, e.g.,
|
|
142
|
+
* whether it carries a valid [FEP-8b32] Object Integrity Proof made by the
|
|
143
|
+
* DID in its portable ID. `verifyPortableObject()` and
|
|
144
|
+
* `verifyPortableObjectProof()` from `@fedify/fedify` satisfy this type, so
|
|
145
|
+
* they can be passed as the `verifyPortableObject` option of generated
|
|
146
|
+
* vocabulary accessors such as `Activity.getObject()`.
|
|
147
|
+
*
|
|
148
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
149
|
+
* [FEP-8b32]: https://w3id.org/fep/8b32
|
|
150
|
+
*
|
|
151
|
+
* @param document The fetched JSON-LD document.
|
|
152
|
+
* @param options Loaders, tracing options, and where the document came from.
|
|
153
|
+
* @returns An object whose `verified` property is `true` if and only if the
|
|
154
|
+
* document satisfies the policy. Other properties, such as
|
|
155
|
+
* a failure reason, are logged when verification fails.
|
|
156
|
+
* @since 2.4.0
|
|
157
|
+
*/
|
|
158
|
+
type PortableObjectVerifier = (document: unknown, options: PortableObjectVerifierOptions) => Promise<PortableObjectVerification>;
|
|
159
|
+
//#endregion
|
|
160
|
+
export { PortableObjectVerifierOptions as i, PortableObjectVerification as n, PortableObjectVerifier as r, PortableObjectReferrer as t };
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { n as DocumentLoader } from "./docloader-CYwqh5Df.js";
|
|
3
|
+
import { TracerProvider } from "@opentelemetry/api";
|
|
4
|
+
|
|
5
|
+
//#region src/portable.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Options passed to a {@link PortableObjectVerifier}.
|
|
8
|
+
* @since 2.4.0
|
|
9
|
+
*/
|
|
10
|
+
interface PortableObjectVerifierOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The document loader for fetching remote documents, such as verification
|
|
13
|
+
* methods that are not `did:key` URLs.
|
|
14
|
+
*/
|
|
15
|
+
readonly documentLoader?: DocumentLoader;
|
|
16
|
+
/**
|
|
17
|
+
* The document loader for fetching remote JSON-LD contexts. During
|
|
18
|
+
* gateway dereferencing, this loader returns the same context documents
|
|
19
|
+
* that the vocabulary parser sees.
|
|
20
|
+
*/
|
|
21
|
+
readonly contextLoader?: DocumentLoader;
|
|
22
|
+
/**
|
|
23
|
+
* The OpenTelemetry tracer provider.
|
|
24
|
+
*/
|
|
25
|
+
readonly tracerProvider?: TracerProvider;
|
|
26
|
+
/**
|
|
27
|
+
* The URL the document was finally retrieved from, i.e., the `documentUrl`
|
|
28
|
+
* of the document loader's result, which may differ from the requested URL
|
|
29
|
+
* after redirects. Trust decisions such as the [FEP-ef61] gateway trust
|
|
30
|
+
* policy for unsecured collections depend on it, so custom document loaders
|
|
31
|
+
* must report it truthfully.
|
|
32
|
+
*
|
|
33
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
34
|
+
* @since 2.4.0
|
|
35
|
+
*/
|
|
36
|
+
readonly documentUrl?: URL;
|
|
37
|
+
/**
|
|
38
|
+
* The gateways that the caller explicitly passed to the accessor through
|
|
39
|
+
* its `gateways` option, in order. It is `undefined` if the caller did not
|
|
40
|
+
* pass the option, and can be empty.
|
|
41
|
+
* @since 2.4.0
|
|
42
|
+
*/
|
|
43
|
+
readonly gateways?: readonly URL[];
|
|
44
|
+
/**
|
|
45
|
+
* The gateways inferred from the reference, in order, when the caller did
|
|
46
|
+
* not pass the `gateways` option: the `@gateway` location hints of
|
|
47
|
+
* a portable IRI, the gateway named by an FEP-ef61 compatible identifier,
|
|
48
|
+
* or the WebFinger server of a portable actor. They only tell where the
|
|
49
|
+
* document and related objects might be retrieved, and must not be
|
|
50
|
+
* trusted to act for the portable object's DID.
|
|
51
|
+
* @since 2.4.0
|
|
52
|
+
*/
|
|
53
|
+
readonly gatewayHints?: readonly URL[];
|
|
54
|
+
/**
|
|
55
|
+
* The object whose property referred to the document, if the document was
|
|
56
|
+
* dereferenced through a property accessor.
|
|
57
|
+
* @since 2.4.0
|
|
58
|
+
*/
|
|
59
|
+
readonly referrer?: PortableObjectReferrer;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* An object whose property referred to a portable object being verified.
|
|
63
|
+
* Referrers form a chain: {@link PortableObjectReferrer.referrer} is the
|
|
64
|
+
* object through which this referrer itself was obtained, and so on.
|
|
65
|
+
* @since 2.4.0
|
|
66
|
+
*/
|
|
67
|
+
interface PortableObjectReferrer {
|
|
68
|
+
/**
|
|
69
|
+
* The referring vocabulary object.
|
|
70
|
+
*/
|
|
71
|
+
readonly object: unknown;
|
|
72
|
+
/**
|
|
73
|
+
* The `@id` of the referring object, if any.
|
|
74
|
+
*/
|
|
75
|
+
readonly id: URL | null;
|
|
76
|
+
/**
|
|
77
|
+
* The expanded URI of the property through which the referring object
|
|
78
|
+
* referred to the next object in the chain, e.g.,
|
|
79
|
+
* `https://www.w3.org/ns/activitystreams#outbox`.
|
|
80
|
+
*/
|
|
81
|
+
readonly property: string;
|
|
82
|
+
/**
|
|
83
|
+
* How the referring object itself was accepted by a
|
|
84
|
+
* {@link PortableObjectVerifier} when it was dereferenced through gateways:
|
|
85
|
+
*
|
|
86
|
+
* - `"verified"`: accepted as verified, e.g., with a valid integrity proof.
|
|
87
|
+
* - `"unsecured"`: accepted without an integrity proof, e.g., as an
|
|
88
|
+
* unsecured collection served by a trusted gateway.
|
|
89
|
+
*
|
|
90
|
+
* It is `undefined` if the referring object was not dereferenced through
|
|
91
|
+
* gateways, e.g., if it was embedded in another object or constructed by
|
|
92
|
+
* the application.
|
|
93
|
+
*/
|
|
94
|
+
readonly acceptance?: "verified" | "unsecured";
|
|
95
|
+
/**
|
|
96
|
+
* The opaque collection context that a {@link PortableObjectVerifier}
|
|
97
|
+
* attached to the referring object when it accepted it. See
|
|
98
|
+
* {@link PortableObjectVerification}.
|
|
99
|
+
*/
|
|
100
|
+
readonly collectionContext?: unknown;
|
|
101
|
+
/**
|
|
102
|
+
* The referrer of the referring object, if any.
|
|
103
|
+
*/
|
|
104
|
+
readonly referrer?: PortableObjectReferrer;
|
|
105
|
+
/**
|
|
106
|
+
* Whether the chain was cut off here because it was too long. If `true`,
|
|
107
|
+
* the referring object may have a referrer which is not included.
|
|
108
|
+
*/
|
|
109
|
+
readonly truncated?: boolean;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The result of a {@link PortableObjectVerifier}.
|
|
113
|
+
* @since 2.4.0
|
|
114
|
+
*/
|
|
115
|
+
type PortableObjectVerification = {
|
|
116
|
+
/** Whether the document is accepted. */readonly verified: false;
|
|
117
|
+
} | {
|
|
118
|
+
/** Whether the document is accepted. */readonly verified: true;
|
|
119
|
+
/**
|
|
120
|
+
* Whether the document was accepted without an integrity proof, e.g., as
|
|
121
|
+
* an unsecured [FEP-ef61] collection served by a gateway that its owner
|
|
122
|
+
* lists. Objects embedded in such a document are not trusted because of
|
|
123
|
+
* their origin; property accessors dereference and verify them one by
|
|
124
|
+
* one instead.
|
|
125
|
+
*
|
|
126
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
127
|
+
*/
|
|
128
|
+
readonly unsecured?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* An opaque value that the verifier wants to receive again as
|
|
131
|
+
* {@link PortableObjectReferrer.collectionContext} when objects referred
|
|
132
|
+
* to by this document, such as collection pages, are verified.
|
|
133
|
+
*/
|
|
134
|
+
readonly collectionContext?: unknown;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* A function that applies the [FEP-ef61] trust policy to a portable object
|
|
138
|
+
* fetched through a gateway.
|
|
139
|
+
*
|
|
140
|
+
* It receives the fetched JSON-LD document as is, and resolves to an object
|
|
141
|
+
* whose `verified` property tells whether the document is acceptable, e.g.,
|
|
142
|
+
* whether it carries a valid [FEP-8b32] Object Integrity Proof made by the
|
|
143
|
+
* DID in its portable ID. `verifyPortableObject()` and
|
|
144
|
+
* `verifyPortableObjectProof()` from `@fedify/fedify` satisfy this type, so
|
|
145
|
+
* they can be passed as the `verifyPortableObject` option of generated
|
|
146
|
+
* vocabulary accessors such as `Activity.getObject()`.
|
|
147
|
+
*
|
|
148
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
149
|
+
* [FEP-8b32]: https://w3id.org/fep/8b32
|
|
150
|
+
*
|
|
151
|
+
* @param document The fetched JSON-LD document.
|
|
152
|
+
* @param options Loaders, tracing options, and where the document came from.
|
|
153
|
+
* @returns An object whose `verified` property is `true` if and only if the
|
|
154
|
+
* document satisfies the policy. Other properties, such as
|
|
155
|
+
* a failure reason, are logged when verification fails.
|
|
156
|
+
* @since 2.4.0
|
|
157
|
+
*/
|
|
158
|
+
type PortableObjectVerifier = (document: unknown, options: PortableObjectVerifierOptions) => Promise<PortableObjectVerification>;
|
|
159
|
+
//#endregion
|
|
160
|
+
export { PortableObjectVerifierOptions as i, PortableObjectVerification as n, PortableObjectVerifier as r, PortableObjectReferrer as t };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { t as FetchError } from "./request-DRaOaTqD.mjs";
|
|
2
|
+
import { getLogger } from "@logtape/logtape";
|
|
3
|
+
//#region src/body.ts
|
|
4
|
+
/** Decoded JSON body limit: 16 MiB. @internal */
|
|
5
|
+
const MAX_BODY_SIZE = 16 * 1024 * 1024;
|
|
6
|
+
/** A body exceeded the byte limit. @internal */
|
|
7
|
+
var BodyTooLargeError = class extends FetchError {
|
|
8
|
+
/** Creates an error for a body exceeding the given limit. */
|
|
9
|
+
constructor(url, maxBytes) {
|
|
10
|
+
super(url, `Body exceeds the limit of ${maxBytes} bytes`);
|
|
11
|
+
this.name = "BodyTooLargeError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/** Validates a finite, positive byte limit. @internal */
|
|
15
|
+
function validateBodySizeLimit(maxBytes) {
|
|
16
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) throw new RangeError("The body size limit must be a positive safe integer.");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Reads UTF-8 text while limiting bytes received from the body stream.
|
|
20
|
+
* Fetch responses are already decompressed, so the stream count is authoritative.
|
|
21
|
+
* @param message The response or request to read.
|
|
22
|
+
* @param maxBytes The maximum number of decoded bytes to read.
|
|
23
|
+
* @param url The URL to include in errors and logs.
|
|
24
|
+
* @returns The decoded body text.
|
|
25
|
+
* @throws {BodyTooLargeError} If the body exceeds the limit.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
async function readBoundedText(message, maxBytes, url) {
|
|
29
|
+
validateBodySizeLimit(maxBytes);
|
|
30
|
+
const reader = message.body?.getReader();
|
|
31
|
+
const tooLarge = () => {
|
|
32
|
+
getLogger([
|
|
33
|
+
"fedify",
|
|
34
|
+
"runtime",
|
|
35
|
+
"body"
|
|
36
|
+
]).warn("Body from {url} exceeds the limit of {maxBytes} bytes.", {
|
|
37
|
+
url: url.toString(),
|
|
38
|
+
maxBytes
|
|
39
|
+
});
|
|
40
|
+
throw new BodyTooLargeError(url, maxBytes);
|
|
41
|
+
};
|
|
42
|
+
try {
|
|
43
|
+
const length = message.headers.get("Content-Length");
|
|
44
|
+
const encoding = message.headers.get("Content-Encoding");
|
|
45
|
+
if ((encoding == null || encoding.toLowerCase() === "identity") && length != null && /^\d+$/.test(length) && Number(length) > maxBytes) tooLarge();
|
|
46
|
+
if (reader == null) return "";
|
|
47
|
+
let size = 0;
|
|
48
|
+
const textReader = new ReadableStream({ async pull(controller) {
|
|
49
|
+
const { done, value } = await reader.read();
|
|
50
|
+
if (done) {
|
|
51
|
+
controller.close();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
size += value.byteLength;
|
|
55
|
+
if (size > maxBytes) tooLarge();
|
|
56
|
+
controller.enqueue(value);
|
|
57
|
+
} }, { highWaterMark: 0 }).pipeThrough(new TextDecoderStream()).getReader();
|
|
58
|
+
try {
|
|
59
|
+
const chunks = [];
|
|
60
|
+
while (true) {
|
|
61
|
+
const { done, value } = await textReader.read();
|
|
62
|
+
if (done) break;
|
|
63
|
+
chunks.push(value);
|
|
64
|
+
}
|
|
65
|
+
return chunks.join("");
|
|
66
|
+
} finally {
|
|
67
|
+
textReader.releaseLock();
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (reader != null) reader.cancel(error).catch(() => {});
|
|
71
|
+
throw error;
|
|
72
|
+
} finally {
|
|
73
|
+
reader?.releaseLock();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Reads raw bytes while limiting bytes received from the body stream.
|
|
78
|
+
* Unlike {@link readBoundedText}, the bytes are returned as they were
|
|
79
|
+
* received, without decoding.
|
|
80
|
+
* @param message The response or request to read.
|
|
81
|
+
* @param maxBytes The maximum number of decoded bytes to read.
|
|
82
|
+
* @param url The URL to include in errors and logs.
|
|
83
|
+
* @returns The body bytes.
|
|
84
|
+
* @throws {BodyTooLargeError} If the body exceeds the limit.
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
async function readBoundedBytes(message, maxBytes, url) {
|
|
88
|
+
validateBodySizeLimit(maxBytes);
|
|
89
|
+
const reader = message.body?.getReader();
|
|
90
|
+
const tooLarge = () => {
|
|
91
|
+
getLogger([
|
|
92
|
+
"fedify",
|
|
93
|
+
"runtime",
|
|
94
|
+
"body"
|
|
95
|
+
]).warn("Body from {url} exceeds the limit of {maxBytes} bytes.", {
|
|
96
|
+
url: url.toString(),
|
|
97
|
+
maxBytes
|
|
98
|
+
});
|
|
99
|
+
throw new BodyTooLargeError(url, maxBytes);
|
|
100
|
+
};
|
|
101
|
+
try {
|
|
102
|
+
const length = message.headers.get("Content-Length");
|
|
103
|
+
const encoding = message.headers.get("Content-Encoding");
|
|
104
|
+
if ((encoding == null || encoding.toLowerCase() === "identity") && length != null && /^\d+$/.test(length) && Number(length) > maxBytes) tooLarge();
|
|
105
|
+
if (reader == null) return /* @__PURE__ */ new Uint8Array(0);
|
|
106
|
+
const chunks = [];
|
|
107
|
+
let size = 0;
|
|
108
|
+
while (true) {
|
|
109
|
+
const { done, value } = await reader.read();
|
|
110
|
+
if (done) break;
|
|
111
|
+
size += value.byteLength;
|
|
112
|
+
if (size > maxBytes) tooLarge();
|
|
113
|
+
chunks.push(value);
|
|
114
|
+
}
|
|
115
|
+
const bytes = new Uint8Array(size);
|
|
116
|
+
let offset = 0;
|
|
117
|
+
for (const chunk of chunks) {
|
|
118
|
+
bytes.set(chunk, offset);
|
|
119
|
+
offset += chunk.byteLength;
|
|
120
|
+
}
|
|
121
|
+
return bytes;
|
|
122
|
+
} catch (error) {
|
|
123
|
+
if (reader != null) reader.cancel(error).catch(() => {});
|
|
124
|
+
throw error;
|
|
125
|
+
} finally {
|
|
126
|
+
reader?.releaseLock();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
130
|
+
export { readBoundedText as i, MAX_BODY_SIZE as n, readBoundedBytes as r, BodyTooLargeError as t };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
const require_request = require("./request-8vPWtV1-.cjs");
|
|
2
|
+
let _logtape_logtape = require("@logtape/logtape");
|
|
3
|
+
//#region src/body.ts
|
|
4
|
+
/** Decoded JSON body limit: 16 MiB. @internal */
|
|
5
|
+
const MAX_BODY_SIZE = 16 * 1024 * 1024;
|
|
6
|
+
/** A body exceeded the byte limit. @internal */
|
|
7
|
+
var BodyTooLargeError = class extends require_request.FetchError {
|
|
8
|
+
/** Creates an error for a body exceeding the given limit. */
|
|
9
|
+
constructor(url, maxBytes) {
|
|
10
|
+
super(url, `Body exceeds the limit of ${maxBytes} bytes`);
|
|
11
|
+
this.name = "BodyTooLargeError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/** Validates a finite, positive byte limit. @internal */
|
|
15
|
+
function validateBodySizeLimit(maxBytes) {
|
|
16
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) throw new RangeError("The body size limit must be a positive safe integer.");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Reads UTF-8 text while limiting bytes received from the body stream.
|
|
20
|
+
* Fetch responses are already decompressed, so the stream count is authoritative.
|
|
21
|
+
* @param message The response or request to read.
|
|
22
|
+
* @param maxBytes The maximum number of decoded bytes to read.
|
|
23
|
+
* @param url The URL to include in errors and logs.
|
|
24
|
+
* @returns The decoded body text.
|
|
25
|
+
* @throws {BodyTooLargeError} If the body exceeds the limit.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
async function readBoundedText(message, maxBytes, url) {
|
|
29
|
+
validateBodySizeLimit(maxBytes);
|
|
30
|
+
const reader = message.body?.getReader();
|
|
31
|
+
const tooLarge = () => {
|
|
32
|
+
(0, _logtape_logtape.getLogger)([
|
|
33
|
+
"fedify",
|
|
34
|
+
"runtime",
|
|
35
|
+
"body"
|
|
36
|
+
]).warn("Body from {url} exceeds the limit of {maxBytes} bytes.", {
|
|
37
|
+
url: url.toString(),
|
|
38
|
+
maxBytes
|
|
39
|
+
});
|
|
40
|
+
throw new BodyTooLargeError(url, maxBytes);
|
|
41
|
+
};
|
|
42
|
+
try {
|
|
43
|
+
const length = message.headers.get("Content-Length");
|
|
44
|
+
const encoding = message.headers.get("Content-Encoding");
|
|
45
|
+
if ((encoding == null || encoding.toLowerCase() === "identity") && length != null && /^\d+$/.test(length) && Number(length) > maxBytes) tooLarge();
|
|
46
|
+
if (reader == null) return "";
|
|
47
|
+
let size = 0;
|
|
48
|
+
const textReader = new ReadableStream({ async pull(controller) {
|
|
49
|
+
const { done, value } = await reader.read();
|
|
50
|
+
if (done) {
|
|
51
|
+
controller.close();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
size += value.byteLength;
|
|
55
|
+
if (size > maxBytes) tooLarge();
|
|
56
|
+
controller.enqueue(value);
|
|
57
|
+
} }, { highWaterMark: 0 }).pipeThrough(new TextDecoderStream()).getReader();
|
|
58
|
+
try {
|
|
59
|
+
const chunks = [];
|
|
60
|
+
while (true) {
|
|
61
|
+
const { done, value } = await textReader.read();
|
|
62
|
+
if (done) break;
|
|
63
|
+
chunks.push(value);
|
|
64
|
+
}
|
|
65
|
+
return chunks.join("");
|
|
66
|
+
} finally {
|
|
67
|
+
textReader.releaseLock();
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (reader != null) reader.cancel(error).catch(() => {});
|
|
71
|
+
throw error;
|
|
72
|
+
} finally {
|
|
73
|
+
reader?.releaseLock();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Reads raw bytes while limiting bytes received from the body stream.
|
|
78
|
+
* Unlike {@link readBoundedText}, the bytes are returned as they were
|
|
79
|
+
* received, without decoding.
|
|
80
|
+
* @param message The response or request to read.
|
|
81
|
+
* @param maxBytes The maximum number of decoded bytes to read.
|
|
82
|
+
* @param url The URL to include in errors and logs.
|
|
83
|
+
* @returns The body bytes.
|
|
84
|
+
* @throws {BodyTooLargeError} If the body exceeds the limit.
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
async function readBoundedBytes(message, maxBytes, url) {
|
|
88
|
+
validateBodySizeLimit(maxBytes);
|
|
89
|
+
const reader = message.body?.getReader();
|
|
90
|
+
const tooLarge = () => {
|
|
91
|
+
(0, _logtape_logtape.getLogger)([
|
|
92
|
+
"fedify",
|
|
93
|
+
"runtime",
|
|
94
|
+
"body"
|
|
95
|
+
]).warn("Body from {url} exceeds the limit of {maxBytes} bytes.", {
|
|
96
|
+
url: url.toString(),
|
|
97
|
+
maxBytes
|
|
98
|
+
});
|
|
99
|
+
throw new BodyTooLargeError(url, maxBytes);
|
|
100
|
+
};
|
|
101
|
+
try {
|
|
102
|
+
const length = message.headers.get("Content-Length");
|
|
103
|
+
const encoding = message.headers.get("Content-Encoding");
|
|
104
|
+
if ((encoding == null || encoding.toLowerCase() === "identity") && length != null && /^\d+$/.test(length) && Number(length) > maxBytes) tooLarge();
|
|
105
|
+
if (reader == null) return /* @__PURE__ */ new Uint8Array(0);
|
|
106
|
+
const chunks = [];
|
|
107
|
+
let size = 0;
|
|
108
|
+
while (true) {
|
|
109
|
+
const { done, value } = await reader.read();
|
|
110
|
+
if (done) break;
|
|
111
|
+
size += value.byteLength;
|
|
112
|
+
if (size > maxBytes) tooLarge();
|
|
113
|
+
chunks.push(value);
|
|
114
|
+
}
|
|
115
|
+
const bytes = new Uint8Array(size);
|
|
116
|
+
let offset = 0;
|
|
117
|
+
for (const chunk of chunks) {
|
|
118
|
+
bytes.set(chunk, offset);
|
|
119
|
+
offset += chunk.byteLength;
|
|
120
|
+
}
|
|
121
|
+
return bytes;
|
|
122
|
+
} catch (error) {
|
|
123
|
+
if (reader != null) reader.cancel(error).catch(() => {});
|
|
124
|
+
throw error;
|
|
125
|
+
} finally {
|
|
126
|
+
reader?.releaseLock();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
130
|
+
Object.defineProperty(exports, "BodyTooLargeError", {
|
|
131
|
+
enumerable: true,
|
|
132
|
+
get: function() {
|
|
133
|
+
return BodyTooLargeError;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
Object.defineProperty(exports, "MAX_BODY_SIZE", {
|
|
137
|
+
enumerable: true,
|
|
138
|
+
get: function() {
|
|
139
|
+
return MAX_BODY_SIZE;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
Object.defineProperty(exports, "readBoundedBytes", {
|
|
143
|
+
enumerable: true,
|
|
144
|
+
get: function() {
|
|
145
|
+
return readBoundedBytes;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
Object.defineProperty(exports, "readBoundedText", {
|
|
149
|
+
enumerable: true,
|
|
150
|
+
get: function() {
|
|
151
|
+
return readBoundedText;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const require_body = require("./body-CkEwROsn.cjs");
|
|
2
|
+
let node_assert_strict = require("node:assert/strict");
|
|
3
|
+
let node_test = require("node:test");
|
|
4
|
+
let node_zlib = require("node:zlib");
|
|
5
|
+
//#region src/body.test.ts
|
|
6
|
+
const url = "https://example.com/document";
|
|
7
|
+
(0, node_test.test)("readBoundedText handles empty bodies and flushes incomplete UTF-8", async () => {
|
|
8
|
+
(0, node_assert_strict.deepStrictEqual)(await require_body.readBoundedText(new Response(null), 1, url), "");
|
|
9
|
+
(0, node_assert_strict.deepStrictEqual)(await require_body.readBoundedText(new Response(""), 1, url), "");
|
|
10
|
+
(0, node_assert_strict.deepStrictEqual)(await require_body.readBoundedText(new Response(new Uint8Array([226, 130])), 2, url), "�");
|
|
11
|
+
});
|
|
12
|
+
(0, node_test.test)("readBoundedText counts bytes and preserves split UTF-8", async () => {
|
|
13
|
+
const bytes = new TextEncoder().encode("\"안녕\"");
|
|
14
|
+
const stream = new ReadableStream({ start(controller) {
|
|
15
|
+
for (const byte of bytes) controller.enqueue(new Uint8Array([byte]));
|
|
16
|
+
controller.close();
|
|
17
|
+
} });
|
|
18
|
+
(0, node_assert_strict.deepStrictEqual)(await require_body.readBoundedText(new Response(stream), bytes.length, url), "\"안녕\"");
|
|
19
|
+
await (0, node_assert_strict.rejects)(require_body.readBoundedText(new Response(bytes), bytes.length - 1, url), require_body.BodyTooLargeError);
|
|
20
|
+
});
|
|
21
|
+
(0, node_test.test)("readBoundedText rejects a declared oversized body without pulling", async () => {
|
|
22
|
+
let pulled = false;
|
|
23
|
+
let canceled = false;
|
|
24
|
+
const response = new Response(new ReadableStream({
|
|
25
|
+
pull() {
|
|
26
|
+
pulled = true;
|
|
27
|
+
},
|
|
28
|
+
cancel() {
|
|
29
|
+
canceled = true;
|
|
30
|
+
}
|
|
31
|
+
}, { highWaterMark: 0 }), { headers: { "Content-Length": "100" } });
|
|
32
|
+
await (0, node_assert_strict.rejects)(require_body.readBoundedText(response, 10, url), require_body.BodyTooLargeError);
|
|
33
|
+
(0, node_assert_strict.deepStrictEqual)(pulled, false);
|
|
34
|
+
(0, node_assert_strict.deepStrictEqual)(canceled, true);
|
|
35
|
+
(0, node_assert_strict.deepStrictEqual)(response.body?.locked, false);
|
|
36
|
+
});
|
|
37
|
+
(0, node_test.test)("readBoundedText cancels chunked bodies despite absent or false lengths", async () => {
|
|
38
|
+
for (const length of [
|
|
39
|
+
void 0,
|
|
40
|
+
"1",
|
|
41
|
+
"invalid"
|
|
42
|
+
]) {
|
|
43
|
+
let pulls = 0;
|
|
44
|
+
let canceled = false;
|
|
45
|
+
const stream = new ReadableStream({
|
|
46
|
+
pull(controller) {
|
|
47
|
+
pulls++;
|
|
48
|
+
controller.enqueue(/* @__PURE__ */ new Uint8Array(4));
|
|
49
|
+
},
|
|
50
|
+
cancel() {
|
|
51
|
+
canceled = true;
|
|
52
|
+
}
|
|
53
|
+
}, { highWaterMark: 0 });
|
|
54
|
+
const response = new Response(stream, { headers: length == null ? {} : { "Content-Length": length } });
|
|
55
|
+
await (0, node_assert_strict.rejects)(require_body.readBoundedText(response, 8, url), require_body.BodyTooLargeError);
|
|
56
|
+
(0, node_assert_strict.deepStrictEqual)(pulls, 3);
|
|
57
|
+
(0, node_assert_strict.deepStrictEqual)(canceled, true);
|
|
58
|
+
(0, node_assert_strict.deepStrictEqual)(response.body?.locked, false);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
(0, node_test.test)("readBoundedText limits decoded gzip bytes, not the compressed length", async () => {
|
|
62
|
+
const compressed = (0, node_zlib.gzipSync)("\"" + "a".repeat(4096) + "\"");
|
|
63
|
+
(0, node_assert_strict.ok)(compressed.length < 128);
|
|
64
|
+
const decoded = (0, node_zlib.gunzipSync)(compressed);
|
|
65
|
+
await (0, node_assert_strict.rejects)(require_body.readBoundedText(new Response(decoded, { headers: {
|
|
66
|
+
"Content-Encoding": "gzip",
|
|
67
|
+
"Content-Length": String(compressed.length)
|
|
68
|
+
} }), 128, url), require_body.BodyTooLargeError);
|
|
69
|
+
(0, node_assert_strict.deepStrictEqual)(await require_body.readBoundedText(new Response("{}", { headers: {
|
|
70
|
+
"Content-Encoding": "gzip",
|
|
71
|
+
"Content-Length": "22"
|
|
72
|
+
} }), 2, url), "{}");
|
|
73
|
+
});
|
|
74
|
+
(0, node_test.test)("readBoundedText rejects invalid limits and releases failed streams", async () => {
|
|
75
|
+
for (const limit of [
|
|
76
|
+
0,
|
|
77
|
+
-1,
|
|
78
|
+
NaN,
|
|
79
|
+
Infinity,
|
|
80
|
+
1.5
|
|
81
|
+
]) await (0, node_assert_strict.rejects)(require_body.readBoundedText(new Response("{}"), limit, url), RangeError);
|
|
82
|
+
const failure = /* @__PURE__ */ new Error("broken stream");
|
|
83
|
+
const response = new Response(new ReadableStream({ pull(controller) {
|
|
84
|
+
controller.error(failure);
|
|
85
|
+
} }));
|
|
86
|
+
await (0, node_assert_strict.rejects)(require_body.readBoundedText(response, 10, url), (error) => error === failure);
|
|
87
|
+
(0, node_assert_strict.deepStrictEqual)(response.body?.locked, false);
|
|
88
|
+
});
|
|
89
|
+
//#endregion
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|