@fedify/vocab-tools 2.1.24 → 2.1.26

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-tools",
3
- "version": "2.1.24",
3
+ "version": "2.1.26",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./src/mod.ts"
package/dist/mod.cjs CHANGED
@@ -8,7 +8,7 @@ let yaml = require("yaml");
8
8
  let es_toolkit = require("es-toolkit");
9
9
  //#region deno.json
10
10
  var name = "@fedify/vocab-tools";
11
- var version = "2.1.24";
11
+ var version = "2.1.26";
12
12
  //#endregion
13
13
  //#region src/type.ts
14
14
  const HEURISTICS_CONTEXTS = [
@@ -331,13 +331,16 @@ const scalarTypes = {
331
331
  return `${v}.href`;
332
332
  },
333
333
  dataCheck(v) {
334
- return `typeof ${v} === "object" && "@value" in ${v}
335
- && typeof ${v}["@value"] === "string"
336
- && ${v}["@value"] !== "" && ${v}["@value"] !== "/"`;
334
+ return `typeof ${v} === "object" &&
335
+ ((typeof ${v}["@id"] === "string" && canDecodeIri(${v}["@id"])) ||
336
+ (typeof ${v}["@value"] === "string" && canDecodeIri(${v}["@value"])))`;
337
337
  },
338
338
  decoder(v) {
339
- return `new URL(${v}["@value"])`;
340
- }
339
+ return `decodeIri(
340
+ typeof ${v}["@id"] === "string" ? ${v}["@id"] : ${v}["@value"]
341
+ )`;
342
+ },
343
+ skipUnparsable: true
341
344
  },
342
345
  "fedify:publicKey": {
343
346
  name: "CryptoKey",
@@ -519,6 +522,9 @@ function getDecoder(typeUri, types, variable, optionsVariable, baseUrlVariable)
519
522
  )`;
520
523
  throw new Error(`Unknown type: ${typeUri}`);
521
524
  }
525
+ function skipsUnparsable(typeUri) {
526
+ return scalarTypes[typeUri]?.skipUnparsable ?? false;
527
+ }
522
528
  function getDataCheck(typeUri, types, variable) {
523
529
  if (typeUri in scalarTypes) return scalarTypes[typeUri].dataCheck(variable);
524
530
  if (typeUri in types) {
@@ -1044,15 +1050,22 @@ async function* generateDecoder(typeUri, types) {
1044
1050
  yield `
1045
1051
  const decoded =
1046
1052
  `;
1047
- if (property.range.length == 1) yield getDecoder(property.range[0], types, "v", "options", `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`);
1048
- else {
1053
+ const lenient = property.range.length == 1 && skipsUnparsable(property.range[0]);
1054
+ if (property.range.length == 1) {
1055
+ if (lenient) {
1056
+ yield getDataCheck(property.range[0], types, "v");
1057
+ yield " ? ";
1058
+ }
1059
+ yield getDecoder(property.range[0], types, "v", "options", `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`);
1060
+ if (lenient) yield " : undefined";
1061
+ } else {
1049
1062
  const decoders = getDecoders(property.range, types, "v", "options", `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`);
1050
1063
  for (const code of decoders) yield code;
1051
1064
  }
1052
1065
  yield `
1053
1066
  ;
1054
1067
  `;
1055
- if (property.range.length > 1) yield `
1068
+ if (property.range.length > 1 || lenient) yield `
1056
1069
  if (typeof decoded === "undefined") {
1057
1070
  shouldCacheJsonLd = false;
1058
1071
  continue;
@@ -1665,7 +1678,16 @@ async function* generateProperty(type, property, types) {
1665
1678
  ${JSON.stringify(property.compactName)}];
1666
1679
  const doc = Array.isArray(prop) ? prop[0] : prop;
1667
1680
  if (doc != null && typeof doc === "object" && "@context" in doc) {
1668
- v = await this.#${property.singularName}_fromJsonLd(doc, options);
1681
+ try {
1682
+ v = await this.#${property.singularName}_fromJsonLd(doc, options);
1683
+ } catch (error) {
1684
+ if (!options.suppressError) throw error;
1685
+ getLogger(["fedify", "vocab"]).debug(
1686
+ "Failed to parse embedded value of {property}: {error}",
1687
+ { property: ${JSON.stringify(property.uri)}, error },
1688
+ );
1689
+ return null;
1690
+ }
1669
1691
  }
1670
1692
  }
1671
1693
  `;
@@ -1762,7 +1784,16 @@ async function* generateProperty(type, property, types) {
1762
1784
  ${JSON.stringify(property.compactName)}];
1763
1785
  const obj = Array.isArray(prop) ? prop[i] : prop;
1764
1786
  if (obj != null && typeof obj === "object" && "@context" in obj) {
1765
- v = await this.#${property.singularName}_fromJsonLd(obj, options);
1787
+ try {
1788
+ v = await this.#${property.singularName}_fromJsonLd(obj, options);
1789
+ } catch (error) {
1790
+ if (!options.suppressError) throw error;
1791
+ getLogger(["fedify", "vocab"]).debug(
1792
+ "Failed to parse embedded value of {property} at index {index}: {error}",
1793
+ { property: ${JSON.stringify(property.uri)}, index: i, error },
1794
+ );
1795
+ continue;
1796
+ }
1766
1797
  }
1767
1798
  }
1768
1799
  `;
@@ -1938,6 +1969,17 @@ async function* generateClasses(types) {
1938
1969
  isTemporalInstant,
1939
1970
  } from "@fedify/vocab-runtime/temporal";\n`;
1940
1971
  yield `
1972
+ function canDecodeIri(iri: string): boolean {
1973
+ return URL.canParse(iri) || iri.startsWith("at://");
1974
+ }
1975
+
1976
+ function decodeIri(iri: string): URL {
1977
+ return !URL.canParse(iri) && iri.startsWith("at://")
1978
+ ? new URL("at://" + encodeURIComponent(iri.substring(5)))
1979
+ : new URL(iri);
1980
+ }
1981
+ `;
1982
+ yield `
1941
1983
  function isValidLanguageTag(language: string): boolean {
1942
1984
  try {
1943
1985
  new Intl.Locale(language);
package/dist/mod.js CHANGED
@@ -7,7 +7,7 @@ import { parse } from "yaml";
7
7
  import { pascalCase } from "es-toolkit";
8
8
  //#region deno.json
9
9
  var name = "@fedify/vocab-tools";
10
- var version = "2.1.24";
10
+ var version = "2.1.26";
11
11
  //#endregion
12
12
  //#region src/type.ts
13
13
  const HEURISTICS_CONTEXTS = [
@@ -330,13 +330,16 @@ const scalarTypes = {
330
330
  return `${v}.href`;
331
331
  },
332
332
  dataCheck(v) {
333
- return `typeof ${v} === "object" && "@value" in ${v}
334
- && typeof ${v}["@value"] === "string"
335
- && ${v}["@value"] !== "" && ${v}["@value"] !== "/"`;
333
+ return `typeof ${v} === "object" &&
334
+ ((typeof ${v}["@id"] === "string" && canDecodeIri(${v}["@id"])) ||
335
+ (typeof ${v}["@value"] === "string" && canDecodeIri(${v}["@value"])))`;
336
336
  },
337
337
  decoder(v) {
338
- return `new URL(${v}["@value"])`;
339
- }
338
+ return `decodeIri(
339
+ typeof ${v}["@id"] === "string" ? ${v}["@id"] : ${v}["@value"]
340
+ )`;
341
+ },
342
+ skipUnparsable: true
340
343
  },
341
344
  "fedify:publicKey": {
342
345
  name: "CryptoKey",
@@ -518,6 +521,9 @@ function getDecoder(typeUri, types, variable, optionsVariable, baseUrlVariable)
518
521
  )`;
519
522
  throw new Error(`Unknown type: ${typeUri}`);
520
523
  }
524
+ function skipsUnparsable(typeUri) {
525
+ return scalarTypes[typeUri]?.skipUnparsable ?? false;
526
+ }
521
527
  function getDataCheck(typeUri, types, variable) {
522
528
  if (typeUri in scalarTypes) return scalarTypes[typeUri].dataCheck(variable);
523
529
  if (typeUri in types) {
@@ -1043,15 +1049,22 @@ async function* generateDecoder(typeUri, types) {
1043
1049
  yield `
1044
1050
  const decoded =
1045
1051
  `;
1046
- if (property.range.length == 1) yield getDecoder(property.range[0], types, "v", "options", `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`);
1047
- else {
1052
+ const lenient = property.range.length == 1 && skipsUnparsable(property.range[0]);
1053
+ if (property.range.length == 1) {
1054
+ if (lenient) {
1055
+ yield getDataCheck(property.range[0], types, "v");
1056
+ yield " ? ";
1057
+ }
1058
+ yield getDecoder(property.range[0], types, "v", "options", `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`);
1059
+ if (lenient) yield " : undefined";
1060
+ } else {
1048
1061
  const decoders = getDecoders(property.range, types, "v", "options", `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`);
1049
1062
  for (const code of decoders) yield code;
1050
1063
  }
1051
1064
  yield `
1052
1065
  ;
1053
1066
  `;
1054
- if (property.range.length > 1) yield `
1067
+ if (property.range.length > 1 || lenient) yield `
1055
1068
  if (typeof decoded === "undefined") {
1056
1069
  shouldCacheJsonLd = false;
1057
1070
  continue;
@@ -1664,7 +1677,16 @@ async function* generateProperty(type, property, types) {
1664
1677
  ${JSON.stringify(property.compactName)}];
1665
1678
  const doc = Array.isArray(prop) ? prop[0] : prop;
1666
1679
  if (doc != null && typeof doc === "object" && "@context" in doc) {
1667
- v = await this.#${property.singularName}_fromJsonLd(doc, options);
1680
+ try {
1681
+ v = await this.#${property.singularName}_fromJsonLd(doc, options);
1682
+ } catch (error) {
1683
+ if (!options.suppressError) throw error;
1684
+ getLogger(["fedify", "vocab"]).debug(
1685
+ "Failed to parse embedded value of {property}: {error}",
1686
+ { property: ${JSON.stringify(property.uri)}, error },
1687
+ );
1688
+ return null;
1689
+ }
1668
1690
  }
1669
1691
  }
1670
1692
  `;
@@ -1761,7 +1783,16 @@ async function* generateProperty(type, property, types) {
1761
1783
  ${JSON.stringify(property.compactName)}];
1762
1784
  const obj = Array.isArray(prop) ? prop[i] : prop;
1763
1785
  if (obj != null && typeof obj === "object" && "@context" in obj) {
1764
- v = await this.#${property.singularName}_fromJsonLd(obj, options);
1786
+ try {
1787
+ v = await this.#${property.singularName}_fromJsonLd(obj, options);
1788
+ } catch (error) {
1789
+ if (!options.suppressError) throw error;
1790
+ getLogger(["fedify", "vocab"]).debug(
1791
+ "Failed to parse embedded value of {property} at index {index}: {error}",
1792
+ { property: ${JSON.stringify(property.uri)}, index: i, error },
1793
+ );
1794
+ continue;
1795
+ }
1765
1796
  }
1766
1797
  }
1767
1798
  `;
@@ -1937,6 +1968,17 @@ async function* generateClasses(types) {
1937
1968
  isTemporalInstant,
1938
1969
  } from "@fedify/vocab-runtime/temporal";\n`;
1939
1970
  yield `
1971
+ function canDecodeIri(iri: string): boolean {
1972
+ return URL.canParse(iri) || iri.startsWith("at://");
1973
+ }
1974
+
1975
+ function decodeIri(iri: string): URL {
1976
+ return !URL.canParse(iri) && iri.startsWith("at://")
1977
+ ? new URL("at://" + encodeURIComponent(iri.substring(5)))
1978
+ : new URL(iri);
1979
+ }
1980
+ `;
1981
+ yield `
1940
1982
  function isValidLanguageTag(language: string): boolean {
1941
1983
  try {
1942
1984
  new Intl.Locale(language);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/vocab-tools",
3
- "version": "2.1.24",
3
+ "version": "2.1.26",
4
4
  "description": "Code generator for Activity Vocabulary APIs",
5
5
  "homepage": "https://fedify.dev/",
6
6
  "repository": {