@sebspark/opensearch 0.1.2 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -20,6 +20,7 @@ type WithId = {
20
20
  };
21
21
  type ExcludeId<T> = Omit<T, 'id'>;
22
22
  type SubstringOf<T extends string> = T extends `${infer Prefix}${infer _Rest}` ? Prefix | SubstringOf<Exclude<T, Prefix>> : never;
23
+ type NotUndefined<T> = T extends undefined ? never : T;
23
24
 
24
25
  type FieldName<T> = NestedStringPaths<ExcludeId<T>> | '*' | (string & {});
25
26
  type FieldObject<T> = {
@@ -76,14 +77,14 @@ type Regexp<T> = {
76
77
  type StandardAnalyzer = 'standard' | 'simple' | 'whitespace' | 'stop' | 'keyword' | 'pattern' | 'fingerprint';
77
78
  type LanguageAnalyzer = 'arabic' | 'armenian' | 'basque' | 'bengali' | 'brazilian' | 'bulgarian' | 'catalan' | 'czech' | 'danish' | 'dutch' | 'english' | 'estonian' | 'finnish' | 'french' | 'galician' | 'german' | 'greek' | 'hindi' | 'hungarian' | 'indonesian' | 'irish' | 'italian' | 'latvian' | 'lithuanian' | 'norwegian' | 'persian' | 'portuguese' | 'romanian' | 'russian' | 'sorani' | 'spanish' | 'swedish' | 'turkish' | 'thai';
78
79
  type Analyzer = StandardAnalyzer | LanguageAnalyzer;
79
- type Match<T> = {
80
+ type Match<T> = Partial<{
80
81
  [P in NestedStringPaths<T>]: string | {
81
82
  query: string;
82
83
  operator?: 'and' | 'or';
83
84
  minimum_should_match?: number;
84
85
  analyzer?: Analyzer;
85
86
  };
86
- };
87
+ }>;
87
88
  type MultiMatchParam<T extends string> = T | `${T}^${number}` | `${SubstringOf<T>}*`;
88
89
  type MultiMatch<T> = {
89
90
  query: string;
@@ -202,6 +203,9 @@ type OpenSearchQueryBody<T extends {
202
203
  fields?: OpenSearchFields<K>;
203
204
  filter?: OpenSearchFilter<T>;
204
205
  match?: Match<T>;
206
+ match_all?: {
207
+ boost?: number;
208
+ };
205
209
  multi_match?: MultiMatch<T>;
206
210
  from?: number;
207
211
  size?: number;
@@ -237,11 +241,18 @@ type OpenSearchQuery<T extends {
237
241
  from?: number;
238
242
  size?: number;
239
243
  } : never;
240
- type BasicOpenSearchFieldTypes = 'text' | 'keyword' | 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float' | 'date' | 'boolean' | 'binary';
244
+ type BasicOpenSearchFieldTypes = 'text' | 'keyword' | 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float' | 'date' | 'boolean' | 'binary' | 'nested';
241
245
  type ElementType<T> = T extends Array<infer U> ? U : T;
242
246
  type OpenSearchFieldType<T> = ElementType<T> extends string ? 'text' | 'keyword' : ElementType<T> extends number ? 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float' : ElementType<T> extends boolean ? 'boolean' : ElementType<T> extends Date ? 'date' : BasicOpenSearchFieldTypes;
243
247
  type FieldOptions<T> = {
244
- type: OpenSearchFieldType<T>;
248
+ type: OpenSearchFieldType<NotUndefined<T>>;
249
+ };
250
+ type NestedFieldOptions<T> = {
251
+ type: 'nested';
252
+ properties: IndexProperties<T>;
253
+ };
254
+ type IndexProperties<T> = {
255
+ [K in keyof Partial<T>]: T[K] extends Date ? FieldOptions<T[K]> : NotUndefined<T[K]> extends object ? NotUndefined<T[K]> extends Array<infer U> ? U extends object ? NestedFieldOptions<U> : FieldOptions<T[K]> : IndexProperties<T[K]> : FieldOptions<T[K]>;
245
256
  };
246
257
  type IndexOptions<T extends WithId> = {
247
258
  settings?: {
@@ -255,9 +266,6 @@ type IndexOptions<T extends WithId> = {
255
266
  };
256
267
  aliases?: Record<string, Record<string, never>>;
257
268
  };
258
- type IndexProperties<T> = {
259
- [K in keyof Partial<T>]: T[K] extends Date ? FieldOptions<T[K]> : T[K] extends object ? T[K] extends Array<infer U> ? FieldOptions<T[K]> : IndexProperties<T[K]> : FieldOptions<T[K]>;
260
- };
261
269
 
262
270
  interface OpenSearchHelper extends Client {
263
271
  typedSearch: <DataType extends WithId, ReturnType = DataType>(query: OpenSearchQuery<DataType, ReturnType>) => Promise<{
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ type WithId = {
20
20
  };
21
21
  type ExcludeId<T> = Omit<T, 'id'>;
22
22
  type SubstringOf<T extends string> = T extends `${infer Prefix}${infer _Rest}` ? Prefix | SubstringOf<Exclude<T, Prefix>> : never;
23
+ type NotUndefined<T> = T extends undefined ? never : T;
23
24
 
24
25
  type FieldName<T> = NestedStringPaths<ExcludeId<T>> | '*' | (string & {});
25
26
  type FieldObject<T> = {
@@ -76,14 +77,14 @@ type Regexp<T> = {
76
77
  type StandardAnalyzer = 'standard' | 'simple' | 'whitespace' | 'stop' | 'keyword' | 'pattern' | 'fingerprint';
77
78
  type LanguageAnalyzer = 'arabic' | 'armenian' | 'basque' | 'bengali' | 'brazilian' | 'bulgarian' | 'catalan' | 'czech' | 'danish' | 'dutch' | 'english' | 'estonian' | 'finnish' | 'french' | 'galician' | 'german' | 'greek' | 'hindi' | 'hungarian' | 'indonesian' | 'irish' | 'italian' | 'latvian' | 'lithuanian' | 'norwegian' | 'persian' | 'portuguese' | 'romanian' | 'russian' | 'sorani' | 'spanish' | 'swedish' | 'turkish' | 'thai';
78
79
  type Analyzer = StandardAnalyzer | LanguageAnalyzer;
79
- type Match<T> = {
80
+ type Match<T> = Partial<{
80
81
  [P in NestedStringPaths<T>]: string | {
81
82
  query: string;
82
83
  operator?: 'and' | 'or';
83
84
  minimum_should_match?: number;
84
85
  analyzer?: Analyzer;
85
86
  };
86
- };
87
+ }>;
87
88
  type MultiMatchParam<T extends string> = T | `${T}^${number}` | `${SubstringOf<T>}*`;
88
89
  type MultiMatch<T> = {
89
90
  query: string;
@@ -202,6 +203,9 @@ type OpenSearchQueryBody<T extends {
202
203
  fields?: OpenSearchFields<K>;
203
204
  filter?: OpenSearchFilter<T>;
204
205
  match?: Match<T>;
206
+ match_all?: {
207
+ boost?: number;
208
+ };
205
209
  multi_match?: MultiMatch<T>;
206
210
  from?: number;
207
211
  size?: number;
@@ -237,11 +241,18 @@ type OpenSearchQuery<T extends {
237
241
  from?: number;
238
242
  size?: number;
239
243
  } : never;
240
- type BasicOpenSearchFieldTypes = 'text' | 'keyword' | 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float' | 'date' | 'boolean' | 'binary';
244
+ type BasicOpenSearchFieldTypes = 'text' | 'keyword' | 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float' | 'date' | 'boolean' | 'binary' | 'nested';
241
245
  type ElementType<T> = T extends Array<infer U> ? U : T;
242
246
  type OpenSearchFieldType<T> = ElementType<T> extends string ? 'text' | 'keyword' : ElementType<T> extends number ? 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float' : ElementType<T> extends boolean ? 'boolean' : ElementType<T> extends Date ? 'date' : BasicOpenSearchFieldTypes;
243
247
  type FieldOptions<T> = {
244
- type: OpenSearchFieldType<T>;
248
+ type: OpenSearchFieldType<NotUndefined<T>>;
249
+ };
250
+ type NestedFieldOptions<T> = {
251
+ type: 'nested';
252
+ properties: IndexProperties<T>;
253
+ };
254
+ type IndexProperties<T> = {
255
+ [K in keyof Partial<T>]: T[K] extends Date ? FieldOptions<T[K]> : NotUndefined<T[K]> extends object ? NotUndefined<T[K]> extends Array<infer U> ? U extends object ? NestedFieldOptions<U> : FieldOptions<T[K]> : IndexProperties<T[K]> : FieldOptions<T[K]>;
245
256
  };
246
257
  type IndexOptions<T extends WithId> = {
247
258
  settings?: {
@@ -255,9 +266,6 @@ type IndexOptions<T extends WithId> = {
255
266
  };
256
267
  aliases?: Record<string, Record<string, never>>;
257
268
  };
258
- type IndexProperties<T> = {
259
- [K in keyof Partial<T>]: T[K] extends Date ? FieldOptions<T[K]> : T[K] extends object ? T[K] extends Array<infer U> ? FieldOptions<T[K]> : IndexProperties<T[K]> : FieldOptions<T[K]>;
260
- };
261
269
 
262
270
  interface OpenSearchHelper extends Client {
263
271
  typedSearch: <DataType extends WithId, ReturnType = DataType>(query: OpenSearchQuery<DataType, ReturnType>) => Promise<{
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -24,10 +34,94 @@ __export(src_exports, {
24
34
  });
25
35
  module.exports = __toCommonJS(src_exports);
26
36
 
37
+ // src/openSearchHelper.ts
38
+ var import_assert = __toESM(require("assert"));
39
+
40
+ // src/fixIds.ts
41
+ var import_omit = __toESM(require("omit"));
42
+ var omitId = (0, import_omit.default)("id");
43
+ var fixIds = (searchQuery) => {
44
+ const q = searchQuery.body.query;
45
+ const body = {
46
+ query: {
47
+ bool: q.bool ? fixBool(q.bool) : void 0,
48
+ match: q.match ? fixId(q.match) : void 0,
49
+ collapse: q.collapse,
50
+ exists: q.exists ? fixExists(q.exists) : void 0,
51
+ fields: q.fields,
52
+ filter: q.filter ? fixFilter(q.filter) : void 0,
53
+ from: q.from,
54
+ fuzzy: q.fuzzy ? fixId(q.fuzzy) : void 0,
55
+ highlight: q.highlight,
56
+ match_all: q.match_all,
57
+ match_phrase: q.match_phrase ? fixId(q.match_phrase) : void 0,
58
+ match_phrase_prefix: q.match_phrase_prefix ? fixId(q.match_phrase_prefix) : void 0,
59
+ more_like_this: q.more_like_this ? fixWithFields(q.more_like_this) : void 0,
60
+ multi_match: q.multi_match ? fixId(q.multi_match) : void 0,
61
+ prefix: q.prefix ? fixId(q.prefix) : void 0,
62
+ range: q.range ? fixId(q.range) : void 0,
63
+ regexp: q.regexp ? fixId(q.regexp) : void 0,
64
+ script_score: q.script_score,
65
+ size: q.size,
66
+ term: q.term ? fixId(q.term) : void 0,
67
+ terms: q.terms ? fixId(q.terms) : void 0,
68
+ wildcard: q.wildcard ? fixId(q.wildcard) : void 0
69
+ }
70
+ };
71
+ return {
72
+ ...searchQuery,
73
+ body: {
74
+ ...clean(body)
75
+ }
76
+ };
77
+ };
78
+ var fixBool = (bool) => ({
79
+ ...bool,
80
+ filter: bool.filter ? Array.isArray(bool.filter) ? bool.filter.map(fixFilter) : fixFilter(bool.filter) : void 0,
81
+ boost: bool.boost,
82
+ minimum_should_match: bool.minimum_should_match,
83
+ must: bool.must ? Array.isArray(bool.must) ? bool.must.map(fixFilter) : fixFilter(bool.must) : void 0,
84
+ must_not: bool.must_not ? Array.isArray(bool.must_not) ? bool.must_not.map(fixFilter) : fixFilter(bool.must_not) : void 0,
85
+ should: bool.should ? Array.isArray(bool.should) ? bool.should.map(fixFilter) : fixFilter(bool.should) : void 0
86
+ });
87
+ var fixFilter = (filter) => clean({
88
+ bool: filter.bool ? fixBool(filter.bool) : void 0,
89
+ exists: filter.exists ? fixExists(filter.exists) : void 0,
90
+ fuzzy: filter.fuzzy ? fixId(filter.fuzzy) : void 0,
91
+ match: filter.match ? fixId(filter.match) : void 0,
92
+ match_phrase: filter.match_phrase ? fixId(filter.match_phrase) : void 0,
93
+ multi_match: filter.multi_match ? fixId(filter.multi_match) : void 0,
94
+ match_phrase_prefix: filter.match_phrase_prefix ? fixId(filter.match_phrase_prefix) : void 0,
95
+ prefix: filter.prefix ? fixId(filter.prefix) : void 0,
96
+ query_string: filter.query_string ? fixWithFields(filter.query_string) : void 0,
97
+ range: filter.range ? fixId(filter.range) : void 0,
98
+ regexp: filter.regexp ? fixId(filter.regexp) : void 0,
99
+ simple_query_string: filter.simple_query_string ? fixWithFields(filter.simple_query_string) : void 0,
100
+ term: filter.term ? fixId(filter.term) : void 0,
101
+ terms: filter.terms ? fixId(filter.terms) : void 0,
102
+ wildcard: filter.wildcard ? fixId(filter.wildcard) : void 0
103
+ });
104
+ var fixWithFields = (old) => ({
105
+ ...old,
106
+ fields: old.fields ? old.fields.map(fixIdValue) : void 0
107
+ });
108
+ var fixExists = (exists) => ({
109
+ ...exists,
110
+ field: fixIdValue(exists.field)
111
+ });
112
+ var fixId = (old) => {
113
+ const fixed = omitId(old);
114
+ if (old.id)
115
+ fixed._id = old.id;
116
+ return fixed;
117
+ };
118
+ var fixIdValue = (val) => val === "id" ? "_id" : val;
119
+ var clean = (obj) => Object.entries(obj).filter(([, val]) => val !== void 0).reduce((m, [prop, val]) => ({ ...m, [prop]: val }), {});
120
+
27
121
  // src/openSearchHelper.ts
28
122
  var typedSearch = async (client, searchQuery) => {
29
123
  const response = await client.search(
30
- searchQuery
124
+ fixIds(searchQuery)
31
125
  );
32
126
  const results = response.body.hits.hits.map(
33
127
  // biome-ignore lint/suspicious/noExplicitAny: <explanation>
@@ -73,10 +167,18 @@ var typedBulkUpsert = async (client, index, items) => {
73
167
  return response;
74
168
  };
75
169
  var isLeafNode = (obj) => {
170
+ if (Object.values(obj).some((value) => value === "nested"))
171
+ return true;
76
172
  return !Object.values(obj).some(
77
173
  (value) => typeof value === "object" && value !== null && !Array.isArray(value)
78
174
  );
79
175
  };
176
+ (0, import_assert.default)(
177
+ isLeafNode({
178
+ type: "nested",
179
+ properties: { name: { type: "keyword" }, type: { type: "keyword" } }
180
+ })
181
+ );
80
182
  var flattenObject = (obj, parentKey = "", result = {}) => {
81
183
  for (const [key, value] of Object.entries(obj)) {
82
184
  const newKey = parentKey ? `${parentKey}.${key}` : key;
package/dist/index.mjs CHANGED
@@ -1,7 +1,91 @@
1
+ // src/openSearchHelper.ts
2
+ import assert from "assert";
3
+
4
+ // src/fixIds.ts
5
+ import omit from "omit";
6
+ var omitId = omit("id");
7
+ var fixIds = (searchQuery) => {
8
+ const q = searchQuery.body.query;
9
+ const body = {
10
+ query: {
11
+ bool: q.bool ? fixBool(q.bool) : void 0,
12
+ match: q.match ? fixId(q.match) : void 0,
13
+ collapse: q.collapse,
14
+ exists: q.exists ? fixExists(q.exists) : void 0,
15
+ fields: q.fields,
16
+ filter: q.filter ? fixFilter(q.filter) : void 0,
17
+ from: q.from,
18
+ fuzzy: q.fuzzy ? fixId(q.fuzzy) : void 0,
19
+ highlight: q.highlight,
20
+ match_all: q.match_all,
21
+ match_phrase: q.match_phrase ? fixId(q.match_phrase) : void 0,
22
+ match_phrase_prefix: q.match_phrase_prefix ? fixId(q.match_phrase_prefix) : void 0,
23
+ more_like_this: q.more_like_this ? fixWithFields(q.more_like_this) : void 0,
24
+ multi_match: q.multi_match ? fixId(q.multi_match) : void 0,
25
+ prefix: q.prefix ? fixId(q.prefix) : void 0,
26
+ range: q.range ? fixId(q.range) : void 0,
27
+ regexp: q.regexp ? fixId(q.regexp) : void 0,
28
+ script_score: q.script_score,
29
+ size: q.size,
30
+ term: q.term ? fixId(q.term) : void 0,
31
+ terms: q.terms ? fixId(q.terms) : void 0,
32
+ wildcard: q.wildcard ? fixId(q.wildcard) : void 0
33
+ }
34
+ };
35
+ return {
36
+ ...searchQuery,
37
+ body: {
38
+ ...clean(body)
39
+ }
40
+ };
41
+ };
42
+ var fixBool = (bool) => ({
43
+ ...bool,
44
+ filter: bool.filter ? Array.isArray(bool.filter) ? bool.filter.map(fixFilter) : fixFilter(bool.filter) : void 0,
45
+ boost: bool.boost,
46
+ minimum_should_match: bool.minimum_should_match,
47
+ must: bool.must ? Array.isArray(bool.must) ? bool.must.map(fixFilter) : fixFilter(bool.must) : void 0,
48
+ must_not: bool.must_not ? Array.isArray(bool.must_not) ? bool.must_not.map(fixFilter) : fixFilter(bool.must_not) : void 0,
49
+ should: bool.should ? Array.isArray(bool.should) ? bool.should.map(fixFilter) : fixFilter(bool.should) : void 0
50
+ });
51
+ var fixFilter = (filter) => clean({
52
+ bool: filter.bool ? fixBool(filter.bool) : void 0,
53
+ exists: filter.exists ? fixExists(filter.exists) : void 0,
54
+ fuzzy: filter.fuzzy ? fixId(filter.fuzzy) : void 0,
55
+ match: filter.match ? fixId(filter.match) : void 0,
56
+ match_phrase: filter.match_phrase ? fixId(filter.match_phrase) : void 0,
57
+ multi_match: filter.multi_match ? fixId(filter.multi_match) : void 0,
58
+ match_phrase_prefix: filter.match_phrase_prefix ? fixId(filter.match_phrase_prefix) : void 0,
59
+ prefix: filter.prefix ? fixId(filter.prefix) : void 0,
60
+ query_string: filter.query_string ? fixWithFields(filter.query_string) : void 0,
61
+ range: filter.range ? fixId(filter.range) : void 0,
62
+ regexp: filter.regexp ? fixId(filter.regexp) : void 0,
63
+ simple_query_string: filter.simple_query_string ? fixWithFields(filter.simple_query_string) : void 0,
64
+ term: filter.term ? fixId(filter.term) : void 0,
65
+ terms: filter.terms ? fixId(filter.terms) : void 0,
66
+ wildcard: filter.wildcard ? fixId(filter.wildcard) : void 0
67
+ });
68
+ var fixWithFields = (old) => ({
69
+ ...old,
70
+ fields: old.fields ? old.fields.map(fixIdValue) : void 0
71
+ });
72
+ var fixExists = (exists) => ({
73
+ ...exists,
74
+ field: fixIdValue(exists.field)
75
+ });
76
+ var fixId = (old) => {
77
+ const fixed = omitId(old);
78
+ if (old.id)
79
+ fixed._id = old.id;
80
+ return fixed;
81
+ };
82
+ var fixIdValue = (val) => val === "id" ? "_id" : val;
83
+ var clean = (obj) => Object.entries(obj).filter(([, val]) => val !== void 0).reduce((m, [prop, val]) => ({ ...m, [prop]: val }), {});
84
+
1
85
  // src/openSearchHelper.ts
2
86
  var typedSearch = async (client, searchQuery) => {
3
87
  const response = await client.search(
4
- searchQuery
88
+ fixIds(searchQuery)
5
89
  );
6
90
  const results = response.body.hits.hits.map(
7
91
  // biome-ignore lint/suspicious/noExplicitAny: <explanation>
@@ -47,10 +131,18 @@ var typedBulkUpsert = async (client, index, items) => {
47
131
  return response;
48
132
  };
49
133
  var isLeafNode = (obj) => {
134
+ if (Object.values(obj).some((value) => value === "nested"))
135
+ return true;
50
136
  return !Object.values(obj).some(
51
137
  (value) => typeof value === "object" && value !== null && !Array.isArray(value)
52
138
  );
53
139
  };
140
+ assert(
141
+ isLeafNode({
142
+ type: "nested",
143
+ properties: { name: { type: "keyword" }, type: { type: "keyword" } }
144
+ })
145
+ );
54
146
  var flattenObject = (obj, parentKey = "", result = {}) => {
55
147
  for (const [key, value] of Object.entries(obj)) {
56
148
  const newKey = parentKey ? `${parentKey}.${key}` : key;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebspark/opensearch",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -16,9 +16,11 @@
16
16
  "typecheck": "vitest --typecheck.only --passWithNoTests"
17
17
  },
18
18
  "devDependencies": {
19
+ "@types/omit": "1.0.3",
19
20
  "tsconfig": "*"
20
21
  },
21
22
  "dependencies": {
22
- "@opensearch-project/opensearch": "2.4.0"
23
+ "@opensearch-project/opensearch": "2.5.0",
24
+ "omit": "1.0.1"
23
25
  }
24
26
  }