@usereactify/search 5.60.0-beta.0 → 5.60.0-beta.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +16 -2
  2. package/dist/package.json +1 -1
  3. package/dist/src/components/Sensor/SensorSearchTerm.d.ts +1 -2
  4. package/dist/src/components/Sensor/SensorSearchTerm.js +38 -120
  5. package/dist/src/components/Sensor/SensorSearchTerm.js.map +1 -1
  6. package/dist/src/components/Sensor/Sensors.d.ts +1 -3
  7. package/dist/src/components/Sensor/Sensors.js +10 -29
  8. package/dist/src/components/Sensor/Sensors.js.map +1 -1
  9. package/dist/src/components/Sensor/index.d.ts +0 -2
  10. package/dist/src/components/Sensor/index.js +0 -4
  11. package/dist/src/components/Sensor/index.js.map +1 -1
  12. package/dist/src/search-request-builder/base-builders.d.ts +18 -0
  13. package/dist/src/search-request-builder/base-builders.js +184 -0
  14. package/dist/src/search-request-builder/base-builders.js.map +1 -0
  15. package/dist/src/search-request-builder/curation-builders.d.ts +2 -0
  16. package/dist/src/search-request-builder/curation-builders.js +44 -0
  17. package/dist/src/search-request-builder/curation-builders.js.map +1 -0
  18. package/dist/src/search-request-builder/index.d.ts +3 -0
  19. package/dist/src/search-request-builder/index.js +12 -0
  20. package/dist/src/search-request-builder/index.js.map +1 -0
  21. package/dist/src/search-request-builder/search-request-builder.d.ts +3 -0
  22. package/dist/src/search-request-builder/search-request-builder.js +54 -0
  23. package/dist/src/search-request-builder/search-request-builder.js.map +1 -0
  24. package/dist/src/search-request-builder/types.d.ts +105 -0
  25. package/dist/src/search-request-builder/types.js +30 -0
  26. package/dist/src/search-request-builder/types.js.map +1 -0
  27. package/dist/src/search-request-builder/utils.d.ts +27 -0
  28. package/dist/src/search-request-builder/utils.js +144 -0
  29. package/dist/src/search-request-builder/utils.js.map +1 -0
  30. package/dist/src/types/elastic.d.ts +6 -9
  31. package/dist/src/types/elastic.js.map +1 -1
  32. package/dist/src/types/firestore.d.ts +2 -2
  33. package/dist/src/types/firestore.js.map +1 -1
  34. package/dist/src/utility/config.d.ts +2 -2
  35. package/dist/src/utility/config.js +5 -8
  36. package/dist/src/utility/config.js.map +1 -1
  37. package/dist/src/utility/props.d.ts +5 -224
  38. package/dist/src/utility/props.js +54 -101
  39. package/dist/src/utility/props.js.map +1 -1
  40. package/dist/src/utility/server.js +1 -1
  41. package/dist/src/utility/server.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/src/components/Sensor/SensorCollectionWeighted.d.ts +0 -1
  44. package/dist/src/components/Sensor/SensorCollectionWeighted.js +0 -21
  45. package/dist/src/components/Sensor/SensorCollectionWeighted.js.map +0 -1
  46. package/dist/src/components/Sensor/SensorSearchWeighted.d.ts +0 -1
  47. package/dist/src/components/Sensor/SensorSearchWeighted.js +0 -22
  48. package/dist/src/components/Sensor/SensorSearchWeighted.js.map +0 -1
  49. package/dist/src/utility/queries.d.ts +0 -393
  50. package/dist/src/utility/queries.js +0 -197
  51. package/dist/src/utility/queries.js.map +0 -1
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateCurationSearchRequest = generateCurationSearchRequest;
4
+ const types_1 = require("./types");
5
+ const utils_1 = require("./utils");
6
+ function generateCurationSearchRequest(options) {
7
+ if (options.curationSearchRequestMode === types_1.CurationSearchRequestMode.Weighted) {
8
+ return generateWeightedCurationSearchRequest(options);
9
+ }
10
+ return generateBoostedCurationSearchRequest(options);
11
+ }
12
+ function generateWeightedCurationSearchRequest(options) {
13
+ const curationRules = extractCurationRules(options.curation);
14
+ return {
15
+ query: {
16
+ function_score: {
17
+ query: { match_all: {} }, // Add required query field
18
+ functions: curationRules.boostingRules
19
+ .map((boostingRule) => (0, utils_1.generateBoostingRule)({ boostingRule, market: options.market }))
20
+ .filter(Boolean),
21
+ score_mode: "sum",
22
+ boost_mode: "replace",
23
+ },
24
+ },
25
+ };
26
+ }
27
+ // This `sort` field is handled by SensorSort.
28
+ // ReactiveSearch does not combine multiple top-level `sort` fields; a `SearchRequest` is limited to one.
29
+ function generateBoostedCurationSearchRequest(options) {
30
+ return {};
31
+ }
32
+ // Supporting Functions
33
+ function extractCurationRules(curation) {
34
+ var _a, _b, _c, _d, _e;
35
+ if (!curation) {
36
+ return { boostingRules: [], groupings: [], sortings: [] };
37
+ }
38
+ return {
39
+ boostingRules: (_a = curation.boostings) !== null && _a !== void 0 ? _a : [],
40
+ groupings: (_c = (_b = curation.boosting) === null || _b === void 0 ? void 0 : _b.groupings) !== null && _c !== void 0 ? _c : [],
41
+ sortings: (_e = (_d = curation.boosting) === null || _d === void 0 ? void 0 : _d.sortings) !== null && _e !== void 0 ? _e : [],
42
+ };
43
+ }
44
+ //# sourceMappingURL=curation-builders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curation-builders.js","sourceRoot":"","sources":["../../../src/search-request-builder/curation-builders.ts"],"names":[],"mappings":";;AAWA,sEAMC;AAjBD,mCAQiB;AACjB,mCAA+C;AAE/C,SAAgB,6BAA6B,CAAC,OAAqC;IACjF,IAAI,OAAO,CAAC,yBAAyB,KAAK,iCAAyB,CAAC,QAAQ,EAAE,CAAC;QAC7E,OAAO,qCAAqC,CAAC,OAAO,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,oCAAoC,CAAC,OAAO,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,qCAAqC,CAAC,OAAqC;IAClF,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE7D,OAAO;QACL,KAAK,EAAE;YACL,cAAc,EAAE;gBACd,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,2BAA2B;gBACrD,SAAS,EAAE,aAAa,CAAC,aAAa;qBACnC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,IAAA,4BAAoB,EAAC,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;qBACrF,MAAM,CAAC,OAAO,CAAC;gBAClB,UAAU,EAAE,KAAK;gBACjB,UAAU,EAAE,SAAS;aACtB;SACF;KACF,CAAC;AACJ,CAAC;AAED,8CAA8C;AAC9C,yGAAyG;AACzG,SAAS,oCAAoC,CAAC,OAAqC;IACjF,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,uBAAuB;AACvB,SAAS,oBAAoB,CAAC,QAA8C;;IAC1E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC5D,CAAC;IAED,OAAO;QACL,aAAa,EAAE,MAAA,QAAQ,CAAC,SAAS,mCAAI,EAAE;QACvC,SAAS,EAAE,MAAA,MAAA,QAAQ,CAAC,QAAQ,0CAAE,SAAS,mCAAI,EAAE;QAC7C,QAAQ,EAAE,MAAA,MAAA,QAAQ,CAAC,QAAQ,0CAAE,QAAQ,mCAAI,EAAE;KAC5C,CAAC;AACJ,CAAC","sourcesContent":["import {\n CurationRules,\n CurationSearchRequestMode,\n GenerateSearchRequestOptions,\n SearchRequest,\n SortOptions,\n SearchCuration,\n CollectionCuration,\n} from \"./types\";\nimport { generateBoostingRule } from \"./utils\";\n\nexport function generateCurationSearchRequest(options: GenerateSearchRequestOptions): Partial<SearchRequest> {\n if (options.curationSearchRequestMode === CurationSearchRequestMode.Weighted) {\n return generateWeightedCurationSearchRequest(options);\n }\n\n return generateBoostedCurationSearchRequest(options);\n}\n\nfunction generateWeightedCurationSearchRequest(options: GenerateSearchRequestOptions): Partial<SearchRequest> {\n const curationRules = extractCurationRules(options.curation);\n\n return {\n query: {\n function_score: {\n query: { match_all: {} }, // Add required query field\n functions: curationRules.boostingRules\n .map((boostingRule) => generateBoostingRule({ boostingRule, market: options.market }))\n .filter(Boolean),\n score_mode: \"sum\",\n boost_mode: \"replace\",\n },\n },\n };\n}\n\n// This `sort` field is handled by SensorSort.\n// ReactiveSearch does not combine multiple top-level `sort` fields; a `SearchRequest` is limited to one.\nfunction generateBoostedCurationSearchRequest(options: GenerateSearchRequestOptions): Partial<SearchRequest> {\n return {};\n}\n\n// Supporting Functions\nfunction extractCurationRules(curation?: SearchCuration | CollectionCuration): CurationRules {\n if (!curation) {\n return { boostingRules: [], groupings: [], sortings: [] };\n }\n\n return {\n boostingRules: curation.boostings ?? [],\n groupings: curation.boosting?.groupings ?? [],\n sortings: curation.boosting?.sortings ?? [],\n };\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { generateSearchRequest, determineSearchRequestModes } from "./search-request-builder";
2
+ export type { SearchRequest, GenerateSearchRequestOptions, SearchRequestModes } from "./types";
3
+ export { BaseSearchRequestMode, CurationSearchRequestMode } from "./types";
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CurationSearchRequestMode = exports.BaseSearchRequestMode = exports.determineSearchRequestModes = exports.generateSearchRequest = void 0;
4
+ // Main public API exports
5
+ var search_request_builder_1 = require("./search-request-builder");
6
+ Object.defineProperty(exports, "generateSearchRequest", { enumerable: true, get: function () { return search_request_builder_1.generateSearchRequest; } });
7
+ Object.defineProperty(exports, "determineSearchRequestModes", { enumerable: true, get: function () { return search_request_builder_1.determineSearchRequestModes; } });
8
+ // Runtime enums (can be used as values)
9
+ var types_1 = require("./types");
10
+ Object.defineProperty(exports, "BaseSearchRequestMode", { enumerable: true, get: function () { return types_1.BaseSearchRequestMode; } });
11
+ Object.defineProperty(exports, "CurationSearchRequestMode", { enumerable: true, get: function () { return types_1.CurationSearchRequestMode; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/search-request-builder/index.ts"],"names":[],"mappings":";;;AAAA,0BAA0B;AAC1B,mEAA8F;AAArF,+HAAA,qBAAqB,OAAA;AAAE,qIAAA,2BAA2B,OAAA;AAK3D,wCAAwC;AACxC,iCAA2E;AAAlE,8GAAA,qBAAqB,OAAA;AAAE,kHAAA,yBAAyB,OAAA","sourcesContent":["// Main public API exports\nexport { generateSearchRequest, determineSearchRequestModes } from \"./search-request-builder\";\n\n// Types and enums (commonly used)\nexport type { SearchRequest, GenerateSearchRequestOptions, SearchRequestModes } from \"./types\";\n\n// Runtime enums (can be used as values)\nexport { BaseSearchRequestMode, CurationSearchRequestMode } from \"./types\";\n"]}
@@ -0,0 +1,3 @@
1
+ import { GenerateSearchRequestOptions, SearchRequest, SearchRequestModes } from "./types";
2
+ export declare function generateSearchRequest(options: GenerateSearchRequestOptions): SearchRequest;
3
+ export declare function determineSearchRequestModes(flags: string[]): SearchRequestModes;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSearchRequest = generateSearchRequest;
4
+ exports.determineSearchRequestModes = determineSearchRequestModes;
5
+ const base_builders_1 = require("./base-builders");
6
+ const curation_builders_1 = require("./curation-builders");
7
+ const types_1 = require("./types");
8
+ // Main Entry Point - Search Request Strategy Router
9
+ function generateSearchRequest(options) {
10
+ const baseSearchRequest = (0, base_builders_1.generateBaseSearchRequest)(options);
11
+ // Only apply curation enhancements if curation exists
12
+ if (options.curation) {
13
+ const curationSearchRequest = (0, curation_builders_1.generateCurationSearchRequest)(options);
14
+ return combineSearchRequest(baseSearchRequest, curationSearchRequest);
15
+ }
16
+ return baseSearchRequest;
17
+ }
18
+ // Combine Search Request Function
19
+ function combineSearchRequest(baseRequestSearch, curationSearchRequest) {
20
+ return Object.assign(Object.assign(Object.assign({}, baseRequestSearch), curationSearchRequest), (baseRequestSearch.query &&
21
+ curationSearchRequest.query && {
22
+ query: mergeQueries(baseRequestSearch.query, curationSearchRequest.query),
23
+ }));
24
+ }
25
+ function mergeQueries(baseQuery, enhancementQuery) {
26
+ if ("function_score" in enhancementQuery && enhancementQuery.function_score) {
27
+ return {
28
+ function_score: {
29
+ query: baseQuery,
30
+ functions: enhancementQuery.function_score.functions || [],
31
+ score_mode: enhancementQuery.function_score.score_mode,
32
+ boost_mode: enhancementQuery.function_score.boost_mode,
33
+ },
34
+ };
35
+ }
36
+ return enhancementQuery;
37
+ }
38
+ // Search Request Mode Detection Functions
39
+ function determineSearchRequestModes(flags) {
40
+ const baseSearchRequestMode = detectBaseSearchRequestMode(flags);
41
+ const curationSearchRequestMode = detectCurationSearchRequestMode(flags);
42
+ return { baseSearchRequestMode, curationSearchRequestMode };
43
+ }
44
+ function detectBaseSearchRequestMode(flags) {
45
+ return (flags === null || flags === void 0 ? void 0 : flags.includes("use_weighted_base_search_request"))
46
+ ? types_1.BaseSearchRequestMode.Weighted
47
+ : types_1.BaseSearchRequestMode.Relevance;
48
+ }
49
+ function detectCurationSearchRequestMode(flags) {
50
+ return (flags === null || flags === void 0 ? void 0 : flags.includes("use_weighted_curation_search_request"))
51
+ ? types_1.CurationSearchRequestMode.Weighted
52
+ : types_1.CurationSearchRequestMode.Boosted;
53
+ }
54
+ //# sourceMappingURL=search-request-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-request-builder.js","sourceRoot":"","sources":["../../../src/search-request-builder/search-request-builder.ts"],"names":[],"mappings":";;AAYA,sDAUC;AAiCD,kEAIC;AA3DD,mDAA4D;AAC5D,2DAAoE;AACpE,mCAOiB;AAEjB,oDAAoD;AACpD,SAAgB,qBAAqB,CAAC,OAAqC;IACzE,MAAM,iBAAiB,GAAG,IAAA,yCAAyB,EAAC,OAAO,CAAC,CAAC;IAE7D,sDAAsD;IACtD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,qBAAqB,GAAG,IAAA,iDAA6B,EAAC,OAAO,CAAC,CAAC;QACrE,OAAO,oBAAoB,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,kCAAkC;AAClC,SAAS,oBAAoB,CAC3B,iBAAgC,EAChC,qBAA6C;IAE7C,qDACK,iBAAiB,GACjB,qBAAqB,GACrB,CAAC,iBAAiB,CAAC,KAAK;QACzB,qBAAqB,CAAC,KAAK,IAAI;QAC7B,KAAK,EAAE,YAAY,CAAC,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,CAAC,KAAK,CAAC;KAC1E,CAAC,EACJ;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,SAAyB,EAAE,gBAAgC;IAC/E,IAAI,gBAAgB,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,cAAc,EAAE,CAAC;QAC5E,OAAO;YACL,cAAc,EAAE;gBACd,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,gBAAgB,CAAC,cAAc,CAAC,SAAS,IAAI,EAAE;gBAC1D,UAAU,EAAE,gBAAgB,CAAC,cAAc,CAAC,UAAU;gBACtD,UAAU,EAAE,gBAAgB,CAAC,cAAc,CAAC,UAAU;aACvD;SACF,CAAC;IACJ,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,0CAA0C;AAC1C,SAAgB,2BAA2B,CAAC,KAAe;IACzD,MAAM,qBAAqB,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,yBAAyB,GAAG,+BAA+B,CAAC,KAAK,CAAC,CAAC;IACzE,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,CAAC;AAC9D,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAgB;IACnD,OAAO,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,QAAQ,CAAC,kCAAkC,CAAC;QACxD,CAAC,CAAC,6BAAqB,CAAC,QAAQ;QAChC,CAAC,CAAC,6BAAqB,CAAC,SAAS,CAAC;AACtC,CAAC;AAED,SAAS,+BAA+B,CAAC,KAAgB;IACvD,OAAO,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,QAAQ,CAAC,sCAAsC,CAAC;QAC5D,CAAC,CAAC,iCAAyB,CAAC,QAAQ;QACpC,CAAC,CAAC,iCAAyB,CAAC,OAAO,CAAC;AACxC,CAAC","sourcesContent":["import { generateBaseSearchRequest } from \"./base-builders\";\nimport { generateCurationSearchRequest } from \"./curation-builders\";\nimport {\n BaseSearchRequestMode,\n CurationSearchRequestMode,\n GenerateSearchRequestOptions,\n QueryContainer,\n SearchRequest,\n SearchRequestModes,\n} from \"./types\";\n\n// Main Entry Point - Search Request Strategy Router\nexport function generateSearchRequest(options: GenerateSearchRequestOptions): SearchRequest {\n const baseSearchRequest = generateBaseSearchRequest(options);\n\n // Only apply curation enhancements if curation exists\n if (options.curation) {\n const curationSearchRequest = generateCurationSearchRequest(options);\n return combineSearchRequest(baseSearchRequest, curationSearchRequest);\n }\n\n return baseSearchRequest;\n}\n\n// Combine Search Request Function\nfunction combineSearchRequest(\n baseRequestSearch: SearchRequest,\n curationSearchRequest: Partial<SearchRequest>\n): SearchRequest {\n return {\n ...baseRequestSearch,\n ...curationSearchRequest,\n ...(baseRequestSearch.query &&\n curationSearchRequest.query && {\n query: mergeQueries(baseRequestSearch.query, curationSearchRequest.query),\n }),\n };\n}\n\nfunction mergeQueries(baseQuery: QueryContainer, enhancementQuery: QueryContainer): QueryContainer {\n if (\"function_score\" in enhancementQuery && enhancementQuery.function_score) {\n return {\n function_score: {\n query: baseQuery,\n functions: enhancementQuery.function_score.functions || [],\n score_mode: enhancementQuery.function_score.score_mode,\n boost_mode: enhancementQuery.function_score.boost_mode,\n },\n };\n }\n\n return enhancementQuery;\n}\n\n// Search Request Mode Detection Functions\nexport function determineSearchRequestModes(flags: string[]): SearchRequestModes {\n const baseSearchRequestMode = detectBaseSearchRequestMode(flags);\n const curationSearchRequestMode = detectCurationSearchRequestMode(flags);\n return { baseSearchRequestMode, curationSearchRequestMode };\n}\n\nfunction detectBaseSearchRequestMode(flags?: string[]): BaseSearchRequestMode {\n return flags?.includes(\"use_weighted_base_search_request\")\n ? BaseSearchRequestMode.Weighted\n : BaseSearchRequestMode.Relevance;\n}\n\nfunction detectCurationSearchRequestMode(flags?: string[]): CurationSearchRequestMode {\n return flags?.includes(\"use_weighted_curation_search_request\")\n ? CurationSearchRequestMode.Weighted\n : CurationSearchRequestMode.Boosted;\n}\n"]}
@@ -0,0 +1,105 @@
1
+ import { Boosting, BoostGrouping, BoostSorting, Curation, CurationType, Relevance, SearchableField } from "../types/firestore";
2
+ export declare const BaseSearchRequestMode: {
3
+ readonly Relevance: "relevance";
4
+ readonly Weighted: "weighted";
5
+ };
6
+ export type BaseSearchRequestMode = typeof BaseSearchRequestMode[keyof typeof BaseSearchRequestMode];
7
+ export declare const CurationSearchRequestMode: {
8
+ readonly Boosted: "boosted";
9
+ readonly Weighted: "weighted";
10
+ };
11
+ export type CurationSearchRequestMode = typeof CurationSearchRequestMode[keyof typeof CurationSearchRequestMode];
12
+ export interface SearchRequestModes {
13
+ baseSearchRequestMode: BaseSearchRequestMode;
14
+ curationSearchRequestMode: CurationSearchRequestMode;
15
+ }
16
+ export interface GenerateSearchRequestBaseOptions {
17
+ relevanceFields?: Relevance[];
18
+ searchableFields?: SearchableField[];
19
+ market?: string;
20
+ baseSearchRequestMode: BaseSearchRequestMode;
21
+ curationSearchRequestMode: CurationSearchRequestMode;
22
+ }
23
+ export interface GenerateSearchRequestSearchOptions extends GenerateSearchRequestBaseOptions {
24
+ searchTerm: string;
25
+ curation?: SearchCuration;
26
+ }
27
+ export interface GenerateSearchRequestCollectionOptions extends GenerateSearchRequestBaseOptions {
28
+ collectionHandle: string;
29
+ curation?: CollectionCuration;
30
+ }
31
+ export type GenerateSearchRequestOptions = GenerateSearchRequestSearchOptions | GenerateSearchRequestCollectionOptions;
32
+ export interface SearchCuration extends Curation {
33
+ type: CurationType.Search;
34
+ searchTerm: string;
35
+ }
36
+ export interface CollectionCuration extends Curation {
37
+ type: CurationType.Collection;
38
+ collectionHandle: string;
39
+ }
40
+ export interface CurationRules {
41
+ boostingRules: Boosting[];
42
+ groupings: BoostGrouping[];
43
+ sortings: BoostSorting[];
44
+ }
45
+ export interface TermSearchRequestOptions {
46
+ searchTerm: string;
47
+ baseSearchRequestMode: BaseSearchRequestMode;
48
+ relevanceFields?: Relevance[];
49
+ searchableFields?: SearchableField[];
50
+ markets: string[];
51
+ }
52
+ export interface CollectionSearchRequestOptions {
53
+ collectionHandle: string;
54
+ markets: string[];
55
+ }
56
+ export interface SearchRequest {
57
+ query?: QueryContainer;
58
+ sort?: SortOptions;
59
+ }
60
+ export interface QueryContainer {
61
+ bool?: BoolQuery;
62
+ function_score?: FunctionScoreQuery;
63
+ multi_match?: MultiMatchQuery;
64
+ match?: Record<string, any>;
65
+ match_all?: Record<string, any>;
66
+ term?: Record<string, any>;
67
+ terms?: Record<string, string[]>;
68
+ wildcard?: Record<string, string>;
69
+ range?: Record<string, any>;
70
+ nested?: NestedQuery;
71
+ }
72
+ export interface BoolQuery {
73
+ must?: QueryContainer | QueryContainer[];
74
+ should?: QueryContainer[];
75
+ must_not?: QueryContainer | QueryContainer[];
76
+ filter?: QueryContainer[];
77
+ minimum_should_match?: string | number;
78
+ }
79
+ export interface FunctionScoreQuery {
80
+ query: QueryContainer;
81
+ functions: FunctionScoreContainer[];
82
+ score_mode: FunctionScoreMode;
83
+ boost_mode: FunctionBoostMode;
84
+ }
85
+ export interface FunctionScoreContainer {
86
+ filter: QueryContainer;
87
+ weight: number;
88
+ }
89
+ export interface MultiMatchQuery {
90
+ query: string;
91
+ fields: string[];
92
+ type: "cross_fields" | "phrase" | "phrase_prefix";
93
+ operator: "and" | "or";
94
+ }
95
+ export interface NestedQuery {
96
+ path: string;
97
+ query: QueryContainer;
98
+ }
99
+ export type SortOptions = Record<string, any>[] | Record<string, any>;
100
+ export type FunctionScoreMode = "sum" | "multiply" | "avg" | "max" | "min" | "first";
101
+ export type FunctionBoostMode = "multiply" | "replace" | "sum" | "avg" | "max" | "min";
102
+ export declare function isSearchOptions(options: GenerateSearchRequestOptions): options is GenerateSearchRequestSearchOptions;
103
+ export declare function isCollectionOptions(options: GenerateSearchRequestOptions): options is GenerateSearchRequestCollectionOptions;
104
+ export declare function isSearchCuration(curation?: Curation): curation is SearchCuration;
105
+ export declare function isCollectionCuration(curation?: Curation): curation is CollectionCuration;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CurationSearchRequestMode = exports.BaseSearchRequestMode = void 0;
4
+ exports.isSearchOptions = isSearchOptions;
5
+ exports.isCollectionOptions = isCollectionOptions;
6
+ exports.isSearchCuration = isSearchCuration;
7
+ exports.isCollectionCuration = isCollectionCuration;
8
+ const firestore_1 = require("../types/firestore");
9
+ exports.BaseSearchRequestMode = {
10
+ Relevance: "relevance",
11
+ Weighted: "weighted",
12
+ };
13
+ exports.CurationSearchRequestMode = {
14
+ Boosted: "boosted",
15
+ Weighted: "weighted",
16
+ };
17
+ // Type guards for runtime type checking
18
+ function isSearchOptions(options) {
19
+ return "searchTerm" in options;
20
+ }
21
+ function isCollectionOptions(options) {
22
+ return "collectionHandle" in options;
23
+ }
24
+ function isSearchCuration(curation) {
25
+ return (curation === null || curation === void 0 ? void 0 : curation.type) === firestore_1.CurationType.Search;
26
+ }
27
+ function isCollectionCuration(curation) {
28
+ return (curation === null || curation === void 0 ? void 0 : curation.type) === firestore_1.CurationType.Collection;
29
+ }
30
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/search-request-builder/types.ts"],"names":[],"mappings":";;;AAwIA,0CAEC;AAED,kDAIC;AAED,4CAEC;AAED,oDAEC;AAxJD,kDAQ4B;AAEf,QAAA,qBAAqB,GAAG;IACnC,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;CACZ,CAAC;AAGE,QAAA,yBAAyB,GAAG;IACvC,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;CACZ,CAAC;AAoHX,wCAAwC;AACxC,SAAgB,eAAe,CAAC,OAAqC;IACnE,OAAO,YAAY,IAAI,OAAO,CAAC;AACjC,CAAC;AAED,SAAgB,mBAAmB,CACjC,OAAqC;IAErC,OAAO,kBAAkB,IAAI,OAAO,CAAC;AACvC,CAAC;AAED,SAAgB,gBAAgB,CAAC,QAAmB;IAClD,OAAO,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,MAAK,wBAAY,CAAC,MAAM,CAAC;AAChD,CAAC;AAED,SAAgB,oBAAoB,CAAC,QAAmB;IACtD,OAAO,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,MAAK,wBAAY,CAAC,UAAU,CAAC;AACpD,CAAC","sourcesContent":["import {\n Boosting,\n BoostGrouping,\n BoostSorting,\n Curation,\n CurationType,\n Relevance,\n SearchableField,\n} from \"../types/firestore\";\n\nexport const BaseSearchRequestMode = {\n Relevance: \"relevance\",\n Weighted: \"weighted\",\n} as const;\nexport type BaseSearchRequestMode = typeof BaseSearchRequestMode[keyof typeof BaseSearchRequestMode];\n\nexport const CurationSearchRequestMode = {\n Boosted: \"boosted\",\n Weighted: \"weighted\",\n} as const;\nexport type CurationSearchRequestMode = typeof CurationSearchRequestMode[keyof typeof CurationSearchRequestMode];\n\nexport interface SearchRequestModes {\n baseSearchRequestMode: BaseSearchRequestMode;\n curationSearchRequestMode: CurationSearchRequestMode;\n}\n\n// Base options shared by all search request types\nexport interface GenerateSearchRequestBaseOptions {\n relevanceFields?: Relevance[];\n searchableFields?: SearchableField[];\n market?: string;\n baseSearchRequestMode: BaseSearchRequestMode;\n curationSearchRequestMode: CurationSearchRequestMode;\n}\n\n// Search-specific options\nexport interface GenerateSearchRequestSearchOptions extends GenerateSearchRequestBaseOptions {\n searchTerm: string;\n curation?: SearchCuration;\n}\n\n// Collection-specific options\nexport interface GenerateSearchRequestCollectionOptions extends GenerateSearchRequestBaseOptions {\n collectionHandle: string;\n curation?: CollectionCuration;\n}\n\n// Union type for the main interface\nexport type GenerateSearchRequestOptions = GenerateSearchRequestSearchOptions | GenerateSearchRequestCollectionOptions;\n\n// Refined curation types with better type safety\nexport interface SearchCuration extends Curation {\n type: CurationType.Search;\n searchTerm: string;\n}\n\nexport interface CollectionCuration extends Curation {\n type: CurationType.Collection;\n collectionHandle: string;\n}\n\nexport interface CurationRules {\n boostingRules: Boosting[];\n groupings: BoostGrouping[];\n sortings: BoostSorting[];\n}\n\nexport interface TermSearchRequestOptions {\n searchTerm: string;\n baseSearchRequestMode: BaseSearchRequestMode;\n relevanceFields?: Relevance[];\n searchableFields?: SearchableField[];\n markets: string[];\n}\n\nexport interface CollectionSearchRequestOptions {\n collectionHandle: string;\n markets: string[];\n}\n\n// Elasticsearch/OpenSearch type aliases - using basic types to avoid external dependency\nexport interface SearchRequest {\n query?: QueryContainer;\n sort?: SortOptions;\n}\n\nexport interface QueryContainer {\n bool?: BoolQuery;\n function_score?: FunctionScoreQuery;\n multi_match?: MultiMatchQuery;\n match?: Record<string, any>;\n match_all?: Record<string, any>;\n term?: Record<string, any>;\n terms?: Record<string, string[]>;\n wildcard?: Record<string, string>;\n range?: Record<string, any>;\n nested?: NestedQuery;\n}\n\nexport interface BoolQuery {\n must?: QueryContainer | QueryContainer[];\n should?: QueryContainer[];\n must_not?: QueryContainer | QueryContainer[];\n filter?: QueryContainer[];\n minimum_should_match?: string | number;\n}\n\nexport interface FunctionScoreQuery {\n query: QueryContainer;\n functions: FunctionScoreContainer[];\n score_mode: FunctionScoreMode;\n boost_mode: FunctionBoostMode;\n}\n\nexport interface FunctionScoreContainer {\n filter: QueryContainer;\n weight: number;\n}\n\nexport interface MultiMatchQuery {\n query: string;\n fields: string[];\n type: \"cross_fields\" | \"phrase\" | \"phrase_prefix\";\n operator: \"and\" | \"or\";\n}\n\nexport interface NestedQuery {\n path: string;\n query: QueryContainer;\n}\n\nexport type SortOptions = Record<string, any>[] | Record<string, any>;\nexport type FunctionScoreMode = \"sum\" | \"multiply\" | \"avg\" | \"max\" | \"min\" | \"first\";\nexport type FunctionBoostMode = \"multiply\" | \"replace\" | \"sum\" | \"avg\" | \"max\" | \"min\";\n// Type guards for runtime type checking\nexport function isSearchOptions(options: GenerateSearchRequestOptions): options is GenerateSearchRequestSearchOptions {\n return \"searchTerm\" in options;\n}\n\nexport function isCollectionOptions(\n options: GenerateSearchRequestOptions\n): options is GenerateSearchRequestCollectionOptions {\n return \"collectionHandle\" in options;\n}\n\nexport function isSearchCuration(curation?: Curation): curation is SearchCuration {\n return curation?.type === CurationType.Search;\n}\n\nexport function isCollectionCuration(curation?: Curation): curation is CollectionCuration {\n return curation?.type === CurationType.Collection;\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import { Boosting, Relevance } from "../types/firestore";
2
+ import { FunctionScoreContainer, QueryContainer, TermSearchRequestOptions } from "./types";
3
+ export declare function generateQueryField(options: {
4
+ fieldName: string;
5
+ market?: string;
6
+ }): string;
7
+ export declare function generateMarketsFilter(markets: string[]): QueryContainer[];
8
+ export declare function generateMarketsClause(markets: string[]): QueryContainer | null;
9
+ export declare function generateBoostingRule(options: {
10
+ boostingRule: Boosting;
11
+ market?: string;
12
+ }): FunctionScoreContainer;
13
+ export declare function generateBoostingRules(options: {
14
+ boostingRules: Boosting[];
15
+ market?: string;
16
+ }): FunctionScoreContainer[];
17
+ export declare function validateSearchInputs(options: TermSearchRequestOptions): void;
18
+ export declare function prepareRelevanceFields(relevanceFields?: Relevance[]): {
19
+ crossFields: string[];
20
+ phrase: string[];
21
+ phrasePrefix: string[];
22
+ };
23
+ export declare function generateMultiMatchQueries(searchTerm: string, fieldMappings: {
24
+ crossFields: string[];
25
+ phrase: string[];
26
+ phrasePrefix: string[];
27
+ }): QueryContainer[];
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateQueryField = generateQueryField;
4
+ exports.generateMarketsFilter = generateMarketsFilter;
5
+ exports.generateMarketsClause = generateMarketsClause;
6
+ exports.generateBoostingRule = generateBoostingRule;
7
+ exports.generateBoostingRules = generateBoostingRules;
8
+ exports.validateSearchInputs = validateSearchInputs;
9
+ exports.prepareRelevanceFields = prepareRelevanceFields;
10
+ exports.generateMultiMatchQueries = generateMultiMatchQueries;
11
+ const firestore_1 = require("../types/firestore");
12
+ const types_1 = require("./types");
13
+ // Field and market utilities
14
+ function generateQueryField(options) {
15
+ if (!options.market) {
16
+ if (options.fieldName === "price")
17
+ return "price_min";
18
+ return options.fieldName;
19
+ }
20
+ if (options.fieldName === "price") {
21
+ return `price_min_market_${options.market}`;
22
+ }
23
+ if (options.fieldName === "price_min") {
24
+ return `price_min_market_${options.market}`;
25
+ }
26
+ if (options.fieldName === "price_max") {
27
+ return `price_max_market_${options.market}`;
28
+ }
29
+ if (options.fieldName === "inventory_total") {
30
+ return `inventory_quantity_market_${options.market}`;
31
+ }
32
+ return options.fieldName;
33
+ }
34
+ function generateMarketsFilter(markets) {
35
+ if (!(markets === null || markets === void 0 ? void 0 : markets.length))
36
+ return [];
37
+ return [{ terms: { markets: markets } }];
38
+ }
39
+ function generateMarketsClause(markets) {
40
+ if (!markets.length)
41
+ return null;
42
+ return { terms: { markets: markets } };
43
+ }
44
+ // Boosting utilities
45
+ function generateBoostingRule(options) {
46
+ const fieldName = generateQueryField({ fieldName: options.boostingRule.fieldName, market: options.market });
47
+ if (options.boostingRule.operation === firestore_1.Operation.Contains) {
48
+ return {
49
+ filter: { wildcard: { [fieldName]: `*${options.boostingRule.value}*` } },
50
+ weight: options.boostingRule.points,
51
+ };
52
+ }
53
+ if (options.boostingRule.operation === firestore_1.Operation.NotContains) {
54
+ return {
55
+ filter: { bool: { must_not: { wildcard: { [fieldName]: `*${options.boostingRule.value}*` } } } },
56
+ weight: options.boostingRule.points,
57
+ };
58
+ }
59
+ if (options.boostingRule.operation === firestore_1.Operation.Equals) {
60
+ return {
61
+ filter: { term: { [fieldName]: options.boostingRule.value } },
62
+ weight: options.boostingRule.points,
63
+ };
64
+ }
65
+ if (options.boostingRule.operation === firestore_1.Operation.GreaterThan) {
66
+ return {
67
+ filter: { range: { [fieldName]: { gt: parseFloat(options.boostingRule.value) } } },
68
+ weight: options.boostingRule.points,
69
+ };
70
+ }
71
+ if (options.boostingRule.operation === firestore_1.Operation.LessThan) {
72
+ return {
73
+ filter: { range: { [fieldName]: { lt: parseFloat(options.boostingRule.value) } } },
74
+ weight: options.boostingRule.points,
75
+ };
76
+ }
77
+ throw new Error(`Unable to process rule`);
78
+ }
79
+ function generateBoostingRules(options) {
80
+ return options.boostingRules
81
+ .map((boostingRule) => generateBoostingRule({ boostingRule: boostingRule, market: options.market }))
82
+ .filter(Boolean);
83
+ }
84
+ // Validation
85
+ function validateSearchInputs(options) {
86
+ var _a, _b, _c;
87
+ if (!((_a = options.searchTerm) === null || _a === void 0 ? void 0 : _a.trim())) {
88
+ throw new Error("Search term is required");
89
+ }
90
+ if (options.baseSearchRequestMode === types_1.BaseSearchRequestMode.Weighted && !((_b = options.searchableFields) === null || _b === void 0 ? void 0 : _b.length)) {
91
+ throw new Error("SearchableFields required for weighted search");
92
+ }
93
+ if (options.baseSearchRequestMode === types_1.BaseSearchRequestMode.Relevance && !((_c = options.relevanceFields) === null || _c === void 0 ? void 0 : _c.length)) {
94
+ throw new Error("RelevanceFields required for relevance search");
95
+ }
96
+ }
97
+ // Relevance field utilities
98
+ function prepareRelevanceFields(relevanceFields) {
99
+ if (!relevanceFields)
100
+ return { crossFields: [], phrase: [], phrasePrefix: [] };
101
+ const enabledFields = relevanceFields.filter((field) => field.enabled);
102
+ return {
103
+ crossFields: enabledFields.map((field) => `${field.field}^${field.importance}`),
104
+ phrase: enabledFields.map((field) => `${field.field}^${field.importance}`),
105
+ phrasePrefix: enabledFields
106
+ .filter((field) => !field.field.includes("."))
107
+ .map((field) => `${field.field}^${field.importance}`),
108
+ };
109
+ }
110
+ function generateMultiMatchQueries(searchTerm, fieldMappings) {
111
+ const queries = [];
112
+ if (fieldMappings.crossFields.length > 0) {
113
+ queries.push({
114
+ multi_match: {
115
+ query: searchTerm,
116
+ fields: fieldMappings.crossFields,
117
+ type: "cross_fields",
118
+ operator: "and",
119
+ },
120
+ });
121
+ }
122
+ if (fieldMappings.phrase.length > 0) {
123
+ queries.push({
124
+ multi_match: {
125
+ query: searchTerm,
126
+ fields: fieldMappings.phrase,
127
+ type: "phrase",
128
+ operator: "and",
129
+ },
130
+ });
131
+ }
132
+ if (fieldMappings.phrasePrefix.length > 0) {
133
+ queries.push({
134
+ multi_match: {
135
+ query: searchTerm,
136
+ fields: fieldMappings.phrasePrefix,
137
+ type: "phrase_prefix",
138
+ operator: "and",
139
+ },
140
+ });
141
+ }
142
+ return queries;
143
+ }
144
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/search-request-builder/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Boosting, Operation, Relevance } from \"../types/firestore\";\nimport { BaseSearchRequestMode, FunctionScoreContainer, QueryContainer, TermSearchRequestOptions } from \"./types\";\n\n// Field and market utilities\nexport function generateQueryField(options: { fieldName: string; market?: string }) {\n if (!options.market) {\n if (options.fieldName === \"price\") return \"price_min\";\n return options.fieldName;\n }\n\n if (options.fieldName === \"price\") {\n return `price_min_market_${options.market}`;\n }\n if (options.fieldName === \"price_min\") {\n return `price_min_market_${options.market}`;\n }\n if (options.fieldName === \"price_max\") {\n return `price_max_market_${options.market}`;\n }\n if (options.fieldName === \"inventory_total\") {\n return `inventory_quantity_market_${options.market}`;\n }\n\n return options.fieldName;\n}\n\nexport function generateMarketsFilter(markets: string[]): QueryContainer[] {\n if (!markets?.length) return [];\n return [{ terms: { markets: markets } }];\n}\n\nexport function generateMarketsClause(markets: string[]): QueryContainer | null {\n if (!markets.length) return null;\n return { terms: { markets: markets } };\n}\n\n// Boosting utilities\nexport function generateBoostingRule(options: { boostingRule: Boosting; market?: string }): FunctionScoreContainer {\n const fieldName = generateQueryField({ fieldName: options.boostingRule.fieldName, market: options.market });\n\n if (options.boostingRule.operation === Operation.Contains) {\n return {\n filter: { wildcard: { [fieldName]: `*${options.boostingRule.value}*` } },\n weight: options.boostingRule.points,\n };\n }\n if (options.boostingRule.operation === Operation.NotContains) {\n return {\n filter: { bool: { must_not: { wildcard: { [fieldName]: `*${options.boostingRule.value}*` } } } },\n weight: options.boostingRule.points,\n };\n }\n if (options.boostingRule.operation === Operation.Equals) {\n return {\n filter: { term: { [fieldName]: options.boostingRule.value } },\n weight: options.boostingRule.points,\n };\n }\n if (options.boostingRule.operation === Operation.GreaterThan) {\n return {\n filter: { range: { [fieldName]: { gt: parseFloat(options.boostingRule.value) } } },\n weight: options.boostingRule.points,\n };\n }\n if (options.boostingRule.operation === Operation.LessThan) {\n return {\n filter: { range: { [fieldName]: { lt: parseFloat(options.boostingRule.value) } } },\n weight: options.boostingRule.points,\n };\n }\n throw new Error(`Unable to process rule`);\n}\n\nexport function generateBoostingRules(options: {\n boostingRules: Boosting[];\n market?: string;\n}): FunctionScoreContainer[] {\n return options.boostingRules\n .map((boostingRule) => generateBoostingRule({ boostingRule: boostingRule, market: options.market }))\n .filter(Boolean);\n}\n\n// Validation\nexport function validateSearchInputs(options: TermSearchRequestOptions) {\n if (!options.searchTerm?.trim()) {\n throw new Error(\"Search term is required\");\n }\n\n if (options.baseSearchRequestMode === BaseSearchRequestMode.Weighted && !options.searchableFields?.length) {\n throw new Error(\"SearchableFields required for weighted search\");\n }\n\n if (options.baseSearchRequestMode === BaseSearchRequestMode.Relevance && !options.relevanceFields?.length) {\n throw new Error(\"RelevanceFields required for relevance search\");\n }\n}\n\n// Relevance field utilities\nexport function prepareRelevanceFields(relevanceFields?: Relevance[]) {\n if (!relevanceFields) return { crossFields: [], phrase: [], phrasePrefix: [] };\n\n const enabledFields = relevanceFields.filter((field) => field.enabled);\n\n return {\n crossFields: enabledFields.map((field) => `${field.field}^${field.importance}`),\n phrase: enabledFields.map((field) => `${field.field}^${field.importance}`),\n phrasePrefix: enabledFields\n .filter((field) => !field.field.includes(\".\"))\n .map((field) => `${field.field}^${field.importance}`),\n };\n}\n\nexport function generateMultiMatchQueries(\n searchTerm: string,\n fieldMappings: { crossFields: string[]; phrase: string[]; phrasePrefix: string[] }\n): QueryContainer[] {\n const queries = [];\n\n if (fieldMappings.crossFields.length > 0) {\n queries.push({\n multi_match: {\n query: searchTerm,\n fields: fieldMappings.crossFields,\n type: \"cross_fields\" as const,\n operator: \"and\" as const,\n },\n });\n }\n\n if (fieldMappings.phrase.length > 0) {\n queries.push({\n multi_match: {\n query: searchTerm,\n fields: fieldMappings.phrase,\n type: \"phrase\" as const,\n operator: \"and\" as const,\n },\n });\n }\n\n if (fieldMappings.phrasePrefix.length > 0) {\n queries.push({\n multi_match: {\n query: searchTerm,\n fields: fieldMappings.phrasePrefix,\n type: \"phrase_prefix\" as const,\n operator: \"and\" as const,\n },\n });\n }\n\n return queries;\n}\n"]}
@@ -217,15 +217,12 @@ export type ElasticBulkOperationUpdate = [
217
217
  doc_as_upsert?: true;
218
218
  }
219
219
  ];
220
- export type ElasticBulkOperationIndex = [
221
- {
222
- index: {
223
- _index: string;
224
- _id: string;
225
- };
226
- },
227
- ElasticDocument
228
- ];
220
+ export type ElasticBulkOperationIndex = [{
221
+ index: {
222
+ _index: string;
223
+ _id: string;
224
+ };
225
+ }, ElasticDocument];
229
226
  export type ElasticBulkOperation = ElasticBulkOperationUpdate | ElasticBulkOperationIndex;
230
227
  export type ElasticSearchResult<T = ElasticDocument> = {
231
228
  hits: {
@@ -1 +1 @@
1
- {"version":3,"file":"elastic.js","sourceRoot":"","sources":["../../../src/types/elastic.ts"],"names":[],"mappings":";;;AAOA,IAAY,mBAGX;AAHD,WAAY,mBAAmB;IAC7B,0CAAmB,CAAA;IACnB,0CAAmB,CAAA;AACrB,CAAC,EAHW,mBAAmB,mCAAnB,mBAAmB,QAG9B;AAqPD,IAAY,eAQX;AARD,WAAY,eAAe;IACzB,gCAAa,CAAA;IACb,gCAAa,CAAA;IACb,gCAAa,CAAA;IACb,kCAAe,CAAA;IACf,oCAAiB,CAAA;IACjB,sCAAmB,CAAA;IACnB,sCAAmB,CAAA;AACrB,CAAC,EARW,eAAe,+BAAf,eAAe,QAQ1B","sourcesContent":["import { Callout } from \"./firestore\";\nimport {\n Maybe,\n ProductVariantInventoryPolicy,\n MetafieldValueType,\n} from \"./graphql\";\n\nexport enum ElasticDocumentType {\n Callout = \"callout\",\n Product = \"product\",\n}\n\nexport interface ElasticDocumentBase {\n /** Elasticsearch score when explain is enabled */\n _score?: number;\n /** Elasticsearch explanation when explain is enabled */\n _explanation?: {\n value: number;\n description: string;\n details?: Array<{\n value: number;\n description: string;\n details?: any[];\n }>;\n };\n}\n\nexport type ElasticDocument = ElasticCallout | ElasticProduct;\n\nexport interface ElasticCallout extends ElasticDocumentBase {\n type: ElasticDocumentType.Callout;\n key: string;\n callout: Omit<Callout, \"keywords\">;\n /** elastic callouts are always published */\n published: true;\n /** elastic callouts are always attached to one curation */\n curations: [ElasticCuration] | [];\n}\n\nexport interface ElasticProduct extends ElasticDocumentBase {\n type: ElasticDocumentType.Product;\n /** the log id from which this product was last uploaded */\n lastLogId: string;\n /** legacy resource id */\n id: number;\n storefrontId: string;\n title: string;\n description: string;\n vendor: string;\n product_type: string;\n handle: string;\n url: string;\n tags: Array<string>;\n collection_titles: Array<string>;\n /** tag prefixes defined in tagKeys are split to their own attributes */\n [key: `tags_${string}`]: Array<string> | undefined;\n /** decimal number e.g. 99.95 */\n price_min: number;\n /** decimal number e.g. 99.95 */\n price_max: number;\n /** market specific price min, decimal number e.g. 99.95 */\n [key: `price_min_market_${number}`]: number;\n /** market specific price max, decimal number e.g. 99.95 */\n [key: `price_max_market_${number}`]: number;\n /** array of option names e.g. [\"Colour\", \"Size\"] */\n options: Array<string>;\n /** @todo it would be better to use ProductStatus directly, which has uppercase */\n status: \"active\" | \"archived\" | \"draft\";\n published: boolean;\n /** ISO 8601 datetime */\n published_at: Maybe<string>;\n /** ISO 8601 datetime */\n updated_at: string;\n /** ISO 8601 datetime */\n created_at: string;\n tracks_inventory: boolean;\n /** originalSrc URL for featured image */\n image: Maybe<string>;\n /** array of images (undefined if images are disabled in sync settings) */\n images?: Array<ElasticImage>;\n /** array of variants attached to product (undefined if variants are disabled in sync settings) */\n variants?: Array<ElasticVariant>;\n /** price ranges from presentment prices (undefined if presentment prices or variants are disabled in sync settings) */\n presentment_price_ranges?: {\n min_variant_price: Array<ElasticPresentmentPrice>;\n max_variant_price: Array<ElasticPresentmentPrice>;\n };\n /** array of variant skus (undefined if variants are disabled in sync settings) */\n variant_skus?: Array<string>;\n /** combined array of option values from all option types (undefined if variants are disabled in sync settings) */\n variant_options?: Array<string>;\n /** array of collections which this product belongs to (undefined if collections are disabled in sync settings) */\n collections?: Array<ElasticCollection>;\n /** array of whitelisted metafields (undefined if metafields are disabled in sync settings) */\n metafields?: Array<ElasticMetafield>;\n /** decimal number e.g. 99.95 (undefined if variants are disabled in sync settings) */\n discount_amount?: number;\n /** combined inventory for all variants (undefined if variants are disabled in sync settings) */\n inventory_total?: number;\n /** number of days since published, null if unpublished */\n published_days: Maybe<number>;\n /** collection of curations that this product is attached to */\n curations?: Array<ElasticCuration>;\n /** related products **/\n related?: Array<ElasticProductRelated>;\n}\n\nexport interface ElasticProductRelated {\n createdAt: string;\n description: string;\n featuredImage: {\n originalSrc: \"https://cdn.shopify.com/s/files/1/0614/3977/0777/p…71d6-e7fd-4f5f-aa99-c722e2832d01.jpg?v=1660776345\";\n };\n handle: string;\n id: string;\n images: Array<ElasticImage>;\n legacyResourceId: string;\n metafields?: Array<ElasticMetafield>;\n options: Array<{\n name: string;\n }>;\n priceRangeV2: {\n maxVariantPrice: {\n amount: string;\n };\n minVariantPrice: {\n amount: string;\n };\n };\n productType: string;\n publishedAt: string;\n status: \"ACTIVE\" | \"ARCHIVED\" | \"DRAFT\";\n storefrontId: string;\n tags: Array<string>;\n title: string;\n tracksInventory: boolean;\n updatedAt: string;\n variants: Array<ElasticVariant>;\n vendor: string;\n __typename: \"Product\";\n}\n\nexport interface ElasticVariant {\n /** legacy resource id */\n id: number;\n storefrontId: string;\n title: string;\n sku: Maybe<string>;\n barcode: Maybe<string>;\n /** array of presentment prices (undefined if presentment prices are disabled in sync settings) */\n presentment_prices?: Array<{\n price: ElasticPresentmentPrice;\n compare_at_price: Maybe<ElasticPresentmentPrice>;\n }>;\n /** decimal number e.g. 99.95 */\n price: number;\n /** decimal number e.g. 99.95 */\n compare_at_price: Maybe<number>;\n /** value string for option 1 e.g. Blue */\n option1: Maybe<string>;\n /** value string for option 2 e.g. Medium */\n option2: Maybe<string>;\n /** value string for option 3 */\n option3: Maybe<string>;\n /** sort position within the product */\n position: number;\n inventory_policy: ProductVariantInventoryPolicy;\n inventory_quantity: number;\n available: boolean;\n /** array of images (only available if this variant has been merged from another product and if images are enabled in sync settings) */\n images?: Array<ElasticImage>;\n}\n\nexport interface ElasticCollection {\n /** legacy resource id */\n id: number;\n storefrontId: string;\n handle: string;\n title: string;\n position: number;\n}\n\nexport interface ElasticMetafield {\n key: string;\n type: string;\n value: string;\n namespace: string;\n /**\n * Legacy valueType attribute which is no longer provided by Shopify. We still\n * populate this field to prevent any frontends breaking which rely on it.\n *\n * @see https://shopify.dev/apps/metafields/definitions/types\n */\n value_type: MetafieldValueType;\n}\n\nexport interface ElasticPresentmentPrice {\n /** decimal number e.g. 99.95 */\n amount: number;\n currency_code: string;\n}\n\nexport interface ElasticImage {\n /** originalSrc URL */\n src: string;\n /** alt text */\n alt: Maybe<string>;\n}\n\nexport interface ElasticCuration {\n id: string;\n hidden: boolean;\n position?: number;\n searchTerm?: string;\n collectionHandle?: string;\n}\n\n// non-exhaustive type for bulk request\n// https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-bulk.html\nexport type ElasticBulkOperationUpdate = [\n { update: { _index: string; _id: string } },\n {\n script?: {\n lang: \"painless\";\n source: string;\n params?: Record<string, any>;\n };\n upsert?: Partial<ElasticProduct>;\n scripted_upsert?: true;\n doc?: Partial<ElasticProduct>;\n doc_as_upsert?: true;\n }\n];\n\nexport type ElasticBulkOperationIndex = [\n { index: { _index: string; _id: string } },\n ElasticDocument\n];\n\nexport type ElasticBulkOperation =\n | ElasticBulkOperationUpdate\n | ElasticBulkOperationIndex;\n\nexport type ElasticSearchResult<T = ElasticDocument> = {\n hits: {\n hits: Array<ElasticHit<T>>;\n };\n};\n\nexport type ElasticHit<T = ElasticDocument> = {\n _id: string;\n _source: T;\n _score: number | null;\n};\n\nexport enum ElasticDataType {\n Text = \"text\",\n Long = \"long\",\n Date = \"date\",\n Float = \"float\",\n Nested = \"nested\",\n Keyword = \"keyword\",\n Boolean = \"boolean\",\n}\n\nexport interface ElasticProperty {\n analyzer?: string;\n type: ElasticDataType;\n ignore_above?: number;\n fields?: { [key: string]: ElasticField };\n properties?: { [key: string]: ElasticProperty };\n}\n\nexport interface ElasticField {\n type: ElasticDataType;\n ignore_above?: number;\n}\n"]}
1
+ {"version":3,"file":"elastic.js","sourceRoot":"","sources":["../../../src/types/elastic.ts"],"names":[],"mappings":";;;AAGA,IAAY,mBAGX;AAHD,WAAY,mBAAmB;IAC7B,0CAAmB,CAAA;IACnB,0CAAmB,CAAA;AACrB,CAAC,EAHW,mBAAmB,mCAAnB,mBAAmB,QAG9B;AAgPD,IAAY,eAQX;AARD,WAAY,eAAe;IACzB,gCAAa,CAAA;IACb,gCAAa,CAAA;IACb,gCAAa,CAAA;IACb,kCAAe,CAAA;IACf,oCAAiB,CAAA;IACjB,sCAAmB,CAAA;IACnB,sCAAmB,CAAA;AACrB,CAAC,EARW,eAAe,+BAAf,eAAe,QAQ1B","sourcesContent":["import { Callout } from \"./firestore\";\nimport { Maybe, ProductVariantInventoryPolicy, MetafieldValueType } from \"./graphql\";\n\nexport enum ElasticDocumentType {\n Callout = \"callout\",\n Product = \"product\",\n}\n\nexport interface ElasticDocumentBase {\n /** Elasticsearch score when explain is enabled */\n _score?: number;\n /** Elasticsearch explanation when explain is enabled */\n _explanation?: {\n value: number;\n description: string;\n details?: Array<{\n value: number;\n description: string;\n details?: any[];\n }>;\n };\n}\n\nexport type ElasticDocument = ElasticCallout | ElasticProduct;\n\nexport interface ElasticCallout extends ElasticDocumentBase {\n type: ElasticDocumentType.Callout;\n key: string;\n callout: Omit<Callout, \"keywords\">;\n /** elastic callouts are always published */\n published: true;\n /** elastic callouts are always attached to one curation */\n curations: [ElasticCuration] | [];\n}\n\nexport interface ElasticProduct extends ElasticDocumentBase {\n type: ElasticDocumentType.Product;\n /** the log id from which this product was last uploaded */\n lastLogId: string;\n /** legacy resource id */\n id: number;\n storefrontId: string;\n title: string;\n description: string;\n vendor: string;\n product_type: string;\n handle: string;\n url: string;\n tags: Array<string>;\n collection_titles: Array<string>;\n /** tag prefixes defined in tagKeys are split to their own attributes */\n [key: `tags_${string}`]: Array<string> | undefined;\n /** decimal number e.g. 99.95 */\n price_min: number;\n /** decimal number e.g. 99.95 */\n price_max: number;\n /** market specific price min, decimal number e.g. 99.95 */\n [key: `price_min_market_${number}`]: number;\n /** market specific price max, decimal number e.g. 99.95 */\n [key: `price_max_market_${number}`]: number;\n /** array of option names e.g. [\"Colour\", \"Size\"] */\n options: Array<string>;\n /** @todo it would be better to use ProductStatus directly, which has uppercase */\n status: \"active\" | \"archived\" | \"draft\";\n published: boolean;\n /** ISO 8601 datetime */\n published_at: Maybe<string>;\n /** ISO 8601 datetime */\n updated_at: string;\n /** ISO 8601 datetime */\n created_at: string;\n tracks_inventory: boolean;\n /** originalSrc URL for featured image */\n image: Maybe<string>;\n /** array of images (undefined if images are disabled in sync settings) */\n images?: Array<ElasticImage>;\n /** array of variants attached to product (undefined if variants are disabled in sync settings) */\n variants?: Array<ElasticVariant>;\n /** price ranges from presentment prices (undefined if presentment prices or variants are disabled in sync settings) */\n presentment_price_ranges?: {\n min_variant_price: Array<ElasticPresentmentPrice>;\n max_variant_price: Array<ElasticPresentmentPrice>;\n };\n /** array of variant skus (undefined if variants are disabled in sync settings) */\n variant_skus?: Array<string>;\n /** combined array of option values from all option types (undefined if variants are disabled in sync settings) */\n variant_options?: Array<string>;\n /** array of collections which this product belongs to (undefined if collections are disabled in sync settings) */\n collections?: Array<ElasticCollection>;\n /** array of whitelisted metafields (undefined if metafields are disabled in sync settings) */\n metafields?: Array<ElasticMetafield>;\n /** decimal number e.g. 99.95 (undefined if variants are disabled in sync settings) */\n discount_amount?: number;\n /** combined inventory for all variants (undefined if variants are disabled in sync settings) */\n inventory_total?: number;\n /** number of days since published, null if unpublished */\n published_days: Maybe<number>;\n /** collection of curations that this product is attached to */\n curations?: Array<ElasticCuration>;\n /** related products **/\n related?: Array<ElasticProductRelated>;\n}\n\nexport interface ElasticProductRelated {\n createdAt: string;\n description: string;\n featuredImage: {\n originalSrc: \"https://cdn.shopify.com/s/files/1/0614/3977/0777/p…71d6-e7fd-4f5f-aa99-c722e2832d01.jpg?v=1660776345\";\n };\n handle: string;\n id: string;\n images: Array<ElasticImage>;\n legacyResourceId: string;\n metafields?: Array<ElasticMetafield>;\n options: Array<{\n name: string;\n }>;\n priceRangeV2: {\n maxVariantPrice: {\n amount: string;\n };\n minVariantPrice: {\n amount: string;\n };\n };\n productType: string;\n publishedAt: string;\n status: \"ACTIVE\" | \"ARCHIVED\" | \"DRAFT\";\n storefrontId: string;\n tags: Array<string>;\n title: string;\n tracksInventory: boolean;\n updatedAt: string;\n variants: Array<ElasticVariant>;\n vendor: string;\n __typename: \"Product\";\n}\n\nexport interface ElasticVariant {\n /** legacy resource id */\n id: number;\n storefrontId: string;\n title: string;\n sku: Maybe<string>;\n barcode: Maybe<string>;\n /** array of presentment prices (undefined if presentment prices are disabled in sync settings) */\n presentment_prices?: Array<{\n price: ElasticPresentmentPrice;\n compare_at_price: Maybe<ElasticPresentmentPrice>;\n }>;\n /** decimal number e.g. 99.95 */\n price: number;\n /** decimal number e.g. 99.95 */\n compare_at_price: Maybe<number>;\n /** value string for option 1 e.g. Blue */\n option1: Maybe<string>;\n /** value string for option 2 e.g. Medium */\n option2: Maybe<string>;\n /** value string for option 3 */\n option3: Maybe<string>;\n /** sort position within the product */\n position: number;\n inventory_policy: ProductVariantInventoryPolicy;\n inventory_quantity: number;\n available: boolean;\n /** array of images (only available if this variant has been merged from another product and if images are enabled in sync settings) */\n images?: Array<ElasticImage>;\n}\n\nexport interface ElasticCollection {\n /** legacy resource id */\n id: number;\n storefrontId: string;\n handle: string;\n title: string;\n position: number;\n}\n\nexport interface ElasticMetafield {\n key: string;\n type: string;\n value: string;\n namespace: string;\n /**\n * Legacy valueType attribute which is no longer provided by Shopify. We still\n * populate this field to prevent any frontends breaking which rely on it.\n *\n * @see https://shopify.dev/apps/metafields/definitions/types\n */\n value_type: MetafieldValueType;\n}\n\nexport interface ElasticPresentmentPrice {\n /** decimal number e.g. 99.95 */\n amount: number;\n currency_code: string;\n}\n\nexport interface ElasticImage {\n /** originalSrc URL */\n src: string;\n /** alt text */\n alt: Maybe<string>;\n}\n\nexport interface ElasticCuration {\n id: string;\n hidden: boolean;\n position?: number;\n searchTerm?: string;\n collectionHandle?: string;\n}\n\n// non-exhaustive type for bulk request\n// https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-bulk.html\nexport type ElasticBulkOperationUpdate = [\n { update: { _index: string; _id: string } },\n {\n script?: {\n lang: \"painless\";\n source: string;\n params?: Record<string, any>;\n };\n upsert?: Partial<ElasticProduct>;\n scripted_upsert?: true;\n doc?: Partial<ElasticProduct>;\n doc_as_upsert?: true;\n }\n];\n\nexport type ElasticBulkOperationIndex = [{ index: { _index: string; _id: string } }, ElasticDocument];\n\nexport type ElasticBulkOperation = ElasticBulkOperationUpdate | ElasticBulkOperationIndex;\n\nexport type ElasticSearchResult<T = ElasticDocument> = {\n hits: {\n hits: Array<ElasticHit<T>>;\n };\n};\n\nexport type ElasticHit<T = ElasticDocument> = {\n _id: string;\n _source: T;\n _score: number | null;\n};\n\nexport enum ElasticDataType {\n Text = \"text\",\n Long = \"long\",\n Date = \"date\",\n Float = \"float\",\n Nested = \"nested\",\n Keyword = \"keyword\",\n Boolean = \"boolean\",\n}\n\nexport interface ElasticProperty {\n analyzer?: string;\n type: ElasticDataType;\n ignore_above?: number;\n fields?: { [key: string]: ElasticField };\n properties?: { [key: string]: ElasticProperty };\n}\n\nexport interface ElasticField {\n type: ElasticDataType;\n ignore_above?: number;\n}\n"]}
@@ -296,9 +296,9 @@ export interface SearchableField extends ResourceDocument {
296
296
  enabled: boolean;
297
297
  hidden?: boolean;
298
298
  points: number;
299
- allowedMistakes: number;
299
+ maxEdits: number;
300
300
  mistakePenaltyPercent: number;
301
- synyonymEnabled: boolean;
301
+ synonymEnabled: boolean;
302
302
  synonymPenaltyPercent: number;
303
303
  }
304
304
  export interface Boosting {