@fedify/vocab-tools 2.1.17 → 2.1.18

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/src/class.ts CHANGED
@@ -57,6 +57,7 @@ async function* generateClass(
57
57
  values?: Record<string, unknown>;
58
58
  };
59
59
  #cachedJsonLd?: unknown;
60
+ #shouldCacheJsonLd = true;
60
61
  readonly id: URL | null;
61
62
 
62
63
  protected get _documentLoader(): DocumentLoader | undefined {
@@ -86,6 +87,20 @@ async function* generateClass(
86
87
  protected set _cachedJsonLd(value: unknown | undefined) {
87
88
  this.#cachedJsonLd = value;
88
89
  }
90
+
91
+ protected get _shouldCacheJsonLd(): boolean {
92
+ return this.#shouldCacheJsonLd;
93
+ }
94
+
95
+ protected set _shouldCacheJsonLd(value: boolean) {
96
+ this.#shouldCacheJsonLd = value;
97
+ }
98
+
99
+ protected static _shouldCacheDecodedJsonLd(value: unknown): boolean {
100
+ if (value == null || typeof value !== "object") return true;
101
+ if (!("_shouldCacheJsonLd" in value)) return true;
102
+ return (value as { _shouldCacheJsonLd: boolean })._shouldCacheJsonLd;
103
+ }
89
104
  `;
90
105
  }
91
106
  yield `
@@ -146,6 +161,17 @@ export async function* generateClasses(
146
161
  isTemporalDuration,
147
162
  isTemporalInstant,
148
163
  } from "@fedify/vocab-runtime/temporal";\n`;
164
+ yield `
165
+ function isValidLanguageTag(language: string): boolean {
166
+ try {
167
+ new Intl.Locale(language);
168
+ return true;
169
+ } catch (error) {
170
+ if (error instanceof RangeError) return false;
171
+ throw error;
172
+ }
173
+ }
174
+ `;
149
175
  yield "\n\n";
150
176
  const sorted = sortTopologically(types);
151
177
  for (const typeUri of sorted) {
package/src/codec.ts CHANGED
@@ -400,6 +400,9 @@ export async function* generateDecoder(
400
400
  }
401
401
  `;
402
402
  }
403
+ yield `
404
+ let shouldCacheJsonLd = instance._shouldCacheJsonLd;
405
+ `;
403
406
  for (const property of type.properties) {
404
407
  const variable = await getFieldName(property.uri, "");
405
408
  yield await generateField(property, types, "const ");
@@ -439,20 +442,18 @@ export async function* generateDecoder(
439
442
  }
440
443
  `;
441
444
  }
445
+ yield `
446
+ const decoded =
447
+ `;
442
448
  if (property.range.length == 1) {
443
- yield `${variable}.push(${
444
- getDecoder(
445
- property.range[0],
446
- types,
447
- "v",
448
- "options",
449
- `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`,
450
- )
451
- })`;
449
+ yield getDecoder(
450
+ property.range[0],
451
+ types,
452
+ "v",
453
+ "options",
454
+ `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`,
455
+ );
452
456
  } else {
453
- yield `
454
- const decoded =
455
- `;
456
457
  const decoders = getDecoders(
457
458
  property.range,
458
459
  types,
@@ -461,19 +462,35 @@ export async function* generateDecoder(
461
462
  `(values["@id"] == null ? options.baseUrl : new URL(values["@id"]))`,
462
463
  );
463
464
  for (const code of decoders) yield code;
464
- yield `
465
+ }
466
+ yield `
465
467
  ;
466
- if (typeof decoded === "undefined") continue;
467
- ${variable}.push(decoded);
468
+ `;
469
+ if (property.range.length > 1) {
470
+ yield `
471
+ if (typeof decoded === "undefined") {
472
+ shouldCacheJsonLd = false;
473
+ continue;
474
+ }
468
475
  `;
469
476
  }
477
+ yield `
478
+ if (!this._shouldCacheDecodedJsonLd(decoded)) {
479
+ shouldCacheJsonLd = false;
480
+ }
481
+ ${variable}.push(decoded);
482
+ `;
470
483
  yield `
471
484
  }
472
485
  instance.${await getFieldName(property.uri)} = ${variable};
473
486
  `;
474
487
  }
475
488
  yield `
476
- if (!("_fromSubclass" in options) || !options._fromSubclass) {
489
+ instance._shouldCacheJsonLd = shouldCacheJsonLd;
490
+ if (
491
+ shouldCacheJsonLd &&
492
+ (!("_fromSubclass" in options) || !options._fromSubclass)
493
+ ) {
477
494
  try {
478
495
  instance._cachedJsonLd = structuredClone(json);
479
496
  } catch {
package/src/type.ts CHANGED
@@ -200,7 +200,8 @@ const scalarTypes: Record<string, ScalarType> = {
200
200
  dataCheck(v) {
201
201
  return `typeof ${v} === "object" && "@language" in ${v} && "@value" in ${v}
202
202
  && typeof ${v}["@language"] === "string"
203
- && typeof ${v}["@value"] === "string"`;
203
+ && typeof ${v}["@value"] === "string"
204
+ && isValidLanguageTag(${v}["@language"])`;
204
205
  },
205
206
  decoder(v) {
206
207
  return `new LanguageString(${v}["@value"], ${v}["@language"])`;