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