@tinacms/search 0.0.0-ee8d9a3-20250429131017 → 0.0.0-f2577b9-20251119082459
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-client.js +0 -1
- package/dist/index-client.mjs +0 -1
- package/dist/index.js +10 -15
- package/package.json +4 -4
- package/dist/index-client.js.map +0 -1
- package/dist/index-client.mjs.map +0 -1
package/dist/index-client.js
CHANGED
package/dist/index-client.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -65,7 +65,6 @@ var StringBuilder = class {
|
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
67
|
var extractText = (data, acc, indexableNodeTypes) => {
|
|
68
|
-
var _a, _b;
|
|
69
68
|
if (data) {
|
|
70
69
|
if (indexableNodeTypes.indexOf(data.type) !== -1 && (data.text || data.value)) {
|
|
71
70
|
const tokens = tokenizeString(data.text || data.value);
|
|
@@ -75,8 +74,7 @@ var extractText = (data, acc, indexableNodeTypes) => {
|
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
|
-
|
|
79
|
-
_a,
|
|
77
|
+
data.children?.forEach?.(
|
|
80
78
|
(child) => extractText(child, acc, indexableNodeTypes)
|
|
81
79
|
);
|
|
82
80
|
}
|
|
@@ -103,7 +101,7 @@ var processDocumentForIndexing = (data, path, collection, textIndexLength, field
|
|
|
103
101
|
data["_id"] = `${collection.name}:${relPath}`;
|
|
104
102
|
data["_relativePath"] = relPath;
|
|
105
103
|
}
|
|
106
|
-
for (const f of
|
|
104
|
+
for (const f of field?.fields || collection.fields || []) {
|
|
107
105
|
if (!f.searchable) {
|
|
108
106
|
delete data[f.name];
|
|
109
107
|
continue;
|
|
@@ -215,7 +213,6 @@ var SearchIndexer = class {
|
|
|
215
213
|
};
|
|
216
214
|
}
|
|
217
215
|
async indexContentByPaths(documentPaths) {
|
|
218
|
-
var _a, _b, _c, _d;
|
|
219
216
|
let batch = [];
|
|
220
217
|
const itemCallback = async (item) => {
|
|
221
218
|
batch.push(item);
|
|
@@ -224,7 +221,7 @@ var SearchIndexer = class {
|
|
|
224
221
|
batch = [];
|
|
225
222
|
}
|
|
226
223
|
};
|
|
227
|
-
await
|
|
224
|
+
await this.client.onStartIndexing?.();
|
|
228
225
|
await (0, import_graphql.scanContentByPaths)(
|
|
229
226
|
this.schema,
|
|
230
227
|
documentPaths,
|
|
@@ -233,11 +230,10 @@ var SearchIndexer = class {
|
|
|
233
230
|
if (batch.length > 0) {
|
|
234
231
|
await this.client.put(batch);
|
|
235
232
|
}
|
|
236
|
-
await
|
|
233
|
+
await this.client.onFinishIndexing?.();
|
|
237
234
|
}
|
|
238
235
|
async indexAllContent() {
|
|
239
|
-
|
|
240
|
-
await ((_b = (_a = this.client).onStartIndexing) == null ? void 0 : _b.call(_a));
|
|
236
|
+
await this.client.onStartIndexing?.();
|
|
241
237
|
let batch = [];
|
|
242
238
|
const itemCallback = async (item) => {
|
|
243
239
|
batch.push(item);
|
|
@@ -254,14 +250,13 @@ var SearchIndexer = class {
|
|
|
254
250
|
if (batch.length > 0) {
|
|
255
251
|
await this.client.put(batch);
|
|
256
252
|
}
|
|
257
|
-
await
|
|
253
|
+
await this.client.onFinishIndexing?.();
|
|
258
254
|
return { warnings };
|
|
259
255
|
}
|
|
260
256
|
async deleteIndexContent(documentPaths) {
|
|
261
|
-
|
|
262
|
-
await ((_b = (_a = this.client).onStartIndexing) == null ? void 0 : _b.call(_a));
|
|
257
|
+
await this.client.onStartIndexing?.();
|
|
263
258
|
await this.client.del(documentPaths);
|
|
264
|
-
await
|
|
259
|
+
await this.client.onFinishIndexing?.();
|
|
265
260
|
}
|
|
266
261
|
};
|
|
267
262
|
|
|
@@ -269,7 +264,7 @@ var SearchIndexer = class {
|
|
|
269
264
|
var import_sqlite_level = require("sqlite-level");
|
|
270
265
|
var import_search_index = __toESM(require("search-index"));
|
|
271
266
|
var import_memory_level = require("memory-level");
|
|
272
|
-
var zlib = __toESM(require("zlib"));
|
|
267
|
+
var zlib = __toESM(require("node:zlib"));
|
|
273
268
|
var DEFAULT_TOKEN_SPLIT_REGEX = /[\p{L}\d_]+/gu;
|
|
274
269
|
var LocalSearchIndexClient = class {
|
|
275
270
|
constructor(options) {
|
|
@@ -337,7 +332,7 @@ var TinaCMSSearchIndexClient = class extends LocalSearchIndexClient {
|
|
|
337
332
|
console.error("Failed to parse error response", e);
|
|
338
333
|
}
|
|
339
334
|
throw new Error(
|
|
340
|
-
`Failed to get upload url. Status: ${res.status}${
|
|
335
|
+
`Failed to get upload url. Status: ${res.status}${json?.message ? ` - ${json.message}` : ``}`
|
|
341
336
|
);
|
|
342
337
|
}
|
|
343
338
|
const { signedUrl } = await res.json();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinacms/search",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-f2577b9-20251119082459",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index-client.mjs",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"search-index": "4.0.0",
|
|
34
34
|
"sqlite-level": "^1.2.1",
|
|
35
35
|
"stopword": "^3.1.4",
|
|
36
|
-
"@tinacms/
|
|
37
|
-
"@tinacms/
|
|
36
|
+
"@tinacms/schema-tools": "0.0.0-f2577b9-20251119082459",
|
|
37
|
+
"@tinacms/graphql": "0.0.0-f2577b9-20251119082459"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"registry": "https://registry.npmjs.org"
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"jest-file-snapshot": "^0.7.0",
|
|
54
54
|
"jest-matcher-utils": "^29.7.0",
|
|
55
55
|
"typescript": "^5.7.3",
|
|
56
|
-
"@tinacms/scripts": "
|
|
56
|
+
"@tinacms/scripts": "0.0.0-f2577b9-20251119082459"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"types": "pnpm tsc",
|
package/dist/index-client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-client.js","sources":["../src/indexer/utils.ts","../src/index-client.ts"],"sourcesContent":["import { Collection, ObjectField } from '@tinacms/schema-tools';\nimport * as sw from 'stopword';\n\nclass StringBuilder {\n private readonly buffer: string[];\n public length = 0;\n private readonly limit: number;\n constructor(limit: number) {\n this.buffer = [];\n this.limit = limit;\n }\n\n public append(str: string) {\n if (this.length + str.length > this.limit) {\n return true;\n } else {\n this.buffer.push(str);\n this.length += str.length;\n if (this.length > this.limit) {\n return true;\n }\n return false;\n }\n }\n\n public toString() {\n // NOTE this is going to add some length to the final string beyond the limit\n return this.buffer.join(' ');\n }\n}\n\nconst extractText = (\n data: any,\n acc: StringBuilder,\n indexableNodeTypes: string[]\n) => {\n if (data) {\n if (\n indexableNodeTypes.indexOf(data.type) !== -1 &&\n (data.text || data.value)\n ) {\n const tokens = tokenizeString(data.text || data.value);\n for (const token of tokens) {\n if (acc.append(token)) {\n return;\n }\n }\n }\n\n data.children?.forEach?.((child: any) =>\n extractText(child, acc, indexableNodeTypes)\n );\n }\n};\n\nconst relativePath = (path: string, collection: Collection) => {\n return path\n .replace(/\\\\/g, '/')\n .replace(collection.path, '')\n .replace(/^\\/|\\/$/g, '');\n};\n\nconst tokenizeString = (str: string) => {\n return str\n .split(/[\\s\\.,]+/)\n .map((s) => s.toLowerCase())\n .filter((s) => s);\n};\n\nconst processTextFieldValue = (value: string, maxLen: number) => {\n const tokens = tokenizeString(value);\n const builder = new StringBuilder(maxLen);\n for (const part of tokens) {\n if (builder.append(part)) {\n break;\n }\n }\n return builder.toString();\n};\n\nexport const processDocumentForIndexing = (\n data: any,\n path: string,\n collection: Collection,\n textIndexLength: number,\n field?: ObjectField\n) => {\n if (!field) {\n const relPath = relativePath(path, collection);\n data['_id'] = `${collection.name}:${relPath}`;\n data['_relativePath'] = relPath;\n }\n for (const f of field?.fields || collection.fields || []) {\n if (!f.searchable) {\n delete data[f.name];\n continue;\n }\n const isList = f.list;\n if (data[f.name]) {\n if (f.type === 'object') {\n if (isList) {\n data[f.name] = data[f.name].map((obj: any) =>\n processDocumentForIndexing(\n obj,\n path,\n collection,\n textIndexLength,\n f\n )\n );\n } else {\n data[f.name] = processDocumentForIndexing(\n data[f.name],\n path,\n collection,\n textIndexLength,\n f\n );\n }\n } else if (f.type === 'string') {\n const fieldTextIndexLength =\n f.maxSearchIndexFieldLength || textIndexLength;\n if (isList) {\n data[f.name] = data[f.name].map((value: string) =>\n processTextFieldValue(value, fieldTextIndexLength)\n );\n } else {\n data[f.name] = processTextFieldValue(\n data[f.name],\n fieldTextIndexLength\n );\n }\n } else if (f.type === 'rich-text') {\n const fieldTextIndexLength =\n f.maxSearchIndexFieldLength || textIndexLength;\n if (isList) {\n data[f.name] = data[f.name].map((value: any) => {\n const acc = new StringBuilder(fieldTextIndexLength);\n extractText(value, acc, ['text', 'code_block', 'html']);\n return acc.toString();\n });\n } else {\n const acc = new StringBuilder(fieldTextIndexLength);\n extractText(data[f.name], acc, ['text', 'code_block', 'html']);\n data[f.name] = acc.toString();\n }\n }\n }\n }\n return data;\n};\n\nconst memo: Record<string, string[]> = {};\nexport const lookupStopwords = (\n keys?: string[],\n defaultStopWords: string[] = sw.eng\n) => {\n let stopwords = defaultStopWords;\n if (keys) {\n if (memo[keys.join(',')]) {\n return memo[keys.join(',')];\n }\n stopwords = [];\n for (const key of keys) {\n stopwords.push(...sw[key]);\n }\n memo[keys.join(',')] = stopwords;\n }\n return stopwords;\n};\n","export type { SearchClient } from './types';\nexport { processDocumentForIndexing } from './indexer/utils';\nimport { lookupStopwords } from './indexer/utils';\n\nexport const queryToSearchIndexQuery = (\n query: string,\n stopwordLanguages?: string[]\n) => {\n let q;\n const parts = query.split(' ');\n const stopwords = lookupStopwords(stopwordLanguages);\n if (parts.length === 1) {\n q = { AND: [parts[0]] };\n } else {\n // TODO only allow AND for now - need parser\n q = {\n AND: parts.filter(\n (part) =>\n part.toLowerCase() !== 'and' &&\n stopwords.indexOf(part.toLowerCase()) === -1\n ),\n };\n }\n return q;\n};\n\nexport const optionsToSearchIndexOptions = (options?: {\n limit?: number;\n cursor?: string;\n}) => {\n const opt = {};\n if (options?.limit) {\n opt['PAGE'] = {\n SIZE: options.limit,\n NUMBER: options?.cursor ? parseInt(options.cursor) : 0,\n };\n }\n return opt;\n};\n\nexport const parseSearchIndexResponse = (\n data: any,\n options?: {\n limit?: number;\n cursor?: string;\n }\n) => {\n const results = data['RESULT'];\n const total = data['RESULT_LENGTH'];\n if (options?.cursor && options?.limit) {\n const prevCursor =\n options.cursor === '0' ? null : (parseInt(options.cursor) - 1).toString();\n const nextCursor =\n total <= (parseInt(options.cursor) + 1) * options.limit\n ? null\n : (parseInt(options.cursor) + 1).toString();\n return {\n results,\n total,\n prevCursor,\n nextCursor,\n };\n } else if (!options?.cursor && options?.limit) {\n const prevCursor = null;\n const nextCursor = total <= options.limit ? null : '1';\n return {\n results,\n total,\n prevCursor,\n nextCursor,\n };\n } else {\n return {\n results,\n total,\n prevCursor: null,\n nextCursor: null,\n };\n }\n};\n"],"names":["sw"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-client.mjs","sources":["../src/indexer/utils.ts","../src/index-client.ts"],"sourcesContent":["import { Collection, ObjectField } from '@tinacms/schema-tools';\nimport * as sw from 'stopword';\n\nclass StringBuilder {\n private readonly buffer: string[];\n public length = 0;\n private readonly limit: number;\n constructor(limit: number) {\n this.buffer = [];\n this.limit = limit;\n }\n\n public append(str: string) {\n if (this.length + str.length > this.limit) {\n return true;\n } else {\n this.buffer.push(str);\n this.length += str.length;\n if (this.length > this.limit) {\n return true;\n }\n return false;\n }\n }\n\n public toString() {\n // NOTE this is going to add some length to the final string beyond the limit\n return this.buffer.join(' ');\n }\n}\n\nconst extractText = (\n data: any,\n acc: StringBuilder,\n indexableNodeTypes: string[]\n) => {\n if (data) {\n if (\n indexableNodeTypes.indexOf(data.type) !== -1 &&\n (data.text || data.value)\n ) {\n const tokens = tokenizeString(data.text || data.value);\n for (const token of tokens) {\n if (acc.append(token)) {\n return;\n }\n }\n }\n\n data.children?.forEach?.((child: any) =>\n extractText(child, acc, indexableNodeTypes)\n );\n }\n};\n\nconst relativePath = (path: string, collection: Collection) => {\n return path\n .replace(/\\\\/g, '/')\n .replace(collection.path, '')\n .replace(/^\\/|\\/$/g, '');\n};\n\nconst tokenizeString = (str: string) => {\n return str\n .split(/[\\s\\.,]+/)\n .map((s) => s.toLowerCase())\n .filter((s) => s);\n};\n\nconst processTextFieldValue = (value: string, maxLen: number) => {\n const tokens = tokenizeString(value);\n const builder = new StringBuilder(maxLen);\n for (const part of tokens) {\n if (builder.append(part)) {\n break;\n }\n }\n return builder.toString();\n};\n\nexport const processDocumentForIndexing = (\n data: any,\n path: string,\n collection: Collection,\n textIndexLength: number,\n field?: ObjectField\n) => {\n if (!field) {\n const relPath = relativePath(path, collection);\n data['_id'] = `${collection.name}:${relPath}`;\n data['_relativePath'] = relPath;\n }\n for (const f of field?.fields || collection.fields || []) {\n if (!f.searchable) {\n delete data[f.name];\n continue;\n }\n const isList = f.list;\n if (data[f.name]) {\n if (f.type === 'object') {\n if (isList) {\n data[f.name] = data[f.name].map((obj: any) =>\n processDocumentForIndexing(\n obj,\n path,\n collection,\n textIndexLength,\n f\n )\n );\n } else {\n data[f.name] = processDocumentForIndexing(\n data[f.name],\n path,\n collection,\n textIndexLength,\n f\n );\n }\n } else if (f.type === 'string') {\n const fieldTextIndexLength =\n f.maxSearchIndexFieldLength || textIndexLength;\n if (isList) {\n data[f.name] = data[f.name].map((value: string) =>\n processTextFieldValue(value, fieldTextIndexLength)\n );\n } else {\n data[f.name] = processTextFieldValue(\n data[f.name],\n fieldTextIndexLength\n );\n }\n } else if (f.type === 'rich-text') {\n const fieldTextIndexLength =\n f.maxSearchIndexFieldLength || textIndexLength;\n if (isList) {\n data[f.name] = data[f.name].map((value: any) => {\n const acc = new StringBuilder(fieldTextIndexLength);\n extractText(value, acc, ['text', 'code_block', 'html']);\n return acc.toString();\n });\n } else {\n const acc = new StringBuilder(fieldTextIndexLength);\n extractText(data[f.name], acc, ['text', 'code_block', 'html']);\n data[f.name] = acc.toString();\n }\n }\n }\n }\n return data;\n};\n\nconst memo: Record<string, string[]> = {};\nexport const lookupStopwords = (\n keys?: string[],\n defaultStopWords: string[] = sw.eng\n) => {\n let stopwords = defaultStopWords;\n if (keys) {\n if (memo[keys.join(',')]) {\n return memo[keys.join(',')];\n }\n stopwords = [];\n for (const key of keys) {\n stopwords.push(...sw[key]);\n }\n memo[keys.join(',')] = stopwords;\n }\n return stopwords;\n};\n","export type { SearchClient } from './types';\nexport { processDocumentForIndexing } from './indexer/utils';\nimport { lookupStopwords } from './indexer/utils';\n\nexport const queryToSearchIndexQuery = (\n query: string,\n stopwordLanguages?: string[]\n) => {\n let q;\n const parts = query.split(' ');\n const stopwords = lookupStopwords(stopwordLanguages);\n if (parts.length === 1) {\n q = { AND: [parts[0]] };\n } else {\n // TODO only allow AND for now - need parser\n q = {\n AND: parts.filter(\n (part) =>\n part.toLowerCase() !== 'and' &&\n stopwords.indexOf(part.toLowerCase()) === -1\n ),\n };\n }\n return q;\n};\n\nexport const optionsToSearchIndexOptions = (options?: {\n limit?: number;\n cursor?: string;\n}) => {\n const opt = {};\n if (options?.limit) {\n opt['PAGE'] = {\n SIZE: options.limit,\n NUMBER: options?.cursor ? parseInt(options.cursor) : 0,\n };\n }\n return opt;\n};\n\nexport const parseSearchIndexResponse = (\n data: any,\n options?: {\n limit?: number;\n cursor?: string;\n }\n) => {\n const results = data['RESULT'];\n const total = data['RESULT_LENGTH'];\n if (options?.cursor && options?.limit) {\n const prevCursor =\n options.cursor === '0' ? null : (parseInt(options.cursor) - 1).toString();\n const nextCursor =\n total <= (parseInt(options.cursor) + 1) * options.limit\n ? null\n : (parseInt(options.cursor) + 1).toString();\n return {\n results,\n total,\n prevCursor,\n nextCursor,\n };\n } else if (!options?.cursor && options?.limit) {\n const prevCursor = null;\n const nextCursor = total <= options.limit ? null : '1';\n return {\n results,\n total,\n prevCursor,\n nextCursor,\n };\n } else {\n return {\n results,\n total,\n prevCursor: null,\n nextCursor: null,\n };\n }\n};\n"],"names":[],"mappings":"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"}
|