@fedify/fedify 2.0.0-pr.449.1725 → 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.
Files changed (193) hide show
  1. package/dist/{actor-T6RyhRgk.d.ts → actor-Cd2CREO0.d.ts} +2 -2
  2. package/dist/{actor-VrXd7EdX.js → actor-Cg8ZhoVF.js} +1 -1
  3. package/dist/{actor-CsRJa7wV.cjs → actor-D020hlx3.cjs} +922 -1451
  4. package/dist/{actor-D6K058Tb.d.cts → actor-DDhZuMGl.d.cts} +2 -2
  5. package/dist/{actor-C0gLJq8I.js → actor-DPD6Gbdn.js} +190 -677
  6. package/dist/{assert_rejects-DiIiJbZn.js → assert_rejects-Ce45JcFg.js} +1 -1
  7. package/dist/{assert_is_error-BPGph1Jx.js → assert_throws-BNXdRGWP.js} +31 -1
  8. package/dist/{builder-JjsppXTK.js → builder-Dn87hy75.js} +3 -4
  9. package/dist/{client-bgSdkFa2.d.ts → client-Bkaw0_PR.d.ts} +1 -1
  10. package/dist/{client-CegPX0Rn.d.cts → client-Cle5j1T1.d.cts} +1 -1
  11. package/dist/{client-BS-GE3XI.js → client-D6-5okV1.js} +1 -1
  12. package/dist/compat/mod.d.cts +11 -11
  13. package/dist/compat/mod.d.ts +12 -12
  14. package/dist/compat/transformers.test.js +20 -20
  15. package/dist/{context-DYCJXr7J.d.cts → context-BOYzcFSe.d.cts} +10 -10
  16. package/dist/{context-B1X8-X33.d.ts → context-DqFifMwj.d.ts} +11 -11
  17. package/dist/{authdocloader-C8LXxsmU.js → docloader-B2BFBGqv.js} +18 -8
  18. package/dist/{esm-CvUgdJZ_.js → esm-CU0Dnk7T.js} +11 -11
  19. package/dist/federation/builder.test.js +8 -10
  20. package/dist/federation/collection.test.js +7 -9
  21. package/dist/federation/handler.test.js +25 -26
  22. package/dist/federation/idempotency.test.js +25 -26
  23. package/dist/federation/inbox.test.js +4 -6
  24. package/dist/federation/keycache.test.js +3 -4
  25. package/dist/federation/kv.test.js +6 -8
  26. package/dist/federation/middleware.test.js +26 -27
  27. package/dist/federation/mod.cjs +10 -11
  28. package/dist/federation/mod.d.cts +10 -10
  29. package/dist/federation/mod.d.ts +12 -12
  30. package/dist/federation/mod.js +10 -11
  31. package/dist/federation/mq.test.js +8 -10
  32. package/dist/federation/negotiation.test.js +7 -9
  33. package/dist/federation/retry.test.js +4 -5
  34. package/dist/federation/router.test.js +6 -8
  35. package/dist/federation/send.test.js +13 -15
  36. package/dist/{http-D-e6AFwR.d.cts → http-B6SKO6NJ.d.cts} +2 -2
  37. package/dist/{http-D6Uj2x2y.d.ts → http-BE7aFuqn.d.ts} +2 -2
  38. package/dist/{http-D_BI5KHC.cjs → http-DMsjudj8.cjs} +289 -9
  39. package/dist/{http-DbyMqL2X.js → http-DN0v2zoF.js} +2 -2
  40. package/dist/{http-DVQEn98K.js → http-DcDb8r1W.js} +256 -6
  41. package/dist/{inbox-DQlf_-Dz.js → inbox-CgGy7Hzc.js} +1 -1
  42. package/dist/{key-BSJX6n9o.js → key-jSvnymAk.js} +3 -2
  43. package/dist/{keycache-CcIfdj0m.js → keycache-IVLjlAK9.js} +1 -1
  44. package/dist/{keys-DnSaJmvD.js → keys-BKM2Mqu2.js} +2 -1
  45. package/dist/{docloader-BdF5STdg.cjs → kv-cache-BHIupktM.cjs} +69 -651
  46. package/dist/kv-cache-DNvS-egZ.js +4236 -0
  47. package/dist/{docloader-AMdJU291.js → kv-cache-ydIs4Ul6.js} +68 -596
  48. package/dist/{ld-CAJ6Q2od.js → ld-CcsryBo0.js} +3 -2
  49. package/dist/{lookup-BGCuyJRy.js → lookup-BV3A9Zbc.js} +63 -2
  50. package/dist/{type-COb6KNlm.js → lookup-BbEekiru.js} +588 -5303
  51. package/dist/{lookup-B2Bsau2g.cjs → lookup-CMAGfQ1Q.cjs} +78 -5
  52. package/dist/{middleware-1oxZY_0z.js → middleware-D-vPitR-.js} +11 -11
  53. package/dist/{middleware-BDqkoMAQ.js → middleware-Dm8sXYUr.js} +18 -17
  54. package/dist/middleware-DzA970CF.js +16 -0
  55. package/dist/middleware-VpoC5jyA.js +26 -0
  56. package/dist/middleware-W_-inBoE.cjs +16 -0
  57. package/dist/{middleware-D0XMPoN8.cjs → middleware-ekn2KaOw.cjs} +31 -31
  58. package/dist/{mod-CxkWO3Mg.d.cts → mod--K7l84wp.d.cts} +3 -2
  59. package/dist/{mod-DBzN0aCM.d.ts → mod-CB80AlIA.d.ts} +1 -1
  60. package/dist/mod-CLKu6Uo_.d.cts +107 -0
  61. package/dist/{mod-Djzcw2ry.d.cts → mod-COlOrmr9.d.cts} +3 -3
  62. package/dist/{mod-DlU8ISoa.d.ts → mod-CRENK2dd.d.ts} +3 -2
  63. package/dist/{mod-DcKxhFQ8.d.ts → mod-CaWbCg0N.d.ts} +2 -2
  64. package/dist/mod-Cm97bAiT.d.ts +109 -0
  65. package/dist/{mod-twdvV2hR.d.cts → mod-D9XZsft2.d.cts} +2 -2
  66. package/dist/{mod-BhUKmBJD.d.ts → mod-DLIidI_j.d.ts} +3 -3
  67. package/dist/{mod-jQ4OODsl.d.cts → mod-DuclhZjh.d.cts} +1 -1
  68. package/dist/mod.cjs +21 -32
  69. package/dist/mod.d.cts +14 -14
  70. package/dist/mod.d.ts +17 -17
  71. package/dist/mod.js +15 -16
  72. package/dist/nodeinfo/client.test.js +8 -10
  73. package/dist/nodeinfo/handler.test.js +24 -25
  74. package/dist/nodeinfo/mod.cjs +3 -3
  75. package/dist/nodeinfo/mod.d.cts +2 -3
  76. package/dist/nodeinfo/mod.d.ts +3 -4
  77. package/dist/nodeinfo/mod.js +3 -3
  78. package/dist/nodeinfo/types.test.js +7 -9
  79. package/dist/{owner-hd9lvQcP.d.ts → owner-CktUdA0h.d.ts} +3 -3
  80. package/dist/{owner-BN_tO3cY.d.cts → owner-dkg5OpSC.d.cts} +3 -3
  81. package/dist/{owner-CaIfLBwg.js → owner-n5c_oZ_M.js} +3 -2
  82. package/dist/{proof-CKXppjee.js → proof-CLwByIT1.js} +5 -4
  83. package/dist/{proof-AhyVJcNZ.cjs → proof-CZfrp13P.cjs} +17 -16
  84. package/dist/{proof-BQwXHakc.js → proof-CsFR7fiS.js} +2 -2
  85. package/dist/request-BbHkedIU.d.cts +35 -0
  86. package/dist/request-DKGQaofB.js +184 -0
  87. package/dist/request-U1t6zZtk.d.ts +39 -0
  88. package/dist/request-XHWUW2bi.cjs +208 -0
  89. package/dist/{send-DQd3R1Oc.js → send-eW9JIzQV.js} +2 -2
  90. package/dist/sig/http.test.js +12 -13
  91. package/dist/sig/key.test.js +9 -11
  92. package/dist/sig/ld.test.js +8 -10
  93. package/dist/sig/mod.cjs +10 -11
  94. package/dist/sig/mod.d.cts +6 -7
  95. package/dist/sig/mod.d.ts +6 -7
  96. package/dist/sig/mod.js +6 -7
  97. package/dist/sig/owner.test.js +10 -12
  98. package/dist/sig/proof.test.js +13 -14
  99. package/dist/testing/docloader.test.js +6 -8
  100. package/dist/testing/mod.d.ts +3 -62
  101. package/dist/testing/mod.js +2 -3
  102. package/dist/{testing-BljKU-GG.js → testing-ClYSmXdi.js} +1 -2
  103. package/dist/{types-DI0yutHB.cjs → types-BT0xc4-R.cjs} +3 -3
  104. package/dist/{types-CEn4wB51.js → types-DaPoJTSc.js} +1 -1
  105. package/dist/{runtime/authdocloader.test.js → utils/docloader.test.js} +13 -15
  106. package/dist/utils/kv-cache.test.js +208 -0
  107. package/dist/utils/mod.cjs +14 -0
  108. package/dist/utils/mod.d.cts +6 -0
  109. package/dist/utils/mod.d.ts +8 -0
  110. package/dist/utils/mod.js +12 -0
  111. package/dist/utils/request.test.js +48 -0
  112. package/dist/utils/url.test.js +41 -0
  113. package/dist/vocab/actor.test.js +8 -10
  114. package/dist/vocab/lookup.test.js +7 -9
  115. package/dist/vocab/mod.cjs +4 -4
  116. package/dist/vocab/mod.d.cts +4 -5
  117. package/dist/vocab/mod.d.ts +4 -5
  118. package/dist/vocab/mod.js +4 -4
  119. package/dist/vocab/type.test.js +2 -3
  120. package/dist/vocab/vocab.test.js +9 -10
  121. package/dist/{vocab-NZXL5Pr-.cjs → vocab-CxTuoEVd.cjs} +6 -5
  122. package/dist/{vocab-Dw1-yVGg.d.cts → vocab-DCBw44JZ.d.cts} +2 -21
  123. package/dist/{vocab-BI0Ak5lL.d.ts → vocab-ivDKb439.d.ts} +2 -21
  124. package/dist/{vocab-CkWH9P5l.js → vocab-yFT-fQBj.js} +4 -3
  125. package/dist/webfinger/handler.test.js +24 -25
  126. package/dist/webfinger/lookup.test.js +7 -9
  127. package/dist/webfinger/mod.cjs +3 -3
  128. package/dist/webfinger/mod.d.cts +2 -3
  129. package/dist/webfinger/mod.d.ts +2 -3
  130. package/dist/webfinger/mod.js +3 -3
  131. package/dist/x/cfworkers.d.cts +1 -1
  132. package/dist/x/cfworkers.d.ts +2 -2
  133. package/dist/x/cfworkers.test.js +6 -8
  134. package/dist/x/hono.d.cts +10 -10
  135. package/dist/x/hono.d.ts +11 -11
  136. package/dist/x/sveltekit.d.cts +10 -10
  137. package/dist/x/sveltekit.d.ts +11 -11
  138. package/package.json +16 -14
  139. package/dist/assert_throws-BOO88avQ.js +0 -39
  140. package/dist/authdocloader-6F9IP-VO.js +0 -52
  141. package/dist/authdocloader-BkuVo8LL.cjs +0 -58
  142. package/dist/docloader-CxWcuWqQ.d.ts +0 -221
  143. package/dist/docloader-D-MrRyHl.d.cts +0 -219
  144. package/dist/key-BBzfhQGE.js +0 -10
  145. package/dist/key-BMz_uAnc.cjs +0 -10
  146. package/dist/key-D-RgWfcf.cjs +0 -290
  147. package/dist/key-DFefr8X2.js +0 -260
  148. package/dist/key-DW2DrPGl.js +0 -10
  149. package/dist/lookup-C3pnuyiD.js +0 -331
  150. package/dist/middleware-B8WWe8Q2.js +0 -26
  151. package/dist/middleware-DipQbJmB.js +0 -17
  152. package/dist/middleware-mLaQeD_Z.cjs +0 -17
  153. package/dist/mod-CerN_Sza.d.ts +0 -104
  154. package/dist/mod-Cj1tHXBR.d.cts +0 -102
  155. package/dist/runtime/docloader.test.js +0 -522
  156. package/dist/runtime/key.test.js +0 -103
  157. package/dist/runtime/langstr.test.d.ts +0 -3
  158. package/dist/runtime/langstr.test.js +0 -39
  159. package/dist/runtime/link.test.d.ts +0 -3
  160. package/dist/runtime/link.test.js +0 -61
  161. package/dist/runtime/mod.cjs +0 -25
  162. package/dist/runtime/mod.d.cts +0 -6
  163. package/dist/runtime/mod.d.ts +0 -8
  164. package/dist/runtime/mod.js +0 -13
  165. package/dist/runtime/multibase/multibase.test.d.ts +0 -3
  166. package/dist/runtime/multibase/multibase.test.js +0 -358
  167. package/dist/runtime/url.test.js +0 -45
  168. /package/dist/{assert_not_equals-f3m3epl3.js → assert_not_equals-C80BG-_5.js} +0 -0
  169. /package/dist/{collection-CcnIw1qY.js → collection-BzWsN9pB.js} +0 -0
  170. /package/dist/{denokv-Bv33Xxea.js → denokv-CCssOzMJ.js} +0 -0
  171. /package/dist/{federation-H2_En3j5.cjs → federation-DOuZpcAw.cjs} +0 -0
  172. /package/dist/{federation-D1U8YY9t.js → federation-pZJsapBn.js} +0 -0
  173. /package/dist/{kv-63Cil1MD.d.cts → kv-BMKIFXNW.d.cts} +0 -0
  174. /package/dist/{kv-C7sopW2E.d.ts → kv-Dt06smFt.d.ts} +0 -0
  175. /package/dist/{mod-1pDWKvUL.d.ts → mod-B-ZQqbGe.d.ts} +0 -0
  176. /package/dist/{mod-g0xFzAP9.d.ts → mod-CjsiSl7_.d.ts} +0 -0
  177. /package/dist/{mq-CRGm1e_F.d.ts → mq-CPRJk4mZ.d.ts} +0 -0
  178. /package/dist/{negotiation-5NPJL6zp.js → negotiation-C4nFufNk.js} +0 -0
  179. /package/dist/{nodeinfo-DfycQ8Wf.js → nodeinfo-B0UefMXO.js} +0 -0
  180. /package/dist/{nodeinfo-Co9lJrWl.cjs → nodeinfo-ByTd7HpT.cjs} +0 -0
  181. /package/dist/{retry-D4GJ670a.js → retry-CfF8Gn4d.js} +0 -0
  182. /package/dist/{runtime-C58AJWSv.cjs → sig-DE_NC_VQ.cjs} +0 -0
  183. /package/dist/{runtime-DPYEDf-o.js → sig-Dx59zAgn.js} +0 -0
  184. /package/dist/{std__assert-X-_kMxKM.js → std__assert-DWivtrGR.js} +0 -0
  185. /package/dist/{types-BSuWJsOm.js → types-C2XVl6gj.js} +0 -0
  186. /package/dist/{runtime → utils}/docloader.test.d.ts +0 -0
  187. /package/dist/{runtime/authdocloader.test.d.ts → utils/kv-cache.test.d.ts} +0 -0
  188. /package/dist/{runtime/key.test.d.ts → utils/request.test.d.ts} +0 -0
  189. /package/dist/{runtime → utils}/url.test.d.ts +0 -0
  190. /package/dist/{sig-ByHXzqUi.cjs → utils-B6yXfxAQ.cjs} +0 -0
  191. /package/dist/{sig-Cj3tk-ig.js → utils-BXMGcmqK.js} +0 -0
  192. /package/dist/{webfinger-BjOEdFPs.cjs → webfinger-C949bxcD.cjs} +0 -0
  193. /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 process from "node:process";
7
- import { lookup } from "node:dns/promises";
8
- import { isIP } from "node:net";
9
+ import { getDocumentLoader, getRemoteDocument } from "@fedify/vocab-runtime";
10
+ import { curry } from "@fxts/core";
9
11
 
10
- //#region deno.json
11
- var name = "@fedify/fedify";
12
- var version = "2.0.0-pr.449.1725+70c3284b";
13
- var license = "MIT";
14
- var exports = {
15
- ".": "./src/mod.ts",
16
- "./compat": "./src/compat/mod.ts",
17
- "./federation": "./src/federation/mod.ts",
18
- "./nodeinfo": "./src/nodeinfo/mod.ts",
19
- "./runtime": "./src/runtime/mod.ts",
20
- "./sig": "./src/sig/mod.ts",
21
- "./testing": "./src/testing/mod.ts",
22
- "./vocab": "./src/vocab/mod.ts",
23
- "./webfinger": "./src/webfinger/mod.ts",
24
- "./x/cfworkers": "./src/x/cfworkers.ts",
25
- "./x/denokv": "./src/x/denokv.ts",
26
- "./x/fresh": "./src/x/fresh.ts",
27
- "./x/hono": "./src/x/hono.ts",
28
- "./x/sveltekit": "./src/x/sveltekit.ts"
29
- };
30
- var imports = {
31
- "@cfworker/json-schema": "npm:@cfworker/json-schema@^4.1.1",
32
- "@multiformats/base-x": "npm:@multiformats/base-x@^4.0.1",
33
- "@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0",
34
- "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@^1.27.0",
35
- "@std/assert": "jsr:@std/assert@^0.226.0",
36
- "@std/testing": "jsr:@std/testing@^0.224.0",
37
- "@std/url": "jsr:@std/url@^0.225.1",
38
- "asn1js": "npm:asn1js@^3.0.5",
39
- "byte-encodings": "npm:byte-encodings@^1.0.11",
40
- "es-toolkit": "jsr:@es-toolkit/es-toolkit@^1.39.5",
41
- "fast-check": "npm:fast-check@^3.22.0",
42
- "fetch-mock": "npm:fetch-mock@^12.5.2",
43
- "json-canon": "npm:json-canon@^1.0.1",
44
- "jsonld": "npm:jsonld@^8.3.2",
45
- "multicodec": "npm:multicodec@^3.2.1",
46
- "pkijs": "npm:pkijs@^3.2.4",
47
- "structured-field-values": "npm:structured-field-values@^2.0.4",
48
- "uri-template-router": "npm:uri-template-router@^0.0.17",
49
- "url-template": "npm:url-template@^3.1.1"
50
- };
51
- var include = ["src/vocab/vocab.ts"];
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/runtime/contexts.ts
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/runtime/link.ts
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
- "runtime",
4524
- "docloader"
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 contexts_default) {
4216
+ if (url in preloadedContexts) {
4744
4217
  logger.debug("Using preloaded context: {url}.", { url });
4745
4218
  return {
4746
4219
  contextUrl: null,
4747
- document: contexts_default[url],
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
- * Gets the user agent string for the given application and URL.
4780
- * @param options The options for making the user agent string.
4781
- * @returns The user agent string.
4782
- * @since 1.3.0
4783
- */
4784
- function getUserAgent({ software, url } = {}) {
4785
- const fedify = `Fedify/${deno_default.version}`;
4786
- const runtime = globalThis.Deno?.version?.deno != null ? `Deno/${Deno.version.deno}` : globalThis.process?.versions?.bun != null ? `Bun/${process.versions.bun}` : "navigator" in globalThis && navigator.userAgent === "Cloudflare-Workers" ? navigator.userAgent : globalThis.process?.versions?.node != null ? `Node.js/${process.versions.node}` : null;
4787
- const userAgent = software == null ? [fedify] : [software, fedify];
4788
- if (runtime != null) userAgent.push(runtime);
4789
- if (url != null) userAgent.push(`+${url.toString()}`);
4790
- const first = userAgent.shift();
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 { FetchError, UrlError, createRequest, deno_default, fetchDocumentLoader, getDocumentLoader, getRemoteDocument, getUserAgent, kvCache, logRequest, validatePublicUrl };
4267
+ export { getAuthenticatedDocumentLoader, kvCache };