ochre-sdk 0.20.12 → 0.20.13
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/dist/index.d.mts +24 -1
- package/dist/index.mjs +106 -4
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -643,6 +643,26 @@ type PropertyValueQueryItem = {
|
|
|
643
643
|
content: string | number | boolean | null;
|
|
644
644
|
label: string | null;
|
|
645
645
|
};
|
|
646
|
+
/**
|
|
647
|
+
* Represents sorting direction for Set items
|
|
648
|
+
*/
|
|
649
|
+
type SetItemsSortDirection = "asc" | "desc";
|
|
650
|
+
/**
|
|
651
|
+
* Represents sorting options for Set items
|
|
652
|
+
*/
|
|
653
|
+
type SetItemsSort = {
|
|
654
|
+
target: "none";
|
|
655
|
+
} | {
|
|
656
|
+
target: "title";
|
|
657
|
+
direction?: SetItemsSortDirection;
|
|
658
|
+
language?: string;
|
|
659
|
+
} | {
|
|
660
|
+
target: "propertyValue";
|
|
661
|
+
propertyVariableUuid: string;
|
|
662
|
+
dataType: Exclude<PropertyValueContentType, "coordinate">;
|
|
663
|
+
direction?: SetItemsSortDirection;
|
|
664
|
+
language?: string;
|
|
665
|
+
};
|
|
646
666
|
/**
|
|
647
667
|
* Represents a query for Set items
|
|
648
668
|
*/
|
|
@@ -1198,6 +1218,8 @@ declare function fetchItem<T extends DataCategory = DataCategory, U extends Data
|
|
|
1198
1218
|
* @param params.belongsToCollectionScopeUuids - The collection scope UUIDs to filter by
|
|
1199
1219
|
* @param params.propertyVariableUuids - The property variable UUIDs to filter by
|
|
1200
1220
|
* @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
|
|
1221
|
+
* @param params.sort - Optional sorting configuration applied before pagination.
|
|
1222
|
+
* For propertyValue sorting, dataType is required and the sort key uses the first valid leaf value (value[not(@i)]).
|
|
1201
1223
|
* @param params.page - The page number (1-indexed)
|
|
1202
1224
|
* @param params.pageSize - The number of items per page
|
|
1203
1225
|
* @param itemCategories - The categories of the items to fetch
|
|
@@ -1211,6 +1233,7 @@ declare function fetchSetItems<U extends Array<DataCategory> = Array<DataCategor
|
|
|
1211
1233
|
belongsToCollectionScopeUuids: Array<string>;
|
|
1212
1234
|
propertyVariableUuids: Array<string>;
|
|
1213
1235
|
queries: Array<Query>;
|
|
1236
|
+
sort?: SetItemsSort;
|
|
1214
1237
|
page: number;
|
|
1215
1238
|
pageSize?: number;
|
|
1216
1239
|
}, itemCategories?: U, options?: {
|
|
@@ -1423,4 +1446,4 @@ declare const DEFAULT_PAGE_SIZE = 48;
|
|
|
1423
1446
|
*/
|
|
1424
1447
|
declare function flattenItemProperties<T extends DataCategory = DataCategory, U extends DataCategory | Array<DataCategory> = (T extends "tree" ? Exclude<DataCategory, "tree"> : T extends "set" ? Array<DataCategory> : never)>(item: Item<T, U>): Item<T, U>;
|
|
1425
1448
|
//#endregion
|
|
1426
|
-
export { ApiVersion, Bibliography, Concept, Context, ContextItem, ContextNode, Coordinate, DEFAULT_API_VERSION, DEFAULT_PAGE_SIZE, Data, DataCategory, Event, FileFormat, Gallery, Identification, Image, ImageMap, ImageMapArea, Interpretation, Item, LevelContext, LevelContextItem, License, Link, Metadata, Note, Observation, Period, Person, Property, PropertyContexts, PropertyValue, PropertyValueContent, PropertyValueContentType, PropertyValueQueryItem, PropertyVariable, Query, Resource, Scope, Section, Set, SpatialUnit, Style, Text, Tree, WebBlock, WebBlockLayout, WebElement, WebElementComponent, WebImage, WebSegment, WebSegmentItem, WebTitle, Webpage, Website, WebsiteType, fetchGallery, fetchItem, fetchSetItems, fetchSetPropertyValuesByPropertyVariables, fetchWebsite, filterProperties, flattenItemProperties, getLeafPropertyValues, getPropertyByLabel, getPropertyByLabelAndValue, getPropertyByLabelAndValues, getPropertyByUuid, getPropertyValueByLabel, getPropertyValueByUuid, getPropertyValuesByLabel, getPropertyValuesByUuid, getUniqueProperties, getUniquePropertyLabels };
|
|
1449
|
+
export { ApiVersion, Bibliography, Concept, Context, ContextItem, ContextNode, Coordinate, DEFAULT_API_VERSION, DEFAULT_PAGE_SIZE, Data, DataCategory, Event, FileFormat, Gallery, Identification, Image, ImageMap, ImageMapArea, Interpretation, Item, LevelContext, LevelContextItem, License, Link, Metadata, Note, Observation, Period, Person, Property, PropertyContexts, PropertyValue, PropertyValueContent, PropertyValueContentType, PropertyValueQueryItem, PropertyVariable, Query, Resource, Scope, Section, Set, SetItemsSort, SetItemsSortDirection, SpatialUnit, Style, Text, Tree, WebBlock, WebBlockLayout, WebElement, WebElementComponent, WebImage, WebSegment, WebSegmentItem, WebTitle, Webpage, Website, WebsiteType, fetchGallery, fetchItem, fetchSetItems, fetchSetPropertyValuesByPropertyVariables, fetchWebsite, filterProperties, flattenItemProperties, getLeafPropertyValues, getPropertyByLabel, getPropertyByLabelAndValue, getPropertyByLabelAndValues, getPropertyByUuid, getPropertyValueByLabel, getPropertyValueByUuid, getPropertyValuesByLabel, getPropertyValuesByUuid, getUniqueProperties, getUniquePropertyLabels };
|
package/dist/index.mjs
CHANGED
|
@@ -831,6 +831,30 @@ const setQuerySchema = z.union([
|
|
|
831
831
|
}).strict()
|
|
832
832
|
]);
|
|
833
833
|
const setQueriesSchema = z.array(setQuerySchema).default([]);
|
|
834
|
+
const setItemsSortSchema = z.discriminatedUnion("target", [
|
|
835
|
+
z.object({ target: z.literal("none") }).strict(),
|
|
836
|
+
z.object({
|
|
837
|
+
target: z.literal("title"),
|
|
838
|
+
direction: z.enum(["asc", "desc"]).default("asc"),
|
|
839
|
+
language: z.string().default("eng")
|
|
840
|
+
}).strict(),
|
|
841
|
+
z.object({
|
|
842
|
+
target: z.literal("propertyValue"),
|
|
843
|
+
propertyVariableUuid: uuidSchema,
|
|
844
|
+
dataType: z.enum([
|
|
845
|
+
"string",
|
|
846
|
+
"integer",
|
|
847
|
+
"decimal",
|
|
848
|
+
"boolean",
|
|
849
|
+
"date",
|
|
850
|
+
"dateTime",
|
|
851
|
+
"time",
|
|
852
|
+
"IDREF"
|
|
853
|
+
]),
|
|
854
|
+
direction: z.enum(["asc", "desc"]).default("asc"),
|
|
855
|
+
language: z.string().default("eng")
|
|
856
|
+
}).strict()
|
|
857
|
+
]).default({ target: "none" });
|
|
834
858
|
function validateSetQueriesOperators(queries, ctx) {
|
|
835
859
|
for (const [index, query] of queries.entries()) if (index > 0 && query.operator == null) ctx.addIssue({
|
|
836
860
|
code: "custom",
|
|
@@ -860,6 +884,7 @@ const setItemsParamsSchema = z.object({
|
|
|
860
884
|
belongsToCollectionScopeUuids: z.array(uuidSchema).default([]),
|
|
861
885
|
propertyVariableUuids: z.array(uuidSchema).default([]),
|
|
862
886
|
queries: setQueriesSchema,
|
|
887
|
+
sort: setItemsSortSchema,
|
|
863
888
|
page: z.number().min(1, "Page must be positive").default(1),
|
|
864
889
|
pageSize: z.number().min(1, "Page size must be positive").default(DEFAULT_PAGE_SIZE)
|
|
865
890
|
}).superRefine((value, ctx) => {
|
|
@@ -2199,12 +2224,82 @@ function buildQueryFilters(queries) {
|
|
|
2199
2224
|
return queries.map((query, index) => {
|
|
2200
2225
|
const clause = buildBooleanQueryClause(query);
|
|
2201
2226
|
if (index === 0) return clause;
|
|
2202
|
-
return `${query.operator === "
|
|
2227
|
+
return `${query.operator === "AND" ? "and" : "or"} ${clause}`;
|
|
2203
2228
|
}).join(" ");
|
|
2204
2229
|
}
|
|
2205
2230
|
|
|
2206
2231
|
//#endregion
|
|
2207
2232
|
//#region src/utils/fetchers/set/items.ts
|
|
2233
|
+
function mapSortDirectionToXQuery(direction) {
|
|
2234
|
+
return direction === "desc" ? "descending" : "ascending";
|
|
2235
|
+
}
|
|
2236
|
+
function buildStringOrderByClause(direction) {
|
|
2237
|
+
return `($sortKey = "") ascending, lower-case($sortKey) ${direction}, $position ascending`;
|
|
2238
|
+
}
|
|
2239
|
+
function buildTypedOrderByClause(direction) {
|
|
2240
|
+
return `empty($sortKey) ascending, $sortKey ${direction}, $position ascending`;
|
|
2241
|
+
}
|
|
2242
|
+
function buildPropertyValueValuePath(sort) {
|
|
2243
|
+
return `$item//properties//property[label/@uuid=${stringLiteral(sort.propertyVariableUuid)}]/value[not(@i)]`;
|
|
2244
|
+
}
|
|
2245
|
+
function buildPropertyValueStringSortKeyExpression(sort) {
|
|
2246
|
+
const languageLiteral = stringLiteral(sort.language ?? "eng");
|
|
2247
|
+
return `string((for $v in ${buildPropertyValueValuePath(sort)}
|
|
2248
|
+
let $candidate := string-join($v/content[@xml:lang=${languageLiteral}]/string, "")
|
|
2249
|
+
where string-length($candidate) gt 0
|
|
2250
|
+
return $candidate)[1])`;
|
|
2251
|
+
}
|
|
2252
|
+
function buildPropertyValueTypedSortKeyExpression(params) {
|
|
2253
|
+
const { sort, dataType } = params;
|
|
2254
|
+
const propertyValuePath = buildPropertyValueValuePath(sort);
|
|
2255
|
+
switch (dataType) {
|
|
2256
|
+
case "integer": return `(for $v in ${propertyValuePath}
|
|
2257
|
+
let $candidate := normalize-space(string($v/@rawValue))
|
|
2258
|
+
where $candidate castable as xs:integer
|
|
2259
|
+
return xs:integer($candidate))[1]`;
|
|
2260
|
+
case "decimal":
|
|
2261
|
+
case "time": return `(for $v in ${propertyValuePath}
|
|
2262
|
+
let $candidate := normalize-space(string($v/@rawValue))
|
|
2263
|
+
where $candidate castable as xs:decimal
|
|
2264
|
+
return xs:decimal($candidate))[1]`;
|
|
2265
|
+
case "boolean": return `(for $v in ${propertyValuePath}
|
|
2266
|
+
let $candidate := lower-case(normalize-space(string($v/@rawValue)))
|
|
2267
|
+
where $candidate = ("true", "false", "1", "0")
|
|
2268
|
+
return if ($candidate = ("true", "1")) then 1 else 0)[1]`;
|
|
2269
|
+
case "date": return `(for $v in ${propertyValuePath}
|
|
2270
|
+
let $candidate := normalize-space(string($v/@rawValue))
|
|
2271
|
+
where $candidate castable as xs:date
|
|
2272
|
+
return xs:date($candidate))[1]`;
|
|
2273
|
+
case "dateTime": return `(for $v in ${propertyValuePath}
|
|
2274
|
+
let $candidate := normalize-space(string($v/@rawValue))
|
|
2275
|
+
where $candidate castable as xs:dateTime
|
|
2276
|
+
return xs:dateTime($candidate))[1]`;
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
function buildPropertyValueOrderByClause(params) {
|
|
2280
|
+
const { dataType, direction } = params;
|
|
2281
|
+
return dataType === "string" || dataType === "IDREF" ? buildStringOrderByClause(direction) : buildTypedOrderByClause(direction);
|
|
2282
|
+
}
|
|
2283
|
+
function buildOrderedItemsClause(sort) {
|
|
2284
|
+
if (sort.target === "none") return "let $orderedItems := $items";
|
|
2285
|
+
const direction = mapSortDirectionToXQuery(sort.direction);
|
|
2286
|
+
if (sort.target === "title") return `let $orderedItems :=
|
|
2287
|
+
for $item at $position in $items
|
|
2288
|
+
let $sortKey := ${`string-join($item/identification/label/content[@xml:lang=${stringLiteral(sort.language ?? "eng")}]/string, "")`}
|
|
2289
|
+
stable order by ${buildStringOrderByClause(direction)}
|
|
2290
|
+
return $item`;
|
|
2291
|
+
return `let $orderedItems :=
|
|
2292
|
+
for $item at $position in $items
|
|
2293
|
+
let $sortKey := ${sort.dataType === "string" || sort.dataType === "IDREF" ? buildPropertyValueStringSortKeyExpression(sort) : buildPropertyValueTypedSortKeyExpression({
|
|
2294
|
+
sort,
|
|
2295
|
+
dataType: sort.dataType
|
|
2296
|
+
})}
|
|
2297
|
+
stable order by ${buildPropertyValueOrderByClause({
|
|
2298
|
+
dataType: sort.dataType,
|
|
2299
|
+
direction
|
|
2300
|
+
})}
|
|
2301
|
+
return $item`;
|
|
2302
|
+
}
|
|
2208
2303
|
/**
|
|
2209
2304
|
* Build an XQuery string to fetch Set items from the OCHRE API
|
|
2210
2305
|
* @param params - The parameters for the fetch
|
|
@@ -2212,6 +2307,8 @@ function buildQueryFilters(queries) {
|
|
|
2212
2307
|
* @param params.belongsToCollectionScopeUuids - An array of collection scope UUIDs to filter by
|
|
2213
2308
|
* @param params.propertyVariableUuids - An array of property variable UUIDs to filter by
|
|
2214
2309
|
* @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
|
|
2310
|
+
* @param params.sort - Optional sorting configuration applied before pagination.
|
|
2311
|
+
* For propertyValue sorting, dataType is required and the sort key uses the first valid leaf value (value[not(@i)]).
|
|
2215
2312
|
* @param params.page - The page number (1-indexed)
|
|
2216
2313
|
* @param params.pageSize - The number of items per page
|
|
2217
2314
|
* @param options - Options for the fetch
|
|
@@ -2220,7 +2317,7 @@ function buildQueryFilters(queries) {
|
|
|
2220
2317
|
*/
|
|
2221
2318
|
function buildXQuery$1(params, options) {
|
|
2222
2319
|
const version = options?.version ?? DEFAULT_API_VERSION;
|
|
2223
|
-
const { propertyVariableUuids, queries, setScopeUuids, belongsToCollectionScopeUuids, page, pageSize } = params;
|
|
2320
|
+
const { propertyVariableUuids, queries, sort, setScopeUuids, belongsToCollectionScopeUuids, page, pageSize } = params;
|
|
2224
2321
|
const startPosition = (page - 1) * pageSize + 1;
|
|
2225
2322
|
const endPosition = page * pageSize;
|
|
2226
2323
|
const setScopeFilter = `/set[(${setScopeUuids.map((uuid) => `@uuid="${uuid}"`).join(" or ")})]/items/*`;
|
|
@@ -2236,14 +2333,16 @@ function buildXQuery$1(params, options) {
|
|
|
2236
2333
|
}
|
|
2237
2334
|
if (queryFilters.length > 0) filterPredicates.push(`(${queryFilters})`);
|
|
2238
2335
|
const itemFilters = filterPredicates.length > 0 ? `[${filterPredicates.join(" and ")}]` : "";
|
|
2336
|
+
const orderedItemsClause = buildOrderedItemsClause(sort);
|
|
2239
2337
|
return `<ochre>{${`let $items := ${version === 2 ? "doc()" : "input()"}/ochre
|
|
2240
2338
|
${setScopeFilter}
|
|
2241
2339
|
${itemFilters}
|
|
2242
2340
|
|
|
2243
2341
|
let $totalCount := count($items)
|
|
2342
|
+
${orderedItemsClause}
|
|
2244
2343
|
|
|
2245
2344
|
return <items totalCount="{$totalCount}" page="${page}" pageSize="${pageSize}">{
|
|
2246
|
-
for $item in $
|
|
2345
|
+
for $item in $orderedItems[position() ge ${startPosition} and position() le ${endPosition}]
|
|
2247
2346
|
return element { node-name($item) } {
|
|
2248
2347
|
$item/@*, $item/node()
|
|
2249
2348
|
}
|
|
@@ -2257,6 +2356,8 @@ function buildXQuery$1(params, options) {
|
|
|
2257
2356
|
* @param params.belongsToCollectionScopeUuids - The collection scope UUIDs to filter by
|
|
2258
2357
|
* @param params.propertyVariableUuids - The property variable UUIDs to filter by
|
|
2259
2358
|
* @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
|
|
2359
|
+
* @param params.sort - Optional sorting configuration applied before pagination.
|
|
2360
|
+
* For propertyValue sorting, dataType is required and the sort key uses the first valid leaf value (value[not(@i)]).
|
|
2260
2361
|
* @param params.page - The page number (1-indexed)
|
|
2261
2362
|
* @param params.pageSize - The number of items per page
|
|
2262
2363
|
* @param itemCategories - The categories of the items to fetch
|
|
@@ -2268,12 +2369,13 @@ function buildXQuery$1(params, options) {
|
|
|
2268
2369
|
async function fetchSetItems(params, itemCategories, options) {
|
|
2269
2370
|
try {
|
|
2270
2371
|
const version = options?.version ?? DEFAULT_API_VERSION;
|
|
2271
|
-
const { setScopeUuids, belongsToCollectionScopeUuids, propertyVariableUuids, queries, page, pageSize } = setItemsParamsSchema.parse(params);
|
|
2372
|
+
const { setScopeUuids, belongsToCollectionScopeUuids, propertyVariableUuids, queries, sort, page, pageSize } = setItemsParamsSchema.parse(params);
|
|
2272
2373
|
const xquery = buildXQuery$1({
|
|
2273
2374
|
setScopeUuids,
|
|
2274
2375
|
belongsToCollectionScopeUuids,
|
|
2275
2376
|
propertyVariableUuids,
|
|
2276
2377
|
queries,
|
|
2378
|
+
sort,
|
|
2277
2379
|
page,
|
|
2278
2380
|
pageSize
|
|
2279
2381
|
}, { version });
|