ochre-sdk 1.1.0 → 1.1.1

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 CHANGED
@@ -84,6 +84,34 @@ title.getExactText("tur");
84
84
  title.getAvailableLanguages();
85
85
  ```
86
86
 
87
+ Reads come in three widths. `getText` and `getRichText` resolve one entry through the language fallback, `getExactText` and `getExactRichText` skip the fallback, and `getEntries`, `getTexts` and `getExactTexts` return every entry when OCHRE carried more than one for a language.
88
+
89
+ Two questions look alike and are not the same. `isEmpty()` asks whether any language carries an entry at all. `hasContent()` asks whether any entry in any language holds text that is not whitespace, which is what a caller deciding whether to render something wants, because OCHRE does serve fields holding a single blank entry.
90
+
91
+ ```ts
92
+ title.isEmpty();
93
+ title.hasContent();
94
+ title.hasLanguage("tur");
95
+ title.hasAliases();
96
+
97
+ title.getAvailableLanguages(); // languages that carry content
98
+ title.getSupportedLanguages(); // languages the string was built to hold
99
+ ```
100
+
101
+ Writes return a new string and never mutate the original.
102
+
103
+ ```ts
104
+ title.with("tur", "Başlık");
105
+ title.with("tur", "another entry", { shouldAppend: true });
106
+ title.without("tur");
107
+ title.withAliases(["ABC"]);
108
+
109
+ title.mapText((text) => text.trim());
110
+ title.filterEntries((entry) => entry.isPrimary);
111
+ ```
112
+
113
+ `mapText` runs against plain text and rebuilds each entry's rich text from the result, so a transform cannot corrupt the markup OCHRE wrote. A transform that needs to keep or rewrite markup returns `{ text, richText }` instead of a string.
114
+
87
115
  For reusable language tuples, use `defineLanguages` to keep runtime validation
88
116
  and literal TypeScript inference together.
89
117
 
@@ -177,8 +205,9 @@ types, query types, property getters, and small data helpers:
177
205
  - `Item`, `SetItem`, `ItemLink`, `Website`, `WebElementOf`,
178
206
  `WebElementComponentOf`, `WebBlockByLayout`, `Query`, and related types.
179
207
  - `getProperty`, `getPropertyValues`, `getPropertyValue`,
180
- `getUniqueProperties`, `getUniquePropertyVariableLabels`, and
181
- `isPropertyMatchingFilter` for reading properties off a parsed item.
208
+ `getUniqueProperties`, `getUniquePropertyVariableLabels`,
209
+ `isPropertyMatchingFilter`, and `getLeafPropertyValues` for reading
210
+ properties off a parsed item.
182
211
  - `flattenItemProperties` and `DEFAULT_PAGE_SIZE` for common collection UI
183
212
  workflows.
184
213
 
@@ -53,6 +53,17 @@ export type PropertySelector<T extends LanguageCodes = LanguageCodes> = {
53
53
  * @returns The normalized label
54
54
  */
55
55
  export declare function normalizePropertyVariableLabel(value: string): string;
56
+ /**
57
+ * Keep only the leaf values from an array of property values
58
+ *
59
+ * OCHRE property values form a hierarchy, and a value with children is usually
60
+ * a grouping rather than something to show. This asks that of a values array
61
+ * the caller already holds; the same filter is available on the lookups
62
+ * through `limitToLeafPropertyValues`.
63
+ * @param propertyValues - The values to filter
64
+ * @returns The values that have no children
65
+ */
66
+ export declare function getLeafPropertyValues<T extends LanguageCodes = LanguageCodes>(propertyValues: ReadonlyArray<PropertyValueContent<T>>): Array<PropertyValueContent<T>>;
56
67
  /**
57
68
  * Find the property a selector names
58
69
  *
package/dist/getters.mjs CHANGED
@@ -88,6 +88,16 @@ function findProperty(properties, isMatch, shouldIncludeNestedProperties) {
88
88
  }
89
89
  return null;
90
90
  }
91
+ /**
92
+ * Keep only the leaf values from an array of property values
93
+ *
94
+ * OCHRE property values form a hierarchy, and a value with children is usually
95
+ * a grouping rather than something to show. This asks that of a values array
96
+ * the caller already holds; the same filter is available on the lookups
97
+ * through `limitToLeafPropertyValues`.
98
+ * @param propertyValues - The values to filter
99
+ * @returns The values that have no children
100
+ */
91
101
  function getLeafPropertyValues(propertyValues) {
92
102
  const leafPropertyValues = [];
93
103
  for (const value of propertyValues) if (value.hierarchy.isLeaf) leafPropertyValues.push(value);
@@ -224,4 +234,4 @@ function isPropertyMatchingFilter(property, filter, options = DEFAULT_OPTIONS) {
224
234
  return false;
225
235
  }
226
236
  //#endregion
227
- export { getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
237
+ export { getLeafPropertyValues, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { MultilingualOptions, MultilingualString, MultilingualStringEntries, MultilingualStringEntry, MultilingualStringInput, MultilingualStringJSON, MultilingualStringObject, MultilingualStringText } from "./parsers/multilingual.mjs";
2
- import { ContextTree, ContextTreeFilterLevel, ContextTreeFilterVariant, ContextTreeLevel, ContextTreeLevelItem, ProtectedWebsite, ResponsiveStyles, Scope, Style, StylesheetItem, WebAccordionItem, WebBlock, WebBlockByLayout, WebBlockItem, WebBlockLayout, WebElement, WebElementComponent, WebElementComponentName, WebElementComponentOf, WebElementOf, WebIiifViewer, WebImage, WebLoadingVariant, WebOptions, WebSectionDisplay, WebSectionVariant, WebSidebar, WebTitle, Webpage, Website, WebsiteMetadata, WebsitePrivacy, WebsitePropertyQuery, WebsitePropertyQueryNode, WebsiteSegment, WebsiteType } from "./types/website.mjs";
3
- import { BaseItem, BaseItemLink, BelongsTo, Bibliography, BibliographyEntryInfo, BibliographyItemLink, BibliographySourceDocument, Concept, ConceptItemLink, ContainedItemCategory, ContainedItemCategoryFromOption, ContainedItemCategoryOption, Context, ContextItem, ContextItemCategory, ContextNode, Coordinates, CoordinatesSource, DictionaryUnitItemLink, Event, Gallery, Heading, HeadingItemCategory, Identification, Image, ImageMap, ImageMapArea, Interpretation, Item, ItemCategory, ItemCategoryFromOption, ItemCategoryOption, ItemCategoryWithEmbeddedItems, ItemContainerCategory, ItemLink, ItemLinkCategory, ItemLinks, ItemPayloadKind, ItemWithoutEmbeddedItems, LanguageCodes, License, Metadata, Note, Observation, OcrString, Period, PeriodItemLink, Person, PersonItemLink, Property, PropertyLike, PropertyRelation, PropertyValue, PropertyValueContent, PropertyValueDataType, PropertyValueItemLink, PropertyValueQueryItem, PropertyVariable, PropertyVariableItemLink, Query, QueryGroup, QueryLeaf, QueryablePropertyValueDataType, Resource, ResourceItemLink, Section, Set, SetAttributeValueQueryItem, SetBibliography, SetConcept, SetItem, SetItemCategory, SetItemLink, SetItemProperty, SetItemSimplifiedProperty, SetItemsSort, SetItemsSortDirection, SetPeriod, SetResource, SetSpatialUnit, SetTree, SimplifiedProperty, SpatialUnit, SpatialUnitItemLink, Text, TextItemLink, Tree, TreeItemCategory, TreeItemLink } from "./types/index.mjs";
2
+ import { AccordionWebBlock, ContextTree, ContextTreeFilterLevel, ContextTreeFilterVariant, ContextTreeLevel, ContextTreeLevelItem, ProtectedWebsite, ResponsiveStyles, Scope, Style, StylesheetCategory, StylesheetItem, WebAccordionItem, WebBlock, WebBlockByLayout, WebBlockItem, WebBlockLayout, WebElement, WebElementComponent, WebElementComponentName, WebElementComponentOf, WebElementOf, WebIiifViewer, WebImage, WebLoadingVariant, WebOptions, WebSectionDisplay, WebSectionVariant, WebSidebar, WebTitle, Webpage, Website, WebsiteMetadata, WebsitePrivacy, WebsitePropertyQuery, WebsitePropertyQueryNode, WebsiteSegment, WebsiteType } from "./types/website.mjs";
3
+ import { AnyBibliography, AnyConcept, AnyItem, AnyPeriod, AnyPerson, AnyPropertyValue, AnyPropertyVariable, AnyResource, AnySet, AnySpatialUnit, AnyText, AnyTree, BaseItem, BaseItemLink, BelongsTo, Bibliography, BibliographyEntryInfo, BibliographyItemLink, BibliographySourceDocument, Concept, ConceptItemLink, ContainedItemCategory, ContainedItemCategoryFromOption, ContainedItemCategoryOption, Context, ContextItem, ContextItemCategory, ContextNode, Coordinates, CoordinatesSource, DictionaryUnitItemLink, EmbeddedBibliography, EmbeddedConcept, EmbeddedItem, EmbeddedPeriod, EmbeddedPerson, EmbeddedPropertyValue, EmbeddedPropertyVariable, EmbeddedResource, EmbeddedSet, EmbeddedSpatialUnit, EmbeddedText, EmbeddedTree, Event, Gallery, Heading, HeadingItemCategory, Identification, Image, ImageMap, ImageMapArea, Interpretation, Item, ItemCategory, ItemCategoryFromOption, ItemCategoryOption, ItemCategoryWithEmbeddedItems, ItemContainerCategory, ItemLink, ItemLinkCategory, ItemLinks, ItemPayloadKind, ItemProperty, ItemWithoutEmbeddedItems, LanguageCodes, License, Metadata, Note, Observation, OcrString, Period, PeriodItemLink, Person, PersonItemLink, Property, PropertyLike, PropertyRelation, PropertyValue, PropertyValueContent, PropertyValueDataType, PropertyValueItemLink, PropertyValueQueryItem, PropertyVariable, PropertyVariableItemLink, Query, QueryGroup, QueryLeaf, QueryablePropertyValueDataType, RecursiveItemCategory, Resource, ResourceItemLink, Section, Set, SetAttributeValueQueryItem, SetBibliography, SetConcept, SetItem, SetItemCategory, SetItemLink, SetItemProperty, SetItemSimplifiedProperty, SetItemsSort, SetItemsSortDirection, SetPeriod, SetResource, SetSpatialUnit, SetTree, SimplifiedProperty, SpatialUnit, SpatialUnitItemLink, Text, TextItemLink, TopLevelItem, Tree, TreeItemCategory, TreeItemLink } from "./types/index.mjs";
4
4
  import { DEFAULT_PAGE_SIZE } from "./constants.mjs";
5
5
  import { fetchGallery } from "./fetchers/gallery.mjs";
6
6
  import { fetchItemChildren } from "./fetchers/item-children.mjs";
@@ -11,7 +11,7 @@ import { fetchSetItems } from "./fetchers/set/items.mjs";
11
11
  import { fetchSetPropertyValues } from "./fetchers/set/property-values.mjs";
12
12
  import { fetchWebsiteMetadata } from "./fetchers/website-metadata.mjs";
13
13
  import { fetchWebsite } from "./fetchers/website.mjs";
14
- import { PropertyOptions, PropertySelector, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel } from "./getters.mjs";
14
+ import { PropertyOptions, PropertySelector, getLeafPropertyValues, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel } from "./getters.mjs";
15
15
  import { flattenItemProperties } from "./helpers.mjs";
16
16
  import { defineLanguages } from "./parsers/languages.mjs";
17
- export { type BaseItem, type BaseItemLink, type BelongsTo, type Bibliography, type BibliographyEntryInfo, type BibliographyItemLink, type BibliographySourceDocument, type Concept, type ConceptItemLink, type ContainedItemCategory, type ContainedItemCategoryFromOption, type ContainedItemCategoryOption, type Context, type ContextItem, type ContextItemCategory, type ContextNode, type ContextTree, type ContextTreeFilterLevel, type ContextTreeFilterVariant, type ContextTreeLevel, type ContextTreeLevelItem, type Coordinates, type CoordinatesSource, DEFAULT_PAGE_SIZE, type DictionaryUnitItemLink, type Event, type Gallery, type Heading, type HeadingItemCategory, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type Item, type ItemCategory, type ItemCategoryFromOption, type ItemCategoryOption, type ItemCategoryWithEmbeddedItems, type ItemContainerCategory, type ItemLink, type ItemLinkCategory, type ItemLinks, type ItemPayloadKind, type ItemWithoutEmbeddedItems, type LanguageCodes, type License, type Metadata, type MultilingualOptions, MultilingualString, type MultilingualStringEntries, type MultilingualStringEntry, type MultilingualStringInput, type MultilingualStringJSON, type MultilingualStringObject, type MultilingualStringText, type Note, type Observation, type OcrString, type Period, type PeriodItemLink, type Person, type PersonItemLink, type Property, type PropertyLike, type PropertyOptions, type PropertyRelation, type PropertySelector, type PropertyValue, type PropertyValueContent, type PropertyValueDataType, type PropertyValueItemLink, type PropertyValueQueryItem, type PropertyVariable, type PropertyVariableItemLink, type ProtectedWebsite, type Query, type QueryGroup, type QueryLeaf, type QueryablePropertyValueDataType, type Resource, type ResourceItemLink, type ResponsiveStyles, type Scope, type Section, type Set, type SetAttributeValueQueryItem, type SetBibliography, type SetConcept, type SetItem, type SetItemCategory, type SetItemLink, type SetItemProperty, type SetItemSimplifiedProperty, type SetItemsSort, type SetItemsSortDirection, type SetPeriod, type SetResource, type SetSpatialUnit, type SetTree, type SimplifiedProperty, type SpatialUnit, type SpatialUnitItemLink, type Style, type StylesheetItem, type Text, type TextItemLink, type Tree, type TreeItemCategory, type TreeItemLink, type WebAccordionItem, type WebBlock, type WebBlockByLayout, type WebBlockItem, type WebBlockLayout, type WebElement, type WebElementComponent, type WebElementComponentName, type WebElementComponentOf, type WebElementOf, type WebIiifViewer, type WebImage, type WebLoadingVariant, type WebOptions, type WebSectionDisplay, type WebSectionVariant, type WebSidebar, type WebTitle, type Webpage, type Website, type WebsiteMetadata, type WebsitePrivacy, type WebsitePropertyQuery, type WebsitePropertyQueryNode, type WebsiteSegment, type WebsiteType, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata, flattenItemProperties, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
17
+ export { type AccordionWebBlock, type AnyBibliography, type AnyConcept, type AnyItem, type AnyPeriod, type AnyPerson, type AnyPropertyValue, type AnyPropertyVariable, type AnyResource, type AnySet, type AnySpatialUnit, type AnyText, type AnyTree, type BaseItem, type BaseItemLink, type BelongsTo, type Bibliography, type BibliographyEntryInfo, type BibliographyItemLink, type BibliographySourceDocument, type Concept, type ConceptItemLink, type ContainedItemCategory, type ContainedItemCategoryFromOption, type ContainedItemCategoryOption, type Context, type ContextItem, type ContextItemCategory, type ContextNode, type ContextTree, type ContextTreeFilterLevel, type ContextTreeFilterVariant, type ContextTreeLevel, type ContextTreeLevelItem, type Coordinates, type CoordinatesSource, DEFAULT_PAGE_SIZE, type DictionaryUnitItemLink, type EmbeddedBibliography, type EmbeddedConcept, type EmbeddedItem, type EmbeddedPeriod, type EmbeddedPerson, type EmbeddedPropertyValue, type EmbeddedPropertyVariable, type EmbeddedResource, type EmbeddedSet, type EmbeddedSpatialUnit, type EmbeddedText, type EmbeddedTree, type Event, type Gallery, type Heading, type HeadingItemCategory, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type Item, type ItemCategory, type ItemCategoryFromOption, type ItemCategoryOption, type ItemCategoryWithEmbeddedItems, type ItemContainerCategory, type ItemLink, type ItemLinkCategory, type ItemLinks, type ItemPayloadKind, type ItemProperty, type ItemWithoutEmbeddedItems, type LanguageCodes, type License, type Metadata, type MultilingualOptions, MultilingualString, type MultilingualStringEntries, type MultilingualStringEntry, type MultilingualStringInput, type MultilingualStringJSON, type MultilingualStringObject, type MultilingualStringText, type Note, type Observation, type OcrString, type Period, type PeriodItemLink, type Person, type PersonItemLink, type Property, type PropertyLike, type PropertyOptions, type PropertyRelation, type PropertySelector, type PropertyValue, type PropertyValueContent, type PropertyValueDataType, type PropertyValueItemLink, type PropertyValueQueryItem, type PropertyVariable, type PropertyVariableItemLink, type ProtectedWebsite, type Query, type QueryGroup, type QueryLeaf, type QueryablePropertyValueDataType, type RecursiveItemCategory, type Resource, type ResourceItemLink, type ResponsiveStyles, type Scope, type Section, type Set, type SetAttributeValueQueryItem, type SetBibliography, type SetConcept, type SetItem, type SetItemCategory, type SetItemLink, type SetItemProperty, type SetItemSimplifiedProperty, type SetItemsSort, type SetItemsSortDirection, type SetPeriod, type SetResource, type SetSpatialUnit, type SetTree, type SimplifiedProperty, type SpatialUnit, type SpatialUnitItemLink, type Style, type StylesheetCategory, type StylesheetItem, type Text, type TextItemLink, type TopLevelItem, type Tree, type TreeItemCategory, type TreeItemLink, type WebAccordionItem, type WebBlock, type WebBlockByLayout, type WebBlockItem, type WebBlockLayout, type WebElement, type WebElementComponent, type WebElementComponentName, type WebElementComponentOf, type WebElementOf, type WebIiifViewer, type WebImage, type WebLoadingVariant, type WebOptions, type WebSectionDisplay, type WebSectionVariant, type WebSidebar, type WebTitle, type Webpage, type Website, type WebsiteMetadata, type WebsitePrivacy, type WebsitePropertyQuery, type WebsitePropertyQueryNode, type WebsiteSegment, type WebsiteType, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata, flattenItemProperties, getLeafPropertyValues, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_PAGE_SIZE } from "./constants.mjs";
2
- import { getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel } from "./getters.mjs";
2
+ import { getLeafPropertyValues, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel } from "./getters.mjs";
3
3
  import { flattenItemProperties } from "./helpers.mjs";
4
4
  import { MultilingualString } from "./parsers/multilingual.mjs";
5
5
  import { defineLanguages } from "./parsers/languages.mjs";
@@ -12,4 +12,4 @@ import { fetchSetItems } from "./fetchers/set/items.mjs";
12
12
  import { fetchSetPropertyValues } from "./fetchers/set/property-values.mjs";
13
13
  import { fetchWebsiteMetadata } from "./fetchers/website-metadata.mjs";
14
14
  import { fetchWebsite } from "./fetchers/website.mjs";
15
- export { DEFAULT_PAGE_SIZE, MultilingualString, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata, flattenItemProperties, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
15
+ export { DEFAULT_PAGE_SIZE, MultilingualString, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata, flattenItemProperties, getLeafPropertyValues, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
@@ -126,6 +126,29 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
126
126
  * Get every entry for a specific language, with no fallback
127
127
  */
128
128
  getExactEntries(language: T[number]): Array<MultilingualStringEntry>;
129
+ /**
130
+ * Get every entry for a language, falling back when it has none
131
+ *
132
+ * The multi-entry counterpart of {@link MultilingualString.getText}: OCHRE
133
+ * can carry several entries for one language, and this returns all of them
134
+ * rather than only the primary. Each entry carries both `text` and
135
+ * `richText`, so a caller rendering a rich field reads them from here.
136
+ * @param language - The language to read, or undefined for the default
137
+ * @returns The entries, or an empty array when no language has any
138
+ */
139
+ getEntries(language?: T[number]): Array<MultilingualStringEntry>;
140
+ /**
141
+ * Get the text of every entry for a language, falling back when it has none
142
+ * @param language - The language to read, or undefined for the default
143
+ * @returns The texts, or an empty array when no language has any
144
+ */
145
+ getTexts(language?: T[number]): Array<string>;
146
+ /**
147
+ * Get the text of every entry for a language, with no fallback
148
+ * @param language - The language to read
149
+ * @returns The texts, or an empty array when that language has none
150
+ */
151
+ getExactTexts(language: T[number]): Array<string>;
129
152
  /**
130
153
  * Get the alias values OCHRE carries as `zxx` content
131
154
  */
@@ -138,6 +161,46 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
138
161
  * Get the language reads fall back to before trying the rest
139
162
  */
140
163
  getDefaultLanguage(): T[number];
164
+ /**
165
+ * Get every language this string was built to hold
166
+ *
167
+ * The configured language list, which is not the same question as
168
+ * {@link MultilingualString.getAvailableLanguages}: that one answers which
169
+ * languages actually carry content, and is a subset of this.
170
+ * @returns The supported languages
171
+ */
172
+ getSupportedLanguages(): Array<T[number]>;
173
+ /**
174
+ * Whether any language carries an entry
175
+ *
176
+ * Answers the structural question. A language whose only entry is blank
177
+ * 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
181
+ */
182
+ isEmpty(): boolean;
183
+ /**
184
+ * Whether any entry in any language carries text that is not whitespace
185
+ *
186
+ * Deliberately not the negation of {@link MultilingualString.isEmpty}, which
187
+ * only asks whether entries exist. OCHRE does serve fields holding a single
188
+ * whitespace entry, so a caller deciding whether to render something wants
189
+ * this one, and it looks at every entry rather than only the primary.
190
+ * @returns True when some entry has non-whitespace text
191
+ */
192
+ hasContent(): boolean;
193
+ /**
194
+ * Whether a specific language carries an entry, with no fallback
195
+ * @param language - The language to test
196
+ * @returns True when that language carries at least one entry
197
+ */
198
+ hasLanguage(language: T[number]): boolean;
199
+ /**
200
+ * Whether OCHRE carried any `zxx` alias values for this string
201
+ * @returns True when there is at least one alias
202
+ */
203
+ hasAliases(): boolean;
141
204
  /**
142
205
  * Set the text for a language, or append another entry to it
143
206
  * @param language - The language to write
@@ -158,6 +221,44 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
158
221
  * @returns A new multilingual string
159
222
  */
160
223
  without(language: T[number]): MultilingualString<T>;
224
+ /**
225
+ * Replace the alias values
226
+ *
227
+ * Aliases are the `zxx` content OCHRE carries alongside a field's languages,
228
+ * so they are set as a whole rather than per language. Empty strings are
229
+ * dropped, matching how they are read from a payload.
230
+ * @param aliases - The aliases to carry
231
+ * @returns A new multilingual string
232
+ */
233
+ withAliases(aliases: ReadonlyArray<string>): MultilingualString<T>;
234
+ /**
235
+ * Transform the text of every entry in every language
236
+ *
237
+ * Replaces the old `map`, which corrupted rich text: it wrote the
238
+ * transformed plain text and left the entry's `richText` to be re-derived,
239
+ * so a transform such as uppercasing turned `<InternalLink uuid="abc">` into
240
+ * markup OCHRE never wrote. The transform here runs against plain text only,
241
+ * and the entry's rich text is rebuilt from the result, so the two can never
242
+ * disagree.
243
+ *
244
+ * A transform that needs to keep or rewrite markup returns
245
+ * `{ text, richText }` instead of a string, and both are used verbatim.
246
+ * @param transform - Produces the new text for one entry
247
+ * @returns A new multilingual string
248
+ */
249
+ mapText(transform: (text: string, language: T[number]) => MultilingualStringInput): MultilingualString<T>;
250
+ /**
251
+ * Keep only the entries a predicate accepts
252
+ *
253
+ * The callback receives the whole entry rather than just its text, so it
254
+ * can also test `richText` and `isPrimary`. Dropping every entry of a
255
+ * language removes that language, and when that was the default the default
256
+ * moves to the first language that still has content, so reads keep
257
+ * resolving.
258
+ * @param shouldKeep - Whether to keep one entry
259
+ * @returns A new multilingual string
260
+ */
261
+ filterEntries(shouldKeep: (entry: MultilingualStringEntry, language: T[number]) => boolean): MultilingualString<T>;
161
262
  /**
162
263
  * Get the string representation, using the default language
163
264
  */
@@ -222,6 +222,35 @@ var MultilingualString = class MultilingualString {
222
222
  return Array.from(this.resolveEntries(language, true), (entry) => ({ ...entry }));
223
223
  }
224
224
  /**
225
+ * Get every entry for a language, falling back when it has none
226
+ *
227
+ * The multi-entry counterpart of {@link MultilingualString.getText}: OCHRE
228
+ * can carry several entries for one language, and this returns all of them
229
+ * rather than only the primary. Each entry carries both `text` and
230
+ * `richText`, so a caller rendering a rich field reads them from here.
231
+ * @param language - The language to read, or undefined for the default
232
+ * @returns The entries, or an empty array when no language has any
233
+ */
234
+ getEntries(language) {
235
+ return Array.from(this.resolveEntries(language, false), (entry) => ({ ...entry }));
236
+ }
237
+ /**
238
+ * Get the text of every entry for a language, falling back when it has none
239
+ * @param language - The language to read, or undefined for the default
240
+ * @returns The texts, or an empty array when no language has any
241
+ */
242
+ getTexts(language) {
243
+ return Array.from(this.resolveEntries(language, false), (entry) => entry.text);
244
+ }
245
+ /**
246
+ * Get the text of every entry for a language, with no fallback
247
+ * @param language - The language to read
248
+ * @returns The texts, or an empty array when that language has none
249
+ */
250
+ getExactTexts(language) {
251
+ return Array.from(this.resolveEntries(language, true), (entry) => entry.text);
252
+ }
253
+ /**
225
254
  * Get the alias values OCHRE carries as `zxx` content
226
255
  */
227
256
  getAliases() {
@@ -240,6 +269,60 @@ var MultilingualString = class MultilingualString {
240
269
  return this._options.defaultLanguage;
241
270
  }
242
271
  /**
272
+ * Get every language this string was built to hold
273
+ *
274
+ * The configured language list, which is not the same question as
275
+ * {@link MultilingualString.getAvailableLanguages}: that one answers which
276
+ * languages actually carry content, and is a subset of this.
277
+ * @returns The supported languages
278
+ */
279
+ getSupportedLanguages() {
280
+ return [...this._options.availableLanguages];
281
+ }
282
+ /**
283
+ * Whether any language carries an entry
284
+ *
285
+ * Answers the structural question. A language whose only entry is blank
286
+ * 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
290
+ */
291
+ isEmpty() {
292
+ return this._availableLanguages.length === 0;
293
+ }
294
+ /**
295
+ * Whether any entry in any language carries text that is not whitespace
296
+ *
297
+ * Deliberately not the negation of {@link MultilingualString.isEmpty}, which
298
+ * only asks whether entries exist. OCHRE does serve fields holding a single
299
+ * whitespace entry, so a caller deciding whether to render something wants
300
+ * this one, and it looks at every entry rather than only the primary.
301
+ * @returns True when some entry has non-whitespace text
302
+ */
303
+ hasContent() {
304
+ for (const language of this._availableLanguages) {
305
+ const entries = this._content[language] ?? [];
306
+ for (const entry of entries) if (entry.text.trim() !== "") return true;
307
+ }
308
+ return false;
309
+ }
310
+ /**
311
+ * Whether a specific language carries an entry, with no fallback
312
+ * @param language - The language to test
313
+ * @returns True when that language carries at least one entry
314
+ */
315
+ hasLanguage(language) {
316
+ return (this._content[language]?.length ?? 0) > 0;
317
+ }
318
+ /**
319
+ * Whether OCHRE carried any `zxx` alias values for this string
320
+ * @returns True when there is at least one alias
321
+ */
322
+ hasAliases() {
323
+ return this._aliases.length > 0;
324
+ }
325
+ /**
243
326
  * Set the text for a language, or append another entry to it
244
327
  * @param language - The language to write
245
328
  * @param text - The text to write
@@ -274,6 +357,72 @@ var MultilingualString = class MultilingualString {
274
357
  }, newAvailableLanguages);
275
358
  }
276
359
  /**
360
+ * Replace the alias values
361
+ *
362
+ * Aliases are the `zxx` content OCHRE carries alongside a field's languages,
363
+ * so they are set as a whole rather than per language. Empty strings are
364
+ * dropped, matching how they are read from a payload.
365
+ * @param aliases - The aliases to carry
366
+ * @returns A new multilingual string
367
+ */
368
+ withAliases(aliases) {
369
+ return MultilingualString.fromNormalized(cloneContent(this._content), {
370
+ ...this._options,
371
+ aliases: normalizeAliases(aliases)
372
+ }, this._availableLanguages);
373
+ }
374
+ /**
375
+ * Transform the text of every entry in every language
376
+ *
377
+ * Replaces the old `map`, which corrupted rich text: it wrote the
378
+ * transformed plain text and left the entry's `richText` to be re-derived,
379
+ * so a transform such as uppercasing turned `<InternalLink uuid="abc">` into
380
+ * markup OCHRE never wrote. The transform here runs against plain text only,
381
+ * and the entry's rich text is rebuilt from the result, so the two can never
382
+ * disagree.
383
+ *
384
+ * A transform that needs to keep or rewrite markup returns
385
+ * `{ text, richText }` instead of a string, and both are used verbatim.
386
+ * @param transform - Produces the new text for one entry
387
+ * @returns A new multilingual string
388
+ */
389
+ mapText(transform) {
390
+ const newContent = {};
391
+ for (const language of this._availableLanguages) {
392
+ const currentEntries = this._content[language] ?? [];
393
+ newContent[language] = normalizePrimary(Array.from(currentEntries, (entry) => ({
394
+ ...normalizeInputText(transform(entry.text, language)),
395
+ isPrimary: entry.isPrimary
396
+ })));
397
+ }
398
+ return MultilingualString.fromNormalized(newContent, this._options, this._availableLanguages);
399
+ }
400
+ /**
401
+ * Keep only the entries a predicate accepts
402
+ *
403
+ * The callback receives the whole entry rather than just its text, so it
404
+ * can also test `richText` and `isPrimary`. Dropping every entry of a
405
+ * language removes that language, and when that was the default the default
406
+ * moves to the first language that still has content, so reads keep
407
+ * resolving.
408
+ * @param shouldKeep - Whether to keep one entry
409
+ * @returns A new multilingual string
410
+ */
411
+ filterEntries(shouldKeep) {
412
+ const newContent = {};
413
+ for (const language of this._availableLanguages) {
414
+ const currentEntries = this._content[language] ?? [];
415
+ const entries = [];
416
+ for (const entry of currentEntries) if (shouldKeep({ ...entry }, language)) entries.push({ ...entry });
417
+ newContent[language] = normalizePrimary(entries);
418
+ }
419
+ const newAvailableLanguages = getLanguagesWithEntries(newContent, this._options.availableLanguages);
420
+ return MultilingualString.fromNormalized(newContent, {
421
+ ...this._options,
422
+ defaultLanguage: newAvailableLanguages.includes(this._options.defaultLanguage) ? this._options.defaultLanguage : resolveDefaultLanguageOption(newAvailableLanguages, this._options.availableLanguages)
423
+ }, newAvailableLanguages);
424
+ }
425
+ /**
277
426
  * Get the string representation, using the default language
278
427
  */
279
428
  toString() {
@@ -888,4 +888,34 @@ export type QueryGroup = {
888
888
  * Represents a query for Set items
889
889
  */
890
890
  export type Query = QueryLeaf | QueryGroup;
891
+ export type AnyBibliography<T extends LanguageCodes = LanguageCodes> = Bibliography<T, ItemPayloadKind>;
892
+ export type AnyConcept<T extends LanguageCodes = LanguageCodes> = Concept<T, ItemPayloadKind>;
893
+ export type AnyItem<U extends ItemCategory = ItemCategory, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes> = Item<U, V, T, ItemPayloadKind>;
894
+ export type AnyPeriod<T extends LanguageCodes = LanguageCodes> = Period<T, ItemPayloadKind>;
895
+ export type AnyPerson<T extends LanguageCodes = LanguageCodes> = Person<T, ItemPayloadKind>;
896
+ export type AnyPropertyValue<T extends LanguageCodes = LanguageCodes> = PropertyValue<T, ItemPayloadKind>;
897
+ export type AnyPropertyVariable<T extends LanguageCodes = LanguageCodes> = PropertyVariable<T, ItemPayloadKind>;
898
+ export type AnyResource<T extends LanguageCodes = LanguageCodes> = Resource<T, ItemPayloadKind>;
899
+ export type AnySet<U extends SetItemCategory = SetItemCategory, T extends LanguageCodes = LanguageCodes> = Set<U, T, ItemPayloadKind>;
900
+ export type AnySpatialUnit<T extends LanguageCodes = LanguageCodes> = SpatialUnit<T, ItemPayloadKind>;
901
+ export type AnyText<T extends LanguageCodes = LanguageCodes> = Text<T, ItemPayloadKind>;
902
+ export type AnyTree<U extends TreeItemCategory = TreeItemCategory, T extends LanguageCodes = LanguageCodes> = Tree<U, T, ItemPayloadKind>;
903
+ export type EmbeddedBibliography<T extends LanguageCodes = LanguageCodes> = Bibliography<T, "embedded">;
904
+ export type EmbeddedConcept<T extends LanguageCodes = LanguageCodes> = Concept<T, "embedded">;
905
+ export type EmbeddedItem<U extends ItemCategory = ItemCategory, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes> = Item<U, V, T, "embedded">;
906
+ export type EmbeddedPeriod<T extends LanguageCodes = LanguageCodes> = Period<T, "embedded">;
907
+ export type EmbeddedPerson<T extends LanguageCodes = LanguageCodes> = Person<T, "embedded">;
908
+ export type EmbeddedPropertyValue<T extends LanguageCodes = LanguageCodes> = PropertyValue<T, "embedded">;
909
+ export type EmbeddedPropertyVariable<T extends LanguageCodes = LanguageCodes> = PropertyVariable<T, "embedded">;
910
+ export type EmbeddedResource<T extends LanguageCodes = LanguageCodes> = Resource<T, "embedded">;
911
+ export type EmbeddedSet<U extends SetItemCategory = SetItemCategory, T extends LanguageCodes = LanguageCodes> = Set<U, T, "embedded">;
912
+ export type EmbeddedSpatialUnit<T extends LanguageCodes = LanguageCodes> = SpatialUnit<T, "embedded">;
913
+ export type EmbeddedText<T extends LanguageCodes = LanguageCodes> = Text<T, "embedded">;
914
+ export type EmbeddedTree<U extends TreeItemCategory = TreeItemCategory, T extends LanguageCodes = LanguageCodes> = Tree<U, T, "embedded">;
915
+ export type ItemProperty<T extends LanguageCodes = LanguageCodes> = Property<T> | SetItemProperty<T>;
916
+ /**
917
+ * The category of items that expose recursive subitem structures.
918
+ */
919
+ export type RecursiveItemCategory = Exclude<ItemCategory, "tree" | "person" | "propertyVariable" | "propertyValue" | "set">;
920
+ export type TopLevelItem<U extends ItemCategory = ItemCategory, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes> = Item<U, V, T, "topLevel">;
891
921
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { MultilingualString } from "../parsers/multilingual.mjs";
2
2
  import { Prettify } from "./utilities.mjs";
3
- import { Bibliography, Identification, LanguageCodes, License, Metadata, Person, QueryablePropertyValueDataType } from "./index.mjs";
3
+ import { Bibliography, Identification, ItemCategory, LanguageCodes, License, Metadata, Person, QueryablePropertyValueDataType } from "./index.mjs";
4
4
  //#region src/types/website.d.ts
5
5
  /**
6
6
  * Represents a context tree level item with a variable and value
@@ -552,4 +552,9 @@ export type ProtectedWebsite<T extends LanguageCodes = LanguageCodes> = {
552
552
  privacy: "password" | "credentials-ochre";
553
553
  };
554
554
  };
555
+ export type AccordionWebBlock<T extends LanguageCodes = LanguageCodes> = WebBlock<T, "accordion">;
556
+ /**
557
+ * Represents a stylesheet item with its UUID and category
558
+ */
559
+ export type StylesheetCategory = Extract<ItemCategory, "propertyVariable" | "propertyValue">;
555
560
  //#endregion
@@ -1,5 +1,5 @@
1
1
  declare namespace types_d_exports {
2
- export { XMLBaseItem, XMLBibliography, XMLConcept, XMLContent, XMLContext, XMLContextGroup, XMLContextItem, XMLContextValue, XMLCoordinate, XMLCoordinates, XMLCoordinatesSource, XMLData, XMLDataItem, XMLDictionaryUnit, XMLEmptyContext, XMLEvent, XMLGallery, XMLGalleryData, XMLHeading, XMLIdentification, XMLImage, XMLImageMap, XMLImageMapArea, XMLInterpretation, XMLItemCategory, XMLItemLinks, XMLItemLinksData, XMLLicense, XMLLink, XMLLinkedBaseItem, XMLLinkedBibliography, XMLLinkedConcept, XMLLinkedPeriod, XMLLinkedPerson, XMLLinkedPropertyValue, XMLLinkedPropertyVariable, XMLLinkedResource, XMLLinkedSet, XMLLinkedSpatialUnit, XMLLinkedText, XMLLinkedTree, XMLMetadata, XMLNote, XMLObservation, XMLPeriod, XMLPerson, XMLProperty, XMLPropertyRelation, XMLPropertyValue, XMLPropertyVariable, XMLRecursiveItemCategory, XMLResource, XMLRichTextEnvelope, XMLSection, XMLSet, XMLSetItems, XMLSetItemsData, XMLSimplifiedProperty, XMLSpatialUnit, XMLString, XMLText, XMLTree, XMLWebsiteContext, XMLWebsiteContextItem, XMLWebsiteContextLevel, XMLWebsiteData, XMLWebsiteFilterContext, XMLWebsiteFilterContextItem, XMLWebsiteOptions, XMLWebsiteProperties, XMLWebsiteResource, XMLWebsiteResourceGroup, XMLWebsiteResourceItem, XMLWebsiteScope, XMLWebsiteSegment, XMLWebsiteStyle, XMLWebsiteTree };
2
+ export { XMLBaseItem, XMLBibliography, XMLConcept, XMLContent, XMLContext, XMLContextGroup, XMLContextItem, XMLContextValue, XMLCoordinate, XMLCoordinates, XMLCoordinatesSource, XMLData, XMLDataItem, XMLDictionaryUnit, XMLEmptyContext, XMLEvent, XMLGallery, XMLGalleryData, XMLHeading, XMLHeadingItemCategory, XMLIdentification, XMLImage, XMLImageMap, XMLImageMapArea, XMLInterpretation, XMLItemCategory, XMLItemLinks, XMLItemLinksData, XMLLicense, XMLLink, XMLLinkedBaseItem, XMLLinkedBibliography, XMLLinkedConcept, XMLLinkedPeriod, XMLLinkedPerson, XMLLinkedPropertyValue, XMLLinkedPropertyVariable, XMLLinkedResource, XMLLinkedSet, XMLLinkedSpatialUnit, XMLLinkedText, XMLLinkedTree, XMLMetadata, XMLNote, XMLObservation, XMLPeriod, XMLPerson, XMLProperty, XMLPropertyRelation, XMLPropertyValue, XMLPropertyVariable, XMLRecursiveItemCategory, XMLResource, XMLRichTextEnvelope, XMLSection, XMLSet, XMLSetItems, XMLSetItemsData, XMLSimplifiedProperty, XMLSpatialUnit, XMLString, XMLText, XMLTree, XMLWebsiteContext, XMLWebsiteContextItem, XMLWebsiteContextLevel, XMLWebsiteData, XMLWebsiteFilterContext, XMLWebsiteFilterContextItem, XMLWebsiteOptions, XMLWebsiteProperties, XMLWebsiteResource, XMLWebsiteResourceGroup, XMLWebsiteResourceItem, XMLWebsiteScope, XMLWebsiteSegment, XMLWebsiteStyle, XMLWebsiteTree };
3
3
  }
4
4
  export type XMLItemCategory = "tree" | "bibliography" | "spatialUnit" | "concept" | "period" | "person" | "propertyVariable" | "variable" | "propertyValue" | "value" | "text" | "resource" | "set";
5
5
  export type XMLRecursiveItemCategory = Exclude<XMLItemCategory, "tree" | "person" | "propertyVariable" | "propertyValue" | "set">;
@@ -901,5 +901,6 @@ export type XMLWebsiteData = {
901
901
  };
902
902
  };
903
903
  };
904
+ export type XMLHeadingItemCategory = Exclude<XMLItemCategory, "tree" | "bibliography" | "spatialUnit" | "concept" | "period">;
904
905
  //#endregion
905
906
  export { types_d_exports };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
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",