@fedify/vocab 2.0.31-dev.2297 → 2.0.31-dev.2308

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/vocab",
3
- "version": "2.0.31-dev.2297+58cbc917",
3
+ "version": "2.0.31-dev.2308+34090b3a",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./src/mod.ts"
package/dist/mod.cjs CHANGED
@@ -33,7 +33,7 @@ let _fedify_vocab_runtime_temporal = require("@fedify/vocab-runtime/temporal");
33
33
  let es_toolkit = require("es-toolkit");
34
34
  //#region deno.json
35
35
  var name = "@fedify/vocab";
36
- var version = "2.0.31-dev.2297+58cbc917";
36
+ var version = "2.0.31-dev.2308+34090b3a";
37
37
  //#endregion
38
38
  //#region src/type.ts
39
39
  function getTypeId(object) {
@@ -50,7 +50,7 @@ function decodeIri(iri) {
50
50
  }
51
51
  function isValidLanguageTag(language) {
52
52
  try {
53
- new Intl.Locale(language);
53
+ new Intl.Locale((0, _fedify_vocab_runtime.normalizeLanguageTag)(language));
54
54
  return true;
55
55
  } catch (error) {
56
56
  if (error instanceof RangeError) return false;
@@ -24443,7 +24443,7 @@ var Link = class Link {
24443
24443
  let _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array = values["https://www.w3.org/ns/activitystreams#hreflang"];
24444
24444
  for (const v of _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array == null ? [] : _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array.length === 1 && "@list" in _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array[0] ? _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array[0]["@list"] : _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array) {
24445
24445
  if (v == null) continue;
24446
- const decoded = new Intl.Locale(v["@value"]);
24446
+ const decoded = new Intl.Locale((0, _fedify_vocab_runtime.normalizeLanguageTag)(v["@value"]));
24447
24447
  if (!this._shouldCacheDecodedJsonLd(decoded)) shouldCacheJsonLd = false;
24448
24448
  _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang.push(decoded);
24449
24449
  }
package/dist/mod.js CHANGED
@@ -4,12 +4,12 @@ import { SpanStatusCode, trace } from "@opentelemetry/api";
4
4
  import { domainToASCII, domainToUnicode } from "node:url";
5
5
  import jsonld from "@fedify/vocab-runtime/jsonld";
6
6
  import { getLogger } from "@logtape/logtape";
7
- import { LanguageString, LanguageString as LanguageString$1, decodeMultibase, encodeMultibase, exportMultibaseKey, exportSpki, getDocumentLoader, importMultibaseKey, importPem } from "@fedify/vocab-runtime";
7
+ import { LanguageString, LanguageString as LanguageString$1, decodeMultibase, encodeMultibase, exportMultibaseKey, exportSpki, getDocumentLoader, importMultibaseKey, importPem, normalizeLanguageTag } from "@fedify/vocab-runtime";
8
8
  import { isTemporalDuration, isTemporalInstant } from "@fedify/vocab-runtime/temporal";
9
9
  import { delay } from "es-toolkit";
10
10
  //#region deno.json
11
11
  var name = "@fedify/vocab";
12
- var version = "2.0.31-dev.2297+58cbc917";
12
+ var version = "2.0.31-dev.2308+34090b3a";
13
13
  //#endregion
14
14
  //#region src/type.ts
15
15
  function getTypeId(object) {
@@ -26,7 +26,7 @@ function decodeIri(iri) {
26
26
  }
27
27
  function isValidLanguageTag(language) {
28
28
  try {
29
- new Intl.Locale(language);
29
+ new Intl.Locale(normalizeLanguageTag(language));
30
30
  return true;
31
31
  } catch (error) {
32
32
  if (error instanceof RangeError) return false;
@@ -24419,7 +24419,7 @@ var Link = class Link {
24419
24419
  let _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array = values["https://www.w3.org/ns/activitystreams#hreflang"];
24420
24420
  for (const v of _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array == null ? [] : _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array.length === 1 && "@list" in _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array[0] ? _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array[0]["@list"] : _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array) {
24421
24421
  if (v == null) continue;
24422
- const decoded = new Intl.Locale(v["@value"]);
24422
+ const decoded = new Intl.Locale(normalizeLanguageTag(v["@value"]));
24423
24423
  if (!this._shouldCacheDecodedJsonLd(decoded)) shouldCacheJsonLd = false;
24424
24424
  _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang.push(decoded);
24425
24425
  }
@@ -1,7 +1,7 @@
1
1
  import "@js-temporal/polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { b as Service, g as Person, h as Organization, i as Application, l as Group, w as __exportAll } from "./vocab-ChQFW7FV.mjs";
4
- import { n as version, r as esm_default, t as name } from "./deno-C8GlsHR3.mjs";
3
+ import { b as Service, g as Person, h as Organization, i as Application, l as Group, w as __exportAll } from "./vocab-CDWIsBqv.mjs";
4
+ import { n as version, r as esm_default, t as name } from "./deno-9vYQUuzB.mjs";
5
5
  import { t as getTypeId } from "./type-Cf-vxmre.mjs";
6
6
  import { test } from "@fedify/fixture";
7
7
  import { deepStrictEqual, ok, rejects, strictEqual, throws } from "node:assert/strict";
@@ -1,6 +1,6 @@
1
1
  import "@js-temporal/polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { C as __commonJSMin, T as __toESM } from "./vocab-ChQFW7FV.mjs";
3
+ import { C as __commonJSMin, T as __toESM } from "./vocab-CDWIsBqv.mjs";
4
4
  //#region ../../node_modules/.pnpm/glob-to-regexp@0.4.1/node_modules/glob-to-regexp/index.js
5
5
  var require_glob_to_regexp = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6
6
  module.exports = function(glob, opts) {
@@ -1204,6 +1204,6 @@ var esm_default = new class FetchMock {
1204
1204
  //#endregion
1205
1205
  //#region deno.json
1206
1206
  var name = "@fedify/vocab";
1207
- var version = "2.0.31-dev.2297+58cbc917";
1207
+ var version = "2.0.31-dev.2308+34090b3a";
1208
1208
  //#endregion
1209
1209
  export { version as n, esm_default as r, name as t };
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { a as Collection, f as Note, g as Person, p as Object$1 } from "./vocab-ChQFW7FV.mjs";
4
- import { n as version, r as esm_default, t as name } from "./deno-C8GlsHR3.mjs";
3
+ import { a as Collection, f as Note, g as Person, p as Object$1 } from "./vocab-CDWIsBqv.mjs";
4
+ import { n as version, r as esm_default, t as name } from "./deno-9vYQUuzB.mjs";
5
5
  import { t as getTypeId } from "./type-Cf-vxmre.mjs";
6
6
  import { t as assertInstanceOf } from "./utils-CE8Dk5hm.mjs";
7
7
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
@@ -1,6 +1,6 @@
1
1
  import "@js-temporal/polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { g as Person } from "./vocab-ChQFW7FV.mjs";
3
+ import { g as Person } from "./vocab-CDWIsBqv.mjs";
4
4
  import { t as getTypeId } from "./type-Cf-vxmre.mjs";
5
5
  import { test } from "@fedify/fixture";
6
6
  import { deepStrictEqual } from "node:assert/strict";
@@ -3,7 +3,7 @@ globalThis.addEventListener = () => {};
3
3
  import { SpanStatusCode, trace } from "@opentelemetry/api";
4
4
  import jsonld from "@fedify/vocab-runtime/jsonld";
5
5
  import { getLogger } from "@logtape/logtape";
6
- import { LanguageString, decodeMultibase, encodeMultibase, exportMultibaseKey, exportSpki, getDocumentLoader, importMultibaseKey, importPem } from "@fedify/vocab-runtime";
6
+ import { LanguageString, decodeMultibase, encodeMultibase, exportMultibaseKey, exportSpki, getDocumentLoader, importMultibaseKey, importPem, normalizeLanguageTag } from "@fedify/vocab-runtime";
7
7
  import { isTemporalDuration, isTemporalInstant } from "@fedify/vocab-runtime/temporal";
8
8
  //#region \0rolldown/runtime.js
9
9
  var __create = Object.create;
@@ -114,7 +114,7 @@ function decodeIri(iri) {
114
114
  }
115
115
  function isValidLanguageTag(language) {
116
116
  try {
117
- new Intl.Locale(language);
117
+ new Intl.Locale(normalizeLanguageTag(language));
118
118
  return true;
119
119
  } catch (error) {
120
120
  if (error instanceof RangeError) return false;
@@ -24507,7 +24507,7 @@ var Link = class Link {
24507
24507
  let _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array = values["https://www.w3.org/ns/activitystreams#hreflang"];
24508
24508
  for (const v of _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array == null ? [] : _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array.length === 1 && "@list" in _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array[0] ? _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array[0]["@list"] : _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang__array) {
24509
24509
  if (v == null) continue;
24510
- const decoded = new Intl.Locale(v["@value"]);
24510
+ const decoded = new Intl.Locale(normalizeLanguageTag(v["@value"]));
24511
24511
  if (!this._shouldCacheDecodedJsonLd(decoded)) shouldCacheJsonLd = false;
24512
24512
  _f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang.push(decoded);
24513
24513
  }
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { S as vocab_exports, _ as Place, a as Collection, c as Follow, d as Link, f as Note, g as Person, m as OrderedCollectionPage, n as Activity, o as Create, p as Object$1, r as Announce, s as CryptographicKey, t as Accept, u as Hashtag, v as PropertyValue, x as Source, y as Question } from "./vocab-ChQFW7FV.mjs";
3
+ import { S as vocab_exports, _ as Place, a as Collection, c as Follow, d as Link, f as Note, g as Person, m as OrderedCollectionPage, n as Activity, o as Create, p as Object$1, r as Announce, s as CryptographicKey, t as Accept, u as Hashtag, v as PropertyValue, x as Source, y as Question } from "./vocab-CDWIsBqv.mjs";
4
4
  import { t as assertInstanceOf } from "./utils-CE8Dk5hm.mjs";
5
5
  import { mockDocumentLoader, test } from "@fedify/fixture";
6
6
  import { deepStrictEqual, notDeepStrictEqual, ok, rejects, strictEqual, throws } from "node:assert/strict";
@@ -189,6 +189,61 @@ test("Note.fromJsonLd() ignores malformed language tags in nested objects", asyn
189
189
  const attachment = (await note.toJsonLd()).attachment;
190
190
  deepStrictEqual(attachment.nameMap, { en: "Valid" });
191
191
  });
192
+ test("Note.fromJsonLd() normalizes extlang language tags", async () => {
193
+ const json = {
194
+ "@context": "https://www.w3.org/ns/activitystreams",
195
+ type: "Note",
196
+ content: "<p>早晨</p>",
197
+ contentMap: {
198
+ "zh-YUE": "<p>早晨</p>",
199
+ "yue": "<p>早晨呀</p>"
200
+ }
201
+ };
202
+ const note = await Note.fromJsonLd(json);
203
+ deepStrictEqual(note.contents, [
204
+ "<p>早晨</p>",
205
+ new LanguageString("<p>早晨呀</p>", "yue"),
206
+ new LanguageString("<p>早晨</p>", "yue")
207
+ ]);
208
+ deepStrictEqual(note.contents.map((c) => typeof c === "string" ? null : c.locale.baseName), [
209
+ null,
210
+ "yue",
211
+ "yue"
212
+ ]);
213
+ deepStrictEqual(await note.toJsonLd(), json);
214
+ deepStrictEqual((await note.toJsonLd({ format: "compact" })).contentMap, { yue: ["<p>早晨呀</p>", "<p>早晨</p>"] });
215
+ deepStrictEqual((await note.toJsonLd({ format: "expand" }))[0]["https://www.w3.org/ns/activitystreams#content"], [
216
+ { "@value": "<p>早晨</p>" },
217
+ {
218
+ "@value": "<p>早晨呀</p>",
219
+ "@language": "yue"
220
+ },
221
+ {
222
+ "@value": "<p>早晨</p>",
223
+ "@language": "yue"
224
+ }
225
+ ]);
226
+ const expandedNote = await Note.fromJsonLd({
227
+ "@type": ["https://www.w3.org/ns/activitystreams#Note"],
228
+ "https://www.w3.org/ns/activitystreams#name": [{
229
+ "@value": "早晨",
230
+ "@language": "zh-yue-HK"
231
+ }]
232
+ });
233
+ deepStrictEqual(expandedNote.names, [new LanguageString("早晨", "yue-HK")]);
234
+ deepStrictEqual(expandedNote.names[0].locale.baseName, "yue-HK");
235
+ });
236
+ test("Note.fromJsonLd() caches original language tags", async () => {
237
+ const json = {
238
+ "@context": "https://www.w3.org/ns/activitystreams",
239
+ type: "Note",
240
+ contentMap: { "EN-us": "Hello" }
241
+ };
242
+ const note = await Note.fromJsonLd(json);
243
+ deepStrictEqual(note.contents, [new LanguageString("Hello", "en-US")]);
244
+ deepStrictEqual(note.contents[0].locale.baseName, "en-US");
245
+ deepStrictEqual(await note.toJsonLd(), json);
246
+ });
192
247
  test("Note.toJsonLd()", async () => {
193
248
  const note = new Note({ tags: [new Hashtag({
194
249
  name: "#Fedify",
@@ -763,6 +818,22 @@ test("Link.fromJsonLd()", async () => {
763
818
  "href": "at://did:plc:ia76kvnndjutgedggx2ibrem"
764
819
  })).href, new URL("at://did%3Aplc%3Aia76kvnndjutgedggx2ibrem"));
765
820
  });
821
+ test("Link.fromJsonLd() normalizes extlang hreflang", async () => {
822
+ const link = await Link.fromJsonLd({
823
+ "@context": "https://www.w3.org/ns/activitystreams",
824
+ type: "Link",
825
+ href: "https://example.com/yue",
826
+ hreflang: "zh-YUE"
827
+ });
828
+ deepStrictEqual(link.language?.baseName, "yue");
829
+ deepStrictEqual((await link.toJsonLd({ format: "compact" })).hreflang, "yue");
830
+ await rejects(() => Link.fromJsonLd({
831
+ "@context": "https://www.w3.org/ns/activitystreams",
832
+ type: "Link",
833
+ href: "https://example.com/en",
834
+ hreflang: "en-USA"
835
+ }), RangeError);
836
+ });
766
837
  test("Person.fromJsonLd() with relative URLs", async () => {
767
838
  deepStrictEqual((await (await Person.fromJsonLd({
768
839
  "@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/vocab",
3
- "version": "2.0.31-dev.2297+58cbc917",
3
+ "version": "2.0.31-dev.2308+34090b3a",
4
4
  "homepage": "https://fedify.dev/",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,9 +46,9 @@
46
46
  "es-toolkit": "1.43.0",
47
47
  "jsonld": "^9.0.0",
48
48
  "pkijs": "^3.3.3",
49
- "@fedify/vocab-tools": "2.0.31-dev.2297+58cbc917",
50
- "@fedify/webfinger": "2.0.31-dev.2297+58cbc917",
51
- "@fedify/vocab-runtime": "2.0.31-dev.2297+58cbc917"
49
+ "@fedify/vocab-tools": "2.0.31-dev.2308+34090b3a",
50
+ "@fedify/vocab-runtime": "2.0.31-dev.2308+34090b3a",
51
+ "@fedify/webfinger": "2.0.31-dev.2308+34090b3a"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/node": "^22.17.0",
package/src/vocab.test.ts CHANGED
@@ -305,6 +305,77 @@ test("Note.fromJsonLd() ignores malformed language tags in nested objects", asyn
305
305
  deepStrictEqual(attachment.nameMap, { en: "Valid" });
306
306
  });
307
307
 
308
+ test("Note.fromJsonLd() normalizes extlang language tags", async () => {
309
+ const json = {
310
+ "@context": "https://www.w3.org/ns/activitystreams",
311
+ type: "Note",
312
+ content: "<p>早晨</p>",
313
+ contentMap: {
314
+ "zh-YUE": "<p>早晨</p>",
315
+ "yue": "<p>早晨呀</p>",
316
+ },
317
+ };
318
+ const note = await Note.fromJsonLd(json);
319
+ // JSON-LD expansion sorts language map keys, so yue comes before zh-yue:
320
+ deepStrictEqual(note.contents, [
321
+ "<p>早晨</p>",
322
+ new LanguageString("<p>早晨呀</p>", "yue"),
323
+ new LanguageString("<p>早晨</p>", "yue"),
324
+ ]);
325
+ deepStrictEqual(
326
+ note.contents.map((c) => typeof c === "string" ? null : c.locale.baseName),
327
+ [null, "yue", "yue"],
328
+ );
329
+
330
+ // The unmodified object is serialized from the cached original document:
331
+ deepStrictEqual(await note.toJsonLd(), json);
332
+ const compact = await note.toJsonLd({ format: "compact" }) as Record<
333
+ string,
334
+ unknown
335
+ >;
336
+ deepStrictEqual(compact.contentMap, {
337
+ yue: ["<p>早晨呀</p>", "<p>早晨</p>"],
338
+ });
339
+ const expanded = await note.toJsonLd({ format: "expand" });
340
+ deepStrictEqual(
341
+ (expanded as Record<string, unknown>[])[0][
342
+ "https://www.w3.org/ns/activitystreams#content"
343
+ ],
344
+ [
345
+ { "@value": "<p>早晨</p>" },
346
+ { "@value": "<p>早晨呀</p>", "@language": "yue" },
347
+ { "@value": "<p>早晨</p>", "@language": "yue" },
348
+ ],
349
+ );
350
+
351
+ const expandedNote = await Note.fromJsonLd({
352
+ "@type": ["https://www.w3.org/ns/activitystreams#Note"],
353
+ "https://www.w3.org/ns/activitystreams#name": [
354
+ { "@value": "早晨", "@language": "zh-yue-HK" },
355
+ ],
356
+ });
357
+ deepStrictEqual(expandedNote.names, [new LanguageString("早晨", "yue-HK")]);
358
+ deepStrictEqual(
359
+ (expandedNote.names[0] as LanguageString).locale.baseName,
360
+ "yue-HK",
361
+ );
362
+ });
363
+
364
+ test("Note.fromJsonLd() caches original language tags", async () => {
365
+ const json = {
366
+ "@context": "https://www.w3.org/ns/activitystreams",
367
+ type: "Note",
368
+ contentMap: { "EN-us": "Hello" },
369
+ };
370
+ const note = await Note.fromJsonLd(json);
371
+ deepStrictEqual(note.contents, [new LanguageString("Hello", "en-US")]);
372
+ deepStrictEqual(
373
+ (note.contents[0] as LanguageString).locale.baseName,
374
+ "en-US",
375
+ );
376
+ deepStrictEqual(await note.toJsonLd(), json);
377
+ });
378
+
308
379
  test("Note.toJsonLd()", async () => {
309
380
  const note = new Note({
310
381
  tags: [
@@ -1151,6 +1222,29 @@ test("Link.fromJsonLd()", async () => {
1151
1222
  );
1152
1223
  });
1153
1224
 
1225
+ test("Link.fromJsonLd() normalizes extlang hreflang", async () => {
1226
+ const link = await Link.fromJsonLd({
1227
+ "@context": "https://www.w3.org/ns/activitystreams",
1228
+ type: "Link",
1229
+ href: "https://example.com/yue",
1230
+ hreflang: "zh-YUE",
1231
+ });
1232
+ deepStrictEqual(link.language?.baseName, "yue");
1233
+ const compact = await link.toJsonLd({ format: "compact" }) as Record<
1234
+ string,
1235
+ unknown
1236
+ >;
1237
+ deepStrictEqual(compact.hreflang, "yue");
1238
+
1239
+ await rejects(() =>
1240
+ Link.fromJsonLd({
1241
+ "@context": "https://www.w3.org/ns/activitystreams",
1242
+ type: "Link",
1243
+ href: "https://example.com/en",
1244
+ hreflang: "en-USA",
1245
+ }), RangeError);
1246
+ });
1247
+
1154
1248
  test("Person.fromJsonLd() with relative URLs", async () => {
1155
1249
  const json = {
1156
1250
  "@context": [