@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.
Files changed (140) hide show
  1. package/deno.json +4 -2
  2. package/dist/{tests/docloader-Xi61Le8w.mjs → contexts-BK1CqBR5.cjs} +164 -269
  3. package/dist/{tests/docloader-BFedvemb.cjs → contexts-DPuJ4UYL.js} +160 -288
  4. package/dist/{docloader-DnUMWHaJ.d.cts → docloader-CYwqh5Df.d.cts} +68 -2
  5. package/dist/{docloader-xRGn1azD.d.ts → docloader-CYwqh5Df.d.ts} +68 -2
  6. package/dist/internal/jsonld-cache.cjs +70 -1
  7. package/dist/internal/jsonld-cache.d.cts +35 -2
  8. package/dist/internal/jsonld-cache.d.ts +35 -2
  9. package/dist/internal/jsonld-cache.js +67 -2
  10. package/dist/internal/portable-dereference.cjs +721 -0
  11. package/dist/internal/portable-dereference.d.cts +349 -0
  12. package/dist/internal/portable-dereference.d.ts +349 -0
  13. package/dist/internal/portable-dereference.js +702 -0
  14. package/dist/internal/signed-representation.cjs +378 -0
  15. package/dist/internal/signed-representation.d.cts +144 -0
  16. package/dist/internal/signed-representation.d.ts +144 -0
  17. package/dist/internal/signed-representation.js +371 -0
  18. package/dist/jsonld.cjs +2 -2
  19. package/dist/mod.cjs +715 -4523
  20. package/dist/mod.d.cts +406 -6
  21. package/dist/mod.d.ts +406 -7
  22. package/dist/mod.js +694 -4518
  23. package/dist/portable-DqtfLy_1.d.cts +160 -0
  24. package/dist/portable-DtWsu2yU.d.ts +160 -0
  25. package/dist/tests/body-CYiu9CO-.mjs +130 -0
  26. package/dist/tests/body-CkEwROsn.cjs +153 -0
  27. package/dist/tests/body.test.cjs +89 -0
  28. package/dist/tests/body.test.d.cts +1 -0
  29. package/dist/tests/body.test.d.mts +1 -0
  30. package/dist/tests/body.test.mjs +90 -0
  31. package/dist/tests/contexts-CIKsin4e.mjs +4512 -0
  32. package/dist/tests/contexts-DizzBjz4.cjs +4523 -0
  33. package/dist/tests/decimal.test.cjs +8 -7
  34. package/dist/tests/decimal.test.mjs +8 -6
  35. package/dist/tests/digest-3FeH2Y-Q.cjs +176 -0
  36. package/dist/tests/digest-COC7xDiQ.mjs +141 -0
  37. package/dist/tests/digest.test.cjs +102 -0
  38. package/dist/tests/digest.test.d.cts +1 -0
  39. package/dist/tests/digest.test.d.mts +1 -0
  40. package/dist/tests/digest.test.mjs +103 -0
  41. package/dist/tests/docloader-C3YFl6y4.cjs +396 -0
  42. package/dist/tests/docloader-CvmS4sVq.mjs +373 -0
  43. package/dist/tests/docloader.test.cjs +692 -39
  44. package/dist/tests/docloader.test.mjs +686 -34
  45. package/dist/tests/internal/multicodec.test.cjs +2 -3
  46. package/dist/tests/internal/multicodec.test.mjs +2 -2
  47. package/dist/tests/internal/portable-dereference.test.cjs +172 -0
  48. package/dist/tests/internal/portable-dereference.test.d.cts +1 -0
  49. package/dist/tests/internal/portable-dereference.test.d.mts +1 -0
  50. package/dist/tests/internal/portable-dereference.test.mjs +173 -0
  51. package/dist/tests/jsonld-cache-BPQmOZWD.mjs +342 -0
  52. package/dist/tests/jsonld-cache-C07AyNOY.cjs +397 -0
  53. package/dist/tests/jsonld-cache.test.cjs +101 -298
  54. package/dist/tests/jsonld-cache.test.mjs +94 -289
  55. package/dist/tests/{key-_wXwomh_.cjs → key-C-AYkdJJ.cjs} +11 -4
  56. package/dist/tests/{key-CDGDH_vC.mjs → key-C2Db_TAJ.mjs} +11 -3
  57. package/dist/tests/key.test.cjs +6 -5
  58. package/dist/tests/key.test.mjs +6 -4
  59. package/dist/tests/langstr.test.cjs +4 -4
  60. package/dist/tests/langstr.test.mjs +2 -2
  61. package/dist/tests/link.test.cjs +2 -3
  62. package/dist/tests/link.test.mjs +2 -2
  63. package/dist/tests/multibase/multibase.test.cjs +8 -9
  64. package/dist/tests/multibase/multibase.test.mjs +6 -6
  65. package/dist/tests/{multibase-Bz_UUDtL.cjs → multibase-B5Mea7Ip.cjs} +19 -2
  66. package/dist/tests/{multibase-B4bvakyA.mjs → multibase-BPnF_L4e.mjs} +12 -1
  67. package/dist/tests/portable-dereference-BNXtgg5U.cjs +278 -0
  68. package/dist/tests/portable-dereference-DRE5bz-l.mjs +249 -0
  69. package/dist/tests/portable-media-BLKllU56.cjs +153 -0
  70. package/dist/tests/portable-media-DRSGBORB.mjs +148 -0
  71. package/dist/tests/portable-media.test.cjs +222 -0
  72. package/dist/tests/portable-media.test.d.cts +1 -0
  73. package/dist/tests/portable-media.test.d.mts +1 -0
  74. package/dist/tests/portable-media.test.mjs +223 -0
  75. package/dist/tests/portable-workers.test.cjs +36 -0
  76. package/dist/tests/portable-workers.test.d.cts +2 -0
  77. package/dist/tests/portable-workers.test.d.mts +2 -0
  78. package/dist/tests/portable-workers.test.mjs +35 -0
  79. package/dist/tests/{request-cCPgOxYG.cjs → request-8vPWtV1-.cjs} +10 -4
  80. package/dist/tests/{request-BOS-hNaf.mjs → request-DRaOaTqD.mjs} +8 -2
  81. package/dist/tests/request.test.cjs +7 -4
  82. package/dist/tests/request.test.mjs +5 -2
  83. package/dist/tests/signed-representation.test.cjs +588 -0
  84. package/dist/tests/signed-representation.test.d.cts +1 -0
  85. package/dist/tests/signed-representation.test.d.mts +1 -0
  86. package/dist/tests/signed-representation.test.mjs +589 -0
  87. package/dist/tests/temporal.test.cjs +1 -2
  88. package/dist/tests/temporal.test.mjs +1 -1
  89. package/dist/tests/url-BNakuZ8k.cjs +998 -0
  90. package/dist/tests/url-DMxmp7ZG.mjs +859 -0
  91. package/dist/tests/url.test.cjs +503 -3
  92. package/dist/tests/url.test.mjs +503 -2
  93. package/dist/url-DrGTR8yv.cjs +993 -0
  94. package/dist/url-Dzyp-NsC.js +860 -0
  95. package/package.json +27 -4
  96. package/scripts/test-bun.mjs +17 -0
  97. package/src/body.test.ts +125 -0
  98. package/src/body.ts +152 -0
  99. package/src/contexts/cid-v1.json +114 -0
  100. package/src/contexts/fep-22cd.json +21 -0
  101. package/src/contexts/fep-ef61.json +10 -0
  102. package/src/contexts/miscellany.json +17 -0
  103. package/src/contexts/security-data-integrity-v1.json +0 -4
  104. package/src/contexts.ts +40 -0
  105. package/src/digest.test.ts +220 -0
  106. package/src/digest.ts +229 -0
  107. package/src/docloader.test.ts +918 -27
  108. package/src/docloader.ts +322 -105
  109. package/src/internal/jsonld-cache.ts +97 -1
  110. package/src/internal/portable-dereference.test.ts +254 -0
  111. package/src/internal/portable-dereference.ts +1000 -0
  112. package/src/internal/signed-representation.ts +565 -0
  113. package/src/jsonld-cache.test.ts +89 -0
  114. package/src/key.test.ts +9 -0
  115. package/src/key.ts +11 -1
  116. package/src/mod.ts +30 -0
  117. package/src/multibase/multibase.test.ts +5 -5
  118. package/src/portable-media.test.ts +293 -0
  119. package/src/portable-media.ts +264 -0
  120. package/src/portable-workers.test.ts +81 -0
  121. package/src/portable.ts +180 -0
  122. package/src/preprocessor.ts +7 -0
  123. package/src/request.test.ts +10 -1
  124. package/src/request.ts +9 -1
  125. package/src/signed-representation.test.ts +338 -0
  126. package/src/url.test.ts +844 -1
  127. package/src/url.ts +717 -17
  128. package/tsdown.config.ts +2 -0
  129. package/dist/tests/url-BvjYQdxL.cjs +0 -456
  130. package/dist/tests/url-a2D8NAgh.mjs +0 -378
  131. package/dist/url-Ck3dGEwH.cjs +0 -457
  132. package/dist/url-m1YxGNZ0.js +0 -379
  133. /package/dist/{chunk-M78iaK0I.cjs → rolldown-runtime-B7lfambq.cjs} +0 -0
  134. /package/dist/tests/{langstr-CbAxaeEZ.cjs → langstr-C4Fl80ae.cjs} +0 -0
  135. /package/dist/tests/{langstr-Di5AvKpB.mjs → langstr-CQ26J_L7.mjs} +0 -0
  136. /package/dist/tests/{link-NUUWCdnK.mjs → link-Cevmc87v.mjs} +0 -0
  137. /package/dist/tests/{link-FguCydMA.cjs → link-DlKm8bEr.cjs} +0 -0
  138. /package/dist/tests/{multicodec-CxGVGa91.cjs → multicodec-CLRPeW4N.cjs} +0 -0
  139. /package/dist/tests/{multicodec-CyFp54fI.mjs → multicodec-CRIj_05H.mjs} +0 -0
  140. /package/dist/tests/{chunk-C2EiDwsr.cjs → rolldown-runtime-emK7D4bc.cjs} +0 -0
package/deno.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@fedify/vocab-runtime",
3
- "version": "2.4.0-pr.934.40+3331d302",
3
+ "version": "2.4.0",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./src/mod.ts",
7
7
  "./internal/jsonld-cache": "./src/internal/jsonld-cache.ts",
8
+ "./internal/portable-dereference": "./src/internal/portable-dereference.ts",
9
+ "./internal/signed-representation": "./src/internal/signed-representation.ts",
8
10
  "./jsonld": "./src/jsonld.ts",
9
11
  "./temporal": "./src/temporal.ts"
10
12
  },
@@ -34,6 +36,6 @@
34
36
  },
35
37
  "tasks": {
36
38
  "check": "deno fmt --check && deno lint && deno check src/*.ts",
37
- "test": "deno test"
39
+ "test": "deno test --allow-net --allow-env=LOG"
38
40
  }
39
41
  }
@@ -1,8 +1,4 @@
1
- import { a as name, i as logRequest, n as createActivityPubRequest, o as version, t as FetchError } from "./request-BOS-hNaf.mjs";
2
- import { t as HttpHeaderLink } from "./link-NUUWCdnK.mjs";
3
- import { p as validatePublicUrl, t as UrlError } from "./url-a2D8NAgh.mjs";
4
- import { getLogger } from "@logtape/logtape";
5
- import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
1
+
6
2
  //#endregion
7
3
  //#region src/contexts.ts
8
4
  const preloadedContexts = {
@@ -459,10 +455,6 @@ const preloadedContexts = {
459
455
  "id": "@id",
460
456
  "type": "@type",
461
457
  "@protected": true,
462
- "digestMultibase": {
463
- "@id": "https://w3id.org/security#digestMultibase",
464
- "@type": "https://w3id.org/security#multibase"
465
- },
466
458
  "proof": {
467
459
  "@id": "https://w3id.org/security#proof",
468
460
  "@type": "@id",
@@ -4243,6 +4235,34 @@ const preloadedContexts = {
4243
4235
  "@type": "@id"
4244
4236
  }
4245
4237
  } },
4238
+ "https://w3id.org/fep/22cd": { "@context": {
4239
+ "fep-22cd": "https://w3id.org/fep/22cd#",
4240
+ "schema": "https://schema.org/",
4241
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
4242
+ "translations": {
4243
+ "@id": "fep-22cd:translations",
4244
+ "@container": "@set"
4245
+ },
4246
+ "Translation": "fep-22cd:Translation",
4247
+ "sourceUpdated": {
4248
+ "@id": "fep-22cd:sourceUpdated",
4249
+ "@type": "xsd:dateTime"
4250
+ },
4251
+ "translator": {
4252
+ "@id": "schema:translator",
4253
+ "@type": "@id",
4254
+ "@container": "@set"
4255
+ },
4256
+ "inLanguage": "schema:inLanguage",
4257
+ "translationOfWork": {
4258
+ "@id": "schema:translationOfWork",
4259
+ "@type": "@id"
4260
+ },
4261
+ "isBasedOn": {
4262
+ "@id": "schema:isBasedOn",
4263
+ "@type": "@id"
4264
+ }
4265
+ } },
4246
4266
  "https://w3id.org/fep/5711": { "@context": {
4247
4267
  "likesOf": {
4248
4268
  "@id": "https://w3id.org/fep/5711#likesOf",
@@ -4277,6 +4297,125 @@ const preloadedContexts = {
4277
4297
  "@type": "@id"
4278
4298
  }
4279
4299
  } },
4300
+ "https://www.w3.org/ns/cid/v1": { "@context": {
4301
+ "@protected": true,
4302
+ "id": "@id",
4303
+ "type": "@type",
4304
+ "alsoKnownAs": {
4305
+ "@id": "https://www.w3.org/ns/activitystreams#alsoKnownAs",
4306
+ "@type": "@id"
4307
+ },
4308
+ "assertionMethod": {
4309
+ "@id": "https://w3id.org/security#assertionMethod",
4310
+ "@type": "@id",
4311
+ "@container": "@set"
4312
+ },
4313
+ "authentication": {
4314
+ "@id": "https://w3id.org/security#authenticationMethod",
4315
+ "@type": "@id",
4316
+ "@container": "@set"
4317
+ },
4318
+ "capabilityDelegation": {
4319
+ "@id": "https://w3id.org/security#capabilityDelegationMethod",
4320
+ "@type": "@id",
4321
+ "@container": "@set"
4322
+ },
4323
+ "capabilityInvocation": {
4324
+ "@id": "https://w3id.org/security#capabilityInvocationMethod",
4325
+ "@type": "@id",
4326
+ "@container": "@set"
4327
+ },
4328
+ "controller": {
4329
+ "@id": "https://w3id.org/security#controller",
4330
+ "@type": "@id"
4331
+ },
4332
+ "keyAgreement": {
4333
+ "@id": "https://w3id.org/security#keyAgreementMethod",
4334
+ "@type": "@id",
4335
+ "@container": "@set"
4336
+ },
4337
+ "service": {
4338
+ "@id": "https://www.w3.org/ns/did#service",
4339
+ "@type": "@id",
4340
+ "@context": {
4341
+ "@protected": true,
4342
+ "id": "@id",
4343
+ "type": "@type",
4344
+ "serviceEndpoint": {
4345
+ "@id": "https://www.w3.org/ns/did#serviceEndpoint",
4346
+ "@type": "@id"
4347
+ }
4348
+ }
4349
+ },
4350
+ "verificationMethod": {
4351
+ "@id": "https://w3id.org/security#verificationMethod",
4352
+ "@type": "@id"
4353
+ },
4354
+ "Multikey": {
4355
+ "@id": "https://w3id.org/security#Multikey",
4356
+ "@context": {
4357
+ "@protected": true,
4358
+ "id": "@id",
4359
+ "type": "@type",
4360
+ "controller": {
4361
+ "@id": "https://w3id.org/security#controller",
4362
+ "@type": "@id"
4363
+ },
4364
+ "revoked": {
4365
+ "@id": "https://w3id.org/security#revoked",
4366
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
4367
+ },
4368
+ "expires": {
4369
+ "@id": "https://w3id.org/security#expiration",
4370
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
4371
+ },
4372
+ "publicKeyMultibase": {
4373
+ "@id": "https://w3id.org/security#publicKeyMultibase",
4374
+ "@type": "https://w3id.org/security#multibase"
4375
+ },
4376
+ "secretKeyMultibase": {
4377
+ "@id": "https://w3id.org/security#secretKeyMultibase",
4378
+ "@type": "https://w3id.org/security#multibase"
4379
+ }
4380
+ }
4381
+ },
4382
+ "JsonWebKey": {
4383
+ "@id": "https://w3id.org/security#JsonWebKey",
4384
+ "@context": {
4385
+ "@protected": true,
4386
+ "id": "@id",
4387
+ "type": "@type",
4388
+ "controller": {
4389
+ "@id": "https://w3id.org/security#controller",
4390
+ "@type": "@id"
4391
+ },
4392
+ "revoked": {
4393
+ "@id": "https://w3id.org/security#revoked",
4394
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
4395
+ },
4396
+ "expires": {
4397
+ "@id": "https://w3id.org/security#expiration",
4398
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
4399
+ },
4400
+ "publicKeyJwk": {
4401
+ "@id": "https://w3id.org/security#publicKeyJwk",
4402
+ "@type": "@json"
4403
+ },
4404
+ "secretKeyJwk": {
4405
+ "@id": "https://w3id.org/security#secretKeyJwk",
4406
+ "@type": "@json"
4407
+ }
4408
+ }
4409
+ }
4410
+ } },
4411
+ "https://w3id.org/fep/ef61": { "@context": {
4412
+ "gateways": {
4413
+ "@id": "https://w3id.org/fep/ef61/gateways",
4414
+ "@type": "@id",
4415
+ "@container": "@list"
4416
+ },
4417
+ "digestMultibase": "https://www.w3.org/ns/credentials/v2#digestMultibase"
4418
+ } },
4280
4419
  "https://w3id.org/fep/7aa9": { "@context": {
4281
4420
  "FeaturedCollection": "https://w3id.org/fep/7aa9#FeaturedCollection",
4282
4421
  "FeaturedItem": "https://w3id.org/fep/7aa9#FeaturedItem",
@@ -4352,267 +4491,23 @@ const preloadedContexts = {
4352
4491
  "@id": "toot:attributionDomains",
4353
4492
  "@type": "@id"
4354
4493
  }
4494
+ } },
4495
+ "https://purl.archive.org/miscellany": { "@context": {
4496
+ "as": "https://www.w3.org/ns/activitystreams#",
4497
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
4498
+ "Hashtag": "as:Hashtag",
4499
+ "manuallyApprovesFollowers": { "@id": "as:manuallyApprovesFollowers" },
4500
+ "movedTo": {
4501
+ "@id": "as:movedTo",
4502
+ "@type": "@id"
4503
+ },
4504
+ "sensitive": { "@id": "as:sensitive" }
4355
4505
  } }
4356
4506
  };
4357
4507
  //#endregion
4358
- //#region src/docloader.ts
4359
- const logger = getLogger([
4360
- "fedify",
4361
- "runtime",
4362
- "docloader"
4363
- ]);
4364
- const DEFAULT_MAX_REDIRECTION = 20;
4365
- const MAX_HTML_SIZE = 1024 * 1024;
4366
- function createResponseMetadata(response) {
4367
- return new Response(null, {
4368
- headers: response.headers,
4369
- status: response.status,
4370
- statusText: response.statusText
4371
- });
4372
- }
4373
- async function cancelResponseBody(response) {
4374
- if (response.body != null) await response.body.cancel();
4375
- }
4376
- async function readBoundedText(response, maxBytes) {
4377
- const contentLength = response.headers.get("Content-Length");
4378
- if (contentLength != null) {
4379
- const size = Number(contentLength);
4380
- if (size > maxBytes) {
4381
- await cancelResponseBody(response);
4382
- return {
4383
- text: "",
4384
- size,
4385
- tooLarge: true
4386
- };
4387
- }
4388
- }
4389
- if (response.body == null) return {
4390
- text: "",
4391
- size: 0,
4392
- tooLarge: false
4393
- };
4394
- const reader = response.body.getReader();
4395
- const decoder = new TextDecoder();
4396
- let text = "";
4397
- let size = 0;
4398
- try {
4399
- while (true) {
4400
- const result = await reader.read();
4401
- if (result.done) break;
4402
- const chunkSize = result.value.byteLength;
4403
- if (size + chunkSize > maxBytes) {
4404
- size += chunkSize;
4405
- await reader.cancel();
4406
- return {
4407
- text: "",
4408
- size,
4409
- tooLarge: true
4410
- };
4411
- }
4412
- size += chunkSize;
4413
- text += decoder.decode(result.value, { stream: true });
4414
- }
4415
- text += decoder.decode();
4416
- return {
4417
- text,
4418
- size,
4419
- tooLarge: false
4420
- };
4421
- } finally {
4422
- reader.releaseLock();
4423
- }
4424
- }
4425
- /**
4426
- * Gets a {@link RemoteDocument} from the given response.
4427
- * @param url The URL of the document to load.
4428
- * @param response The response to get the document from.
4429
- * @param fetch The function to fetch the document.
4430
- * @returns The loaded remote document.
4431
- * @throws {FetchError} If the response is not OK.
4432
- * @internal
4433
- */
4434
- async function getRemoteDocument(url, response, fetch) {
4435
- const documentUrl = response.url === "" ? url : response.url;
4436
- const docUrl = new URL(documentUrl);
4437
- if (!response.ok) {
4438
- logger.error("Failed to fetch document: {status} {url} {headers}", {
4439
- status: response.status,
4440
- url: documentUrl,
4441
- headers: Object.fromEntries(response.headers.entries())
4442
- });
4443
- throw new FetchError(documentUrl, `HTTP ${response.status}: ${documentUrl}`, response.clone());
4508
+ Object.defineProperty(exports, "preloadedContexts", {
4509
+ enumerable: true,
4510
+ get: function() {
4511
+ return preloadedContexts;
4444
4512
  }
4445
- const contentType = response.headers.get("Content-Type");
4446
- const jsonLd = contentType == null || contentType === "application/activity+json" || contentType.startsWith("application/activity+json;") || contentType === "application/ld+json" || contentType.startsWith("application/ld+json;");
4447
- const linkHeader = response.headers.get("Link");
4448
- let contextUrl = null;
4449
- if (linkHeader != null) {
4450
- let link;
4451
- try {
4452
- link = new HttpHeaderLink(linkHeader);
4453
- } catch (e) {
4454
- if (e instanceof SyntaxError) link = new HttpHeaderLink();
4455
- else throw e;
4456
- }
4457
- if (jsonLd) {
4458
- const entries = link.getByRel("http://www.w3.org/ns/json-ld#context");
4459
- for (const [uri, params] of entries) if ("type" in params && params.type === "application/ld+json") {
4460
- contextUrl = uri;
4461
- break;
4462
- }
4463
- } else {
4464
- const entries = link.getByRel("alternate");
4465
- for (const [uri, params] of entries) {
4466
- const altUri = new URL(uri, docUrl);
4467
- if ("type" in params && (params.type === "application/activity+json" || params.type === "application/ld+json" || params.type.startsWith("application/ld+json;")) && altUri.href !== docUrl.href) {
4468
- logger.debug("Found alternate document: {alternateUrl} from {url}", {
4469
- alternateUrl: altUri.href,
4470
- url: documentUrl
4471
- });
4472
- return await fetch(altUri.href);
4473
- }
4474
- }
4475
- }
4476
- }
4477
- let document;
4478
- if (!jsonLd && (contentType === "text/html" || contentType?.startsWith("text/html;") || contentType === "application/xhtml+xml" || contentType?.startsWith("application/xhtml+xml;"))) {
4479
- const errorResponse = createResponseMetadata(response);
4480
- const html = await readBoundedText(response, MAX_HTML_SIZE);
4481
- if (html.tooLarge) {
4482
- logger.warn("HTML response too large, skipping alternate link discovery: {url}", {
4483
- url: documentUrl,
4484
- size: html.size
4485
- });
4486
- throw new FetchError(documentUrl, `HTML document is too large to scan for an ActivityPub alternate link (Content-Type: ${contentType})`, errorResponse);
4487
- } else {
4488
- const tagPattern = /<(a|link)\s+([^>]*?)\s*\/?>/gi;
4489
- const attrPattern = /([a-z][a-z:_-]*)=(?:"([^"]*)"|'([^']*)'|([^\s>]+))/gi;
4490
- let tagMatch;
4491
- while ((tagMatch = tagPattern.exec(html.text)) !== null) {
4492
- const tagContent = tagMatch[2];
4493
- let attrMatch;
4494
- const attribs = {};
4495
- attrPattern.lastIndex = 0;
4496
- while ((attrMatch = attrPattern.exec(tagContent)) !== null) {
4497
- const key = attrMatch[1].toLowerCase();
4498
- attribs[key] = attrMatch[2] ?? attrMatch[3] ?? attrMatch[4] ?? "";
4499
- }
4500
- 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) {
4501
- logger.debug("Found alternate document: {alternateUrl} from {url}", {
4502
- alternateUrl: attribs.href,
4503
- url: documentUrl
4504
- });
4505
- return await fetch(new URL(attribs.href, docUrl).href);
4506
- }
4507
- }
4508
- try {
4509
- document = JSON.parse(html.text);
4510
- } catch (error) {
4511
- if (!(error instanceof SyntaxError)) throw error;
4512
- throw new FetchError(documentUrl, `HTML document has no ActivityPub alternate link (Content-Type: ${contentType})`, errorResponse);
4513
- }
4514
- }
4515
- } else document = await response.json();
4516
- logger.debug("Fetched document: {status} {url} {headers}", {
4517
- status: response.status,
4518
- url: documentUrl,
4519
- headers: Object.fromEntries(response.headers.entries())
4520
- });
4521
- return {
4522
- contextUrl,
4523
- document,
4524
- documentUrl
4525
- };
4526
- }
4527
- /**
4528
- * Creates a JSON-LD document loader that utilizes the browser's `fetch` API.
4529
- *
4530
- * The created loader preloads the below frequently used contexts by default
4531
- * (unless `options.skipPreloadedContexts` is set to `true`):
4532
- *
4533
- * - <https://www.w3.org/ns/activitystreams>
4534
- * - <https://w3id.org/security/v1>
4535
- * - <https://w3id.org/security/data-integrity/v1>
4536
- * - <https://www.w3.org/ns/did/v1>
4537
- * - <https://w3id.org/security/multikey/v1>
4538
- * - <https://purl.archive.org/socialweb/webfinger>
4539
- * - <http://schema.org/>
4540
- * @param options Options for the document loader.
4541
- * @returns The document loader.
4542
- * @since 1.3.0
4543
- */
4544
- function getDocumentLoader({ allowPrivateAddress, maxRedirection, skipPreloadedContexts, userAgent } = {}) {
4545
- const tracer = trace.getTracerProvider().getTracer(name, version);
4546
- const maximumRedirection = maxRedirection ?? DEFAULT_MAX_REDIRECTION;
4547
- async function load(url, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
4548
- options?.signal?.throwIfAborted();
4549
- const currentUrl = new URL(url).href;
4550
- if (!skipPreloadedContexts && currentUrl in preloadedContexts) {
4551
- logger.debug("Using preloaded context: {url}.", { url: currentUrl });
4552
- return {
4553
- contextUrl: null,
4554
- document: preloadedContexts[currentUrl],
4555
- documentUrl: currentUrl
4556
- };
4557
- }
4558
- if (!allowPrivateAddress) try {
4559
- await validatePublicUrl(currentUrl);
4560
- } catch (error) {
4561
- if (error instanceof UrlError) logger.error("Disallowed private URL: {url}", {
4562
- url: currentUrl,
4563
- error
4564
- });
4565
- throw error;
4566
- }
4567
- visited.add(currentUrl);
4568
- return await tracer.startActiveSpan("activitypub.fetch_document", {
4569
- kind: SpanKind.CLIENT,
4570
- attributes: { "url.full": currentUrl }
4571
- }, async (span) => {
4572
- try {
4573
- const request = createActivityPubRequest(currentUrl, { userAgent });
4574
- logRequest(logger, request);
4575
- const response = await fetch(request, {
4576
- redirect: "manual",
4577
- signal: options?.signal
4578
- });
4579
- span.setAttribute("http.response.status_code", response.status);
4580
- if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
4581
- if (redirected >= maximumRedirection) {
4582
- logger.error("Too many redirections ({redirections}) while fetching document.", {
4583
- redirections: redirected + 1,
4584
- url: currentUrl
4585
- });
4586
- throw new FetchError(currentUrl, `Too many redirections (${redirected + 1})`);
4587
- }
4588
- const redirectUrl = new URL(response.headers.get("Location"), response.url === "" ? currentUrl : response.url).href;
4589
- span.setAttribute("http.redirect.url", redirectUrl);
4590
- if (visited.has(redirectUrl)) {
4591
- logger.error("Detected a redirect loop while fetching document: {url} -> {redirectUrl}", {
4592
- url: currentUrl,
4593
- redirectUrl
4594
- });
4595
- throw new FetchError(currentUrl, `Redirect loop detected: ${redirectUrl}`);
4596
- }
4597
- return await load(redirectUrl, options, redirected + 1, visited);
4598
- }
4599
- const result = await getRemoteDocument(currentUrl, response, load);
4600
- span.setAttribute("docloader.document_url", result.documentUrl);
4601
- if (result.contextUrl != null) span.setAttribute("docloader.context_url", result.contextUrl);
4602
- return result;
4603
- } catch (error) {
4604
- span.recordException(error);
4605
- span.setStatus({
4606
- code: SpanStatusCode.ERROR,
4607
- message: String(error)
4608
- });
4609
- throw error;
4610
- } finally {
4611
- span.end();
4612
- }
4613
- });
4614
- }
4615
- return load;
4616
- }
4617
- //#endregion
4618
- export { getRemoteDocument as n, preloadedContexts as r, getDocumentLoader as t };
4513
+ });