@magicpages/ghost-typesense-core 1.9.1 → 1.9.3
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 +20 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +150 -18
- package/dist/index.mjs +150 -18
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -35,6 +35,26 @@ declare class GhostTypesenseManager {
|
|
|
35
35
|
* Fetch all posts from Ghost and index them in Typesense
|
|
36
36
|
*/
|
|
37
37
|
indexAllPosts(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Index documents in batches with retry logic and backpressure handling
|
|
40
|
+
* @private
|
|
41
|
+
*/
|
|
42
|
+
private indexDocumentsBatched;
|
|
43
|
+
/**
|
|
44
|
+
* Process a single batch with retry logic and backpressure handling
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
private processBatchWithRetry;
|
|
48
|
+
/**
|
|
49
|
+
* Retry failed batches with smaller batch sizes
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
private retryFailedBatches;
|
|
53
|
+
/**
|
|
54
|
+
* Sleep utility for backoff delays
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
private sleep;
|
|
38
58
|
/**
|
|
39
59
|
* Index a single post in Typesense
|
|
40
60
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -35,6 +35,26 @@ declare class GhostTypesenseManager {
|
|
|
35
35
|
* Fetch all posts from Ghost and index them in Typesense
|
|
36
36
|
*/
|
|
37
37
|
indexAllPosts(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Index documents in batches with retry logic and backpressure handling
|
|
40
|
+
* @private
|
|
41
|
+
*/
|
|
42
|
+
private indexDocumentsBatched;
|
|
43
|
+
/**
|
|
44
|
+
* Process a single batch with retry logic and backpressure handling
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
private processBatchWithRetry;
|
|
48
|
+
/**
|
|
49
|
+
* Retry failed batches with smaller batch sizes
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
private retryFailedBatches;
|
|
53
|
+
/**
|
|
54
|
+
* Sleep utility for backoff delays
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
private sleep;
|
|
38
58
|
/**
|
|
39
59
|
* Index a single post in Typesense
|
|
40
60
|
*/
|
package/dist/index.js
CHANGED
|
@@ -41,9 +41,10 @@ var GhostTypesenseManager = class {
|
|
|
41
41
|
this.typesense = new import_typesense.Client({
|
|
42
42
|
nodes: config.typesense.nodes,
|
|
43
43
|
apiKey: config.typesense.apiKey,
|
|
44
|
-
connectionTimeoutSeconds: config.typesense.connectionTimeoutSeconds,
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
connectionTimeoutSeconds: config.typesense.connectionTimeoutSeconds || 3600,
|
|
45
|
+
// 60 minutes for bulk operations
|
|
46
|
+
retryIntervalSeconds: config.typesense.retryIntervalSeconds || 2,
|
|
47
|
+
numRetries: 5
|
|
47
48
|
});
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
@@ -163,23 +164,154 @@ var GhostTypesenseManager = class {
|
|
|
163
164
|
}
|
|
164
165
|
console.log(`Found ${allPosts.length} posts to index`);
|
|
165
166
|
const documents = allPosts.map((post) => this.transformPost(post));
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
167
|
+
await this.indexDocumentsBatched(documents);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Index documents in batches with retry logic and backpressure handling
|
|
171
|
+
* @private
|
|
172
|
+
*/
|
|
173
|
+
async indexDocumentsBatched(documents) {
|
|
174
|
+
const batchSize = this.config.typesense.batchSize || 200;
|
|
175
|
+
const maxConcurrentBatches = this.config.typesense.maxConcurrentBatches || 12;
|
|
176
|
+
const batches = [];
|
|
177
|
+
for (let i = 0; i < documents.length; i += batchSize) {
|
|
178
|
+
batches.push(documents.slice(i, i + batchSize));
|
|
179
|
+
}
|
|
180
|
+
console.log(`Processing ${documents.length} documents in ${batches.length} batches (batch size: ${batchSize})`);
|
|
181
|
+
const collection = this.typesense.collections(this.collectionName);
|
|
182
|
+
let totalSucceeded = 0;
|
|
183
|
+
let totalFailed = 0;
|
|
184
|
+
const failedBatches = [];
|
|
185
|
+
for (let i = 0; i < batches.length; i += maxConcurrentBatches) {
|
|
186
|
+
const batchGroup = batches.slice(i, i + maxConcurrentBatches);
|
|
187
|
+
const batchPromises = batchGroup.map(async (batch, batchIndex) => {
|
|
188
|
+
const actualBatchIndex = i + batchIndex;
|
|
189
|
+
return this.processBatchWithRetry(collection, batch, actualBatchIndex, batches.length);
|
|
190
|
+
});
|
|
191
|
+
const results = await Promise.allSettled(batchPromises);
|
|
192
|
+
results.forEach((result, batchIndex) => {
|
|
193
|
+
const actualBatchIndex = i + batchIndex;
|
|
194
|
+
if (result.status === "fulfilled") {
|
|
195
|
+
totalSucceeded += result.value.succeeded;
|
|
196
|
+
totalFailed += result.value.failed;
|
|
197
|
+
if (result.value.error) {
|
|
198
|
+
failedBatches.push({
|
|
199
|
+
batchIndex: actualBatchIndex,
|
|
200
|
+
documents: batchGroup[batchIndex],
|
|
201
|
+
error: result.value.error
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
const batchSize2 = batchGroup[batchIndex].length;
|
|
206
|
+
totalFailed += batchSize2;
|
|
207
|
+
failedBatches.push({
|
|
208
|
+
batchIndex: actualBatchIndex,
|
|
209
|
+
documents: batchGroup[batchIndex],
|
|
210
|
+
error: result.reason?.message || "Unknown batch error"
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
console.log(`Progress: ${Math.min(i + maxConcurrentBatches, batches.length)}/${batches.length} batch groups processed`);
|
|
215
|
+
}
|
|
216
|
+
console.log(`Indexing complete: ${totalSucceeded} succeeded, ${totalFailed} failed`);
|
|
217
|
+
if (failedBatches.length > 0) {
|
|
218
|
+
console.log(`Retrying ${failedBatches.length} failed batches with smaller batch size...`);
|
|
219
|
+
const retryResults = await this.retryFailedBatches(collection, failedBatches);
|
|
220
|
+
totalSucceeded += retryResults.succeeded;
|
|
221
|
+
totalFailed = totalFailed - retryResults.retryAttempted + retryResults.failed;
|
|
222
|
+
console.log(`Final result: ${totalSucceeded} succeeded, ${totalFailed} failed`);
|
|
223
|
+
}
|
|
224
|
+
if (totalFailed > 0) {
|
|
225
|
+
console.log(`\u26A0\uFE0F ${totalFailed} documents failed to index. Consider running sync again or checking server capacity.`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Process a single batch with retry logic and backpressure handling
|
|
230
|
+
* @private
|
|
231
|
+
*/
|
|
232
|
+
async processBatchWithRetry(collection, documents, batchIndex, totalBatches) {
|
|
233
|
+
const maxRetries = 3;
|
|
234
|
+
let lastError = "";
|
|
235
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
236
|
+
try {
|
|
237
|
+
console.log(`Processing batch ${batchIndex + 1}/${totalBatches} (${documents.length} docs) - attempt ${attempt}`);
|
|
238
|
+
const result = await collection.documents().import(documents, {
|
|
239
|
+
action: "upsert",
|
|
240
|
+
batch_size: documents.length,
|
|
241
|
+
return_doc: false,
|
|
242
|
+
return_id: false
|
|
243
|
+
});
|
|
244
|
+
const succeeded = result.filter((r) => r.success === true).length;
|
|
245
|
+
const failed = documents.length - succeeded;
|
|
246
|
+
if (failed > 0) {
|
|
247
|
+
console.log(`Batch ${batchIndex + 1}: ${succeeded} succeeded, ${failed} failed`);
|
|
248
|
+
}
|
|
249
|
+
return { succeeded, failed };
|
|
250
|
+
} catch (error) {
|
|
251
|
+
lastError = error.message || error;
|
|
252
|
+
if (error.httpStatus === 503 || lastError.includes("503") || lastError.includes("Not Ready")) {
|
|
253
|
+
const backoffDelay = Math.min(1e3 * Math.pow(2, attempt), 1e4);
|
|
254
|
+
console.log(`Batch ${batchIndex + 1}: Server overload (503), retrying in ${backoffDelay}ms...`);
|
|
255
|
+
await this.sleep(backoffDelay);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (lastError.includes("timeout") || lastError.includes("ECONNABORTED")) {
|
|
259
|
+
const backoffDelay = Math.min(2e3 * attempt, 8e3);
|
|
260
|
+
console.log(`Batch ${batchIndex + 1}: Timeout error, retrying in ${backoffDelay}ms...`);
|
|
261
|
+
await this.sleep(backoffDelay);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (attempt < maxRetries) {
|
|
265
|
+
const backoffDelay = 1e3 * attempt;
|
|
266
|
+
console.log(`Batch ${batchIndex + 1}: Error (${lastError}), retrying in ${backoffDelay}ms...`);
|
|
267
|
+
await this.sleep(backoffDelay);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
178
270
|
}
|
|
179
|
-
} catch (error) {
|
|
180
|
-
console.error("Indexing error:", error);
|
|
181
|
-
throw error;
|
|
182
271
|
}
|
|
272
|
+
console.error(`Batch ${batchIndex + 1} failed after ${maxRetries} attempts: ${lastError}`);
|
|
273
|
+
return { succeeded: 0, failed: documents.length, error: lastError };
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Retry failed batches with smaller batch sizes
|
|
277
|
+
* @private
|
|
278
|
+
*/
|
|
279
|
+
async retryFailedBatches(collection, failedBatches) {
|
|
280
|
+
let succeeded = 0;
|
|
281
|
+
let failed = 0;
|
|
282
|
+
let retryAttempted = 0;
|
|
283
|
+
for (const failedBatch of failedBatches) {
|
|
284
|
+
retryAttempted += failedBatch.documents.length;
|
|
285
|
+
const smallBatches = [];
|
|
286
|
+
for (let i = 0; i < failedBatch.documents.length; i += 50) {
|
|
287
|
+
smallBatches.push(failedBatch.documents.slice(i, i + 50));
|
|
288
|
+
}
|
|
289
|
+
for (const smallBatch of smallBatches) {
|
|
290
|
+
try {
|
|
291
|
+
const result = await collection.documents().import(smallBatch, {
|
|
292
|
+
action: "upsert",
|
|
293
|
+
batch_size: smallBatch.length,
|
|
294
|
+
return_doc: false,
|
|
295
|
+
return_id: false
|
|
296
|
+
});
|
|
297
|
+
const batchSucceeded = result.filter((r) => r.success === true).length;
|
|
298
|
+
succeeded += batchSucceeded;
|
|
299
|
+
failed += smallBatch.length - batchSucceeded;
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error(`Small batch retry failed: ${error.message || error}`);
|
|
302
|
+
failed += smallBatch.length;
|
|
303
|
+
}
|
|
304
|
+
await this.sleep(500);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return { succeeded, failed, retryAttempted };
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Sleep utility for backoff delays
|
|
311
|
+
* @private
|
|
312
|
+
*/
|
|
313
|
+
sleep(ms) {
|
|
314
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
183
315
|
}
|
|
184
316
|
/**
|
|
185
317
|
* Index a single post in Typesense
|
package/dist/index.mjs
CHANGED
|
@@ -17,9 +17,10 @@ var GhostTypesenseManager = class {
|
|
|
17
17
|
this.typesense = new Client({
|
|
18
18
|
nodes: config.typesense.nodes,
|
|
19
19
|
apiKey: config.typesense.apiKey,
|
|
20
|
-
connectionTimeoutSeconds: config.typesense.connectionTimeoutSeconds,
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
connectionTimeoutSeconds: config.typesense.connectionTimeoutSeconds || 3600,
|
|
21
|
+
// 60 minutes for bulk operations
|
|
22
|
+
retryIntervalSeconds: config.typesense.retryIntervalSeconds || 2,
|
|
23
|
+
numRetries: 5
|
|
23
24
|
});
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
@@ -139,23 +140,154 @@ var GhostTypesenseManager = class {
|
|
|
139
140
|
}
|
|
140
141
|
console.log(`Found ${allPosts.length} posts to index`);
|
|
141
142
|
const documents = allPosts.map((post) => this.transformPost(post));
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
143
|
+
await this.indexDocumentsBatched(documents);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Index documents in batches with retry logic and backpressure handling
|
|
147
|
+
* @private
|
|
148
|
+
*/
|
|
149
|
+
async indexDocumentsBatched(documents) {
|
|
150
|
+
const batchSize = this.config.typesense.batchSize || 200;
|
|
151
|
+
const maxConcurrentBatches = this.config.typesense.maxConcurrentBatches || 12;
|
|
152
|
+
const batches = [];
|
|
153
|
+
for (let i = 0; i < documents.length; i += batchSize) {
|
|
154
|
+
batches.push(documents.slice(i, i + batchSize));
|
|
155
|
+
}
|
|
156
|
+
console.log(`Processing ${documents.length} documents in ${batches.length} batches (batch size: ${batchSize})`);
|
|
157
|
+
const collection = this.typesense.collections(this.collectionName);
|
|
158
|
+
let totalSucceeded = 0;
|
|
159
|
+
let totalFailed = 0;
|
|
160
|
+
const failedBatches = [];
|
|
161
|
+
for (let i = 0; i < batches.length; i += maxConcurrentBatches) {
|
|
162
|
+
const batchGroup = batches.slice(i, i + maxConcurrentBatches);
|
|
163
|
+
const batchPromises = batchGroup.map(async (batch, batchIndex) => {
|
|
164
|
+
const actualBatchIndex = i + batchIndex;
|
|
165
|
+
return this.processBatchWithRetry(collection, batch, actualBatchIndex, batches.length);
|
|
166
|
+
});
|
|
167
|
+
const results = await Promise.allSettled(batchPromises);
|
|
168
|
+
results.forEach((result, batchIndex) => {
|
|
169
|
+
const actualBatchIndex = i + batchIndex;
|
|
170
|
+
if (result.status === "fulfilled") {
|
|
171
|
+
totalSucceeded += result.value.succeeded;
|
|
172
|
+
totalFailed += result.value.failed;
|
|
173
|
+
if (result.value.error) {
|
|
174
|
+
failedBatches.push({
|
|
175
|
+
batchIndex: actualBatchIndex,
|
|
176
|
+
documents: batchGroup[batchIndex],
|
|
177
|
+
error: result.value.error
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
const batchSize2 = batchGroup[batchIndex].length;
|
|
182
|
+
totalFailed += batchSize2;
|
|
183
|
+
failedBatches.push({
|
|
184
|
+
batchIndex: actualBatchIndex,
|
|
185
|
+
documents: batchGroup[batchIndex],
|
|
186
|
+
error: result.reason?.message || "Unknown batch error"
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
console.log(`Progress: ${Math.min(i + maxConcurrentBatches, batches.length)}/${batches.length} batch groups processed`);
|
|
191
|
+
}
|
|
192
|
+
console.log(`Indexing complete: ${totalSucceeded} succeeded, ${totalFailed} failed`);
|
|
193
|
+
if (failedBatches.length > 0) {
|
|
194
|
+
console.log(`Retrying ${failedBatches.length} failed batches with smaller batch size...`);
|
|
195
|
+
const retryResults = await this.retryFailedBatches(collection, failedBatches);
|
|
196
|
+
totalSucceeded += retryResults.succeeded;
|
|
197
|
+
totalFailed = totalFailed - retryResults.retryAttempted + retryResults.failed;
|
|
198
|
+
console.log(`Final result: ${totalSucceeded} succeeded, ${totalFailed} failed`);
|
|
199
|
+
}
|
|
200
|
+
if (totalFailed > 0) {
|
|
201
|
+
console.log(`\u26A0\uFE0F ${totalFailed} documents failed to index. Consider running sync again or checking server capacity.`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Process a single batch with retry logic and backpressure handling
|
|
206
|
+
* @private
|
|
207
|
+
*/
|
|
208
|
+
async processBatchWithRetry(collection, documents, batchIndex, totalBatches) {
|
|
209
|
+
const maxRetries = 3;
|
|
210
|
+
let lastError = "";
|
|
211
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
212
|
+
try {
|
|
213
|
+
console.log(`Processing batch ${batchIndex + 1}/${totalBatches} (${documents.length} docs) - attempt ${attempt}`);
|
|
214
|
+
const result = await collection.documents().import(documents, {
|
|
215
|
+
action: "upsert",
|
|
216
|
+
batch_size: documents.length,
|
|
217
|
+
return_doc: false,
|
|
218
|
+
return_id: false
|
|
219
|
+
});
|
|
220
|
+
const succeeded = result.filter((r) => r.success === true).length;
|
|
221
|
+
const failed = documents.length - succeeded;
|
|
222
|
+
if (failed > 0) {
|
|
223
|
+
console.log(`Batch ${batchIndex + 1}: ${succeeded} succeeded, ${failed} failed`);
|
|
224
|
+
}
|
|
225
|
+
return { succeeded, failed };
|
|
226
|
+
} catch (error) {
|
|
227
|
+
lastError = error.message || error;
|
|
228
|
+
if (error.httpStatus === 503 || lastError.includes("503") || lastError.includes("Not Ready")) {
|
|
229
|
+
const backoffDelay = Math.min(1e3 * Math.pow(2, attempt), 1e4);
|
|
230
|
+
console.log(`Batch ${batchIndex + 1}: Server overload (503), retrying in ${backoffDelay}ms...`);
|
|
231
|
+
await this.sleep(backoffDelay);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (lastError.includes("timeout") || lastError.includes("ECONNABORTED")) {
|
|
235
|
+
const backoffDelay = Math.min(2e3 * attempt, 8e3);
|
|
236
|
+
console.log(`Batch ${batchIndex + 1}: Timeout error, retrying in ${backoffDelay}ms...`);
|
|
237
|
+
await this.sleep(backoffDelay);
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (attempt < maxRetries) {
|
|
241
|
+
const backoffDelay = 1e3 * attempt;
|
|
242
|
+
console.log(`Batch ${batchIndex + 1}: Error (${lastError}), retrying in ${backoffDelay}ms...`);
|
|
243
|
+
await this.sleep(backoffDelay);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
154
246
|
}
|
|
155
|
-
} catch (error) {
|
|
156
|
-
console.error("Indexing error:", error);
|
|
157
|
-
throw error;
|
|
158
247
|
}
|
|
248
|
+
console.error(`Batch ${batchIndex + 1} failed after ${maxRetries} attempts: ${lastError}`);
|
|
249
|
+
return { succeeded: 0, failed: documents.length, error: lastError };
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Retry failed batches with smaller batch sizes
|
|
253
|
+
* @private
|
|
254
|
+
*/
|
|
255
|
+
async retryFailedBatches(collection, failedBatches) {
|
|
256
|
+
let succeeded = 0;
|
|
257
|
+
let failed = 0;
|
|
258
|
+
let retryAttempted = 0;
|
|
259
|
+
for (const failedBatch of failedBatches) {
|
|
260
|
+
retryAttempted += failedBatch.documents.length;
|
|
261
|
+
const smallBatches = [];
|
|
262
|
+
for (let i = 0; i < failedBatch.documents.length; i += 50) {
|
|
263
|
+
smallBatches.push(failedBatch.documents.slice(i, i + 50));
|
|
264
|
+
}
|
|
265
|
+
for (const smallBatch of smallBatches) {
|
|
266
|
+
try {
|
|
267
|
+
const result = await collection.documents().import(smallBatch, {
|
|
268
|
+
action: "upsert",
|
|
269
|
+
batch_size: smallBatch.length,
|
|
270
|
+
return_doc: false,
|
|
271
|
+
return_id: false
|
|
272
|
+
});
|
|
273
|
+
const batchSucceeded = result.filter((r) => r.success === true).length;
|
|
274
|
+
succeeded += batchSucceeded;
|
|
275
|
+
failed += smallBatch.length - batchSucceeded;
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.error(`Small batch retry failed: ${error.message || error}`);
|
|
278
|
+
failed += smallBatch.length;
|
|
279
|
+
}
|
|
280
|
+
await this.sleep(500);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return { succeeded, failed, retryAttempted };
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Sleep utility for backoff delays
|
|
287
|
+
* @private
|
|
288
|
+
*/
|
|
289
|
+
sleep(ms) {
|
|
290
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
159
291
|
}
|
|
160
292
|
/**
|
|
161
293
|
* Index a single post in Typesense
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magicpages/ghost-typesense-core",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.3",
|
|
4
4
|
"description": "Core functionality for Ghost-Typesense integration",
|
|
5
5
|
"author": "MagicPages",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"typecheck": "tsc --noEmit"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@magicpages/ghost-typesense-config": "^1.9.
|
|
27
|
+
"@magicpages/ghost-typesense-config": "^1.9.3",
|
|
28
28
|
"@ts-ghost/content-api": "^4.0.6",
|
|
29
29
|
"@ts-ghost/core-api": "^4.0.6",
|
|
30
30
|
"typesense": "^1.7.2",
|