@fedify/vocab-tools 2.4.0-dev.1666 → 2.4.0-dev.1727
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/README.md +21 -0
- package/deno.json +1 -1
- package/dist/mod.cjs +91 -23
- package/dist/mod.js +91 -23
- package/package.json +1 -1
- package/src/__snapshots__/class.test.ts.deno.snap +7787 -1548
- package/src/__snapshots__/class.test.ts.node.snap +7787 -1548
- package/src/__snapshots__/class.test.ts.snap +7787 -1548
- package/src/class.ts +27 -0
- package/src/codec.ts +71 -28
- package/src/type.ts +2 -1
package/src/class.ts
CHANGED
|
@@ -93,6 +93,7 @@ async function* generateClass(
|
|
|
93
93
|
};
|
|
94
94
|
#cachedJsonLd?: unknown;
|
|
95
95
|
readonly #_baseUrl?: URL;
|
|
96
|
+
#shouldCacheJsonLd = true;
|
|
96
97
|
readonly id: URL | null;
|
|
97
98
|
|
|
98
99
|
protected get _documentLoader(): DocumentLoader | undefined {
|
|
@@ -126,6 +127,20 @@ async function* generateClass(
|
|
|
126
127
|
protected get _baseUrl(): URL | undefined {
|
|
127
128
|
return this.#_baseUrl;
|
|
128
129
|
}
|
|
130
|
+
|
|
131
|
+
protected get _shouldCacheJsonLd(): boolean {
|
|
132
|
+
return this.#shouldCacheJsonLd;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
protected set _shouldCacheJsonLd(value: boolean) {
|
|
136
|
+
this.#shouldCacheJsonLd = value;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
protected static _shouldCacheDecodedJsonLd(value: unknown): boolean {
|
|
140
|
+
if (value == null || typeof value !== "object") return true;
|
|
141
|
+
if (!("_shouldCacheJsonLd" in value)) return true;
|
|
142
|
+
return (value as { _shouldCacheJsonLd: boolean })._shouldCacheJsonLd;
|
|
143
|
+
}
|
|
129
144
|
`;
|
|
130
145
|
}
|
|
131
146
|
yield `
|
|
@@ -257,6 +272,18 @@ export async function* generateClasses(
|
|
|
257
272
|
isTemporalDuration,
|
|
258
273
|
isTemporalInstant,
|
|
259
274
|
} from "@fedify/vocab-runtime/temporal";\n`;
|
|
275
|
+
yield `
|
|
276
|
+
function isValidLanguageTag(language: string): boolean {
|
|
277
|
+
try {
|
|
278
|
+
new Intl.Locale(language);
|
|
279
|
+
return true;
|
|
280
|
+
} catch (error) {
|
|
281
|
+
if (error instanceof RangeError) return false;
|
|
282
|
+
throw error;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
`;
|
|
286
|
+
yield "\n\n";
|
|
260
287
|
const portableIriKeys = new Set(["@id", "id"]);
|
|
261
288
|
for (const type of Object.values(types)) {
|
|
262
289
|
for (const property of type.properties) {
|
package/src/codec.ts
CHANGED
|
@@ -207,7 +207,7 @@ export async function* generateEncoder(
|
|
|
207
207
|
yield `
|
|
208
208
|
array = [];
|
|
209
209
|
for (const v of this.${await getFieldName(property.uri)}) {
|
|
210
|
-
|
|
210
|
+
let element = (
|
|
211
211
|
`;
|
|
212
212
|
if (!areAllScalarTypes(property.range, types)) {
|
|
213
213
|
yield 'v instanceof URL ? { "@id": formatIri(v) } : ';
|
|
@@ -217,6 +217,11 @@ export async function* generateEncoder(
|
|
|
217
217
|
}
|
|
218
218
|
yield `
|
|
219
219
|
);
|
|
220
|
+
if (Array.isArray(element)) {
|
|
221
|
+
if (element.length < 1) continue;
|
|
222
|
+
if (element.length == 1) element = element[0];
|
|
223
|
+
}
|
|
224
|
+
if (typeof element === "undefined") continue;
|
|
220
225
|
`;
|
|
221
226
|
if (isNonFunctionalProperty(property) && property.container === "graph") {
|
|
222
227
|
yield `array.push({ "@graph": element });`;
|
|
@@ -254,7 +259,10 @@ export async function* generateEncoder(
|
|
|
254
259
|
if (options.format === "expand") {
|
|
255
260
|
return await jsonld.expand(
|
|
256
261
|
values,
|
|
257
|
-
{
|
|
262
|
+
{
|
|
263
|
+
documentLoader: options.contextLoader,
|
|
264
|
+
keepFreeFloatingNodes: true,
|
|
265
|
+
},
|
|
258
266
|
);
|
|
259
267
|
}
|
|
260
268
|
const docContext = options.context ??
|
|
@@ -394,7 +402,17 @@ export async function* generateDecoder(
|
|
|
394
402
|
// deno-lint-ignore no-explicit-any
|
|
395
403
|
let values: Record<string, any[]> & { "@id"?: string };
|
|
396
404
|
let expanded: unknown[];
|
|
397
|
-
if (
|
|
405
|
+
if (
|
|
406
|
+
"_fromSubclass" in options &&
|
|
407
|
+
options._fromSubclass &&
|
|
408
|
+
typeof json === "object" &&
|
|
409
|
+
!Array.isArray(json)
|
|
410
|
+
) {
|
|
411
|
+
values =
|
|
412
|
+
// deno-lint-ignore no-explicit-any
|
|
413
|
+
json as (Record<string, any[]> & { "@id"?: string });
|
|
414
|
+
expanded = [values];
|
|
415
|
+
} else if (globalThis.Object.keys(json).length == 0) {
|
|
398
416
|
values = {};
|
|
399
417
|
expanded = [values];
|
|
400
418
|
} else {
|
|
@@ -455,8 +473,9 @@ export async function* generateDecoder(
|
|
|
455
473
|
`;
|
|
456
474
|
} else {
|
|
457
475
|
yield `
|
|
458
|
-
|
|
459
|
-
|
|
476
|
+
const superValues = structuredClone(values);
|
|
477
|
+
delete superValues["@type"];
|
|
478
|
+
const instance = await super.fromJsonLd(superValues, {
|
|
460
479
|
...options,
|
|
461
480
|
// @ts-ignore: an internal option
|
|
462
481
|
_fromSubclass: true,
|
|
@@ -466,6 +485,9 @@ export async function* generateDecoder(
|
|
|
466
485
|
}
|
|
467
486
|
`;
|
|
468
487
|
}
|
|
488
|
+
yield `
|
|
489
|
+
let shouldCacheJsonLd = instance._shouldCacheJsonLd;
|
|
490
|
+
`;
|
|
469
491
|
for (const property of type.properties) {
|
|
470
492
|
const variable = await getFieldName(property.uri, "");
|
|
471
493
|
yield await generateField(property, types, "const ");
|
|
@@ -482,13 +504,25 @@ export async function* generateDecoder(
|
|
|
482
504
|
`;
|
|
483
505
|
}
|
|
484
506
|
}
|
|
507
|
+
let itemsExpression =
|
|
508
|
+
`${arrayVariable}.length === 1 && "@list" in ${arrayVariable}[0]
|
|
509
|
+
? ${arrayVariable}[0]["@list"]
|
|
510
|
+
: ${arrayVariable}`;
|
|
511
|
+
if (
|
|
512
|
+
isNonFunctionalProperty(property) && property.container === "graph"
|
|
513
|
+
) {
|
|
514
|
+
itemsExpression = `(${itemsExpression}).flatMap((item: unknown) =>
|
|
515
|
+
item != null && typeof item === "object" && "@graph" in item &&
|
|
516
|
+
Array.isArray((item as { "@graph": unknown })["@graph"])
|
|
517
|
+
? (item as { "@graph": unknown[] })["@graph"]
|
|
518
|
+
: [item]
|
|
519
|
+
)`;
|
|
520
|
+
}
|
|
485
521
|
yield `
|
|
486
522
|
for (
|
|
487
523
|
const v of ${arrayVariable} == null
|
|
488
524
|
? []
|
|
489
|
-
: ${
|
|
490
|
-
? ${arrayVariable}[0]["@list"]
|
|
491
|
-
: ${arrayVariable}
|
|
525
|
+
: ${itemsExpression}
|
|
492
526
|
) {
|
|
493
527
|
if (v == null) continue;
|
|
494
528
|
`;
|
|
@@ -510,23 +544,18 @@ export async function* generateDecoder(
|
|
|
510
544
|
}
|
|
511
545
|
`;
|
|
512
546
|
}
|
|
547
|
+
yield `
|
|
548
|
+
const decoded =
|
|
549
|
+
`;
|
|
513
550
|
if (property.range.length == 1) {
|
|
514
|
-
yield
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
propertyBaseUrl,
|
|
522
|
-
)
|
|
523
|
-
};
|
|
524
|
-
if (typeof decoded === "undefined") continue;
|
|
525
|
-
${variable}.push(decoded);`;
|
|
551
|
+
yield getDecoder(
|
|
552
|
+
property.range[0],
|
|
553
|
+
types,
|
|
554
|
+
"v",
|
|
555
|
+
"options",
|
|
556
|
+
propertyBaseUrl,
|
|
557
|
+
);
|
|
526
558
|
} else {
|
|
527
|
-
yield `
|
|
528
|
-
const decoded =
|
|
529
|
-
`;
|
|
530
559
|
const decoders = getDecoders(
|
|
531
560
|
property.range,
|
|
532
561
|
types,
|
|
@@ -535,19 +564,33 @@ export async function* generateDecoder(
|
|
|
535
564
|
propertyBaseUrl,
|
|
536
565
|
);
|
|
537
566
|
for (const code of decoders) yield code;
|
|
538
|
-
|
|
567
|
+
}
|
|
568
|
+
yield `
|
|
539
569
|
;
|
|
540
|
-
|
|
570
|
+
`;
|
|
571
|
+
yield `
|
|
572
|
+
if (typeof decoded === "undefined") {
|
|
573
|
+
shouldCacheJsonLd = false;
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
`;
|
|
577
|
+
yield `
|
|
578
|
+
if (!this._shouldCacheDecodedJsonLd(decoded)) {
|
|
579
|
+
shouldCacheJsonLd = false;
|
|
580
|
+
}
|
|
541
581
|
${variable}.push(decoded);
|
|
542
|
-
|
|
543
|
-
}
|
|
582
|
+
`;
|
|
544
583
|
yield `
|
|
545
584
|
}
|
|
546
585
|
instance.${await getFieldName(property.uri)} = ${variable};
|
|
547
586
|
`;
|
|
548
587
|
}
|
|
549
588
|
yield `
|
|
550
|
-
|
|
589
|
+
instance._shouldCacheJsonLd = shouldCacheJsonLd;
|
|
590
|
+
if (
|
|
591
|
+
shouldCacheJsonLd &&
|
|
592
|
+
(!("_fromSubclass" in options) || !options._fromSubclass)
|
|
593
|
+
) {
|
|
551
594
|
try {
|
|
552
595
|
if (cacheJsonLd != null && cacheJsonLd !== expanded) {
|
|
553
596
|
const compactArray = Array.isArray(json) && json.length === 1;
|
package/src/type.ts
CHANGED
|
@@ -187,7 +187,8 @@ const scalarTypes: Record<string, ScalarType> = {
|
|
|
187
187
|
dataCheck(v) {
|
|
188
188
|
return `typeof ${v} === "object" && "@language" in ${v} && "@value" in ${v}
|
|
189
189
|
&& typeof ${v}["@language"] === "string"
|
|
190
|
-
&& typeof ${v}["@value"] === "string"
|
|
190
|
+
&& typeof ${v}["@value"] === "string"
|
|
191
|
+
&& isValidLanguageTag(${v}["@language"])`;
|
|
191
192
|
},
|
|
192
193
|
decoder(v) {
|
|
193
194
|
return `new LanguageString(${v}["@value"], ${v}["@language"])`;
|