@fedify/vocab-tools 2.3.9-dev.2048 → 2.3.10
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 +1 -1
- package/dist/mod.cjs +60 -30
- package/dist/mod.js +60 -30
- package/package.json +1 -1
- package/src/__snapshots__/class.test.ts.deno.snap +2318 -1060
- package/src/__snapshots__/class.test.ts.node.snap +2318 -1060
- package/src/__snapshots__/class.test.ts.snap +2318 -1060
- package/src/class.ts +11 -0
- package/src/codec.ts +9 -0
- package/src/property.ts +28 -16
- package/src/type.ts +17 -4
package/src/class.ts
CHANGED
|
@@ -222,6 +222,17 @@ export async function* generateClasses(
|
|
|
222
222
|
isTemporalInstant,
|
|
223
223
|
} from "@fedify/vocab-runtime/temporal";\n`;
|
|
224
224
|
yield `
|
|
225
|
+
function canDecodeIri(iri: string): boolean {
|
|
226
|
+
return URL.canParse(iri) || iri.startsWith("at://");
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function decodeIri(iri: string): URL {
|
|
230
|
+
return !URL.canParse(iri) && iri.startsWith("at://")
|
|
231
|
+
? new URL("at://" + encodeURIComponent(iri.substring(5)))
|
|
232
|
+
: new URL(iri);
|
|
233
|
+
}
|
|
234
|
+
`;
|
|
235
|
+
yield `
|
|
225
236
|
function isValidLanguageTag(language: string): boolean {
|
|
226
237
|
try {
|
|
227
238
|
new Intl.Locale(language);
|
package/src/codec.ts
CHANGED
|
@@ -6,12 +6,14 @@ import {
|
|
|
6
6
|
areAllScalarTypes,
|
|
7
7
|
emitOverride,
|
|
8
8
|
getAllProperties,
|
|
9
|
+
getDataCheck,
|
|
9
10
|
getDecoder,
|
|
10
11
|
getDecoders,
|
|
11
12
|
getEncoders,
|
|
12
13
|
getSubtypes,
|
|
13
14
|
getTypeNames,
|
|
14
15
|
isCompactableType,
|
|
16
|
+
skipsUnparsable,
|
|
15
17
|
} from "./type.ts";
|
|
16
18
|
|
|
17
19
|
function* generatePreprocessorBlock(
|
|
@@ -506,7 +508,13 @@ export async function* generateDecoder(
|
|
|
506
508
|
yield `
|
|
507
509
|
const decoded =
|
|
508
510
|
`;
|
|
511
|
+
const lenient = property.range.length == 1 &&
|
|
512
|
+
skipsUnparsable(property.range[0]);
|
|
509
513
|
if (property.range.length == 1) {
|
|
514
|
+
if (lenient) {
|
|
515
|
+
yield getDataCheck(property.range[0], types, "v");
|
|
516
|
+
yield " ? ";
|
|
517
|
+
}
|
|
510
518
|
yield getDecoder(
|
|
511
519
|
property.range[0],
|
|
512
520
|
types,
|
|
@@ -514,6 +522,7 @@ export async function* generateDecoder(
|
|
|
514
522
|
"options",
|
|
515
523
|
propertyBaseUrl,
|
|
516
524
|
);
|
|
525
|
+
if (lenient) yield " : undefined";
|
|
517
526
|
} else {
|
|
518
527
|
const decoders = getDecoders(
|
|
519
528
|
property.range,
|
package/src/property.ts
CHANGED
|
@@ -302,14 +302,19 @@ async function* generateProperty(
|
|
|
302
302
|
${JSON.stringify(property.compactName)}];
|
|
303
303
|
const doc = Array.isArray(prop) ? prop[0] : prop;
|
|
304
304
|
if (doc != null && typeof doc === "object" && "@context" in doc) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
|
|
305
|
+
try {
|
|
306
|
+
v = await this.#${property.singularName}_fromJsonLd(doc, {
|
|
307
|
+
...options,
|
|
308
|
+
baseUrl: ${cachedPropertyBaseUrl},
|
|
309
|
+
});
|
|
310
|
+
} catch (error) {
|
|
311
|
+
if (!options.suppressError) throw error;
|
|
312
|
+
getLogger(["fedify", "vocab"]).debug(
|
|
313
|
+
"Failed to parse embedded value of {property}: {error}",
|
|
314
|
+
{ property: ${JSON.stringify(property.uri)}, error },
|
|
315
|
+
);
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
313
318
|
}
|
|
314
319
|
}
|
|
315
320
|
`;
|
|
@@ -408,14 +413,21 @@ async function* generateProperty(
|
|
|
408
413
|
${JSON.stringify(property.compactName)}];
|
|
409
414
|
const obj = Array.isArray(prop) ? prop[i] : prop;
|
|
410
415
|
if (obj != null && typeof obj === "object" && "@context" in obj) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
})
|
|
417
|
-
|
|
418
|
-
|
|
416
|
+
try {
|
|
417
|
+
v = await this.#${property.singularName}_fromJsonLd(obj, {
|
|
418
|
+
...options,
|
|
419
|
+
baseUrl: ${cachedPropertyBaseUrl},
|
|
420
|
+
});
|
|
421
|
+
} catch (error) {
|
|
422
|
+
if (!options.suppressError) throw error;
|
|
423
|
+
getLogger(["fedify", "vocab"]).debug(
|
|
424
|
+
"Failed to parse embedded value of {property} at index {index}: {error}",
|
|
425
|
+
{ property: ${
|
|
426
|
+
JSON.stringify(property.uri)
|
|
427
|
+
}, index: i, error },
|
|
428
|
+
);
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
419
431
|
}
|
|
420
432
|
}
|
|
421
433
|
`;
|
package/src/type.ts
CHANGED
|
@@ -17,6 +17,12 @@ interface ScalarType {
|
|
|
17
17
|
compactEncoder?: (variable: string) => string;
|
|
18
18
|
dataCheck(variable: string): string;
|
|
19
19
|
decoder(variable: string, baseUrlVar: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Whether a value that fails `dataCheck()` should be skipped instead of
|
|
22
|
+
* being handed to `decoder()`. Set this for types decoded from untrusted
|
|
23
|
+
* remote input, where one malformed value must not fail the whole object.
|
|
24
|
+
*/
|
|
25
|
+
skipUnparsable?: boolean;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
const scalarTypes: Record<string, ScalarType> = {
|
|
@@ -332,13 +338,16 @@ const scalarTypes: Record<string, ScalarType> = {
|
|
|
332
338
|
return `${v}.href`;
|
|
333
339
|
},
|
|
334
340
|
dataCheck(v) {
|
|
335
|
-
return `typeof ${v} === "object" &&
|
|
336
|
-
|
|
337
|
-
|
|
341
|
+
return `typeof ${v} === "object" &&
|
|
342
|
+
((typeof ${v}["@id"] === "string" && canDecodeIri(${v}["@id"])) ||
|
|
343
|
+
(typeof ${v}["@value"] === "string" && canDecodeIri(${v}["@value"])))`;
|
|
338
344
|
},
|
|
339
345
|
decoder(v) {
|
|
340
|
-
return `
|
|
346
|
+
return `decodeIri(
|
|
347
|
+
typeof ${v}["@id"] === "string" ? ${v}["@id"] : ${v}["@value"]
|
|
348
|
+
)`;
|
|
341
349
|
},
|
|
350
|
+
skipUnparsable: true,
|
|
342
351
|
},
|
|
343
352
|
"fedify:publicKey": {
|
|
344
353
|
name: "CryptoKey",
|
|
@@ -649,6 +658,10 @@ export function getDecoder(
|
|
|
649
658
|
throw new Error(`Unknown type: ${typeUri}`);
|
|
650
659
|
}
|
|
651
660
|
|
|
661
|
+
export function skipsUnparsable(typeUri: string): boolean {
|
|
662
|
+
return scalarTypes[typeUri]?.skipUnparsable ?? false;
|
|
663
|
+
}
|
|
664
|
+
|
|
652
665
|
export function getDataCheck(
|
|
653
666
|
typeUri: string,
|
|
654
667
|
types: Record<string, TypeSchema>,
|