ochre-sdk 0.20.6 → 0.20.10
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 +3 -1
- package/dist/index.mjs +122 -101
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -951,7 +951,7 @@ type WebElementComponent = {
|
|
|
951
951
|
isResultsBarDisplayed: boolean;
|
|
952
952
|
isMapDisplayed: boolean;
|
|
953
953
|
isInputDisplayed: boolean;
|
|
954
|
-
|
|
954
|
+
isLimitedToInputFilter: boolean;
|
|
955
955
|
isLimitedToLeafPropertyValues: boolean;
|
|
956
956
|
sidebarSort: "default" | "alphabetical";
|
|
957
957
|
};
|
|
@@ -1238,6 +1238,7 @@ declare function fetchSetItems<U extends Array<DataCategory> = Array<DataCategor
|
|
|
1238
1238
|
* @param params.setScopeUuids - An array of set scope UUIDs to filter by
|
|
1239
1239
|
* @param params.belongsToCollectionScopeUuids - The collection scope UUIDs to filter by
|
|
1240
1240
|
* @param params.propertyVariableUuids - The property variable UUIDs to query by
|
|
1241
|
+
* @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
|
|
1241
1242
|
* @param params.isLimitedToLeafPropertyValues - Whether to limit the property values to leaf property values
|
|
1242
1243
|
* @param options - Options for the fetch
|
|
1243
1244
|
* @param options.fetch - The fetch function to use
|
|
@@ -1248,6 +1249,7 @@ declare function fetchSetPropertyValuesByPropertyVariables(params: {
|
|
|
1248
1249
|
setScopeUuids: Array<string>;
|
|
1249
1250
|
belongsToCollectionScopeUuids: Array<string>;
|
|
1250
1251
|
propertyVariableUuids: Array<string>;
|
|
1252
|
+
queries?: Array<Query>;
|
|
1251
1253
|
isLimitedToLeafPropertyValues?: boolean;
|
|
1252
1254
|
}, options?: {
|
|
1253
1255
|
fetch?: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response>;
|
package/dist/index.mjs
CHANGED
|
@@ -760,81 +760,70 @@ const boundsSchema = z.string().transform((str, ctx) => {
|
|
|
760
760
|
}
|
|
761
761
|
}).pipe(z.tuple([z.tuple([z.number(), z.number()]), z.tuple([z.number(), z.number()])], { message: "Must contain exactly 2 coordinate pairs" }));
|
|
762
762
|
/**
|
|
763
|
-
*
|
|
763
|
+
* Shared schema for Set queries
|
|
764
764
|
* @internal
|
|
765
765
|
*/
|
|
766
|
-
const
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
z.
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
z.
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
z.
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
z.
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
matchMode: z.enum(["includes", "exact"]),
|
|
828
|
-
isCaseSensitive: z.boolean(),
|
|
829
|
-
language: z.string().default("eng"),
|
|
830
|
-
operator: z.enum(["AND", "OR"]).optional(),
|
|
831
|
-
isNegated: z.boolean().optional().default(false)
|
|
832
|
-
}).strict()
|
|
833
|
-
])).default([]),
|
|
834
|
-
page: z.number().min(1, "Page must be positive").default(1),
|
|
835
|
-
pageSize: z.number().min(1, "Page size must be positive").default(DEFAULT_PAGE_SIZE)
|
|
836
|
-
}).superRefine((value, ctx) => {
|
|
837
|
-
for (const [index, query] of value.queries.entries()) {
|
|
766
|
+
const setQuerySchema = z.union([
|
|
767
|
+
z.object({
|
|
768
|
+
target: z.literal("propertyValue"),
|
|
769
|
+
dataType: z.enum([
|
|
770
|
+
"string",
|
|
771
|
+
"integer",
|
|
772
|
+
"decimal",
|
|
773
|
+
"boolean",
|
|
774
|
+
"time",
|
|
775
|
+
"IDREF"
|
|
776
|
+
]),
|
|
777
|
+
value: z.string(),
|
|
778
|
+
matchMode: z.enum(["includes", "exact"]),
|
|
779
|
+
isCaseSensitive: z.boolean(),
|
|
780
|
+
language: z.string().default("eng"),
|
|
781
|
+
operator: z.enum(["AND", "OR"]).optional(),
|
|
782
|
+
isNegated: z.boolean().optional().default(false)
|
|
783
|
+
}).strict(),
|
|
784
|
+
z.object({
|
|
785
|
+
target: z.literal("propertyValue"),
|
|
786
|
+
dataType: z.enum(["date", "dateTime"]),
|
|
787
|
+
value: z.string(),
|
|
788
|
+
from: z.string(),
|
|
789
|
+
to: z.string().optional(),
|
|
790
|
+
matchMode: z.enum(["includes", "exact"]),
|
|
791
|
+
isCaseSensitive: z.boolean(),
|
|
792
|
+
language: z.string().default("eng"),
|
|
793
|
+
operator: z.enum(["AND", "OR"]).optional(),
|
|
794
|
+
isNegated: z.boolean().optional().default(false)
|
|
795
|
+
}).strict(),
|
|
796
|
+
z.object({
|
|
797
|
+
target: z.literal("propertyValue"),
|
|
798
|
+
dataType: z.enum(["date", "dateTime"]),
|
|
799
|
+
value: z.string(),
|
|
800
|
+
from: z.string().optional(),
|
|
801
|
+
to: z.string(),
|
|
802
|
+
matchMode: z.enum(["includes", "exact"]),
|
|
803
|
+
isCaseSensitive: z.boolean(),
|
|
804
|
+
language: z.string().default("eng"),
|
|
805
|
+
operator: z.enum(["AND", "OR"]).optional(),
|
|
806
|
+
isNegated: z.boolean().optional().default(false)
|
|
807
|
+
}).strict(),
|
|
808
|
+
z.object({
|
|
809
|
+
target: z.enum([
|
|
810
|
+
"title",
|
|
811
|
+
"description",
|
|
812
|
+
"image",
|
|
813
|
+
"periods",
|
|
814
|
+
"bibliography"
|
|
815
|
+
]),
|
|
816
|
+
value: z.string(),
|
|
817
|
+
matchMode: z.enum(["includes", "exact"]),
|
|
818
|
+
isCaseSensitive: z.boolean(),
|
|
819
|
+
language: z.string().default("eng"),
|
|
820
|
+
operator: z.enum(["AND", "OR"]).optional(),
|
|
821
|
+
isNegated: z.boolean().optional().default(false)
|
|
822
|
+
}).strict()
|
|
823
|
+
]);
|
|
824
|
+
const setQueriesSchema = z.array(setQuerySchema).default([]);
|
|
825
|
+
function validateSetQueriesOperators(queries, ctx) {
|
|
826
|
+
for (const [index, query] of queries.entries()) {
|
|
838
827
|
if (index === 0 && query.operator != null) ctx.addIssue({
|
|
839
828
|
code: "custom",
|
|
840
829
|
path: [
|
|
@@ -854,6 +843,29 @@ const setItemsParamsSchema = z.object({
|
|
|
854
843
|
message: "Query rules after the first must include an operator"
|
|
855
844
|
});
|
|
856
845
|
}
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Schema for validating the parameters for the Set property values by property variables fetching function
|
|
849
|
+
* @internal
|
|
850
|
+
*/
|
|
851
|
+
const setPropertyValuesByPropertyVariablesParamsSchema = z.object({
|
|
852
|
+
setScopeUuids: z.array(uuidSchema).min(1, "At least one set scope UUID is required"),
|
|
853
|
+
belongsToCollectionScopeUuids: z.array(uuidSchema).default([]),
|
|
854
|
+
propertyVariableUuids: z.array(uuidSchema).min(1, "At least one property variable UUID is required"),
|
|
855
|
+
queries: setQueriesSchema,
|
|
856
|
+
isLimitedToLeafPropertyValues: z.boolean().default(false)
|
|
857
|
+
}).superRefine((value, ctx) => {
|
|
858
|
+
validateSetQueriesOperators(value.queries, ctx);
|
|
859
|
+
});
|
|
860
|
+
const setItemsParamsSchema = z.object({
|
|
861
|
+
setScopeUuids: z.array(uuidSchema).min(1, "At least one set scope UUID is required"),
|
|
862
|
+
belongsToCollectionScopeUuids: z.array(uuidSchema).default([]),
|
|
863
|
+
propertyVariableUuids: z.array(uuidSchema).default([]),
|
|
864
|
+
queries: setQueriesSchema,
|
|
865
|
+
page: z.number().min(1, "Page must be positive").default(1),
|
|
866
|
+
pageSize: z.number().min(1, "Page size must be positive").default(DEFAULT_PAGE_SIZE)
|
|
867
|
+
}).superRefine((value, ctx) => {
|
|
868
|
+
validateSetQueriesOperators(value.queries, ctx);
|
|
857
869
|
});
|
|
858
870
|
|
|
859
871
|
//#endregion
|
|
@@ -2099,15 +2111,9 @@ async function fetchItem(uuid, category, itemCategories, options) {
|
|
|
2099
2111
|
}
|
|
2100
2112
|
|
|
2101
2113
|
//#endregion
|
|
2102
|
-
//#region src/utils/fetchers/set/
|
|
2114
|
+
//#region src/utils/fetchers/set/query-helpers.ts
|
|
2103
2115
|
/**
|
|
2104
2116
|
* Build a string match predicate for an XQuery string
|
|
2105
|
-
* @param params - The parameters for the predicate
|
|
2106
|
-
* @param params.path - The path to the string
|
|
2107
|
-
* @param params.value - The value to match
|
|
2108
|
-
* @param params.matchMode - The match mode (includes or exact)
|
|
2109
|
-
* @param params.isCaseSensitive - Whether to match case-sensitively
|
|
2110
|
-
* @returns The string match predicate
|
|
2111
2117
|
*/
|
|
2112
2118
|
function buildStringMatchPredicate(params) {
|
|
2113
2119
|
const { path, value, matchMode, isCaseSensitive } = params;
|
|
@@ -2128,8 +2134,6 @@ function buildDateRangePredicate(params) {
|
|
|
2128
2134
|
}
|
|
2129
2135
|
/**
|
|
2130
2136
|
* Build a property value predicate for an XQuery string
|
|
2131
|
-
* @param query - The propertyValue query
|
|
2132
|
-
* @returns The property value predicate
|
|
2133
2137
|
*/
|
|
2134
2138
|
function buildPropertyValuePredicate(query) {
|
|
2135
2139
|
if (query.dataType === "IDREF") return `.//properties//property[value[@uuid=${stringLiteral(query.value)}]]`;
|
|
@@ -2147,8 +2151,6 @@ function buildPropertyValuePredicate(query) {
|
|
|
2147
2151
|
}
|
|
2148
2152
|
/**
|
|
2149
2153
|
* Build a query predicate for an XQuery string
|
|
2150
|
-
* @param query - The query to build the predicate for
|
|
2151
|
-
* @returns The query predicate
|
|
2152
2154
|
*/
|
|
2153
2155
|
function buildQueryPredicate(query) {
|
|
2154
2156
|
switch (query.target) {
|
|
@@ -2193,6 +2195,19 @@ function buildBooleanQueryClause(query) {
|
|
|
2193
2195
|
return query.isNegated ? `not(${baseClause})` : baseClause;
|
|
2194
2196
|
}
|
|
2195
2197
|
/**
|
|
2198
|
+
* Build query filters for an XQuery string.
|
|
2199
|
+
*/
|
|
2200
|
+
function buildQueryFilters(queries) {
|
|
2201
|
+
return queries.map((query, index) => {
|
|
2202
|
+
const clause = buildBooleanQueryClause(query);
|
|
2203
|
+
if (index === 0) return clause;
|
|
2204
|
+
return `${query.operator === "OR" ? "or" : "and"} ${clause}`;
|
|
2205
|
+
}).join(" ");
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
//#endregion
|
|
2209
|
+
//#region src/utils/fetchers/set/items.ts
|
|
2210
|
+
/**
|
|
2196
2211
|
* Build an XQuery string to fetch Set items from the OCHRE API
|
|
2197
2212
|
* @param params - The parameters for the fetch
|
|
2198
2213
|
* @param params.setScopeUuids - An array of Set scope UUIDs to filter by
|
|
@@ -2211,11 +2226,7 @@ function buildXQuery$1(params, options) {
|
|
|
2211
2226
|
const startPosition = (page - 1) * pageSize + 1;
|
|
2212
2227
|
const endPosition = page * pageSize;
|
|
2213
2228
|
const setScopeFilter = `/set[(${setScopeUuids.map((uuid) => `@uuid="${uuid}"`).join(" or ")})]/items/*`;
|
|
2214
|
-
const queryFilters = queries
|
|
2215
|
-
const clause = buildBooleanQueryClause(query);
|
|
2216
|
-
if (index === 0) return clause;
|
|
2217
|
-
return `${query.operator === "OR" ? "or" : "and"} ${clause}`;
|
|
2218
|
-
}).join(" ");
|
|
2229
|
+
const queryFilters = buildQueryFilters(queries);
|
|
2219
2230
|
const filterPredicates = [];
|
|
2220
2231
|
if (belongsToCollectionScopeUuids.length > 0) {
|
|
2221
2232
|
const belongsToCollectionScopeValues = belongsToCollectionScopeUuids.map((uuid) => `@uuid="${uuid}"`).join(" or ");
|
|
@@ -2447,6 +2458,7 @@ const responseSchema = z.object({ result: z.union([z.object({ ochre: z.object({
|
|
|
2447
2458
|
* @param params.setScopeUuids - An array of set scope UUIDs to filter by
|
|
2448
2459
|
* @param params.belongsToCollectionScopeUuids - An array of collection scope UUIDs to filter by
|
|
2449
2460
|
* @param params.propertyVariableUuids - An array of property variable UUIDs to fetch
|
|
2461
|
+
* @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
|
|
2450
2462
|
* @param params.isLimitedToLeafPropertyValues - Whether to limit the property values to leaf property values
|
|
2451
2463
|
* @param options - Options for the fetch
|
|
2452
2464
|
* @param options.version - The version of the OCHRE API to use
|
|
@@ -2454,16 +2466,23 @@ const responseSchema = z.object({ result: z.union([z.object({ ochre: z.object({
|
|
|
2454
2466
|
*/
|
|
2455
2467
|
function buildXQuery(params, options) {
|
|
2456
2468
|
const version = options?.version ?? DEFAULT_API_VERSION;
|
|
2457
|
-
const { setScopeUuids, belongsToCollectionScopeUuids, propertyVariableUuids, isLimitedToLeafPropertyValues } = params;
|
|
2458
|
-
let setScopeFilter = "";
|
|
2459
|
-
if (setScopeUuids.length > 0) setScopeFilter = `/set[(${setScopeUuids.map((uuid) => `@uuid="${uuid}"`).join(" or ")})]/items
|
|
2460
|
-
let collectionScopeFilter = "";
|
|
2461
|
-
if (belongsToCollectionScopeUuids.length > 0) collectionScopeFilter = `//properties[property[label/@uuid="${BELONGS_TO_COLLECTION_UUID}" and value/(${belongsToCollectionScopeUuids.map((uuid) => `@uuid="${uuid}"`).join(" or ")})]]`;
|
|
2469
|
+
const { setScopeUuids, belongsToCollectionScopeUuids, propertyVariableUuids, queries, isLimitedToLeafPropertyValues } = params;
|
|
2470
|
+
let setScopeFilter = "/set/items/*";
|
|
2471
|
+
if (setScopeUuids.length > 0) setScopeFilter = `/set[(${setScopeUuids.map((uuid) => `@uuid="${uuid}"`).join(" or ")})]/items/*`;
|
|
2462
2472
|
const propertyVariableFilters = propertyVariableUuids.map((uuid) => `@uuid="${uuid}"`).join(" or ");
|
|
2463
|
-
|
|
2473
|
+
const queryFilters = buildQueryFilters(queries);
|
|
2474
|
+
const filterPredicates = [];
|
|
2475
|
+
if (belongsToCollectionScopeUuids.length > 0) {
|
|
2476
|
+
const belongsToCollectionScopeValues = belongsToCollectionScopeUuids.map((uuid) => `@uuid="${uuid}"`).join(" or ");
|
|
2477
|
+
filterPredicates.push(`.//properties[property[label/@uuid="${BELONGS_TO_COLLECTION_UUID}" and value/(${belongsToCollectionScopeValues})]]`);
|
|
2478
|
+
}
|
|
2479
|
+
if (queryFilters.length > 0) filterPredicates.push(`(${queryFilters})`);
|
|
2480
|
+
const itemFilters = filterPredicates.length > 0 ? `[${filterPredicates.join(" and ")}]` : "";
|
|
2481
|
+
return `<ochre>{${`let $items := ${version === 2 ? "doc()" : "input()"}/ochre
|
|
2464
2482
|
${setScopeFilter}
|
|
2465
|
-
${
|
|
2466
|
-
|
|
2483
|
+
${itemFilters}
|
|
2484
|
+
|
|
2485
|
+
let $matching-props := $items//property[label/(${propertyVariableFilters})]
|
|
2467
2486
|
|
|
2468
2487
|
for $p in $matching-props
|
|
2469
2488
|
for $v in $p/value${isLimitedToLeafPropertyValues ? "[not(@i)]" : ""}
|
|
@@ -2480,6 +2499,7 @@ function buildXQuery(params, options) {
|
|
|
2480
2499
|
* @param params.setScopeUuids - An array of set scope UUIDs to filter by
|
|
2481
2500
|
* @param params.belongsToCollectionScopeUuids - The collection scope UUIDs to filter by
|
|
2482
2501
|
* @param params.propertyVariableUuids - The property variable UUIDs to query by
|
|
2502
|
+
* @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
|
|
2483
2503
|
* @param params.isLimitedToLeafPropertyValues - Whether to limit the property values to leaf property values
|
|
2484
2504
|
* @param options - Options for the fetch
|
|
2485
2505
|
* @param options.fetch - The fetch function to use
|
|
@@ -2489,11 +2509,12 @@ function buildXQuery(params, options) {
|
|
|
2489
2509
|
async function fetchSetPropertyValuesByPropertyVariables(params, options) {
|
|
2490
2510
|
try {
|
|
2491
2511
|
const version = options?.version ?? DEFAULT_API_VERSION;
|
|
2492
|
-
const { setScopeUuids, belongsToCollectionScopeUuids, propertyVariableUuids, isLimitedToLeafPropertyValues } = setPropertyValuesByPropertyVariablesParamsSchema.parse(params);
|
|
2512
|
+
const { setScopeUuids, belongsToCollectionScopeUuids, propertyVariableUuids, queries, isLimitedToLeafPropertyValues } = setPropertyValuesByPropertyVariablesParamsSchema.parse(params);
|
|
2493
2513
|
const xquery = buildXQuery({
|
|
2494
2514
|
setScopeUuids,
|
|
2495
2515
|
belongsToCollectionScopeUuids,
|
|
2496
2516
|
propertyVariableUuids,
|
|
2517
|
+
queries,
|
|
2497
2518
|
isLimitedToLeafPropertyValues
|
|
2498
2519
|
}, { version });
|
|
2499
2520
|
const response = await (options?.fetch ?? fetch)(version === 2 ? `https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?xquery=${encodeURIComponent(xquery)}&format=json&lang="*"` : `https://ochre.lib.uchicago.edu/ochre?xquery=${encodeURIComponent(xquery)}&format=json&lang="*"`);
|
|
@@ -3027,8 +3048,8 @@ function parseWebElementProperties(componentProperty, elementResource) {
|
|
|
3027
3048
|
isFilterMapDisplayed ??= false;
|
|
3028
3049
|
let isFilterInputDisplayed = getPropertyValueByLabel(componentProperty.properties, "filter-input-displayed");
|
|
3029
3050
|
isFilterInputDisplayed ??= false;
|
|
3030
|
-
let
|
|
3031
|
-
|
|
3051
|
+
let isFilterLimitedToInputFilter = getPropertyValueByLabel(componentProperty.properties, "filter-limit-to-input-filter");
|
|
3052
|
+
isFilterLimitedToInputFilter ??= false;
|
|
3032
3053
|
let isFilterLimitedToLeafPropertyValues = getPropertyValueByLabel(componentProperty.properties, "filter-limit-to-leaf-property-values");
|
|
3033
3054
|
isFilterLimitedToLeafPropertyValues ??= false;
|
|
3034
3055
|
let isSortDisplayed = getPropertyValueByLabel(componentProperty.properties, "sort-displayed");
|
|
@@ -3078,7 +3099,7 @@ function parseWebElementProperties(componentProperty, elementResource) {
|
|
|
3078
3099
|
isResultsBarDisplayed: isFilterResultsBarDisplayed,
|
|
3079
3100
|
isMapDisplayed: isFilterMapDisplayed,
|
|
3080
3101
|
isInputDisplayed: isFilterInputDisplayed,
|
|
3081
|
-
|
|
3102
|
+
isLimitedToInputFilter: isFilterLimitedToInputFilter,
|
|
3082
3103
|
isLimitedToLeafPropertyValues: isFilterLimitedToLeafPropertyValues,
|
|
3083
3104
|
sidebarSort: filterSidebarSort
|
|
3084
3105
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ochre-sdk",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.10",
|
|
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",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@antfu/eslint-config": "^7.6.1",
|
|
50
|
-
"@types/node": "^24.10.
|
|
50
|
+
"@types/node": "^24.10.15",
|
|
51
51
|
"bumpp": "^10.4.1",
|
|
52
52
|
"eslint": "^10.0.2",
|
|
53
53
|
"prettier": "^3.8.1",
|