ochre-sdk 0.20.29 → 0.21.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.
package/dist/index.d.mts CHANGED
@@ -671,9 +671,9 @@ type SetItemsSort = {
671
671
  language?: string;
672
672
  };
673
673
  /**
674
- * Represents a query for Set items
674
+ * Represents a leaf query for Set items
675
675
  */
676
- type Query = {
676
+ type QueryLeaf = {
677
677
  target: "property";
678
678
  propertyVariables?: Array<string>;
679
679
  dataType: Exclude<Exclude<PropertyValueContentType, "coordinate">, "date" | "dateTime">;
@@ -683,7 +683,6 @@ type Query = {
683
683
  matchMode: "includes" | "exact";
684
684
  isCaseSensitive: boolean;
685
685
  language: string;
686
- operator?: "AND" | "OR";
687
686
  isNegated?: boolean;
688
687
  } | {
689
688
  target: "property";
@@ -695,7 +694,6 @@ type Query = {
695
694
  matchMode: "includes" | "exact";
696
695
  isCaseSensitive: boolean;
697
696
  language: string;
698
- operator?: "AND" | "OR";
699
697
  isNegated?: boolean;
700
698
  } | {
701
699
  target: "property";
@@ -707,7 +705,6 @@ type Query = {
707
705
  matchMode: "includes" | "exact";
708
706
  isCaseSensitive: boolean;
709
707
  language: string;
710
- operator?: "AND" | "OR";
711
708
  isNegated?: boolean;
712
709
  } | {
713
710
  target: "string";
@@ -715,7 +712,6 @@ type Query = {
715
712
  matchMode: "includes" | "exact";
716
713
  isCaseSensitive: boolean;
717
714
  language: string;
718
- operator?: "AND" | "OR";
719
715
  isNegated?: boolean;
720
716
  } | {
721
717
  target: "title" | "description" | "image" | "periods" | "bibliography";
@@ -723,9 +719,20 @@ type Query = {
723
719
  matchMode: "includes" | "exact";
724
720
  isCaseSensitive: boolean;
725
721
  language: string;
726
- operator?: "AND" | "OR";
727
722
  isNegated?: boolean;
728
723
  };
724
+ /**
725
+ * Represents a boolean query group for Set items
726
+ */
727
+ type QueryGroup = {
728
+ and: Array<Query>;
729
+ } | {
730
+ or: Array<Query>;
731
+ };
732
+ /**
733
+ * Represents a query for Set items
734
+ */
735
+ type Query = QueryLeaf | QueryGroup;
729
736
  //#endregion
730
737
  //#region src/types/website.d.ts
731
738
  /**
@@ -1234,7 +1241,7 @@ declare function fetchItem<T extends DataCategory = DataCategory, U extends Data
1234
1241
  *
1235
1242
  * @param params - The parameters for the fetch
1236
1243
  * @param params.setScopeUuids - The Set scope UUIDs to filter by
1237
- * @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
1244
+ * @param params.queries - Recursive query tree used to filter matching items
1238
1245
  * @param params.sort - Optional sorting configuration applied before pagination.
1239
1246
  * For propertyValue sorting, dataType is required and the sort key uses the first valid leaf value (value[not(@i)]).
1240
1247
  * @param params.page - The page number (1-indexed)
@@ -1247,7 +1254,7 @@ declare function fetchItem<T extends DataCategory = DataCategory, U extends Data
1247
1254
  */
1248
1255
  declare function fetchSetItems<U extends Array<DataCategory> = Array<DataCategory>>(params: {
1249
1256
  setScopeUuids: Array<string>;
1250
- queries: Array<Query>;
1257
+ queries?: Query | null;
1251
1258
  sort?: SetItemsSort;
1252
1259
  page: number;
1253
1260
  pageSize?: number;
@@ -1274,7 +1281,7 @@ declare function fetchSetItems<U extends Array<DataCategory> = Array<DataCategor
1274
1281
  *
1275
1282
  * @param params - The parameters for the fetch
1276
1283
  * @param params.setScopeUuids - An array of set scope UUIDs to filter by
1277
- * @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
1284
+ * @param params.queries - Recursive query tree used to filter matching items
1278
1285
  * @param params.attributes - Whether to return values for bibliographies and periods
1279
1286
  * @param params.attributes.bibliographies - Whether to return values for bibliographies
1280
1287
  * @param params.attributes.periods - Whether to return values for periods
@@ -1287,7 +1294,7 @@ declare function fetchSetItems<U extends Array<DataCategory> = Array<DataCategor
1287
1294
  */
1288
1295
  declare function fetchSetPropertyValues(params: {
1289
1296
  setScopeUuids: Array<string>;
1290
- queries?: Array<Query>;
1297
+ queries?: Query | null;
1291
1298
  attributes?: {
1292
1299
  bibliographies: boolean;
1293
1300
  periods: boolean;
@@ -1470,4 +1477,4 @@ declare const DEFAULT_PAGE_SIZE = 48;
1470
1477
  */
1471
1478
  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>;
1472
1479
  //#endregion
1473
- 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, SetAttributeValueQueryItem, SetItemsSort, SetItemsSortDirection, SpatialUnit, Style, Text, Tree, WebBlock, WebBlockLayout, WebElement, WebElementComponent, WebImage, WebSegment, WebSegmentItem, WebTitle, Webpage, Website, WebsiteType, fetchGallery, fetchItem, fetchSetItems, fetchSetPropertyValues, fetchWebsite, filterProperties, flattenItemProperties, getLeafPropertyValues, getPropertyByLabel, getPropertyByLabelAndValue, getPropertyByLabelAndValues, getPropertyByUuid, getPropertyValueByLabel, getPropertyValueByUuid, getPropertyValuesByLabel, getPropertyValuesByUuid, getUniqueProperties, getUniquePropertyLabels };
1480
+ 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, QueryGroup, QueryLeaf, Resource, Scope, Section, Set, SetAttributeValueQueryItem, SetItemsSort, SetItemsSortDirection, SpatialUnit, Style, Text, Tree, WebBlock, WebBlockLayout, WebElement, WebElementComponent, WebImage, WebSegment, WebSegmentItem, WebTitle, Webpage, Website, WebsiteType, fetchGallery, fetchItem, fetchSetItems, fetchSetPropertyValues, fetchWebsite, filterProperties, flattenItemProperties, getLeafPropertyValues, getPropertyByLabel, getPropertyByLabelAndValue, getPropertyByLabelAndValues, getPropertyByUuid, getPropertyValueByLabel, getPropertyValueByUuid, getPropertyValuesByLabel, getPropertyValuesByUuid, getUniqueProperties, getUniquePropertyLabels };
package/dist/index.mjs CHANGED
@@ -756,7 +756,7 @@ const boundsSchema = z.string().transform((str, ctx) => {
756
756
  * Shared schema for Set queries
757
757
  * @internal
758
758
  */
759
- const setQuerySchema = z.union([
759
+ const setQueryLeafSchema = z.union([
760
760
  z.object({
761
761
  target: z.literal("property"),
762
762
  propertyVariables: z.array(uuidSchema).default([]),
@@ -772,7 +772,6 @@ const setQuerySchema = z.union([
772
772
  matchMode: z.enum(["includes", "exact"]),
773
773
  isCaseSensitive: z.boolean(),
774
774
  language: z.string().default("eng"),
775
- operator: z.enum(["AND", "OR"]).optional(),
776
775
  isNegated: z.boolean().optional().default(false)
777
776
  }).strict().superRefine((value, ctx) => {
778
777
  if (value.propertyVariables.length === 0 && value.propertyValues == null) ctx.addIssue({
@@ -789,7 +788,6 @@ const setQuerySchema = z.union([
789
788
  matchMode: z.enum(["includes", "exact"]),
790
789
  isCaseSensitive: z.boolean(),
791
790
  language: z.string().default("eng"),
792
- operator: z.enum(["AND", "OR"]).optional(),
793
791
  isNegated: z.boolean().optional().default(false)
794
792
  }).strict(),
795
793
  z.object({
@@ -801,7 +799,6 @@ const setQuerySchema = z.union([
801
799
  matchMode: z.enum(["includes", "exact"]),
802
800
  isCaseSensitive: z.boolean(),
803
801
  language: z.string().default("eng"),
804
- operator: z.enum(["AND", "OR"]).optional(),
805
802
  isNegated: z.boolean().optional().default(false)
806
803
  }).strict(),
807
804
  z.object({
@@ -810,7 +807,6 @@ const setQuerySchema = z.union([
810
807
  matchMode: z.enum(["includes", "exact"]),
811
808
  isCaseSensitive: z.boolean(),
812
809
  language: z.string().default("eng"),
813
- operator: z.enum(["AND", "OR"]).optional(),
814
810
  isNegated: z.boolean().optional().default(false)
815
811
  }).strict(),
816
812
  z.object({
@@ -825,11 +821,15 @@ const setQuerySchema = z.union([
825
821
  matchMode: z.enum(["includes", "exact"]),
826
822
  isCaseSensitive: z.boolean(),
827
823
  language: z.string().default("eng"),
828
- operator: z.enum(["AND", "OR"]).optional(),
829
824
  isNegated: z.boolean().optional().default(false)
830
825
  }).strict()
831
826
  ]);
832
- const setQueriesSchema = z.array(setQuerySchema).default([]);
827
+ const setQuerySchema = z.lazy(() => z.union([
828
+ setQueryLeafSchema,
829
+ z.object({ and: z.array(setQuerySchema).min(1, "AND groups must contain at least one query") }).strict(),
830
+ z.object({ or: z.array(setQuerySchema).min(1, "OR groups must contain at least one query") }).strict()
831
+ ]));
832
+ const setQueriesSchema = setQuerySchema.nullable().default(null);
833
833
  const setItemsSortSchema = z.discriminatedUnion("target", [
834
834
  z.object({ target: z.literal("none") }).strict(),
835
835
  z.object({
@@ -854,16 +854,12 @@ const setItemsSortSchema = z.discriminatedUnion("target", [
854
854
  language: z.string().default("eng")
855
855
  }).strict()
856
856
  ]).default({ target: "none" });
857
- function validateSetQueriesOperators(queries, ctx) {
858
- for (const [index, query] of queries.entries()) if (index > 0 && query.operator == null) ctx.addIssue({
859
- code: "custom",
860
- path: [
861
- "queries",
862
- index,
863
- "operator"
864
- ],
865
- message: "Query rules after the first must include an operator"
866
- });
857
+ function hasPropertyQueryWithPropertyVariables(query) {
858
+ if (query == null) return false;
859
+ if ("target" in query) return query.target === "property" && (query.propertyVariables?.length ?? 0) > 0;
860
+ const groupQueries = "and" in query ? query.and : query.or;
861
+ for (const groupQuery of groupQueries) if (hasPropertyQueryWithPropertyVariables(groupQuery)) return true;
862
+ return false;
867
863
  }
868
864
  /**
869
865
  * Schema for validating the parameters for the Set property values fetching function
@@ -882,8 +878,7 @@ const setPropertyValuesParamsSchema = z.object({
882
878
  }),
883
879
  isLimitedToLeafPropertyValues: z.boolean().default(false)
884
880
  }).superRefine((value, ctx) => {
885
- validateSetQueriesOperators(value.queries, ctx);
886
- if (!value.queries.some((query) => query.target === "property" && query.propertyVariables.length > 0)) ctx.addIssue({
881
+ if (!hasPropertyQueryWithPropertyVariables(value.queries)) ctx.addIssue({
887
882
  code: "custom",
888
883
  path: ["queries"],
889
884
  message: "At least one property query with propertyVariables is required"
@@ -896,8 +891,6 @@ const setItemsParamsSchema = z.object({
896
891
  sort: setItemsSortSchema,
897
892
  page: z.number().min(1, "Page must be positive").default(1),
898
893
  pageSize: z.number().min(1, "Page size must be positive").default(48)
899
- }).superRefine((value, ctx) => {
900
- validateSetQueriesOperators(value.queries, ctx);
901
894
  });
902
895
  //#endregion
903
896
  //#region src/utils/parse/index.ts
@@ -2409,6 +2402,15 @@ function buildOrCtsQueryExpression(queries) {
2409
2402
  if (queries.length === 1) return queries[0] ?? "cts:false-query()";
2410
2403
  return `cts:or-query((${queries.join(", ")}))`;
2411
2404
  }
2405
+ function isQueryLeaf(query) {
2406
+ return "target" in query;
2407
+ }
2408
+ function getQueryGroupChildren(query) {
2409
+ return "and" in query ? query.and : query.or;
2410
+ }
2411
+ function getQueryGroupOperator(query) {
2412
+ return "and" in query ? "and" : "or";
2413
+ }
2412
2414
  function buildContentTargetCandidateBranch(params) {
2413
2415
  const { containerElementName, termExpression, isCaseSensitive, language } = params;
2414
2416
  return `cts:element-query(xs:QName("${containerElementName}"),
@@ -2561,31 +2563,32 @@ function buildIncludesGroupMember(query) {
2561
2563
  case "property": return buildPropertyStringIncludesGroupMember(query);
2562
2564
  }
2563
2565
  }
2564
- function findCompatibleIncludesGroup(params) {
2565
- const { queries, startIndex, version } = params;
2566
- const startQuery = queries[startIndex];
2567
- if (startQuery == null) return null;
2568
- const groupValue = getGroupableIncludesValue(startQuery);
2566
+ function getCompatibleIncludesGroupLeaves(params) {
2567
+ const { query, version } = params;
2568
+ if (!("or" in query) || query.or.length <= 1) return null;
2569
+ const leafQueries = [];
2570
+ for (const childQuery of query.or) {
2571
+ if (!isQueryLeaf(childQuery)) return null;
2572
+ leafQueries.push(childQuery);
2573
+ }
2574
+ const firstQuery = leafQueries[0];
2575
+ if (firstQuery == null) return null;
2576
+ const groupValue = getGroupableIncludesValue(firstQuery);
2569
2577
  if (groupValue == null || !isCompatibleIncludesGroupQuery({
2570
- query: startQuery,
2578
+ query: firstQuery,
2571
2579
  value: groupValue,
2572
- isCaseSensitive: startQuery.isCaseSensitive,
2573
- language: startQuery.language,
2580
+ isCaseSensitive: firstQuery.isCaseSensitive,
2581
+ language: firstQuery.language,
2574
2582
  version
2575
- }) || startIndex > 0 && queries[startIndex]?.operator === "AND") return null;
2576
- const groupedQueries = [startQuery];
2577
- for (let index = startIndex + 1; index < queries.length; index += 1) {
2578
- const query = queries[index];
2579
- if (query?.operator !== "OR" || !isCompatibleIncludesGroupQuery({
2580
- query,
2581
- value: groupValue,
2582
- isCaseSensitive: startQuery.isCaseSensitive,
2583
- language: startQuery.language,
2584
- version
2585
- })) break;
2586
- groupedQueries.push(query);
2587
- }
2588
- return groupedQueries.length > 1 ? groupedQueries : null;
2583
+ })) return null;
2584
+ for (const leafQuery of leafQueries.slice(1)) if (!isCompatibleIncludesGroupQuery({
2585
+ query: leafQuery,
2586
+ value: groupValue,
2587
+ isCaseSensitive: firstQuery.isCaseSensitive,
2588
+ language: firstQuery.language,
2589
+ version
2590
+ })) return null;
2591
+ return leafQueries;
2589
2592
  }
2590
2593
  function buildIncludesGroupClause(params) {
2591
2594
  const { queries, queryKey } = params;
@@ -2843,7 +2846,7 @@ function buildQueryClause(params) {
2843
2846
  /**
2844
2847
  * Build a boolean query clause for an XQuery string.
2845
2848
  */
2846
- function buildBooleanQueryClause(params) {
2849
+ function buildBooleanQueryNode(params) {
2847
2850
  const { query, version, queryKey } = params;
2848
2851
  const compiledQueryClause = buildQueryClause({
2849
2852
  query,
@@ -2854,45 +2857,79 @@ function buildBooleanQueryClause(params) {
2854
2857
  return {
2855
2858
  declarations: compiledQueryClause.declarations,
2856
2859
  predicate: query.isNegated ? `not(${baseClause})` : baseClause,
2857
- candidateQueryVar: query.isNegated ? null : compiledQueryClause.candidateQueryVar
2860
+ candidateQueryVars: query.isNegated || compiledQueryClause.candidateQueryVar == null ? [] : [compiledQueryClause.candidateQueryVar]
2858
2861
  };
2859
2862
  }
2860
- function buildQueryPlan(params) {
2861
- const { queries, version, baseItemsExpression } = params;
2863
+ function buildQueryNode(params) {
2864
+ const { query, version, queryKey } = params;
2865
+ if (isQueryLeaf(query)) return buildBooleanQueryNode({
2866
+ query,
2867
+ version,
2868
+ queryKey
2869
+ });
2870
+ const groupQueries = getQueryGroupChildren(query);
2871
+ const optimizedIncludesGroupQueries = getCompatibleIncludesGroupLeaves({
2872
+ query,
2873
+ version
2874
+ });
2875
+ if (groupQueries.length === 1) {
2876
+ const onlyQuery = groupQueries[0];
2877
+ if (onlyQuery == null) return {
2878
+ declarations: [],
2879
+ predicate: "",
2880
+ candidateQueryVars: []
2881
+ };
2882
+ return buildQueryNode({
2883
+ query: onlyQuery,
2884
+ version,
2885
+ queryKey
2886
+ });
2887
+ }
2888
+ if (optimizedIncludesGroupQueries != null) {
2889
+ const compiledClause = buildIncludesGroupClause({
2890
+ queries: optimizedIncludesGroupQueries,
2891
+ queryKey
2892
+ });
2893
+ return {
2894
+ declarations: compiledClause.declarations,
2895
+ predicate: compiledClause.predicate,
2896
+ candidateQueryVars: compiledClause.candidateQueryVar == null ? [] : [compiledClause.candidateQueryVar]
2897
+ };
2898
+ }
2862
2899
  const declarations = [];
2863
- const predicateParts = [];
2900
+ const predicates = [];
2864
2901
  const candidateQueryVars = [];
2865
- let hasCtsIncludesClauses = false;
2866
- for (let index = 0; index < queries.length;) {
2867
- const groupedQueries = findCompatibleIncludesGroup({
2868
- queries,
2869
- startIndex: index,
2870
- version
2902
+ for (const [groupIndex, groupQuery] of groupQueries.entries()) {
2903
+ const compiledQueryNode = buildQueryNode({
2904
+ query: groupQuery,
2905
+ version,
2906
+ queryKey: `${queryKey}_${groupIndex + 1}`
2871
2907
  });
2872
- const query = queries[index];
2873
- if (query == null) break;
2874
- const compiledClause = groupedQueries != null ? buildIncludesGroupClause({
2875
- queries: groupedQueries,
2876
- queryKey: `${index + 1}`
2877
- }) : buildBooleanQueryClause({
2878
- query,
2908
+ declarations.push(...compiledQueryNode.declarations);
2909
+ predicates.push(compiledQueryNode.predicate);
2910
+ candidateQueryVars.push(...compiledQueryNode.candidateQueryVars);
2911
+ }
2912
+ return {
2913
+ declarations,
2914
+ predicate: getQueryGroupOperator(query) === "and" ? buildAndPredicate(predicates) : buildOrPredicate(predicates),
2915
+ candidateQueryVars
2916
+ };
2917
+ }
2918
+ function buildQueryPlan(params) {
2919
+ const { queries, version, baseItemsExpression } = params;
2920
+ const declarations = [];
2921
+ let predicate = "";
2922
+ let candidateQueryVars = [];
2923
+ if (queries != null) {
2924
+ const compiledQueryNode = buildQueryNode({
2925
+ query: queries,
2879
2926
  version,
2880
- queryKey: `${index + 1}`
2927
+ queryKey: "1"
2881
2928
  });
2882
- if (compiledClause.declarations.length > 0) {
2883
- hasCtsIncludesClauses = true;
2884
- declarations.push(...compiledClause.declarations);
2885
- }
2886
- if (compiledClause.candidateQueryVar != null) candidateQueryVars.push(compiledClause.candidateQueryVar);
2887
- if (index === 0) {
2888
- predicateParts.push(compiledClause.predicate);
2889
- index += groupedQueries?.length ?? 1;
2890
- continue;
2891
- }
2892
- predicateParts.push(`${query.operator === "AND" ? "and" : "or"} ${compiledClause.predicate}`);
2893
- index += groupedQueries?.length ?? 1;
2929
+ if (compiledQueryNode.declarations.length > 0) declarations.push(`let ${CTS_INCLUDES_STOP_WORDS_VAR} := (${CTS_INCLUDES_STOP_WORDS.map((stopWord) => stringLiteral(stopWord)).join(", ")})`, ...compiledQueryNode.declarations);
2930
+ predicate = compiledQueryNode.predicate;
2931
+ candidateQueryVars = compiledQueryNode.candidateQueryVars;
2894
2932
  }
2895
- if (hasCtsIncludesClauses) declarations.unshift(`let ${CTS_INCLUDES_STOP_WORDS_VAR} := (${CTS_INCLUDES_STOP_WORDS.map((stopWord) => stringLiteral(stopWord)).join(", ")})`);
2896
2933
  let itemsExpression = `(${baseItemsExpression})`;
2897
2934
  if (candidateQueryVars.length > 0) {
2898
2935
  const candidateQueriesExpression = `(${candidateQueryVars.join(", ")})`;
@@ -2910,7 +2947,7 @@ function buildQueryPlan(params) {
2910
2947
  return {
2911
2948
  declarations,
2912
2949
  itemsExpression,
2913
- predicate: predicateParts.join(" ")
2950
+ predicate
2914
2951
  };
2915
2952
  }
2916
2953
  //#endregion
@@ -2990,7 +3027,7 @@ function buildOrderedItemsClause(sort) {
2990
3027
  * @param params - The parameters for the fetch
2991
3028
  * @param params.setScopeUuids - An array of Set scope UUIDs to filter by
2992
3029
  * @param params.belongsToCollectionScopeUuids - An array of collection scope UUIDs to filter by
2993
- * @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
3030
+ * @param params.queries - Recursive query tree used to filter matching items
2994
3031
  * @param params.sort - Optional sorting configuration applied before pagination.
2995
3032
  * For propertyValue sorting, dataType is required and the sort key uses the first valid leaf value (value[not(@i)]).
2996
3033
  * @param params.page - The page number (1-indexed)
@@ -3036,7 +3073,7 @@ function buildXQuery$1(params, options) {
3036
3073
  *
3037
3074
  * @param params - The parameters for the fetch
3038
3075
  * @param params.setScopeUuids - The Set scope UUIDs to filter by
3039
- * @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
3076
+ * @param params.queries - Recursive query tree used to filter matching items
3040
3077
  * @param params.sort - Optional sorting configuration applied before pagination.
3041
3078
  * For propertyValue sorting, dataType is required and the sort key uses the first valid leaf value (value[not(@i)]).
3042
3079
  * @param params.page - The page number (1-indexed)
@@ -3215,9 +3252,15 @@ function aggregateAttributeValues(values) {
3215
3252
  }
3216
3253
  function getPropertyVariableUuidsFromQueries(queries) {
3217
3254
  const propertyVariableUuids = /* @__PURE__ */ new Set();
3218
- for (const query of queries) {
3219
- if (query.target !== "property") continue;
3220
- for (const propertyVariableUuid of query.propertyVariables ?? []) propertyVariableUuids.add(propertyVariableUuid);
3255
+ if (queries == null) return [];
3256
+ const pendingQueries = [queries];
3257
+ for (const query of pendingQueries) {
3258
+ if ("target" in query) {
3259
+ if (query.target !== "property") continue;
3260
+ for (const propertyVariableUuid of query.propertyVariables ?? []) propertyVariableUuids.add(propertyVariableUuid);
3261
+ continue;
3262
+ }
3263
+ pendingQueries.push(..."and" in query ? query.and : query.or);
3221
3264
  }
3222
3265
  return [...propertyVariableUuids];
3223
3266
  }
@@ -3289,7 +3332,7 @@ const responseSchema = z.object({ result: z.union([z.object({ ochre: z.object({
3289
3332
  * @param params - The parameters for the fetch
3290
3333
  * @param params.setScopeUuids - An array of set scope UUIDs to filter by
3291
3334
  * @param params.belongsToCollectionScopeUuids - An array of collection scope UUIDs to filter by
3292
- * @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
3335
+ * @param params.queries - Recursive query tree used to filter matching items
3293
3336
  * @param params.attributes - Whether to return values for bibliographies and periods
3294
3337
  * @param params.attributes.bibliographies - Whether to return values for bibliographies
3295
3338
  * @param params.attributes.periods - Whether to return values for periods
@@ -3357,7 +3400,7 @@ return (${returnedSequences.join(", ")})`}}</ochre>`;
3357
3400
  *
3358
3401
  * @param params - The parameters for the fetch
3359
3402
  * @param params.setScopeUuids - An array of set scope UUIDs to filter by
3360
- * @param params.queries - Ordered queries to combine with AND/OR and optional NOT via negation
3403
+ * @param params.queries - Recursive query tree used to filter matching items
3361
3404
  * @param params.attributes - Whether to return values for bibliographies and periods
3362
3405
  * @param params.attributes.bibliographies - Whether to return values for bibliographies
3363
3406
  * @param params.attributes.periods - Whether to return values for periods
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "0.20.29",
3
+ "version": "0.21.0",
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",
@@ -52,7 +52,7 @@
52
52
  "eslint": "^10.1.0",
53
53
  "prettier": "^3.8.1",
54
54
  "tsdown": "^0.21.4",
55
- "typescript": "^5.9.3"
55
+ "typescript": "^6.0.2"
56
56
  },
57
57
  "scripts": {
58
58
  "dev": "tsdown src/index.ts --watch",