ochre-sdk 1.3.5 → 1.3.6

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.
@@ -19,6 +19,13 @@ export type MultilingualStringInput = string | {
19
19
  export type MultilingualStringJSON<T extends ReadonlyArray<string> = ReadonlyArray<string>> = {
20
20
  content: Partial<Record<T[number], Array<MultilingualStringEntry>>>;
21
21
  aliases: Array<string>;
22
+ /**
23
+ * Text in no language, read from `zxx` content that has no other language
24
+ * beside it
25
+ *
26
+ * Optional so payloads written before it existed still parse.
27
+ */
28
+ nonLinguistic?: Array<MultilingualStringEntry>;
22
29
  /**
23
30
  * The language reads fall back to first
24
31
  *
@@ -42,17 +49,25 @@ export type MultilingualOptions = {
42
49
  */
43
50
  availableLanguages?: ReadonlyArray<string>;
44
51
  /**
45
- Alias values carried by OCHRE as zxx content
52
+ Alternative names, which OCHRE publishes as zxx content beside a field's
53
+ languages
46
54
  */
47
55
  aliases?: ReadonlyArray<string>;
56
+ /**
57
+ Text in no language, such as an identifier or a code, which OCHRE publishes
58
+ as zxx content with no other language beside it
59
+ */
60
+ nonLinguistic?: ReadonlyArray<MultilingualStringInput>;
48
61
  };
62
+ type StoredOptions = Required<Omit<MultilingualOptions, "nonLinguistic">>;
49
63
  type MultilingualContent<T extends ReadonlyArray<string>> = Partial<Record<T[number], ReadonlyArray<MultilingualStringEntry>>>;
50
64
  declare const MULTILINGUAL_STRING_INTERNAL_INIT: unique symbol;
51
65
  type MultilingualStringInternalInit<T extends ReadonlyArray<string>> = {
52
66
  readonly [MULTILINGUAL_STRING_INTERNAL_INIT]: true;
53
67
  content: MultilingualContent<T>;
54
- options: Required<MultilingualOptions>;
68
+ options: StoredOptions;
55
69
  availableLanguages: ReadonlyArray<T[number]>;
70
+ nonLinguistic: ReadonlyArray<MultilingualStringEntry>;
56
71
  };
57
72
  /**
58
73
  * Multilingual string
@@ -82,12 +97,13 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
82
97
  /**
83
98
  * Recreate a multilingual string from its JSON representation.
84
99
  */
85
- static fromJSON<U extends ReadonlyArray<string>>(json: MultilingualStringJSON<U>, languages: U, options?: Omit<MultilingualOptions, "aliases">): MultilingualString<U>;
86
- static fromJSON(json: MultilingualStringJSON, languages?: undefined, options?: Omit<MultilingualOptions, "aliases">): MultilingualString<ReadonlyArray<string>>;
100
+ static fromJSON<U extends ReadonlyArray<string>>(json: MultilingualStringJSON<U>, languages: U, options?: Omit<MultilingualOptions, "aliases" | "nonLinguistic">): MultilingualString<U>;
101
+ static fromJSON(json: MultilingualStringJSON, languages?: undefined, options?: Omit<MultilingualOptions, "aliases" | "nonLinguistic">): MultilingualString<ReadonlyArray<string>>;
87
102
  private readonly _content;
88
103
  private readonly _options;
89
104
  private readonly _availableLanguages;
90
105
  private readonly _aliases;
106
+ private readonly _nonLinguistic;
91
107
  /**
92
108
  * Create a new multilingual string from an object of language codes to text.
93
109
  */
@@ -103,6 +119,8 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
103
119
  * The fallback order is requested language, then the dataset's default
104
120
  * language, then the first language that has any content. This is the only
105
121
  * place that order is written down; every reader below is a projection of it.
122
+ * Non-linguistic text is the same in every language, so it answers every
123
+ * read, exact ones included.
106
124
  */
107
125
  private resolveEntries;
108
126
  private resolvePrimaryEntry;
@@ -150,11 +168,17 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
150
168
  */
151
169
  getExactTexts(language: T[number]): Array<string>;
152
170
  /**
153
- * Get the alias values OCHRE carries as `zxx` content
171
+ * Get the alternative names OCHRE publishes as `zxx` content beside the
172
+ * string's languages
173
+ *
174
+ * A non-linguistic string has none: its `zxx` content is the text itself.
154
175
  */
155
176
  getAliases(): Array<string>;
156
177
  /**
157
- * Get the languages that actually carry content
178
+ * Get the languages that carry language-specific content
179
+ *
180
+ * A non-linguistic string has none, although every language reads its text;
181
+ * {@link MultilingualString.isNonLinguistic} tells the two apart.
158
182
  */
159
183
  getAvailableLanguages(): Array<T[number]>;
160
184
  /**
@@ -175,11 +199,22 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
175
199
  *
176
200
  * Answers the structural question. A language whose only entry is blank
177
201
  * still counts here; {@link MultilingualString.hasContent} is the question
178
- * about text. Aliases are not entries, so a string carrying only aliases is
179
- * empty by this measure and {@link MultilingualString.hasAliases} is true.
180
- * @returns True when no language carries an entry
202
+ * about text. Non-linguistic text counts as an entry; aliases never stand
203
+ * without one, since `zxx` content alone is read as non-linguistic text.
204
+ * @returns True when no language carries an entry and there is no
205
+ * non-linguistic text
181
206
  */
182
207
  isEmpty(): boolean;
208
+ /**
209
+ * Whether the string is text in no language, such as an identifier or a code
210
+ *
211
+ * OCHRE publishes this as `zxx` content with no other language beside it.
212
+ * Its text answers every language, so a caller that needs to know whether
213
+ * text was written in a language, to set an HTML `lang` attribute or to
214
+ * leave it out of a translation check, asks this.
215
+ * @returns True when the string holds non-linguistic text
216
+ */
217
+ isNonLinguistic(): boolean;
183
218
  /**
184
219
  * Whether any entry in any language carries text that is not whitespace
185
220
  *
@@ -191,13 +226,16 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
191
226
  */
192
227
  hasContent(): boolean;
193
228
  /**
194
- * Whether a specific language carries an entry, with no fallback
229
+ * Whether a specific language reads an entry, with no fallback
230
+ *
231
+ * True for every language when the string is non-linguistic, matching the
232
+ * exact readers, which return non-linguistic text for any language.
195
233
  * @param language - The language to test
196
234
  * @returns True when that language carries at least one entry
197
235
  */
198
236
  hasLanguage(language: T[number]): boolean;
199
237
  /**
200
- * Whether OCHRE carried any `zxx` alias values for this string
238
+ * Whether OCHRE published any alternative names for this string
201
239
  * @returns True when there is at least one alias
202
240
  */
203
241
  hasAliases(): boolean;
@@ -224,9 +262,11 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
224
262
  /**
225
263
  * Replace the alias values
226
264
  *
227
- * Aliases are the `zxx` content OCHRE carries alongside a field's languages,
265
+ * Aliases are the `zxx` content OCHRE publishes beside a field's languages,
228
266
  * so they are set as a whole rather than per language. Empty strings are
229
- * dropped, matching how they are read from a payload.
267
+ * dropped, matching how they are read from a payload, and on a string with
268
+ * no language they become its non-linguistic text, as the same content
269
+ * would be read.
230
270
  * @param aliases - The aliases to carry
231
271
  * @returns A new multilingual string
232
272
  */
@@ -243,10 +283,11 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
243
283
  *
244
284
  * A transform that needs to keep or rewrite markup returns
245
285
  * `{ text, richText }` instead of a string, and both are used verbatim.
286
+ * Non-linguistic text is transformed too, with `null` as its language.
246
287
  * @param transform - Produces the new text for one entry
247
288
  * @returns A new multilingual string
248
289
  */
249
- mapText(transform: (text: string, language: T[number]) => MultilingualStringInput): MultilingualString<T>;
290
+ mapText(transform: (text: string, language: T[number] | null) => MultilingualStringInput): MultilingualString<T>;
250
291
  /**
251
292
  * Keep only the entries a predicate accepts
252
293
  *
@@ -254,11 +295,12 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
254
295
  * can also test `richText` and `isPrimary`. Dropping every entry of a
255
296
  * language removes that language, and when that was the default the default
256
297
  * moves to the first language that still has content, so reads keep
257
- * resolving.
298
+ * resolving. Non-linguistic entries are tested too, with `null` as their
299
+ * language.
258
300
  * @param shouldKeep - Whether to keep one entry
259
301
  * @returns A new multilingual string
260
302
  */
261
- filterEntries(shouldKeep: (entry: MultilingualStringEntry, language: T[number]) => boolean): MultilingualString<T>;
303
+ filterEntries(shouldKeep: (entry: MultilingualStringEntry, language: T[number] | null) => boolean): MultilingualString<T>;
262
304
  /**
263
305
  * Get the JSON representation
264
306
  *
@@ -18,6 +18,28 @@ function normalizeAliases(aliases) {
18
18
  for (const alias of candidateAliases) if (alias !== "") normalizedAliases.push(alias);
19
19
  return normalizedAliases;
20
20
  }
21
+ /**
22
+ * Apply the rule OCHRE publishes `zxx` content by
23
+ *
24
+ * `zxx` content beside a field's languages names the same thing again, so it
25
+ * is aliases; `zxx` content with no language beside it is the text itself,
26
+ * in no language. Normalizing every string through this keeps the two
27
+ * readings from ever coexisting, whichever way a string was built or edited.
28
+ * @param hasLanguages - Whether any language carries an entry
29
+ * @param aliases - The aliases the string would carry
30
+ * @param nonLinguistic - The non-linguistic entries the string would carry
31
+ * @returns The aliases and non-linguistic entries to store
32
+ */
33
+ function normalizeUntaggedText(hasLanguages, aliases, nonLinguistic) {
34
+ if (hasLanguages) return {
35
+ aliases: normalizeAliases([...aliases, ...Array.from(nonLinguistic, (entry) => entry.text)]),
36
+ nonLinguistic: []
37
+ };
38
+ return {
39
+ aliases: [],
40
+ nonLinguistic: normalizePrimary([...nonLinguistic, ...entriesFromTexts(normalizeAliases(aliases))])
41
+ };
42
+ }
21
43
  function entriesFromTexts(texts) {
22
44
  const entries = [];
23
45
  for (const text of texts) entries.push({
@@ -84,12 +106,17 @@ function isInternalInit(value) {
84
106
  * Multilingual string
85
107
  */
86
108
  var MultilingualString = class MultilingualString {
87
- static fromNormalized(content, options, availableLanguages) {
109
+ static fromNormalized(content, options, availableLanguages, nonLinguistic) {
110
+ const untaggedText = normalizeUntaggedText(availableLanguages.length > 0, options.aliases, nonLinguistic);
88
111
  return new MultilingualString({
89
112
  [MULTILINGUAL_STRING_INTERNAL_INIT]: true,
90
113
  content,
91
- options,
92
- availableLanguages
114
+ options: {
115
+ ...options,
116
+ aliases: untaggedText.aliases
117
+ },
118
+ availableLanguages,
119
+ nonLinguistic: untaggedText.nonLinguistic
93
120
  });
94
121
  }
95
122
  static fromObject(content, languages, options = {}) {
@@ -109,7 +136,7 @@ var MultilingualString = class MultilingualString {
109
136
  availableLanguages: actualLanguages,
110
137
  aliases: normalizeAliases(options.aliases)
111
138
  };
112
- return this.fromNormalized(normalizedContent, defaultOptions, availableLanguages);
139
+ return this.fromNormalized(normalizedContent, defaultOptions, availableLanguages, entriesFromTexts(options.nonLinguistic ?? []));
113
140
  }
114
141
  const normalizedContent = {};
115
142
  for (const language of languages) {
@@ -122,7 +149,7 @@ var MultilingualString = class MultilingualString {
122
149
  availableLanguages: languages,
123
150
  aliases: normalizeAliases(options.aliases)
124
151
  };
125
- return this.fromNormalized(normalizedContent, defaultOptions, availableLanguages);
152
+ return this.fromNormalized(normalizedContent, defaultOptions, availableLanguages, entriesFromTexts(options.nonLinguistic ?? []));
126
153
  }
127
154
  static create(language, text, languages, options = {}) {
128
155
  if (languages === void 0) return this.fromObject({ [language]: text }, void 0, {
@@ -143,7 +170,8 @@ var MultilingualString = class MultilingualString {
143
170
  const mergedOptions = {
144
171
  defaultLanguage: json.defaultLanguage,
145
172
  ...options,
146
- aliases: json.aliases
173
+ aliases: json.aliases,
174
+ nonLinguistic: json.nonLinguistic
147
175
  };
148
176
  if (languages === void 0) return this.fromEntries(content, void 0, mergedOptions);
149
177
  return this.fromEntries(content, languages, mergedOptions);
@@ -152,12 +180,14 @@ var MultilingualString = class MultilingualString {
152
180
  _options;
153
181
  _availableLanguages;
154
182
  _aliases;
183
+ _nonLinguistic;
155
184
  constructor(content = {}, languages, options = {}) {
156
185
  if (isInternalInit(content)) {
157
186
  this._content = Object.freeze(cloneContent(content.content));
158
187
  this._options = Object.freeze({ ...content.options });
159
188
  this._availableLanguages = Object.freeze([...content.availableLanguages]);
160
189
  this._aliases = Object.freeze([...content.options.aliases]);
190
+ this._nonLinguistic = Object.freeze(normalizePrimary(content.nonLinguistic));
161
191
  return;
162
192
  }
163
193
  const parsed = languages === void 0 ? MultilingualString.fromObject(content, void 0, options) : MultilingualString.fromObject(content, languages, options);
@@ -165,6 +195,7 @@ var MultilingualString = class MultilingualString {
165
195
  this._options = parsed._options;
166
196
  this._availableLanguages = parsed._availableLanguages;
167
197
  this._aliases = parsed._aliases;
198
+ this._nonLinguistic = parsed._nonLinguistic;
168
199
  }
169
200
  /**
170
201
  * Resolve the entries to read for a language
@@ -172,6 +203,8 @@ var MultilingualString = class MultilingualString {
172
203
  * The fallback order is requested language, then the dataset's default
173
204
  * language, then the first language that has any content. This is the only
174
205
  * place that order is written down; every reader below is a projection of it.
206
+ * Non-linguistic text is the same in every language, so it answers every
207
+ * read, exact ones included.
175
208
  */
176
209
  resolveEntries(language, isExact) {
177
210
  const candidateLanguages = isExact ? [language] : [
@@ -184,7 +217,7 @@ var MultilingualString = class MultilingualString {
184
217
  const entries = this._content[candidateLanguage] ?? [];
185
218
  if (entries.length > 0) return entries;
186
219
  }
187
- return [];
220
+ return this._nonLinguistic;
188
221
  }
189
222
  resolvePrimaryEntry(language, isExact) {
190
223
  const entries = this.resolveEntries(language, isExact);
@@ -251,13 +284,19 @@ var MultilingualString = class MultilingualString {
251
284
  return Array.from(this.resolveEntries(language, true), (entry) => entry.text);
252
285
  }
253
286
  /**
254
- * Get the alias values OCHRE carries as `zxx` content
287
+ * Get the alternative names OCHRE publishes as `zxx` content beside the
288
+ * string's languages
289
+ *
290
+ * A non-linguistic string has none: its `zxx` content is the text itself.
255
291
  */
256
292
  getAliases() {
257
293
  return [...this._aliases];
258
294
  }
259
295
  /**
260
- * Get the languages that actually carry content
296
+ * Get the languages that carry language-specific content
297
+ *
298
+ * A non-linguistic string has none, although every language reads its text;
299
+ * {@link MultilingualString.isNonLinguistic} tells the two apart.
261
300
  */
262
301
  getAvailableLanguages() {
263
302
  return [...this._availableLanguages];
@@ -284,12 +323,25 @@ var MultilingualString = class MultilingualString {
284
323
  *
285
324
  * Answers the structural question. A language whose only entry is blank
286
325
  * still counts here; {@link MultilingualString.hasContent} is the question
287
- * about text. Aliases are not entries, so a string carrying only aliases is
288
- * empty by this measure and {@link MultilingualString.hasAliases} is true.
289
- * @returns True when no language carries an entry
326
+ * about text. Non-linguistic text counts as an entry; aliases never stand
327
+ * without one, since `zxx` content alone is read as non-linguistic text.
328
+ * @returns True when no language carries an entry and there is no
329
+ * non-linguistic text
290
330
  */
291
331
  isEmpty() {
292
- return this._availableLanguages.length === 0;
332
+ return this._availableLanguages.length === 0 && this._nonLinguistic.length === 0;
333
+ }
334
+ /**
335
+ * Whether the string is text in no language, such as an identifier or a code
336
+ *
337
+ * OCHRE publishes this as `zxx` content with no other language beside it.
338
+ * Its text answers every language, so a caller that needs to know whether
339
+ * text was written in a language, to set an HTML `lang` attribute or to
340
+ * leave it out of a translation check, asks this.
341
+ * @returns True when the string holds non-linguistic text
342
+ */
343
+ isNonLinguistic() {
344
+ return this._nonLinguistic.length > 0;
293
345
  }
294
346
  /**
295
347
  * Whether any entry in any language carries text that is not whitespace
@@ -305,18 +357,22 @@ var MultilingualString = class MultilingualString {
305
357
  const entries = this._content[language] ?? [];
306
358
  for (const entry of entries) if (entry.text.trim() !== "") return true;
307
359
  }
360
+ for (const entry of this._nonLinguistic) if (entry.text.trim() !== "") return true;
308
361
  return false;
309
362
  }
310
363
  /**
311
- * Whether a specific language carries an entry, with no fallback
364
+ * Whether a specific language reads an entry, with no fallback
365
+ *
366
+ * True for every language when the string is non-linguistic, matching the
367
+ * exact readers, which return non-linguistic text for any language.
312
368
  * @param language - The language to test
313
369
  * @returns True when that language carries at least one entry
314
370
  */
315
371
  hasLanguage(language) {
316
- return (this._content[language]?.length ?? 0) > 0;
372
+ return (this._content[language]?.length ?? 0) > 0 || this._nonLinguistic.length > 0;
317
373
  }
318
374
  /**
319
- * Whether OCHRE carried any `zxx` alias values for this string
375
+ * Whether OCHRE published any alternative names for this string
320
376
  * @returns True when there is at least one alias
321
377
  */
322
378
  hasAliases() {
@@ -336,7 +392,7 @@ var MultilingualString = class MultilingualString {
336
392
  ...normalizeInputText(text),
337
393
  isPrimary: false
338
394
  }]) : entriesFromTexts([text]);
339
- return MultilingualString.fromNormalized(newContent, this._options, getLanguagesWithEntries(newContent, this._options.availableLanguages));
395
+ return MultilingualString.fromNormalized(newContent, this._options, getLanguagesWithEntries(newContent, this._options.availableLanguages), this._nonLinguistic);
340
396
  }
341
397
  /**
342
398
  * Remove the content for a language
@@ -354,14 +410,16 @@ var MultilingualString = class MultilingualString {
354
410
  return MultilingualString.fromNormalized(newContent, {
355
411
  ...this._options,
356
412
  defaultLanguage: this._options.defaultLanguage === language ? resolveDefaultLanguageOption(newAvailableLanguages, this._options.availableLanguages) : this._options.defaultLanguage
357
- }, newAvailableLanguages);
413
+ }, newAvailableLanguages, this._nonLinguistic);
358
414
  }
359
415
  /**
360
416
  * Replace the alias values
361
417
  *
362
- * Aliases are the `zxx` content OCHRE carries alongside a field's languages,
418
+ * Aliases are the `zxx` content OCHRE publishes beside a field's languages,
363
419
  * so they are set as a whole rather than per language. Empty strings are
364
- * dropped, matching how they are read from a payload.
420
+ * dropped, matching how they are read from a payload, and on a string with
421
+ * no language they become its non-linguistic text, as the same content
422
+ * would be read.
365
423
  * @param aliases - The aliases to carry
366
424
  * @returns A new multilingual string
367
425
  */
@@ -369,7 +427,7 @@ var MultilingualString = class MultilingualString {
369
427
  return MultilingualString.fromNormalized(cloneContent(this._content), {
370
428
  ...this._options,
371
429
  aliases: normalizeAliases(aliases)
372
- }, this._availableLanguages);
430
+ }, this._availableLanguages, this._nonLinguistic);
373
431
  }
374
432
  /**
375
433
  * Transform the text of every entry in every language
@@ -383,6 +441,7 @@ var MultilingualString = class MultilingualString {
383
441
  *
384
442
  * A transform that needs to keep or rewrite markup returns
385
443
  * `{ text, richText }` instead of a string, and both are used verbatim.
444
+ * Non-linguistic text is transformed too, with `null` as its language.
386
445
  * @param transform - Produces the new text for one entry
387
446
  * @returns A new multilingual string
388
447
  */
@@ -395,7 +454,10 @@ var MultilingualString = class MultilingualString {
395
454
  isPrimary: entry.isPrimary
396
455
  })));
397
456
  }
398
- return MultilingualString.fromNormalized(newContent, this._options, this._availableLanguages);
457
+ return MultilingualString.fromNormalized(newContent, this._options, this._availableLanguages, Array.from(this._nonLinguistic, (entry) => ({
458
+ ...normalizeInputText(transform(entry.text, null)),
459
+ isPrimary: entry.isPrimary
460
+ })));
399
461
  }
400
462
  /**
401
463
  * Keep only the entries a predicate accepts
@@ -404,7 +466,8 @@ var MultilingualString = class MultilingualString {
404
466
  * can also test `richText` and `isPrimary`. Dropping every entry of a
405
467
  * language removes that language, and when that was the default the default
406
468
  * moves to the first language that still has content, so reads keep
407
- * resolving.
469
+ * resolving. Non-linguistic entries are tested too, with `null` as their
470
+ * language.
408
471
  * @param shouldKeep - Whether to keep one entry
409
472
  * @returns A new multilingual string
410
473
  */
@@ -420,7 +483,7 @@ var MultilingualString = class MultilingualString {
420
483
  return MultilingualString.fromNormalized(newContent, {
421
484
  ...this._options,
422
485
  defaultLanguage: newAvailableLanguages.includes(this._options.defaultLanguage) ? this._options.defaultLanguage : resolveDefaultLanguageOption(newAvailableLanguages, this._options.availableLanguages)
423
- }, newAvailableLanguages);
486
+ }, newAvailableLanguages, this._nonLinguistic.filter((entry) => shouldKeep({ ...entry }, null)));
424
487
  }
425
488
  /**
426
489
  * Get the JSON representation
@@ -435,6 +498,7 @@ var MultilingualString = class MultilingualString {
435
498
  return {
436
499
  content,
437
500
  aliases: this.getAliases(),
501
+ nonLinguistic: Array.from(this._nonLinguistic, (entry) => ({ ...entry })),
438
502
  defaultLanguage: this._options.defaultLanguage
439
503
  };
440
504
  }
@@ -37,6 +37,9 @@ export declare function parseXMLContent<V extends ReadonlyArray<string>>(item: X
37
37
  }): MultilingualString<V>;
38
38
  /**
39
39
  * Extracts alias strings from XMLContent where lang="zxx"
40
+ *
41
+ * They are aliases only beside another language; parseXMLContent reads
42
+ * `zxx` content standing alone as non-linguistic text instead.
40
43
  * @param content - The XMLContent to extract aliases from
41
44
  * @returns Array of alias strings, or null if none found
42
45
  *
@@ -459,8 +459,10 @@ function parseXMLContent(item, options) {
459
459
  defaultLanguage: options.defaultLanguage
460
460
  });
461
461
  }
462
+ const nonLinguistic = [];
463
+ for (const contentItem of item.content) if (contentItem.lang === "zxx") nonLinguistic.push(parseXMLContentItem(contentItem, { languages: ["zxx"] }));
462
464
  return MultilingualString.empty(languages, {
463
- aliases,
465
+ nonLinguistic,
464
466
  defaultLanguage: options.defaultLanguage
465
467
  });
466
468
  }
@@ -487,6 +489,9 @@ function parseXMLContentItem(contentItem, options) {
487
489
  }
488
490
  /**
489
491
  * Extracts alias strings from XMLContent where lang="zxx"
492
+ *
493
+ * They are aliases only beside another language; parseXMLContent reads
494
+ * `zxx` content standing alone as non-linguistic text instead.
490
495
  * @param content - The XMLContent to extract aliases from
491
496
  * @returns Array of alias strings, or null if none found
492
497
  *
@@ -14,10 +14,13 @@ export declare function isPseudoUuid(value: string): boolean;
14
14
  */
15
15
  export declare const uuidSchema: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.CheckAction<string, "Invalid pseudo-UUID">]>;
16
16
  /**
17
- * Schema for validating language codes
17
+ * Schema for validating OCHRE language codes
18
+ *
19
+ * Rejects standard codes OCHRE does not store, naming the OCHRE code to use
20
+ * instead (`per` for ISO 639-3 `fas`).
18
21
  * @internal
19
22
  */
20
- export declare const iso639_3Schema: v.SchemaWithPipe<readonly [v.StringSchema<"Language code must be a string">, v.RegexAction<string, "Language code must be exactly 3 lowercase letters">]>;
23
+ export declare const ochreLanguageCodeSchema: v.SchemaWithPipe<readonly [v.StringSchema<"Language code must be a string">, v.CheckAction<string, (issue: v.CheckIssue<string>) => string>]>;
21
24
  /**
22
25
  * Valid component types for web elements
23
26
  * @internal
package/dist/schemas.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import "./constants.mjs";
2
+ import { getOchreLanguageCode, isOchreLanguageCode } from "./languages.mjs";
2
3
  import * as v from "valibot";
3
4
  //#region src/schemas.ts
4
5
  const PSEUDO_UUID_REGEX = /^[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}$/i;
@@ -21,10 +22,17 @@ const sortDirectionSchema = v.optional(v.picklist(["asc", "desc"]), "asc");
21
22
  */
22
23
  const uuidSchema = v.pipe(v.string(), v.check(isPseudoUuid, "Invalid pseudo-UUID"));
23
24
  /**
24
- * Schema for validating language codes
25
+ * Schema for validating OCHRE language codes
26
+ *
27
+ * Rejects standard codes OCHRE does not store, naming the OCHRE code to use
28
+ * instead (`per` for ISO 639-3 `fas`).
25
29
  * @internal
26
30
  */
27
- const iso639_3Schema = v.pipe(v.string("Language code must be a string"), v.regex(/^[a-z]{3}$/, "Language code must be exactly 3 lowercase letters"));
31
+ const ochreLanguageCodeSchema = v.pipe(v.string("Language code must be a string"), v.check(isOchreLanguageCode, (issue) => {
32
+ const input = issue.input;
33
+ const ochreCode = getOchreLanguageCode(input);
34
+ return ochreCode == null ? `Unknown OCHRE language code "${input}"` : `Unknown OCHRE language code "${input}"; OCHRE stores this language as "${ochreCode}"`;
35
+ }));
28
36
  /**
29
37
  * Valid component types for web elements
30
38
  * @internal
@@ -281,4 +289,4 @@ const treeItemsParametersSchema = v.object({
281
289
  ...containerItemsParametersEntries
282
290
  });
283
291
  //#endregion
284
- export { componentSchema, gallerySchema, isPseudoUuid, iso639_3Schema, itemOcrDataParametersSchema, renderOptionsSchema, setItemLocationsParametersSchema, setItemsParametersSchema, setPropertyValuesParametersSchema, treeItemsParametersSchema, uuidSchema };
292
+ export { componentSchema, gallerySchema, isPseudoUuid, itemOcrDataParametersSchema, ochreLanguageCodeSchema, renderOptionsSchema, setItemLocationsParametersSchema, setItemsParametersSchema, setPropertyValuesParametersSchema, treeItemsParametersSchema, uuidSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Node.js library for working with OCHRE (Online Cultural and Historical Research Environment) data",