@fedify/vocab-tools 2.4.0-dev.1564 → 2.4.0-dev.1570

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.4.0-dev.1564+5a2c6c2c",
3
+ "version": "2.4.0-dev.1570+f1b6aaa3",
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.4.0-dev.1564+5a2c6c2c";
11
+ var version = "2.4.0-dev.1570+f1b6aaa3";
12
12
  //#endregion
13
13
  //#region src/type.ts
14
14
  const HEURISTICS_CONTEXTS = [
@@ -156,10 +156,10 @@ const scalarTypes = {
156
156
  return `${v} instanceof URL`;
157
157
  },
158
158
  encoder(v) {
159
- return `{ "@id": formatIri(${v}) }`;
159
+ return `{ "@id": ${v}.href }`;
160
160
  },
161
161
  compactEncoder(v) {
162
- return `formatIri(${v})`;
162
+ return `${v}.href`;
163
163
  },
164
164
  dataCheck(v) {
165
165
  return `${v} != null && typeof ${v} === "object" && "@id" in ${v}
@@ -167,7 +167,22 @@ const scalarTypes = {
167
167
  && ${v}["@id"] !== ""`;
168
168
  },
169
169
  decoder(v, baseUrlVar) {
170
- return `parseIri(${v}["@id"], ${baseUrlVar})`;
170
+ return `${v}["@id"].startsWith("at://")
171
+ ? new URL("at://" +
172
+ encodeURIComponent(
173
+ ${v}["@id"].includes("/", 5)
174
+ ? ${v}["@id"].slice(5, ${v}["@id"].indexOf("/", 5))
175
+ : ${v}["@id"].slice(5)
176
+ ) +
177
+ (
178
+ ${v}["@id"].includes("/", 5)
179
+ ? ${v}["@id"].slice(${v}["@id"].indexOf("/", 5))
180
+ : ""
181
+ )
182
+ )
183
+ : URL.canParse(${v}["@id"]) && ${baseUrlVar}
184
+ ? new URL(${v}["@id"])
185
+ : new URL(${v}["@id"], ${baseUrlVar})`;
171
186
  }
172
187
  },
173
188
  "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString": {
@@ -309,10 +324,10 @@ const scalarTypes = {
309
324
  return `${v} instanceof URL`;
310
325
  },
311
326
  encoder(v) {
312
- return `{ "@value": formatIri(${v}) }`;
327
+ return `{ "@value": ${v}.href }`;
313
328
  },
314
329
  compactEncoder(v) {
315
- return `formatIri(${v})`;
330
+ return `${v}.href`;
316
331
  },
317
332
  dataCheck(v) {
318
333
  return `typeof ${v} === "object" && "@value" in ${v}
@@ -320,7 +335,7 @@ const scalarTypes = {
320
335
  && ${v}["@value"] !== "" && ${v}["@value"] !== "/"`;
321
336
  },
322
337
  decoder(v) {
323
- return `parseIri(${v}["@value"])`;
338
+ return `new URL(${v}["@value"])`;
324
339
  }
325
340
  },
326
341
  "fedify:publicKey": {
@@ -790,7 +805,7 @@ async function* generateEncoder(typeUri, types) {
790
805
  for (const v of this.${await getFieldName(property.uri)}) {
791
806
  const item = (
792
807
  `;
793
- if (!areAllScalarTypes(property.range, types)) yield "v instanceof URL ? formatIri(v) : ";
808
+ if (!areAllScalarTypes(property.range, types)) yield "v instanceof URL ? v.href : ";
794
809
  const encoders = getEncoders(property.range, types, "v", "options", true);
795
810
  for (const code of encoders) yield code;
796
811
  yield `
@@ -821,7 +836,7 @@ async function* generateEncoder(typeUri, types) {
821
836
  }
822
837
  yield `
823
838
  ${type.typeless ? "" : `result["type"] = ${JSON.stringify(type.compactName ?? type.uri)};`}
824
- if (this.id != null) result["id"] = formatIri(this.id);
839
+ if (this.id != null) result["id"] = this.id.href;
825
840
  result["@context"] = ${JSON.stringify(type.defaultContext)};
826
841
  return result;
827
842
  }
@@ -849,7 +864,7 @@ async function* generateEncoder(typeUri, types) {
849
864
  for (const v of this.${await getFieldName(property.uri)}) {
850
865
  const element = (
851
866
  `;
852
- if (!areAllScalarTypes(property.range, types)) yield "v instanceof URL ? { \"@id\": formatIri(v) } : ";
867
+ if (!areAllScalarTypes(property.range, types)) yield "v instanceof URL ? { \"@id\": v.href } : ";
853
868
  for (const code of getEncoders(property.range, types, "v", "options")) yield code;
854
869
  yield `
855
870
  );
@@ -876,7 +891,7 @@ async function* generateEncoder(typeUri, types) {
876
891
  }
877
892
  yield `
878
893
  ${type.typeless ? "" : `values["@type"] = [${JSON.stringify(type.uri)}];`}
879
- if (this.id != null) values["@id"] = formatIri(this.id);
894
+ if (this.id != null) values["@id"] = this.id.href;
880
895
  if (options.format === "expand") {
881
896
  return await jsonld.expand(
882
897
  values,
@@ -1002,12 +1017,10 @@ async function* generateDecoder(typeUri, types, moduleVarNames) {
1002
1017
  };
1003
1018
  // deno-lint-ignore no-explicit-any
1004
1019
  let values: Record<string, any[]> & { "@id"?: string };
1005
- let expanded: unknown[];
1006
1020
  if (globalThis.Object.keys(json).length == 0) {
1007
1021
  values = {};
1008
- expanded = [values];
1009
1022
  } else {
1010
- expanded = await jsonld.expand(json, {
1023
+ const expanded = await jsonld.expand(json, {
1011
1024
  documentLoader: options.contextLoader,
1012
1025
  keepFreeFloatingNodes: true,
1013
1026
  });
@@ -1015,9 +1028,11 @@ async function* generateDecoder(typeUri, types, moduleVarNames) {
1015
1028
  // deno-lint-ignore no-explicit-any
1016
1029
  (expanded[0] ?? {}) as (Record<string, any[]> & { "@id"?: string });
1017
1030
  }
1018
- const id = parseJsonLdId(values["@id"], options.baseUrl);
1019
- if (id != null && options.baseUrl == null) {
1020
- options = { ...options, baseUrl: id };
1031
+ if (values["@id"] != null && !values["@id"].startsWith("_:") && !URL.canParse(values["@id"], options.baseUrl)) {
1032
+ throw new TypeError("Invalid @id: " + values["@id"]);
1033
+ }
1034
+ if (options.baseUrl == null && values["@id"] != null && !values["@id"].startsWith("_:") && URL.canParse(values["@id"])) {
1035
+ options = { ...options, baseUrl: new URL(values["@id"]) };
1021
1036
  }
1022
1037
  `;
1023
1038
  const subtypes = getSubtypes(typeUri, types, true);
@@ -1038,24 +1053,10 @@ async function* generateDecoder(typeUri, types, moduleVarNames) {
1038
1053
  throw new TypeError("Invalid type: " + values["@type"]);
1039
1054
  }
1040
1055
  }
1041
- `;
1042
- yield `
1043
- let cacheJsonLd = !("_fromSubclass" in options) || !options._fromSubclass
1044
- ? normalizeJsonLdIris(
1045
- expanded,
1046
- PORTABLE_IRI_KEYS,
1047
- PORTABLE_IRI_PATTERN,
1048
- )
1049
- : undefined;
1050
- if (cacheJsonLd != null && cacheJsonLd !== expanded) {
1051
- cacheJsonLd = structuredClone(cacheJsonLd);
1052
- }
1053
1056
  `;
1054
1057
  if (type.extends == null) yield `
1055
1058
  const instance = new this(
1056
- {
1057
- id
1058
- },
1059
+ { id: values["@id"] != null && !values["@id"].startsWith("_:") && URL.canParse(values["@id"], options.baseUrl) ? new URL(values["@id"], options.baseUrl) : undefined },
1059
1060
  options,
1060
1061
  );
1061
1062
  `;
@@ -1098,7 +1099,11 @@ async function* generateDecoder(typeUri, types, moduleVarNames) {
1098
1099
  if (typeof v === "object" && "@id" in v && !("@type" in v)
1099
1100
  && globalThis.Object.keys(v).length === 1) {
1100
1101
  if (v["@id"].startsWith("_:")) continue;
1101
- ${variable}.push(parseIri(v["@id"], ${propertyBaseUrl}));
1102
+ ${variable}.push(
1103
+ !URL.canParse(v["@id"], ${propertyBaseUrl}) && v["@id"].startsWith("at://")
1104
+ ? new URL("at://" + encodeURIComponent(v["@id"].substring(5)))
1105
+ : new URL(v["@id"], ${propertyBaseUrl})
1106
+ );
1102
1107
  continue;
1103
1108
  }
1104
1109
  `;
@@ -1126,19 +1131,7 @@ async function* generateDecoder(typeUri, types, moduleVarNames) {
1126
1131
  yield `
1127
1132
  if (!("_fromSubclass" in options) || !options._fromSubclass) {
1128
1133
  try {
1129
- if (cacheJsonLd != null && cacheJsonLd !== expanded) {
1130
- const compactArray = Array.isArray(json) && json.length === 1;
1131
- const jsonLd = compactArray ? json[0] : json;
1132
- const normalized = cacheJsonLd;
1133
- const cachedJsonLd = await compactJsonLdCache(
1134
- normalized,
1135
- jsonLd,
1136
- options.contextLoader,
1137
- );
1138
- instance._cachedJsonLd = compactArray ? [cachedJsonLd] : cachedJsonLd;
1139
- } else {
1140
- instance._cachedJsonLd = structuredClone(json);
1141
- }
1134
+ instance._cachedJsonLd = structuredClone(json);
1142
1135
  } catch {
1143
1136
  getLogger(["fedify", "vocab"]).warn(
1144
1137
  "Failed to cache JSON-LD: {json}",
@@ -1565,10 +1558,9 @@ async function* generateProperty(type, property, types, moduleVarNames) {
1565
1558
  ${JSON.stringify(version)},
1566
1559
  );
1567
1560
  return await tracer.startActiveSpan("activitypub.lookup_object", async (span) => {
1568
- const lookupUrl = formatIri(url);
1569
1561
  let fetchResult: RemoteDocument;
1570
1562
  try {
1571
- fetchResult = await documentLoader(lookupUrl);
1563
+ fetchResult = await documentLoader(url.href);
1572
1564
  } catch (error) {
1573
1565
  span.setStatus({
1574
1566
  code: SpanStatusCode.ERROR,
@@ -1578,20 +1570,21 @@ async function* generateProperty(type, property, types, moduleVarNames) {
1578
1570
  if (options.suppressError) {
1579
1571
  getLogger(["fedify", "vocab"]).error(
1580
1572
  "Failed to fetch {url}: {error}",
1581
- { error, url: lookupUrl }
1573
+ { error, url: url.href }
1582
1574
  );
1583
1575
  return null;
1584
1576
  }
1585
1577
  throw error;
1586
1578
  }
1587
1579
  const { document, documentUrl } = fetchResult;
1588
- const baseUrl = parseIri(documentUrl);
1580
+ const baseUrl = new URL(documentUrl);
1589
1581
  try {
1590
1582
  const obj = await this.#${property.singularName}_fromJsonLd(
1591
1583
  document,
1592
1584
  { documentLoader, contextLoader, tracerProvider, baseUrl }
1593
1585
  );
1594
- if (obj?.id != null && !isTrustedIriOrigin(options, obj.id, baseUrl)) {
1586
+ if (options.crossOrigin !== "trust" && obj?.id != null &&
1587
+ obj.id.origin !== baseUrl.origin) {
1595
1588
  if (options.crossOrigin === "throw") {
1596
1589
  throw new Error(
1597
1590
  "The object's @id (" + obj.id.href + ") has a different origin " +
@@ -1620,7 +1613,7 @@ async function* generateProperty(type, property, types, moduleVarNames) {
1620
1613
  if (options.suppressError) {
1621
1614
  getLogger(["fedify", "vocab"]).error(
1622
1615
  "Failed to parse {url}: {error}",
1623
- { error: e, url: lookupUrl }
1616
+ { error: e, url: url.href }
1624
1617
  );
1625
1618
  return null;
1626
1619
  }
@@ -1740,9 +1733,8 @@ async function* generateProperty(type, property, types, moduleVarNames) {
1740
1733
  }
1741
1734
  if (this.${await getFieldName(property.uri)}.length < 1) return null;
1742
1735
  let v = this.${await getFieldName(property.uri)}[0];
1743
- if (!(v instanceof URL) &&
1744
- v.id != null &&
1745
- !isTrustedIriOrigin(options, v.id, this.id) &&
1736
+ if (options.crossOrigin !== "trust" && !(v instanceof URL) &&
1737
+ v.id != null && v.id.origin !== this.id?.origin &&
1746
1738
  !this.${await getFieldName(property.uri, "#_trust")}.has(0)) {
1747
1739
  v = v.id;
1748
1740
  }
@@ -1781,8 +1773,8 @@ async function* generateProperty(type, property, types, moduleVarNames) {
1781
1773
  `;
1782
1774
  }
1783
1775
  yield `
1784
- if (v?.id != null &&
1785
- this.id != null && !isTrustedIriOrigin(options, v.id, this.id) &&
1776
+ if (options.crossOrigin !== "trust" && v?.id != null &&
1777
+ this.id != null && v.id.origin !== this.id.origin &&
1786
1778
  !this.${await getFieldName(property.uri, "#_trust")}.has(0)) {
1787
1779
  if (options.crossOrigin === "throw") {
1788
1780
  throw new Error(
@@ -1846,9 +1838,8 @@ async function* generateProperty(type, property, types, moduleVarNames) {
1846
1838
  const vs = this.${await getFieldName(property.uri)};
1847
1839
  for (let i = 0; i < vs.length; i++) {
1848
1840
  let v = vs[i];
1849
- if (!(v instanceof URL) &&
1850
- v.id != null &&
1851
- !isTrustedIriOrigin(options, v.id, this.id) &&
1841
+ if (options.crossOrigin !== "trust" && !(v instanceof URL) &&
1842
+ v.id != null && v.id.origin !== this.id?.origin &&
1852
1843
  !this.${await getFieldName(property.uri, "#_trust")}.has(i)) {
1853
1844
  v = v.id;
1854
1845
  }
@@ -1888,9 +1879,9 @@ async function* generateProperty(type, property, types, moduleVarNames) {
1888
1879
  `;
1889
1880
  }
1890
1881
  yield `
1891
- if (v?.id != null &&
1892
- this.id != null && !isTrustedIriOrigin(options, v.id, this.id) &&
1893
- !this.${await getFieldName(property.uri, "#_trust")}.has(i)) {
1882
+ if (options.crossOrigin !== "trust" && v?.id != null &&
1883
+ this.id != null && v.id.origin !== this.id.origin &&
1884
+ !this.${await getFieldName(property.uri, "#_trust")}.has(0)) {
1894
1885
  if (options.crossOrigin === "throw") {
1895
1886
  throw new Error(
1896
1887
  "The property object's @id (" + v.id.href + ") has a different " +
@@ -1923,33 +1914,6 @@ async function* generateProperties(typeUri, types, moduleVarNames) {
1923
1914
  }
1924
1915
  //#endregion
1925
1916
  //#region src/class.ts
1926
- const XSD_ANY_URI = "http://www.w3.org/2001/XMLSchema#anyURI";
1927
- const FEDIFY_URL = "fedify:url";
1928
- const INTERNAL_RUNTIME_IMPORTS = [
1929
- "compactJsonLdCache",
1930
- "getJsonLdContext",
1931
- "isTrustedIriOrigin",
1932
- "normalizeJsonLdIris"
1933
- ].join(",\n ");
1934
- const RUNTIME_IMPORTS = [
1935
- "canParseDecimal",
1936
- "decodeMultibase",
1937
- "type Decimal",
1938
- "type DocumentLoader",
1939
- "encodeMultibase",
1940
- "exportMultibaseKey",
1941
- "exportSpki",
1942
- "formatIri",
1943
- "getDocumentLoader",
1944
- "importMultibaseKey",
1945
- "importPem",
1946
- "isDecimal",
1947
- "LanguageString",
1948
- "parseDecimal",
1949
- "parseIri",
1950
- "parseJsonLdId",
1951
- "type RemoteDocument"
1952
- ].join(",\n ");
1953
1917
  /**
1954
1918
  * Sorts the given types topologically so that the base types come before the
1955
1919
  * extended types.
@@ -2083,18 +2047,6 @@ export function getEntityTypeById(id: string | URL): $EntityType | undefined {
2083
2047
 
2084
2048
  `;
2085
2049
  }
2086
- function canContainIriValue(property, types) {
2087
- return property.range.some((typeUri) => typeUri === XSD_ANY_URI || typeUri === FEDIFY_URL || types[typeUri]?.entity);
2088
- }
2089
- function addKeys(keys, property) {
2090
- keys.add(property.uri);
2091
- if (property.compactName != null) keys.add(property.compactName);
2092
- }
2093
- function addPortableIriKeys(keys, property, types) {
2094
- if (!canContainIriValue(property, types)) return;
2095
- addKeys(keys, property);
2096
- if ("redundantProperties" in property && property.redundantProperties != null) for (const redundantProperty of property.redundantProperties) addKeys(keys, redundantProperty);
2097
- }
2098
2050
  /**
2099
2051
  * Generates the TypeScript classes from the given types.
2100
2052
  * @param types The types to generate classes from.
@@ -2102,21 +2054,33 @@ function addPortableIriKeys(keys, property, types) {
2102
2054
  */
2103
2055
  async function* generateClasses(types) {
2104
2056
  validateTypeSchemas(types);
2057
+ const runtimeImports = [
2058
+ "canParseDecimal",
2059
+ "decodeMultibase",
2060
+ "type Decimal",
2061
+ "type DocumentLoader",
2062
+ "encodeMultibase",
2063
+ "exportMultibaseKey",
2064
+ "exportSpki",
2065
+ "getDocumentLoader",
2066
+ "importMultibaseKey",
2067
+ "importPem",
2068
+ "isDecimal",
2069
+ "LanguageString",
2070
+ "parseDecimal",
2071
+ "type RemoteDocument"
2072
+ ];
2105
2073
  yield "// deno-lint-ignore-file ban-unused-ignore no-explicit-any no-unused-vars prefer-const verbatim-module-syntax\n";
2106
2074
  yield "import jsonld from \"@fedify/vocab-runtime/jsonld\";\n";
2107
2075
  yield "import { getLogger } from \"@logtape/logtape\";\n";
2108
2076
  yield `import { type Span, SpanStatusCode, type TracerProvider, trace }
2109
2077
  from "@opentelemetry/api";\n`;
2110
- yield `import {\n ${RUNTIME_IMPORTS}\n} from "@fedify/vocab-runtime";\n`;
2111
- yield `import {\n ${INTERNAL_RUNTIME_IMPORTS}\n} from "@fedify/vocab-runtime/internal/jsonld-cache";\n`;
2078
+ yield `import {\n ${runtimeImports.join(",\n ")}\n} from "@fedify/vocab-runtime";\n`;
2112
2079
  yield `import {
2113
2080
  isTemporalDuration,
2114
2081
  isTemporalInstant,
2115
2082
  } from "@fedify/vocab-runtime/temporal";\n`;
2116
- const portableIriKeys = new Set(["@id", "id"]);
2117
- for (const type of Object.values(types)) for (const property of type.properties) addPortableIriKeys(portableIriKeys, property, types);
2118
- yield "const PORTABLE_IRI_PATTERN = /^ap(?:\\+ef61)?:\\/\\//i;\n";
2119
- yield `const PORTABLE_IRI_KEYS: ReadonlySet<string> = new Set(${JSON.stringify([...portableIriKeys].sort())});\n\n`;
2083
+ yield "\n\n";
2120
2084
  const moduleVarNames = /* @__PURE__ */ new Map();
2121
2085
  const sorted = sortTopologically(types);
2122
2086
  for (const typeUri of sorted) for (const property of types[typeUri].properties) {