ochre-sdk 1.0.78 → 1.1.0

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.
Files changed (84) hide show
  1. package/README.md +31 -3
  2. package/dist/_virtual/_rolldown/runtime.mjs +13 -0
  3. package/dist/categories.d.mts +249 -0
  4. package/dist/categories.mjs +259 -0
  5. package/dist/constants.d.mts +14 -0
  6. package/dist/constants.mjs +18 -1
  7. package/dist/errors.d.mts +23 -0
  8. package/dist/{utilities.mjs → errors.mjs} +33 -84
  9. package/dist/fetchers/gallery.mjs +15 -51
  10. package/dist/fetchers/item-children.mjs +20 -66
  11. package/dist/fetchers/item-links.mjs +26 -79
  12. package/dist/fetchers/item-ocr-data.d.mts +2 -2
  13. package/dist/fetchers/item-ocr-data.mjs +11 -15
  14. package/dist/fetchers/item.d.mts +0 -15
  15. package/dist/fetchers/item.mjs +20 -72
  16. package/dist/fetchers/request.d.mts +70 -0
  17. package/dist/fetchers/request.mjs +100 -0
  18. package/dist/fetchers/set/items.mjs +27 -73
  19. package/dist/fetchers/set/property-values.d.mts +2 -3
  20. package/dist/fetchers/set/property-values.mjs +96 -130
  21. package/dist/fetchers/website-metadata.mjs +35 -57
  22. package/dist/fetchers/website.d.mts +2 -3
  23. package/dist/fetchers/website.mjs +22 -31
  24. package/dist/getters.d.mts +78 -148
  25. package/dist/getters.mjs +127 -208
  26. package/dist/helpers.d.mts +0 -4
  27. package/dist/helpers.mjs +19 -6
  28. package/dist/index.d.mts +8 -6
  29. package/dist/index.mjs +6 -4
  30. package/dist/ocr.d.mts +37 -0
  31. package/dist/ocr.mjs +52 -0
  32. package/dist/parsers/helpers.d.mts +21 -1
  33. package/dist/parsers/helpers.mjs +26 -6
  34. package/dist/parsers/index.d.mts +0 -8
  35. package/dist/parsers/index.mjs +118 -259
  36. package/dist/parsers/languages.d.mts +72 -0
  37. package/dist/parsers/languages.mjs +132 -0
  38. package/dist/parsers/multilingual.d.mts +49 -74
  39. package/dist/parsers/multilingual.mjs +88 -189
  40. package/dist/parsers/property-token.d.mts +34 -0
  41. package/dist/parsers/property-token.mjs +29 -0
  42. package/dist/parsers/string.d.mts +19 -0
  43. package/dist/parsers/string.mjs +45 -25
  44. package/dist/parsers/website/bounds.d.mts +10 -0
  45. package/dist/parsers/website/bounds.mjs +28 -0
  46. package/dist/parsers/website/components.d.mts +91 -0
  47. package/dist/parsers/website/components.mjs +681 -0
  48. package/dist/parsers/website/index.d.mts +0 -7
  49. package/dist/parsers/website/index.mjs +92 -1153
  50. package/dist/parsers/website/links.d.mts +36 -0
  51. package/dist/parsers/website/links.mjs +58 -0
  52. package/dist/parsers/website/messages.d.mts +24 -0
  53. package/dist/parsers/website/messages.mjs +31 -0
  54. package/dist/parsers/website/options.d.mts +6 -0
  55. package/dist/parsers/website/options.mjs +114 -0
  56. package/dist/parsers/website/properties.d.mts +12 -0
  57. package/dist/parsers/website/properties.mjs +158 -0
  58. package/dist/parsers/website/reader.d.mts +54 -4
  59. package/dist/parsers/website/reader.mjs +65 -20
  60. package/dist/parsers/website/slug.d.mts +64 -0
  61. package/dist/parsers/website/slug.mjs +82 -0
  62. package/dist/parsers/website/styles.d.mts +28 -0
  63. package/dist/parsers/website/styles.mjs +103 -0
  64. package/dist/parsers/website/walk.d.mts +68 -0
  65. package/dist/parsers/website/walk.mjs +116 -0
  66. package/dist/query.d.mts +66 -18
  67. package/dist/query.mjs +202 -48
  68. package/dist/reflection.d.mts +64 -0
  69. package/dist/reflection.mjs +79 -0
  70. package/dist/schemas.d.mts +7 -0
  71. package/dist/schemas.mjs +12 -3
  72. package/dist/types/index.d.mts +1 -31
  73. package/dist/types/utilities.d.mts +9 -0
  74. package/dist/types/utilities.mjs +1 -0
  75. package/dist/types/website.d.mts +49 -58
  76. package/dist/xml/metadata.d.mts +16 -0
  77. package/dist/xml/metadata.mjs +32 -11
  78. package/dist/xml/schemas.d.mts +5970 -3
  79. package/dist/xml/schemas.mjs +43 -45
  80. package/dist/xml/types.d.mts +13 -30
  81. package/dist/xquery.d.mts +46 -0
  82. package/dist/xquery.mjs +66 -0
  83. package/package.json +3 -3
  84. package/dist/utilities.d.mts +0 -54
@@ -0,0 +1,72 @@
1
+ import { XMLMetadata } from "../xml/types.mjs";
2
+ //#region src/parsers/languages.d.ts
3
+ /**
4
+ * Validate language codes while preserving literal tuple inference
5
+ * @param languages - The language codes to validate
6
+ * @returns The same tuple, with its literal types intact
7
+ * @internal
8
+ */
9
+ export declare function parseLanguages<const T extends ReadonlyArray<string>>(languages: T): T;
10
+ /**
11
+ * Define a reusable languages tuple with validation and literal type inference
12
+ *
13
+ * Inline arrays can be passed directly to a fetcher
14
+ * (`fetchItem(uuid, { languages: ["eng", "spa"] })`); use this when the
15
+ * language set is stored separately.
16
+ * @param languages - The language codes to validate
17
+ * @returns The same tuple, with its literal types intact
18
+ */
19
+ export declare function defineLanguages<const TLanguages extends ReadonlyArray<string>>(...languages: TLanguages): TLanguages;
20
+ /**
21
+ * Validate an optional caller-supplied language tuple
22
+ * @param languages - The language codes to validate, or undefined
23
+ * @returns The validated codes, or an empty array when none were requested
24
+ * @internal
25
+ */
26
+ export declare function parseRequestedLanguages(languages: ReadonlyArray<string> | undefined): ReadonlyArray<string>;
27
+ /**
28
+ * Resolve which languages to parse from the content of a payload
29
+ *
30
+ * Requested languages win. Otherwise every `content/@xml:lang` found anywhere
31
+ * beneath the node is used, falling back to {@link DEFAULT_LANGUAGES} when the
32
+ * payload carries no tagged content at all.
33
+ * @param node - The payload node to walk
34
+ * @param requestedLanguages - The languages the caller asked for
35
+ * @returns The languages to parse
36
+ * @internal
37
+ */
38
+ export declare function resolveContentLanguages(node: unknown, requestedLanguages: ReadonlyArray<string>): ReadonlyArray<string>;
39
+ /**
40
+ * Read the languages a dataset declares in its metadata
41
+ * @param rawOchre - The raw OCHRE payload root
42
+ * @param rawOchre.metadata - The payload metadata declaring the languages
43
+ * @param rawOchre.languages - The semicolon-separated fallback language list
44
+ * @returns The declared languages, falling back to {@link DEFAULT_LANGUAGES}
45
+ * @internal
46
+ */
47
+ export declare function parseMetadataLanguages(rawOchre: {
48
+ metadata: XMLMetadata;
49
+ languages?: string;
50
+ }): Array<string>;
51
+ /**
52
+ * Reconcile requested languages against the ones a dataset declares
53
+ * @param requestedLanguages - The languages the caller asked for
54
+ * @param metadataLanguages - The languages the dataset declares
55
+ * @returns The languages to parse
56
+ * @throws When a requested language is not offered by the dataset
57
+ * @internal
58
+ */
59
+ export declare function resolveLanguages<T extends ReadonlyArray<string>>(requestedLanguages: T | undefined, metadataLanguages: Array<string>): T;
60
+ /**
61
+ * Pick the language a dataset treats as its default
62
+ * @param rawOchre - The raw OCHRE payload root
63
+ * @param rawOchre.metadata - The payload metadata declaring the default
64
+ * @param languages - The languages being parsed
65
+ * @returns The default language
66
+ * @throws When `languages` is empty
67
+ * @internal
68
+ */
69
+ export declare function resolveDefaultLanguage<T extends ReadonlyArray<string>>(rawOchre: {
70
+ metadata: XMLMetadata;
71
+ }, languages: T): T[number];
72
+ //#endregion
@@ -0,0 +1,132 @@
1
+ import { DEFAULT_LANGUAGES } from "../constants.mjs";
2
+ import { readArrayProperty, readEntries } from "../reflection.mjs";
3
+ import { iso639_3Schema } from "../schemas.mjs";
4
+ import { parseStringLike } from "./helpers.mjs";
5
+ import * as v from "valibot";
6
+ //#region src/parsers/languages.ts
7
+ /**
8
+ * A content entry carrying a language tag
9
+ *
10
+ * A schema rather than a hand-written predicate, because this is exactly a
11
+ * shape check: `v.is` narrows only what it has verified, and an array or a
12
+ * `Date` cannot pass because neither carries a string `lang`.
13
+ */
14
+ const languageTaggedContentSchema = v.looseObject({ lang: v.string() });
15
+ /**
16
+ * The language tag OCHRE uses for content that has no language
17
+ */
18
+ const UNTAGGED_LANGUAGE = "zxx";
19
+ function collectContentLanguages(value, languages) {
20
+ if (Array.isArray(value)) {
21
+ for (const item of value) collectContentLanguages(item, languages);
22
+ return;
23
+ }
24
+ for (const contentItem of readArrayProperty(value, "content")) if (v.is(languageTaggedContentSchema, contentItem) && contentItem.lang !== UNTAGGED_LANGUAGE) languages.add(contentItem.lang);
25
+ for (const [, child] of readEntries(value)) collectContentLanguages(child, languages);
26
+ }
27
+ /**
28
+ * Validate language codes while preserving literal tuple inference
29
+ * @param languages - The language codes to validate
30
+ * @returns The same tuple, with its literal types intact
31
+ * @internal
32
+ */
33
+ function parseLanguages(languages) {
34
+ for (const language of languages) v.parse(iso639_3Schema, language);
35
+ return languages;
36
+ }
37
+ /**
38
+ * Define a reusable languages tuple with validation and literal type inference
39
+ *
40
+ * Inline arrays can be passed directly to a fetcher
41
+ * (`fetchItem(uuid, { languages: ["eng", "spa"] })`); use this when the
42
+ * language set is stored separately.
43
+ * @param languages - The language codes to validate
44
+ * @returns The same tuple, with its literal types intact
45
+ */
46
+ function defineLanguages(...languages) {
47
+ return parseLanguages(languages);
48
+ }
49
+ /**
50
+ * Validate an optional caller-supplied language tuple
51
+ * @param languages - The language codes to validate, or undefined
52
+ * @returns The validated codes, or an empty array when none were requested
53
+ * @internal
54
+ */
55
+ function parseRequestedLanguages(languages) {
56
+ return languages == null ? [] : parseLanguages(languages);
57
+ }
58
+ /**
59
+ * Resolve which languages to parse from the content of a payload
60
+ *
61
+ * Requested languages win. Otherwise every `content/@xml:lang` found anywhere
62
+ * beneath the node is used, falling back to {@link DEFAULT_LANGUAGES} when the
63
+ * payload carries no tagged content at all.
64
+ * @param node - The payload node to walk
65
+ * @param requestedLanguages - The languages the caller asked for
66
+ * @returns The languages to parse
67
+ * @internal
68
+ */
69
+ function resolveContentLanguages(node, requestedLanguages) {
70
+ if (requestedLanguages.length > 0) return requestedLanguages;
71
+ const languages = /* @__PURE__ */ new Set();
72
+ collectContentLanguages(node, languages);
73
+ return languages.size > 0 ? [...languages] : [...DEFAULT_LANGUAGES];
74
+ }
75
+ /**
76
+ * Read the languages a dataset declares in its metadata
77
+ * @param rawOchre - The raw OCHRE payload root
78
+ * @param rawOchre.metadata - The payload metadata declaring the languages
79
+ * @param rawOchre.languages - The semicolon-separated fallback language list
80
+ * @returns The declared languages, falling back to {@link DEFAULT_LANGUAGES}
81
+ * @internal
82
+ */
83
+ function parseMetadataLanguages(rawOchre) {
84
+ const languages = [];
85
+ const metadataLanguages = rawOchre.metadata.language ?? [];
86
+ for (const language of metadataLanguages) {
87
+ const parsedLanguage = parseStringLike(language);
88
+ if (parsedLanguage != null) languages.push(parsedLanguage);
89
+ }
90
+ if (languages.length > 0) return languages;
91
+ if (rawOchre.languages != null) {
92
+ for (const language of rawOchre.languages.split(";")) if (language !== "") languages.push(language);
93
+ }
94
+ return languages.length > 0 ? languages : [...DEFAULT_LANGUAGES];
95
+ }
96
+ /**
97
+ * Reconcile requested languages against the ones a dataset declares
98
+ * @param requestedLanguages - The languages the caller asked for
99
+ * @param metadataLanguages - The languages the dataset declares
100
+ * @returns The languages to parse
101
+ * @throws When a requested language is not offered by the dataset
102
+ * @internal
103
+ */
104
+ function resolveLanguages(requestedLanguages, metadataLanguages) {
105
+ if (requestedLanguages == null || requestedLanguages.length === 0) return metadataLanguages;
106
+ const unsupportedLanguages = [];
107
+ for (const requestedLanguage of requestedLanguages) if (!metadataLanguages.some((metadataLanguage) => metadataLanguage.toLocaleLowerCase("en-US") === requestedLanguage.toLocaleLowerCase("en-US"))) unsupportedLanguages.push(requestedLanguage);
108
+ if (unsupportedLanguages.length > 0) throw new Error(`The following language(s) are not supported by the dataset: ${unsupportedLanguages.toSorted((a, b) => a.localeCompare(b, "en-US")).join(", ")}. Available languages: ${metadataLanguages.toSorted((a, b) => a.localeCompare(b, "en-US")).join(", ")}`, { cause: unsupportedLanguages });
109
+ return requestedLanguages;
110
+ }
111
+ /**
112
+ * Pick the language a dataset treats as its default
113
+ * @param rawOchre - The raw OCHRE payload root
114
+ * @param rawOchre.metadata - The payload metadata declaring the default
115
+ * @param languages - The languages being parsed
116
+ * @returns The default language
117
+ * @throws When `languages` is empty
118
+ * @internal
119
+ */
120
+ function resolveDefaultLanguage(rawOchre, languages) {
121
+ const metadataLanguages = rawOchre.metadata.language ?? [];
122
+ for (const language of metadataLanguages) {
123
+ const parsedLanguage = parseStringLike(language);
124
+ if (parsedLanguage != null && language.default === "true" && languages.includes(parsedLanguage)) return parsedLanguage;
125
+ }
126
+ for (const language of languages) if (language === DEFAULT_LANGUAGES[0]) return language;
127
+ const firstLanguage = languages[0];
128
+ if (firstLanguage == null) throw new Error("Default language not found", { cause: languages });
129
+ return firstLanguage;
130
+ }
131
+ //#endregion
132
+ export { defineLanguages, parseLanguages, parseMetadataLanguages, parseRequestedLanguages, resolveContentLanguages, resolveDefaultLanguage, resolveLanguages };
@@ -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
+ * The language reads fall back to first
24
+ *
25
+ * Optional so payloads written before it existed still parse; when absent the
26
+ * first available language is used, which is what the old shape implied.
27
+ */
28
+ defaultLanguage?: string;
22
29
  };
23
30
  export type MultilingualStringObject<T extends ReadonlyArray<string> = ReadonlyArray<string>> = Partial<Record<T[number], MultilingualStringInput>>;
24
31
  export type MultilingualStringEntries<T extends ReadonlyArray<string> = ReadonlyArray<string>> = Partial<Record<T[number], ReadonlyArray<MultilingualStringInput>>>;
@@ -90,109 +97,77 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
90
97
  constructor(init: MultilingualStringInternalInit<T>);
91
98
  constructor(content: MultilingualStringObject<T>, languages: T, options?: MultilingualOptions);
92
99
  constructor(content?: Partial<Record<string, MultilingualStringInput>>, languages?: undefined, options?: MultilingualOptions);
93
- private getPrimaryEntry;
94
- /**
95
- * Get text in a specific language with automatic fallback
96
- */
97
- getText(language?: T[number]): string;
98
- /**
99
- * Get rich text in a specific language with automatic fallback
100
- */
101
- getRichText(language?: T[number]): string;
102
100
  /**
103
- * Get primary text in a specific language without fallback
101
+ * Resolve the entries to read for a language
102
+ *
103
+ * The fallback order is requested language, then the dataset's default
104
+ * language, then the first language that has any content. This is the only
105
+ * place that order is written down; every reader below is a projection of it.
104
106
  */
105
- getExactText(language: T[number]): string | null;
107
+ private resolveEntries;
108
+ private resolvePrimaryEntry;
106
109
  /**
107
- * Get primary rich text in a specific language without fallback
110
+ * Get text in a specific language, falling back when it has none
108
111
  */
109
- getExactRichText(language: T[number]): string | null;
110
- /**
111
- * Get all text entries in a specific language without fallback
112
- */
113
- getExactTexts(language: T[number]): Array<string>;
112
+ getText(language?: T[number]): string;
114
113
  /**
115
- * Get all rich text entries in a specific language without fallback
114
+ * Get rich text in a specific language, falling back when it has none
116
115
  */
117
- getExactRichTexts(language: T[number]): Array<string>;
116
+ getRichText(language?: T[number]): string;
118
117
  /**
119
- * Get all text entries in a specific language with fallback
118
+ * Get text in a specific language, with no fallback
120
119
  */
121
- getTexts(language?: T[number]): Array<string>;
120
+ getExactText(language: T[number]): string;
122
121
  /**
123
- * Get all rich text entries in a specific language with fallback
122
+ * Get rich text in a specific language, with no fallback
124
123
  */
125
- getRichTexts(language?: T[number]): Array<string>;
124
+ getExactRichText(language: T[number]): string;
126
125
  /**
127
- * Get all entries in a specific language without fallback
126
+ * Get every entry for a specific language, with no fallback
128
127
  */
129
128
  getExactEntries(language: T[number]): Array<MultilingualStringEntry>;
130
129
  /**
131
- * Get all entries in a specific language with fallback
132
- */
133
- getEntries(language?: T[number]): Array<MultilingualStringEntry>;
134
- /**
135
- * Get aliases carried by OCHRE as zxx content
130
+ * Get the alias values OCHRE carries as `zxx` content
136
131
  */
137
132
  getAliases(): Array<string>;
138
133
  /**
139
- * Check if text exists for a specific language
140
- */
141
- hasLanguage(language: T[number]): boolean;
142
- /**
143
- * Check if aliases exist
134
+ * Get the languages that actually carry content
144
135
  */
145
- hasAliases(): boolean;
136
+ getAvailableLanguages(): Array<T[number]>;
146
137
  /**
147
- * Get all available languages
148
- */
149
- getAvailableLanguages(): ReadonlyArray<T[number]>;
150
- /**
151
- * Get all supported languages (the full language array passed to constructor)
152
- */
153
- getSupportedLanguages(): T;
154
- /**
155
- * Check if the multilingual string is empty (no content in any language)
156
- */
157
- isEmpty(): boolean;
158
- /**
159
- * Check if the multilingual string has any content
160
- */
161
- hasContent(): boolean;
162
- /**
163
- * Get the default language
138
+ * Get the language reads fall back to before trying the rest
164
139
  */
165
140
  getDefaultLanguage(): T[number];
166
141
  /**
167
- * Add or update the primary text for a language (returns new instance)
168
- */
169
- withText(language: T[number], text: MultilingualStringInput): MultilingualString<T>;
170
- /**
171
- * Add another text entry for a language (returns new instance)
172
- */
173
- withEntry(language: T[number], text: MultilingualStringInput): MultilingualString<T>;
174
- /**
175
- * Replace aliases (returns new instance)
176
- */
177
- withAliases(aliases: ReadonlyArray<string>): MultilingualString<T>;
178
- /**
179
- * Remove text for a language (returns new instance)
180
- */
181
- withoutLanguage(language: T[number]): MultilingualString<T>;
182
- /**
183
- * Transform all language versions (returns new instance)
142
+ * Set the text for a language, or append another entry to it
143
+ * @param language - The language to write
144
+ * @param text - The text to write
145
+ * @param options - Write options
146
+ * @param options.shouldAppend - Append as an additional entry instead of replacing
147
+ * @returns A new multilingual string
184
148
  */
185
- map(function_: (text: string, language: T[number]) => string): MultilingualString<T>;
149
+ with(language: T[number], text: MultilingualStringInput, options?: {
150
+ shouldAppend?: boolean;
151
+ }): MultilingualString<T>;
186
152
  /**
187
- * Filter languages based on predicate (returns new instance)
153
+ * Remove the content for a language
154
+ *
155
+ * When the removed language was the default, the default moves to the first
156
+ * language that still has content, so reads keep resolving.
157
+ * @param language - The language to remove
158
+ * @returns A new multilingual string
188
159
  */
189
- filter(shouldInclude: (text: string, language: T[number]) => boolean): MultilingualString<T>;
160
+ without(language: T[number]): MultilingualString<T>;
190
161
  /**
191
- * Get the string representation (uses default language)
162
+ * Get the string representation, using the default language
192
163
  */
193
164
  toString(): string;
194
165
  /**
195
- * Get JSON representation
166
+ * Get the JSON representation
167
+ *
168
+ * Carries `defaultLanguage`, because it is not derivable from the content:
169
+ * without it {@link MultilingualString.fromJSON} would fall back to the first
170
+ * available language and `getText()` would resolve differently.
196
171
  */
197
172
  toJSON(): MultilingualStringJSON<T>;
198
173
  }