@fedify/fedify 2.0.0-pr.445.1694 → 2.0.0-pr.451.1730
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/dist/{actor-T6RyhRgk.d.ts → actor-Cd2CREO0.d.ts} +2 -2
- package/dist/{actor-D8gCwLzv.js → actor-Cg8ZhoVF.js} +1 -1
- package/dist/{actor-CwZ2m5rG.cjs → actor-D020hlx3.cjs} +922 -1451
- package/dist/{actor-D6K058Tb.d.cts → actor-DDhZuMGl.d.cts} +2 -2
- package/dist/{actor-DoMcqXsW.js → actor-DPD6Gbdn.js} +190 -677
- package/dist/{assert_rejects-DiIiJbZn.js → assert_rejects-Ce45JcFg.js} +1 -1
- package/dist/{assert_is_error-BPGph1Jx.js → assert_throws-BNXdRGWP.js} +31 -1
- package/dist/{builder-1_skw-d2.js → builder-Dn87hy75.js} +7 -8
- package/dist/{client-bgSdkFa2.d.ts → client-Bkaw0_PR.d.ts} +1 -1
- package/dist/{client-CegPX0Rn.d.cts → client-Cle5j1T1.d.cts} +1 -1
- package/dist/{client-D5CBsPrc.js → client-D6-5okV1.js} +1 -1
- package/dist/compat/mod.d.cts +11 -11
- package/dist/compat/mod.d.ts +12 -12
- package/dist/compat/transformers.test.js +20 -20
- package/dist/{context-DiqjMRef.d.cts → context-BOYzcFSe.d.cts} +130 -97
- package/dist/{context-DBKpNBnc.d.ts → context-DqFifMwj.d.ts} +131 -98
- package/dist/{authdocloader-DYTNpaMA.js → docloader-B2BFBGqv.js} +18 -8
- package/dist/{esm-Dl5T1RNE.js → esm-CU0Dnk7T.js} +11 -11
- package/dist/federation/builder.test.js +8 -10
- package/dist/federation/collection.test.js +7 -9
- package/dist/federation/handler.test.js +25 -26
- package/dist/federation/idempotency.test.js +25 -26
- package/dist/federation/inbox.test.js +4 -6
- package/dist/federation/keycache.test.js +3 -4
- package/dist/federation/kv.test.js +6 -8
- package/dist/federation/middleware.test.js +26 -27
- package/dist/federation/mod.cjs +10 -11
- package/dist/federation/mod.d.cts +11 -11
- package/dist/federation/mod.d.ts +13 -13
- package/dist/federation/mod.js +10 -11
- package/dist/federation/mq.test.js +8 -10
- package/dist/federation/negotiation.test.js +7 -9
- package/dist/federation/retry.test.js +4 -5
- package/dist/federation/router.test.js +6 -8
- package/dist/federation/send.test.js +13 -15
- package/dist/{http-D-e6AFwR.d.cts → http-B6SKO6NJ.d.cts} +2 -2
- package/dist/{http-D6Uj2x2y.d.ts → http-BE7aFuqn.d.ts} +2 -2
- package/dist/{http-CAusBl_3.cjs → http-DMsjudj8.cjs} +289 -9
- package/dist/{http-CuS-d4U0.js → http-DN0v2zoF.js} +2 -2
- package/dist/{http-C_Qc2neP.js → http-DcDb8r1W.js} +256 -6
- package/dist/{inbox-IETv_Qez.js → inbox-CgGy7Hzc.js} +1 -1
- package/dist/{key-DnqhSgAv.js → key-jSvnymAk.js} +3 -2
- package/dist/{keycache-CSBkusP8.js → keycache-IVLjlAK9.js} +1 -1
- package/dist/{keys-D3_MDK7n.js → keys-BKM2Mqu2.js} +2 -1
- package/dist/{docloader-CYnQRIXv.cjs → kv-cache-BHIupktM.cjs} +69 -651
- package/dist/kv-cache-DNvS-egZ.js +4236 -0
- package/dist/{docloader-Czl3xV10.js → kv-cache-ydIs4Ul6.js} +68 -596
- package/dist/{ld-Isot0tiW.js → ld-CcsryBo0.js} +3 -2
- package/dist/{lookup-Dhm78GlK.js → lookup-BV3A9Zbc.js} +63 -2
- package/dist/{type-DaUr3Il7.js → lookup-BbEekiru.js} +588 -5303
- package/dist/{lookup-D6dro5Au.cjs → lookup-CMAGfQ1Q.cjs} +78 -5
- package/dist/{middleware-BuHr2fzh.js → middleware-D-vPitR-.js} +37 -38
- package/dist/{middleware-DQYscW90.js → middleware-Dm8sXYUr.js} +40 -40
- package/dist/middleware-DzA970CF.js +16 -0
- package/dist/middleware-VpoC5jyA.js +26 -0
- package/dist/middleware-W_-inBoE.cjs +16 -0
- package/dist/{middleware-Dgmdgrvb.cjs → middleware-ekn2KaOw.cjs} +57 -58
- package/dist/{mod-CxkWO3Mg.d.cts → mod--K7l84wp.d.cts} +3 -2
- package/dist/{mod-DBzN0aCM.d.ts → mod-CB80AlIA.d.ts} +1 -1
- package/dist/mod-CLKu6Uo_.d.cts +107 -0
- package/dist/{mod-Djzcw2ry.d.cts → mod-COlOrmr9.d.cts} +3 -3
- package/dist/{mod-DlU8ISoa.d.ts → mod-CRENK2dd.d.ts} +3 -2
- package/dist/{mod-D_y2y32N.d.ts → mod-CaWbCg0N.d.ts} +2 -2
- package/dist/mod-Cm97bAiT.d.ts +109 -0
- package/dist/{mod-Bpb5QLaZ.d.cts → mod-D9XZsft2.d.cts} +2 -2
- package/dist/{mod-BhUKmBJD.d.ts → mod-DLIidI_j.d.ts} +3 -3
- package/dist/{mod-jQ4OODsl.d.cts → mod-DuclhZjh.d.cts} +1 -1
- package/dist/mod.cjs +21 -32
- package/dist/mod.d.cts +14 -14
- package/dist/mod.d.ts +17 -17
- package/dist/mod.js +15 -16
- package/dist/nodeinfo/client.test.js +8 -10
- package/dist/nodeinfo/handler.test.js +24 -25
- package/dist/nodeinfo/mod.cjs +3 -3
- package/dist/nodeinfo/mod.d.cts +2 -3
- package/dist/nodeinfo/mod.d.ts +3 -4
- package/dist/nodeinfo/mod.js +3 -3
- package/dist/nodeinfo/types.test.js +7 -9
- package/dist/{owner-hd9lvQcP.d.ts → owner-CktUdA0h.d.ts} +3 -3
- package/dist/{owner-BN_tO3cY.d.cts → owner-dkg5OpSC.d.cts} +3 -3
- package/dist/{owner-ChSL4aJ7.js → owner-n5c_oZ_M.js} +3 -2
- package/dist/{proof-BiSCuwyA.js → proof-CLwByIT1.js} +5 -4
- package/dist/{proof-ONNmhInb.cjs → proof-CZfrp13P.cjs} +17 -16
- package/dist/{proof-x3IBewan.js → proof-CsFR7fiS.js} +2 -2
- package/dist/request-BbHkedIU.d.cts +35 -0
- package/dist/request-DKGQaofB.js +184 -0
- package/dist/request-U1t6zZtk.d.ts +39 -0
- package/dist/request-XHWUW2bi.cjs +208 -0
- package/dist/{send-D5fjmUEj.js → send-eW9JIzQV.js} +2 -2
- package/dist/sig/http.test.js +12 -13
- package/dist/sig/key.test.js +9 -11
- package/dist/sig/ld.test.js +8 -10
- package/dist/sig/mod.cjs +10 -11
- package/dist/sig/mod.d.cts +6 -7
- package/dist/sig/mod.d.ts +6 -7
- package/dist/sig/mod.js +6 -7
- package/dist/sig/owner.test.js +10 -12
- package/dist/sig/proof.test.js +13 -14
- package/dist/testing/docloader.test.js +6 -8
- package/dist/testing/mod.d.ts +122 -148
- package/dist/testing/mod.js +2 -3
- package/dist/{testing-tWr1VQxx.js → testing-ClYSmXdi.js} +1 -2
- package/dist/{types-D2Nyz0tR.cjs → types-BT0xc4-R.cjs} +3 -3
- package/dist/{types-DQuSDtDg.js → types-DaPoJTSc.js} +1 -1
- package/dist/{runtime/authdocloader.test.js → utils/docloader.test.js} +13 -15
- package/dist/utils/kv-cache.test.js +208 -0
- package/dist/utils/mod.cjs +14 -0
- package/dist/utils/mod.d.cts +6 -0
- package/dist/utils/mod.d.ts +8 -0
- package/dist/utils/mod.js +12 -0
- package/dist/utils/request.test.js +48 -0
- package/dist/utils/url.test.js +41 -0
- package/dist/vocab/actor.test.js +8 -10
- package/dist/vocab/lookup.test.js +7 -9
- package/dist/vocab/mod.cjs +4 -4
- package/dist/vocab/mod.d.cts +4 -5
- package/dist/vocab/mod.d.ts +4 -5
- package/dist/vocab/mod.js +4 -4
- package/dist/vocab/type.test.js +2 -3
- package/dist/vocab/vocab.test.js +9 -10
- package/dist/{vocab-Dd4VMrr0.cjs → vocab-CxTuoEVd.cjs} +6 -5
- package/dist/{vocab-Dw1-yVGg.d.cts → vocab-DCBw44JZ.d.cts} +2 -21
- package/dist/{vocab-BI0Ak5lL.d.ts → vocab-ivDKb439.d.ts} +2 -21
- package/dist/{vocab-w--qk7HF.js → vocab-yFT-fQBj.js} +4 -3
- package/dist/webfinger/handler.test.js +24 -25
- package/dist/webfinger/lookup.test.js +7 -9
- package/dist/webfinger/mod.cjs +3 -3
- package/dist/webfinger/mod.d.cts +2 -3
- package/dist/webfinger/mod.d.ts +2 -3
- package/dist/webfinger/mod.js +3 -3
- package/dist/x/cfworkers.d.cts +1 -1
- package/dist/x/cfworkers.d.ts +2 -2
- package/dist/x/cfworkers.test.js +6 -8
- package/dist/x/hono.d.cts +10 -10
- package/dist/x/hono.d.ts +11 -11
- package/dist/x/sveltekit.d.cts +10 -10
- package/dist/x/sveltekit.d.ts +11 -11
- package/package.json +16 -14
- package/dist/assert_throws-BOO88avQ.js +0 -39
- package/dist/authdocloader-Cv_qEn1G.js +0 -52
- package/dist/authdocloader-bsmVF6eO.cjs +0 -58
- package/dist/docloader-CxWcuWqQ.d.ts +0 -221
- package/dist/docloader-D-MrRyHl.d.cts +0 -219
- package/dist/key-BNJQQm3h.js +0 -260
- package/dist/key-C_ruQbbl.js +0 -10
- package/dist/key-DIMJMxf4.cjs +0 -10
- package/dist/key-DpFjiItf.js +0 -10
- package/dist/key-DuXv64tg.cjs +0 -290
- package/dist/lookup-CbtuFbtg.js +0 -331
- package/dist/middleware-BpR6186a.js +0 -26
- package/dist/middleware-DDMxdtWM.cjs +0 -17
- package/dist/middleware-T-knSMwl.js +0 -17
- package/dist/mod-CerN_Sza.d.ts +0 -104
- package/dist/mod-Cj1tHXBR.d.cts +0 -102
- package/dist/runtime/docloader.test.js +0 -522
- package/dist/runtime/key.test.js +0 -103
- package/dist/runtime/langstr.test.d.ts +0 -3
- package/dist/runtime/langstr.test.js +0 -39
- package/dist/runtime/link.test.d.ts +0 -3
- package/dist/runtime/link.test.js +0 -61
- package/dist/runtime/mod.cjs +0 -25
- package/dist/runtime/mod.d.cts +0 -6
- package/dist/runtime/mod.d.ts +0 -8
- package/dist/runtime/mod.js +0 -13
- package/dist/runtime/multibase/multibase.test.d.ts +0 -3
- package/dist/runtime/multibase/multibase.test.js +0 -358
- package/dist/runtime/url.test.js +0 -45
- /package/dist/{assert_not_equals-f3m3epl3.js → assert_not_equals-C80BG-_5.js} +0 -0
- /package/dist/{collection-CcnIw1qY.js → collection-BzWsN9pB.js} +0 -0
- /package/dist/{denokv-Bv33Xxea.js → denokv-CCssOzMJ.js} +0 -0
- /package/dist/{federation-H2_En3j5.cjs → federation-DOuZpcAw.cjs} +0 -0
- /package/dist/{federation-D1U8YY9t.js → federation-pZJsapBn.js} +0 -0
- /package/dist/{kv-63Cil1MD.d.cts → kv-BMKIFXNW.d.cts} +0 -0
- /package/dist/{kv-C7sopW2E.d.ts → kv-Dt06smFt.d.ts} +0 -0
- /package/dist/{mod-1pDWKvUL.d.ts → mod-B-ZQqbGe.d.ts} +0 -0
- /package/dist/{mod-g0xFzAP9.d.ts → mod-CjsiSl7_.d.ts} +0 -0
- /package/dist/{mq-CRGm1e_F.d.ts → mq-CPRJk4mZ.d.ts} +0 -0
- /package/dist/{negotiation-5NPJL6zp.js → negotiation-C4nFufNk.js} +0 -0
- /package/dist/{nodeinfo-DfycQ8Wf.js → nodeinfo-B0UefMXO.js} +0 -0
- /package/dist/{nodeinfo-Co9lJrWl.cjs → nodeinfo-ByTd7HpT.cjs} +0 -0
- /package/dist/{retry-D4GJ670a.js → retry-CfF8Gn4d.js} +0 -0
- /package/dist/{runtime-C58AJWSv.cjs → sig-DE_NC_VQ.cjs} +0 -0
- /package/dist/{runtime-DPYEDf-o.js → sig-Dx59zAgn.js} +0 -0
- /package/dist/{std__assert-X-_kMxKM.js → std__assert-DWivtrGR.js} +0 -0
- /package/dist/{types-BSuWJsOm.js → types-C2XVl6gj.js} +0 -0
- /package/dist/{runtime → utils}/docloader.test.d.ts +0 -0
- /package/dist/{runtime/authdocloader.test.d.ts → utils/kv-cache.test.d.ts} +0 -0
- /package/dist/{runtime/key.test.d.ts → utils/request.test.d.ts} +0 -0
- /package/dist/{runtime → utils}/url.test.d.ts +0 -0
- /package/dist/{sig-ByHXzqUi.cjs → utils-B6yXfxAQ.cjs} +0 -0
- /package/dist/{sig-Cj3tk-ig.js → utils-BXMGcmqK.js} +0 -0
- /package/dist/{webfinger-BjOEdFPs.cjs → webfinger-C949bxcD.cjs} +0 -0
- /package/dist/{webfinger-De_bU0iE.js → webfinger-qG8R5jc3.js} +0 -0
@@ -2,136 +2,58 @@
|
|
2
2
|
import { Temporal } from "@js-temporal/polyfill";
|
3
3
|
import { URLPattern } from "urlpattern-polyfill";
|
4
4
|
|
5
|
+
import { createActivityPubRequest, logRequest } from "./request-DKGQaofB.js";
|
6
|
+
import { UrlError, validatePublicUrl } from "./lookup-BV3A9Zbc.js";
|
7
|
+
import { doubleKnock, validateCryptoKey } from "./http-DcDb8r1W.js";
|
5
8
|
import { getLogger } from "@logtape/logtape";
|
6
|
-
import
|
7
|
-
import {
|
8
|
-
import { isIP } from "node:net";
|
9
|
+
import { getDocumentLoader, getRemoteDocument } from "@fedify/vocab-runtime";
|
10
|
+
import { curry } from "@fxts/core";
|
9
11
|
|
10
|
-
//#region
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
var exclude = [
|
53
|
-
".test-report.xml",
|
54
|
-
"apidoc/",
|
55
|
-
"dist/",
|
56
|
-
"node_modules/",
|
57
|
-
"npm/",
|
58
|
-
"pnpm-lock.yaml",
|
59
|
-
"src/cfworkers/dist/",
|
60
|
-
"src/cfworkers/fixtures/",
|
61
|
-
"src/cfworkers/imports.ts",
|
62
|
-
"src/cfworkers/README.md",
|
63
|
-
"src/cfworkers/server.ts",
|
64
|
-
"src/cfworkers/server.js",
|
65
|
-
"src/cfworkers/server.js.map",
|
66
|
-
"src/codegen/schema.yaml",
|
67
|
-
"src/vocab/*.yaml",
|
68
|
-
"!src/vocab/vocab.ts"
|
69
|
-
];
|
70
|
-
var tasks = {
|
71
|
-
"codegen": "GENPATH=vocab-$(deno eval \"console.log(crypto.randomUUID());\").ts && deno run --allow-read --allow-write --check src/codegen/main.ts src/vocab/ ../runtime/ src/vocab/$GENPATH && deno fmt src/vocab/$GENPATH && mv src/vocab/$GENPATH src/vocab/vocab.ts && deno cache src/vocab/vocab.ts && deno check src/vocab/vocab.ts",
|
72
|
-
"cache": {
|
73
|
-
"command": "deno cache src/mod.ts",
|
74
|
-
"dependencies": ["codegen"]
|
75
|
-
},
|
76
|
-
"check": {
|
77
|
-
"command": "deno fmt --check && deno lint && deno check src/**/*.ts",
|
78
|
-
"dependencies": ["codegen"]
|
79
|
-
},
|
80
|
-
"test": {
|
81
|
-
"command": "deno test --check --doc --allow-read --allow-write --allow-env --unstable-kv --trace-leaks --parallel",
|
82
|
-
"dependencies": ["codegen"]
|
83
|
-
},
|
84
|
-
"coverage": "deno task test --clean --coverage && deno coverage --html coverage",
|
85
|
-
"bench": {
|
86
|
-
"command": "deno bench --allow-read --allow-write --allow-net --allow-env --allow-run --unstable-kv",
|
87
|
-
"dependencies": ["codegen"]
|
88
|
-
},
|
89
|
-
"apidoc": {
|
90
|
-
"command": "deno doc --html --name=Fedify --output=apidoc/ src/mod.ts",
|
91
|
-
"dependencies": ["codegen"]
|
92
|
-
},
|
93
|
-
"publish": {
|
94
|
-
"command": "deno publish",
|
95
|
-
"dependencies": ["codegen"]
|
96
|
-
},
|
97
|
-
"pnpm:install": "pnpm install --silent",
|
98
|
-
"pnpm:build": {
|
99
|
-
"command": "pnpm exec tsdown",
|
100
|
-
"dependencies": ["codegen", "pnpm:install"]
|
101
|
-
},
|
102
|
-
"test:node": {
|
103
|
-
"command": "cd dist/ && node --test",
|
104
|
-
"dependencies": ["pnpm:build"]
|
105
|
-
},
|
106
|
-
"test:bun": {
|
107
|
-
"command": "cd dist/ && bun test --timeout 60000",
|
108
|
-
"dependencies": ["pnpm:build"]
|
109
|
-
},
|
110
|
-
"test:cfworkers": {
|
111
|
-
"command": "pnpm exec wrangler deploy --dry-run --outdir src/cfworkers && node --import=tsx src/cfworkers/client.ts",
|
112
|
-
"dependencies": ["pnpm:build"]
|
113
|
-
},
|
114
|
-
"test-all": { "dependencies": [
|
115
|
-
"check",
|
116
|
-
"test",
|
117
|
-
"test:node",
|
118
|
-
"test:bun",
|
119
|
-
"test:cfworkers"
|
120
|
-
] }
|
121
|
-
};
|
122
|
-
var deno_default = {
|
123
|
-
name,
|
124
|
-
version,
|
125
|
-
license,
|
126
|
-
exports,
|
127
|
-
imports,
|
128
|
-
include,
|
129
|
-
exclude,
|
130
|
-
tasks
|
131
|
-
};
|
12
|
+
//#region src/utils/docloader.ts
|
13
|
+
const logger$1 = getLogger([
|
14
|
+
"fedify",
|
15
|
+
"utils",
|
16
|
+
"docloader"
|
17
|
+
]);
|
18
|
+
/**
|
19
|
+
* Gets an authenticated {@link DocumentLoader} for the given identity.
|
20
|
+
* Note that an authenticated document loader intentionally does not cache
|
21
|
+
* the fetched documents.
|
22
|
+
* @param identity The identity to get the document loader for.
|
23
|
+
* The actor's key pair.
|
24
|
+
* @param options The options for the document loader.
|
25
|
+
* @returns The authenticated document loader.
|
26
|
+
* @throws {TypeError} If the key is invalid or unsupported.
|
27
|
+
* @since 0.4.0
|
28
|
+
*/
|
29
|
+
function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, userAgent, specDeterminer, tracerProvider } = {}) {
|
30
|
+
validateCryptoKey(identity.privateKey);
|
31
|
+
async function load(url, options) {
|
32
|
+
if (!allowPrivateAddress) try {
|
33
|
+
await validatePublicUrl(url);
|
34
|
+
} catch (error) {
|
35
|
+
if (error instanceof UrlError) logger$1.error("Disallowed private URL: {url}", {
|
36
|
+
url,
|
37
|
+
error
|
38
|
+
});
|
39
|
+
throw error;
|
40
|
+
}
|
41
|
+
const originalRequest = createActivityPubRequest(url, { userAgent });
|
42
|
+
const response = await doubleKnock(originalRequest, identity, {
|
43
|
+
specDeterminer,
|
44
|
+
log: curry(logRequest)(logger$1),
|
45
|
+
tracerProvider,
|
46
|
+
signal: options?.signal
|
47
|
+
});
|
48
|
+
return getRemoteDocument(url, response, load);
|
49
|
+
}
|
50
|
+
return load;
|
51
|
+
}
|
52
|
+
const _fetchDocumentLoader = getDocumentLoader();
|
53
|
+
const _fetchDocumentLoader_allowPrivateAddress = getDocumentLoader({ allowPrivateAddress: true });
|
132
54
|
|
133
55
|
//#endregion
|
134
|
-
//#region src/
|
56
|
+
//#region src/utils/contexts.ts
|
135
57
|
const preloadedContexts = {
|
136
58
|
"https://www.w3.org/ns/activitystreams": { "@context": {
|
137
59
|
"@vocab": "_:",
|
@@ -4273,450 +4195,15 @@ const preloadedContexts = {
|
|
4273
4195
|
}
|
4274
4196
|
} }
|
4275
4197
|
};
|
4276
|
-
var contexts_default = preloadedContexts;
|
4277
4198
|
|
4278
4199
|
//#endregion
|
4279
|
-
//#region src/
|
4280
|
-
const parametersNeedLowerCase = ["rel", "type"];
|
4281
|
-
const regexpLinkWhitespace = /[\n\r\s\t]/;
|
4282
|
-
function validateURI(uri) {
|
4283
|
-
if (uri.includes("\n") || regexpLinkWhitespace.test(uri)) throw new SyntaxError(`\`${uri}\` is not a valid URI!`);
|
4284
|
-
}
|
4285
|
-
function* parseLinkFromString(input) {
|
4286
|
-
const inputFmt = input.replaceAll("\xA0", "").replaceAll("", "");
|
4287
|
-
for (let cursor = 0; cursor < inputFmt.length; cursor += 1) {
|
4288
|
-
while (regexpLinkWhitespace.test(inputFmt.charAt(cursor))) cursor += 1;
|
4289
|
-
if (inputFmt.charAt(cursor) !== "<") throw new SyntaxError(`Unexpected character \`${inputFmt.charAt(cursor)}\` at position ${cursor}; Expect character \`<\`!`);
|
4290
|
-
cursor += 1;
|
4291
|
-
const cursorEndUri = inputFmt.indexOf(">", cursor);
|
4292
|
-
if (cursorEndUri === -1) throw new SyntaxError(`Missing end of URI delimiter character \`>\` after position ${cursor}!`);
|
4293
|
-
if (cursorEndUri === cursor) throw new SyntaxError(`Missing URI at position ${cursor}!`);
|
4294
|
-
const uriSlice = inputFmt.slice(cursor, cursorEndUri);
|
4295
|
-
validateURI(uriSlice);
|
4296
|
-
const uri = decodeURI(uriSlice);
|
4297
|
-
const parameters = {};
|
4298
|
-
cursor = cursorEndUri + 1;
|
4299
|
-
while (regexpLinkWhitespace.test(inputFmt.charAt(cursor))) cursor += 1;
|
4300
|
-
if (cursor === inputFmt.length || inputFmt.charAt(cursor) === ",") {
|
4301
|
-
yield [uri, parameters];
|
4302
|
-
continue;
|
4303
|
-
}
|
4304
|
-
if (inputFmt.charAt(cursor) !== ";") throw new SyntaxError(`Unexpected character \`${inputFmt.charAt(cursor)}\` at position ${cursor}; Expect character \`;\`!`);
|
4305
|
-
cursor += 1;
|
4306
|
-
while (cursor < inputFmt.length) {
|
4307
|
-
while (regexpLinkWhitespace.test(inputFmt.charAt(cursor))) cursor += 1;
|
4308
|
-
const parameterKey = inputFmt.slice(cursor).match(/^[\w-]+\*?/)?.[0].toLowerCase();
|
4309
|
-
if (typeof parameterKey === "undefined") throw new SyntaxError(`Unexpected character \`${inputFmt.charAt(cursor)}\` at position ${cursor}; Expect a valid parameter key!`);
|
4310
|
-
cursor += parameterKey.length;
|
4311
|
-
while (regexpLinkWhitespace.test(inputFmt.charAt(cursor))) cursor += 1;
|
4312
|
-
if (cursor === inputFmt.length || inputFmt.charAt(cursor) === ",") {
|
4313
|
-
parameters[parameterKey] = "";
|
4314
|
-
break;
|
4315
|
-
}
|
4316
|
-
if (inputFmt.charAt(cursor) === ";") {
|
4317
|
-
parameters[parameterKey] = "";
|
4318
|
-
cursor += 1;
|
4319
|
-
continue;
|
4320
|
-
}
|
4321
|
-
if (inputFmt.charAt(cursor) !== "=") throw new SyntaxError(`Unexpected character \`${inputFmt.charAt(cursor)}\` at position ${cursor}; Expect character \`=\`!`);
|
4322
|
-
cursor += 1;
|
4323
|
-
while (regexpLinkWhitespace.test(inputFmt.charAt(cursor))) cursor += 1;
|
4324
|
-
let parameterValue = "";
|
4325
|
-
if (inputFmt.charAt(cursor) === "\"") {
|
4326
|
-
cursor += 1;
|
4327
|
-
while (cursor < inputFmt.length) {
|
4328
|
-
if (inputFmt.charAt(cursor) === "\"") {
|
4329
|
-
cursor += 1;
|
4330
|
-
break;
|
4331
|
-
}
|
4332
|
-
if (inputFmt.charAt(cursor) === "\\") cursor += 1;
|
4333
|
-
parameterValue += inputFmt.charAt(cursor);
|
4334
|
-
cursor += 1;
|
4335
|
-
}
|
4336
|
-
} else {
|
4337
|
-
const cursorDiffParameterValue = inputFmt.slice(cursor).search(/[\s;,]/);
|
4338
|
-
if (cursorDiffParameterValue === -1) {
|
4339
|
-
parameterValue += inputFmt.slice(cursor);
|
4340
|
-
cursor += parameterValue.length;
|
4341
|
-
} else {
|
4342
|
-
parameterValue += inputFmt.slice(cursor, cursorDiffParameterValue);
|
4343
|
-
cursor += cursorDiffParameterValue;
|
4344
|
-
}
|
4345
|
-
}
|
4346
|
-
parameters[parameterKey] = parametersNeedLowerCase.includes(parameterKey) ? parameterValue.toLowerCase() : parameterValue;
|
4347
|
-
while (regexpLinkWhitespace.test(inputFmt.charAt(cursor))) cursor += 1;
|
4348
|
-
if (cursor === inputFmt.length || inputFmt.charAt(cursor) === ",") break;
|
4349
|
-
if (inputFmt.charAt(cursor) === ";") {
|
4350
|
-
cursor += 1;
|
4351
|
-
continue;
|
4352
|
-
}
|
4353
|
-
throw new SyntaxError(`Unexpected character \`${inputFmt.charAt(cursor)}\` at position ${cursor}; Expect character \`,\`, character \`;\`, or end of the string!`);
|
4354
|
-
}
|
4355
|
-
yield [uri, parameters];
|
4356
|
-
}
|
4357
|
-
}
|
4358
|
-
/**
|
4359
|
-
* Handle the HTTP header `Link` according to the specification RFC 8288.
|
4360
|
-
*/
|
4361
|
-
var HttpHeaderLink = class HttpHeaderLink {
|
4362
|
-
get [Symbol.toStringTag]() {
|
4363
|
-
return "HTTPHeaderLink";
|
4364
|
-
}
|
4365
|
-
#entries = [];
|
4366
|
-
/**
|
4367
|
-
* Handle the HTTP header `Link` according to the specification RFC 8288.
|
4368
|
-
* @param {...(string | Headers | HttpHeaderLink | HttpHeaderLinkEntry[] | Response)} inputs Input.
|
4369
|
-
*/
|
4370
|
-
constructor(...inputs) {
|
4371
|
-
if (inputs.length > 0) this.add(...inputs);
|
4372
|
-
}
|
4373
|
-
/**
|
4374
|
-
* Add entries.
|
4375
|
-
* @param {...(string | Headers | HttpHeaderLink | HttpHeaderLinkEntry[] | Response)} inputs Input.
|
4376
|
-
* @returns {this}
|
4377
|
-
*/
|
4378
|
-
add(...inputs) {
|
4379
|
-
for (const input of inputs) if (input instanceof HttpHeaderLink) this.#entries.push(...structuredClone(input.#entries));
|
4380
|
-
else if (Array.isArray(input)) this.#entries.push(...input.map(([uri, parameters]) => {
|
4381
|
-
validateURI(uri);
|
4382
|
-
Object.entries(parameters).forEach(([key, value]) => {
|
4383
|
-
if (key !== key.toLowerCase() || !/^[\w-]+\*?$/.test(key)) throw new SyntaxError(`\`${key}\` is not a valid parameter key!`);
|
4384
|
-
if (parametersNeedLowerCase.includes(key) && value !== value.toLowerCase()) throw new SyntaxError(`\`${value}\` is not a valid parameter value!`);
|
4385
|
-
});
|
4386
|
-
return [uri, structuredClone(parameters)];
|
4387
|
-
}));
|
4388
|
-
else for (const entry of parseLinkFromString((input instanceof Headers || input instanceof Response ? (input instanceof Headers ? input : input.headers).get("Link") : input) ?? "")) this.#entries.push(entry);
|
4389
|
-
return this;
|
4390
|
-
}
|
4391
|
-
/**
|
4392
|
-
* Return all of the entries.
|
4393
|
-
* @returns {HttpHeaderLinkEntry[]} Entries.
|
4394
|
-
*/
|
4395
|
-
entries() {
|
4396
|
-
return structuredClone(this.#entries);
|
4397
|
-
}
|
4398
|
-
/**
|
4399
|
-
* Get entries by parameter.
|
4400
|
-
* @param {string} key Key of the parameter.
|
4401
|
-
* @param {string} value Value of the parameter.
|
4402
|
-
* @returns {HttpHeaderLinkEntry[]} Entries which match the parameter.
|
4403
|
-
*/
|
4404
|
-
getByParameter(key, value) {
|
4405
|
-
if (key !== key.toLowerCase()) throw new SyntaxError(`\`${key}\` is not a valid parameter key!`);
|
4406
|
-
if (key === "rel") return this.getByRel(value);
|
4407
|
-
return structuredClone(this.#entries.filter((entry) => {
|
4408
|
-
return entry[1][key] === value;
|
4409
|
-
}));
|
4410
|
-
}
|
4411
|
-
/**
|
4412
|
-
* Get entries by parameter `rel`.
|
4413
|
-
* @param {string} value Value of the parameter `rel`.
|
4414
|
-
* @returns {HttpHeaderLinkEntry[]} Entries which match the parameter.
|
4415
|
-
*/
|
4416
|
-
getByRel(value) {
|
4417
|
-
if (value !== value.toLowerCase()) throw new SyntaxError(`\`${value}\` is not a valid parameter \`rel\` value!`);
|
4418
|
-
return structuredClone(this.#entries.filter((entity) => {
|
4419
|
-
return entity[1].rel?.toLowerCase() === value;
|
4420
|
-
}));
|
4421
|
-
}
|
4422
|
-
/**
|
4423
|
-
* Whether have entries that match parameter.
|
4424
|
-
* @param {string} key Key of the parameter.
|
4425
|
-
* @param {string} value Value of the parameter.
|
4426
|
-
* @returns {boolean} Determine result.
|
4427
|
-
*/
|
4428
|
-
hasParameter(key, value) {
|
4429
|
-
return this.getByParameter(key, value).length > 0;
|
4430
|
-
}
|
4431
|
-
/**
|
4432
|
-
* Stringify entries.
|
4433
|
-
* @returns {string} Stringified entries.
|
4434
|
-
*/
|
4435
|
-
toString() {
|
4436
|
-
return this.#entries.map(([uri, parameters]) => {
|
4437
|
-
return [`<${encodeURI(uri)}>`, ...Object.entries(parameters).map(([key, value]) => {
|
4438
|
-
return value.length > 0 ? `${key}="${value.replaceAll("\"", "\\\"")}"` : key;
|
4439
|
-
})].join("; ");
|
4440
|
-
}).join(", ");
|
4441
|
-
}
|
4442
|
-
/**
|
4443
|
-
* Parse the HTTP header `Link` according to the specification RFC 8288.
|
4444
|
-
* @param {...(string | Headers | HttpHeaderLink | HttpHeaderLinkEntry[] | Response)} inputs Input.
|
4445
|
-
* @returns {HttpHeaderLink}
|
4446
|
-
*/
|
4447
|
-
static parse(...inputs) {
|
4448
|
-
return new this(...inputs);
|
4449
|
-
}
|
4450
|
-
/**
|
4451
|
-
* Stringify as the HTTP header `Link` according to the specification RFC 8288.
|
4452
|
-
* @param {...(string | Headers | HttpHeaderLink | HttpHeaderLinkEntry[] | Response)} inputs Input.
|
4453
|
-
* @returns {string}
|
4454
|
-
*/
|
4455
|
-
static stringify(...inputs) {
|
4456
|
-
return new this(...inputs).toString();
|
4457
|
-
}
|
4458
|
-
};
|
4459
|
-
|
4460
|
-
//#endregion
|
4461
|
-
//#region src/runtime/url.ts
|
4462
|
-
var UrlError = class extends Error {
|
4463
|
-
constructor(message) {
|
4464
|
-
super(message);
|
4465
|
-
this.name = "UrlError";
|
4466
|
-
}
|
4467
|
-
};
|
4468
|
-
/**
|
4469
|
-
* Validates a URL to prevent SSRF attacks.
|
4470
|
-
*/
|
4471
|
-
async function validatePublicUrl(url) {
|
4472
|
-
const parsed = new URL(url);
|
4473
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new UrlError(`Unsupported protocol: ${parsed.protocol}`);
|
4474
|
-
let hostname = parsed.hostname;
|
4475
|
-
if (hostname.startsWith("[") && hostname.endsWith("]")) hostname = hostname.substring(1, hostname.length - 2);
|
4476
|
-
if (hostname === "localhost") throw new UrlError("Localhost is not allowed");
|
4477
|
-
if ("Deno" in globalThis && !isIP(hostname)) {
|
4478
|
-
const netPermission = await Deno.permissions.query({ name: "net" });
|
4479
|
-
if (netPermission.state !== "granted") return;
|
4480
|
-
}
|
4481
|
-
if ("Bun" in globalThis) {
|
4482
|
-
if (hostname === "example.com" || hostname.endsWith(".example.com")) return;
|
4483
|
-
else if (hostname === "fedify-test.internal") throw new UrlError("Invalid or private address: fedify-test.internal");
|
4484
|
-
}
|
4485
|
-
let addresses;
|
4486
|
-
try {
|
4487
|
-
addresses = await lookup(hostname, { all: true });
|
4488
|
-
} catch {
|
4489
|
-
addresses = [];
|
4490
|
-
}
|
4491
|
-
for (const { address, family } of addresses) if (family === 4 && !isValidPublicIPv4Address(address) || family === 6 && !isValidPublicIPv6Address(address) || family < 4 || family === 5 || family > 6) throw new UrlError(`Invalid or private address: ${address}`);
|
4492
|
-
}
|
4493
|
-
function isValidPublicIPv4Address(address) {
|
4494
|
-
const parts = address.split(".");
|
4495
|
-
const first = parseInt(parts[0]);
|
4496
|
-
if (first === 0 || first === 10 || first === 127) return false;
|
4497
|
-
const second = parseInt(parts[1]);
|
4498
|
-
if (first === 169 && second === 254) return false;
|
4499
|
-
if (first === 172 && second >= 16 && second <= 31) return false;
|
4500
|
-
if (first === 192 && second === 168) return false;
|
4501
|
-
return true;
|
4502
|
-
}
|
4503
|
-
function isValidPublicIPv6Address(address) {
|
4504
|
-
address = expandIPv6Address(address);
|
4505
|
-
if (address.at(4) !== ":") return false;
|
4506
|
-
const firstWord = parseInt(address.substring(0, 4), 16);
|
4507
|
-
return !(firstWord >= 64512 && firstWord <= 65023 || firstWord >= 65152 && firstWord <= 65215 || firstWord === 0 || firstWord >= 65280);
|
4508
|
-
}
|
4509
|
-
function expandIPv6Address(address) {
|
4510
|
-
address = address.toLowerCase();
|
4511
|
-
if (address === "::") return "0000:0000:0000:0000:0000:0000:0000:0000";
|
4512
|
-
if (address.startsWith("::")) address = "0000" + address;
|
4513
|
-
if (address.endsWith("::")) address = address + "0000";
|
4514
|
-
address = address.replace("::", ":0000".repeat(8 - (address.match(/:/g) || []).length) + ":");
|
4515
|
-
const parts = address.split(":");
|
4516
|
-
return parts.map((part) => part.padStart(4, "0")).join(":");
|
4517
|
-
}
|
4518
|
-
|
4519
|
-
//#endregion
|
4520
|
-
//#region src/runtime/docloader.ts
|
4200
|
+
//#region src/utils/kv-cache.ts
|
4521
4201
|
const logger = getLogger([
|
4522
4202
|
"fedify",
|
4523
|
-
"
|
4524
|
-
"
|
4203
|
+
"utils",
|
4204
|
+
"kv-cache"
|
4525
4205
|
]);
|
4526
4206
|
/**
|
4527
|
-
* Error thrown when fetching a JSON-LD document failed.
|
4528
|
-
*/
|
4529
|
-
var FetchError = class extends Error {
|
4530
|
-
/**
|
4531
|
-
* The URL that failed to fetch.
|
4532
|
-
*/
|
4533
|
-
url;
|
4534
|
-
/**
|
4535
|
-
* Constructs a new `FetchError`.
|
4536
|
-
*
|
4537
|
-
* @param url The URL that failed to fetch.
|
4538
|
-
* @param message Error message.
|
4539
|
-
*/
|
4540
|
-
constructor(url, message) {
|
4541
|
-
super(message == null ? url.toString() : `${url}: ${message}`);
|
4542
|
-
this.name = "FetchError";
|
4543
|
-
this.url = typeof url === "string" ? new URL(url) : url;
|
4544
|
-
}
|
4545
|
-
};
|
4546
|
-
/**
|
4547
|
-
* Creates a request for the given URL.
|
4548
|
-
* @param url The URL to create the request for.
|
4549
|
-
* @param options The options for the request.
|
4550
|
-
* @returns The created request.
|
4551
|
-
* @internal
|
4552
|
-
*/
|
4553
|
-
function createRequest(url, options = {}) {
|
4554
|
-
return new Request(url, {
|
4555
|
-
headers: {
|
4556
|
-
Accept: "application/activity+json, application/ld+json",
|
4557
|
-
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
4558
|
-
},
|
4559
|
-
redirect: "manual"
|
4560
|
-
});
|
4561
|
-
}
|
4562
|
-
/**
|
4563
|
-
* Logs the request.
|
4564
|
-
* @param request The request to log.
|
4565
|
-
* @internal
|
4566
|
-
*/
|
4567
|
-
function logRequest(request) {
|
4568
|
-
logger.debug("Fetching document: {method} {url} {headers}", {
|
4569
|
-
method: request.method,
|
4570
|
-
url: request.url,
|
4571
|
-
headers: Object.fromEntries(request.headers.entries())
|
4572
|
-
});
|
4573
|
-
}
|
4574
|
-
/**
|
4575
|
-
* Gets a {@link RemoteDocument} from the given response.
|
4576
|
-
* @param url The URL of the document to load.
|
4577
|
-
* @param response The response to get the document from.
|
4578
|
-
* @param fetch The function to fetch the document.
|
4579
|
-
* @returns The loaded remote document.
|
4580
|
-
* @throws {FetchError} If the response is not OK.
|
4581
|
-
* @internal
|
4582
|
-
*/
|
4583
|
-
async function getRemoteDocument(url, response, fetch$1) {
|
4584
|
-
const documentUrl = response.url === "" ? url : response.url;
|
4585
|
-
const docUrl = new URL(documentUrl);
|
4586
|
-
if (!response.ok) {
|
4587
|
-
logger.error("Failed to fetch document: {status} {url} {headers}", {
|
4588
|
-
status: response.status,
|
4589
|
-
url: documentUrl,
|
4590
|
-
headers: Object.fromEntries(response.headers.entries())
|
4591
|
-
});
|
4592
|
-
throw new FetchError(documentUrl, `HTTP ${response.status}: ${documentUrl}`);
|
4593
|
-
}
|
4594
|
-
const contentType = response.headers.get("Content-Type");
|
4595
|
-
const jsonLd = contentType == null || contentType === "application/activity+json" || contentType.startsWith("application/activity+json;") || contentType === "application/ld+json" || contentType.startsWith("application/ld+json;");
|
4596
|
-
const linkHeader = response.headers.get("Link");
|
4597
|
-
let contextUrl = null;
|
4598
|
-
if (linkHeader != null) {
|
4599
|
-
let link;
|
4600
|
-
try {
|
4601
|
-
link = new HttpHeaderLink(linkHeader);
|
4602
|
-
} catch (e) {
|
4603
|
-
if (e instanceof SyntaxError) link = new HttpHeaderLink();
|
4604
|
-
else throw e;
|
4605
|
-
}
|
4606
|
-
if (jsonLd) {
|
4607
|
-
const entries = link.getByRel("http://www.w3.org/ns/json-ld#context");
|
4608
|
-
for (const [uri, params] of entries) if ("type" in params && params.type === "application/ld+json") {
|
4609
|
-
contextUrl = uri;
|
4610
|
-
break;
|
4611
|
-
}
|
4612
|
-
} else {
|
4613
|
-
const entries = link.getByRel("alternate");
|
4614
|
-
for (const [uri, params] of entries) {
|
4615
|
-
const altUri = new URL(uri, docUrl);
|
4616
|
-
if ("type" in params && (params.type === "application/activity+json" || params.type === "application/ld+json" || params.type.startsWith("application/ld+json;")) && altUri.href !== docUrl.href) {
|
4617
|
-
logger.debug("Found alternate document: {alternateUrl} from {url}", {
|
4618
|
-
alternateUrl: altUri.href,
|
4619
|
-
url: documentUrl
|
4620
|
-
});
|
4621
|
-
return await fetch$1(altUri.href);
|
4622
|
-
}
|
4623
|
-
}
|
4624
|
-
}
|
4625
|
-
}
|
4626
|
-
let document;
|
4627
|
-
if (!jsonLd && (contentType === "text/html" || contentType?.startsWith("text/html;") || contentType === "application/xhtml+xml" || contentType?.startsWith("application/xhtml+xml;"))) {
|
4628
|
-
const p = /<(a|link)((\s+[a-z][a-z:_-]*=("[^"]*"|'[^']*'|[^\s>]+))+)\s*\/?>/gi;
|
4629
|
-
const p2 = /\s+([a-z][a-z:_-]*)=("([^"]*)"|'([^']*)'|([^\s>]+))/gi;
|
4630
|
-
const html = await response.text();
|
4631
|
-
let m;
|
4632
|
-
const rawAttribs = [];
|
4633
|
-
while ((m = p.exec(html)) !== null) rawAttribs.push(m[2]);
|
4634
|
-
for (const rawAttrs of rawAttribs) {
|
4635
|
-
let m2;
|
4636
|
-
const attribs = {};
|
4637
|
-
while ((m2 = p2.exec(rawAttrs)) !== null) {
|
4638
|
-
const key = m2[1].toLowerCase();
|
4639
|
-
const value = m2[3] ?? m2[4] ?? m2[5] ?? "";
|
4640
|
-
attribs[key] = value;
|
4641
|
-
}
|
4642
|
-
if (attribs.rel === "alternate" && "type" in attribs && (attribs.type === "application/activity+json" || attribs.type === "application/ld+json" || attribs.type.startsWith("application/ld+json;")) && "href" in attribs && new URL(attribs.href, docUrl).href !== docUrl.href) {
|
4643
|
-
logger.debug("Found alternate document: {alternateUrl} from {url}", {
|
4644
|
-
alternateUrl: attribs.href,
|
4645
|
-
url: documentUrl
|
4646
|
-
});
|
4647
|
-
return await fetch$1(new URL(attribs.href, docUrl).href);
|
4648
|
-
}
|
4649
|
-
}
|
4650
|
-
document = JSON.parse(html);
|
4651
|
-
} else document = await response.json();
|
4652
|
-
logger.debug("Fetched document: {status} {url} {headers}", {
|
4653
|
-
status: response.status,
|
4654
|
-
url: documentUrl,
|
4655
|
-
headers: Object.fromEntries(response.headers.entries())
|
4656
|
-
});
|
4657
|
-
return {
|
4658
|
-
contextUrl,
|
4659
|
-
document,
|
4660
|
-
documentUrl
|
4661
|
-
};
|
4662
|
-
}
|
4663
|
-
/**
|
4664
|
-
* Creates a JSON-LD document loader that utilizes the browser's `fetch` API.
|
4665
|
-
*
|
4666
|
-
* The created loader preloads the below frequently used contexts by default
|
4667
|
-
* (unless `options.ignorePreloadedContexts` is set to `true`):
|
4668
|
-
*
|
4669
|
-
* - <https://www.w3.org/ns/activitystreams>
|
4670
|
-
* - <https://w3id.org/security/v1>
|
4671
|
-
* - <https://w3id.org/security/data-integrity/v1>
|
4672
|
-
* - <https://www.w3.org/ns/did/v1>
|
4673
|
-
* - <https://w3id.org/security/multikey/v1>
|
4674
|
-
* - <https://purl.archive.org/socialweb/webfinger>
|
4675
|
-
* - <http://schema.org/>
|
4676
|
-
* @param options Options for the document loader.
|
4677
|
-
* @returns The document loader.
|
4678
|
-
* @since 1.3.0
|
4679
|
-
*/
|
4680
|
-
function getDocumentLoader({ allowPrivateAddress, skipPreloadedContexts, userAgent } = {}) {
|
4681
|
-
async function load(url, options) {
|
4682
|
-
options?.signal?.throwIfAborted();
|
4683
|
-
if (!skipPreloadedContexts && url in contexts_default) {
|
4684
|
-
logger.debug("Using preloaded context: {url}.", { url });
|
4685
|
-
return {
|
4686
|
-
contextUrl: null,
|
4687
|
-
document: contexts_default[url],
|
4688
|
-
documentUrl: url
|
4689
|
-
};
|
4690
|
-
}
|
4691
|
-
if (!allowPrivateAddress) try {
|
4692
|
-
await validatePublicUrl(url);
|
4693
|
-
} catch (error) {
|
4694
|
-
if (error instanceof UrlError) logger.error("Disallowed private URL: {url}", {
|
4695
|
-
url,
|
4696
|
-
error
|
4697
|
-
});
|
4698
|
-
throw error;
|
4699
|
-
}
|
4700
|
-
const request = createRequest(url, { userAgent });
|
4701
|
-
logRequest(request);
|
4702
|
-
const response = await fetch(request, {
|
4703
|
-
redirect: "manual",
|
4704
|
-
signal: options?.signal
|
4705
|
-
});
|
4706
|
-
if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) return load(response.headers.get("Location"), options);
|
4707
|
-
return getRemoteDocument(url, response, load);
|
4708
|
-
}
|
4709
|
-
return load;
|
4710
|
-
}
|
4711
|
-
const _fetchDocumentLoader = getDocumentLoader();
|
4712
|
-
const _fetchDocumentLoader_allowPrivateAddress = getDocumentLoader({ allowPrivateAddress: true });
|
4713
|
-
function fetchDocumentLoader(url, arg = false) {
|
4714
|
-
const allowPrivateAddress = typeof arg === "boolean" ? arg : false;
|
4715
|
-
logger.warn("fetchDocumentLoader() function is deprecated. Use getDocumentLoader() function instead.");
|
4716
|
-
const loader = allowPrivateAddress ? _fetchDocumentLoader_allowPrivateAddress : _fetchDocumentLoader;
|
4717
|
-
return loader(url);
|
4718
|
-
}
|
4719
|
-
/**
|
4720
4207
|
* Decorates a {@link DocumentLoader} with a cache backed by a {@link Deno.Kv}.
|
4721
4208
|
* @param parameters The parameters for the cache.
|
4722
4209
|
* @returns The decorated document loader which is cache-enabled.
|
@@ -4725,30 +4212,16 @@ function kvCache({ loader, kv, prefix, rules }) {
|
|
4725
4212
|
const keyPrefix = prefix ?? ["_fedify", "remoteDocument"];
|
4726
4213
|
rules ??= [[new URLPattern({}), Temporal.Duration.from({ minutes: 5 })]];
|
4727
4214
|
for (const [p, duration] of rules) if (Temporal.Duration.compare(duration, { days: 30 }) > 0) throw new TypeError("The maximum cache duration is 30 days: " + (p instanceof URLPattern ? `${p.protocol}://${p.username}:${p.password}@${p.hostname}:${p.port}/${p.pathname}?${p.search}#${p.hash}` : p.toString()));
|
4728
|
-
function matchRule(url) {
|
4729
|
-
for (const [pattern, duration] of rules) {
|
4730
|
-
if (typeof pattern === "string") {
|
4731
|
-
if (url === pattern) return duration;
|
4732
|
-
continue;
|
4733
|
-
}
|
4734
|
-
if (pattern instanceof URL) {
|
4735
|
-
if (pattern.href == url) return duration;
|
4736
|
-
continue;
|
4737
|
-
}
|
4738
|
-
if (pattern.test(url)) return duration;
|
4739
|
-
}
|
4740
|
-
return null;
|
4741
|
-
}
|
4742
4215
|
return async (url, options) => {
|
4743
|
-
if (url in
|
4216
|
+
if (url in preloadedContexts) {
|
4744
4217
|
logger.debug("Using preloaded context: {url}.", { url });
|
4745
4218
|
return {
|
4746
4219
|
contextUrl: null,
|
4747
|
-
document:
|
4220
|
+
document: preloadedContexts[url],
|
4748
4221
|
documentUrl: url
|
4749
4222
|
};
|
4750
4223
|
}
|
4751
|
-
const match = matchRule(url);
|
4224
|
+
const match = matchRule(url, rules);
|
4752
4225
|
if (match == null) return await loader(url, options);
|
4753
4226
|
const key = [...keyPrefix, url];
|
4754
4227
|
let cache = void 0;
|
@@ -4775,21 +4248,20 @@ function kvCache({ loader, kv, prefix, rules }) {
|
|
4775
4248
|
return cache;
|
4776
4249
|
};
|
4777
4250
|
}
|
4778
|
-
|
4779
|
-
|
4780
|
-
|
4781
|
-
|
4782
|
-
|
4783
|
-
|
4784
|
-
|
4785
|
-
|
4786
|
-
|
4787
|
-
|
4788
|
-
|
4789
|
-
|
4790
|
-
|
4791
|
-
return `${first} (${userAgent.join("; ")})`;
|
4251
|
+
function matchRule(url, rules) {
|
4252
|
+
for (const [pattern, duration] of rules) {
|
4253
|
+
if (typeof pattern === "string") {
|
4254
|
+
if (url === pattern) return duration;
|
4255
|
+
continue;
|
4256
|
+
}
|
4257
|
+
if (pattern instanceof URL) {
|
4258
|
+
if (pattern.href == url) return duration;
|
4259
|
+
continue;
|
4260
|
+
}
|
4261
|
+
if (pattern.test(url)) return duration;
|
4262
|
+
}
|
4263
|
+
return null;
|
4792
4264
|
}
|
4793
4265
|
|
4794
4266
|
//#endregion
|
4795
|
-
export {
|
4267
|
+
export { getAuthenticatedDocumentLoader, kvCache };
|