@contentrain/query 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +209 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +209 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -272,6 +272,11 @@ declare class MemoryCache {
|
|
|
272
272
|
getStats(): CacheStats;
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
declare const logger: {
|
|
276
|
+
debug: (...args: unknown[]) => void;
|
|
277
|
+
error: (...args: unknown[]) => void;
|
|
278
|
+
};
|
|
279
|
+
|
|
275
280
|
declare class ContentrainSDK {
|
|
276
281
|
private loader;
|
|
277
282
|
private executor;
|
|
@@ -283,4 +288,4 @@ declare class ContentrainSDK {
|
|
|
283
288
|
getCacheStats(): CacheStats;
|
|
284
289
|
}
|
|
285
290
|
|
|
286
|
-
export { type ArrayOperator, type AssetMetadata, type BaseContentrainType, type CacheEntry, type CacheStats, type ContentFile, ContentLoader, type ContentLoaderOptions, type ContentrainComponentId, type ContentrainConfig, type ContentrainFieldType, type ContentrainLocales, ContentrainQueryBuilder, ContentrainSDK, type ContentrainStatus, type FieldMetadata, type FieldOptions, type FieldValidations, type Filter, type Include, type LoaderResult, MemoryCache, type MemoryCacheOptions, type ModelConfig, type ModelMetadata, type NumericOperator, type Operator, type Pagination, type QueryConfig, QueryExecutor, type QueryOptions, type QueryResult, type RelationConfig, type Sort, type StringOperator };
|
|
291
|
+
export { type ArrayOperator, type AssetMetadata, type BaseContentrainType, type CacheEntry, type CacheStats, type ContentFile, ContentLoader, type ContentLoaderOptions, type ContentrainComponentId, type ContentrainConfig, type ContentrainFieldType, type ContentrainLocales, ContentrainQueryBuilder, ContentrainSDK, type ContentrainStatus, type FieldMetadata, type FieldOptions, type FieldValidations, type Filter, type Include, type LoaderResult, MemoryCache, type MemoryCacheOptions, type ModelConfig, type ModelMetadata, type NumericOperator, type Operator, type Pagination, type QueryConfig, QueryExecutor, type QueryOptions, type QueryResult, type RelationConfig, type Sort, type StringOperator, logger };
|
package/dist/index.d.ts
CHANGED
|
@@ -272,6 +272,11 @@ declare class MemoryCache {
|
|
|
272
272
|
getStats(): CacheStats;
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
declare const logger: {
|
|
276
|
+
debug: (...args: unknown[]) => void;
|
|
277
|
+
error: (...args: unknown[]) => void;
|
|
278
|
+
};
|
|
279
|
+
|
|
275
280
|
declare class ContentrainSDK {
|
|
276
281
|
private loader;
|
|
277
282
|
private executor;
|
|
@@ -283,4 +288,4 @@ declare class ContentrainSDK {
|
|
|
283
288
|
getCacheStats(): CacheStats;
|
|
284
289
|
}
|
|
285
290
|
|
|
286
|
-
export { type ArrayOperator, type AssetMetadata, type BaseContentrainType, type CacheEntry, type CacheStats, type ContentFile, ContentLoader, type ContentLoaderOptions, type ContentrainComponentId, type ContentrainConfig, type ContentrainFieldType, type ContentrainLocales, ContentrainQueryBuilder, ContentrainSDK, type ContentrainStatus, type FieldMetadata, type FieldOptions, type FieldValidations, type Filter, type Include, type LoaderResult, MemoryCache, type MemoryCacheOptions, type ModelConfig, type ModelMetadata, type NumericOperator, type Operator, type Pagination, type QueryConfig, QueryExecutor, type QueryOptions, type QueryResult, type RelationConfig, type Sort, type StringOperator };
|
|
291
|
+
export { type ArrayOperator, type AssetMetadata, type BaseContentrainType, type CacheEntry, type CacheStats, type ContentFile, ContentLoader, type ContentLoaderOptions, type ContentrainComponentId, type ContentrainConfig, type ContentrainFieldType, type ContentrainLocales, ContentrainQueryBuilder, ContentrainSDK, type ContentrainStatus, type FieldMetadata, type FieldOptions, type FieldValidations, type Filter, type Include, type LoaderResult, MemoryCache, type MemoryCacheOptions, type ModelConfig, type ModelMetadata, type NumericOperator, type Operator, type Pagination, type QueryConfig, QueryExecutor, type QueryOptions, type QueryResult, type RelationConfig, type Sort, type StringOperator, logger };
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,25 @@
|
|
|
3
3
|
var promises = require('fs/promises');
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var tinyLru = require('tiny-lru');
|
|
6
|
+
var process = require('process');
|
|
6
7
|
|
|
7
8
|
var __defProp = Object.defineProperty;
|
|
8
9
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
10
|
+
var isDevelopment = process.env.NODE_ENV === "development";
|
|
11
|
+
var logger = {
|
|
12
|
+
debug: /* @__PURE__ */ __name((...args) => {
|
|
13
|
+
if (isDevelopment) {
|
|
14
|
+
console.log(...args);
|
|
15
|
+
}
|
|
16
|
+
}, "debug"),
|
|
17
|
+
error: /* @__PURE__ */ __name((...args) => {
|
|
18
|
+
if (isDevelopment) {
|
|
19
|
+
console.error(...args);
|
|
20
|
+
}
|
|
21
|
+
}, "error")
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/cache/memory.ts
|
|
9
25
|
var _MemoryCache = class _MemoryCache {
|
|
10
26
|
constructor(options = {}) {
|
|
11
27
|
this.stats = {
|
|
@@ -29,6 +45,10 @@ var _MemoryCache = class _MemoryCache {
|
|
|
29
45
|
return new TextEncoder().encode(str).length;
|
|
30
46
|
}
|
|
31
47
|
async set(key, data, ttl) {
|
|
48
|
+
logger.debug("Saving data to cache:", {
|
|
49
|
+
key,
|
|
50
|
+
ttl
|
|
51
|
+
});
|
|
32
52
|
await this.cleanupCache();
|
|
33
53
|
const size = this.calculateSize(data);
|
|
34
54
|
const now = Date.now();
|
|
@@ -51,6 +71,10 @@ var _MemoryCache = class _MemoryCache {
|
|
|
51
71
|
}
|
|
52
72
|
this.cache.set(key, entry);
|
|
53
73
|
this.stats.size += size;
|
|
74
|
+
logger.debug("Data saved to cache:", {
|
|
75
|
+
key,
|
|
76
|
+
expiry: expireAt ? new Date(expireAt).toISOString() : "no expiry"
|
|
77
|
+
});
|
|
54
78
|
}
|
|
55
79
|
findOldestKey() {
|
|
56
80
|
let oldestKey = null;
|
|
@@ -65,8 +89,10 @@ var _MemoryCache = class _MemoryCache {
|
|
|
65
89
|
return oldestKey;
|
|
66
90
|
}
|
|
67
91
|
async get(key) {
|
|
92
|
+
logger.debug("Getting data from cache:", { key });
|
|
68
93
|
const entry = this.cache.get(key);
|
|
69
94
|
if (!entry) {
|
|
95
|
+
logger.debug("Data not found in cache:", { key });
|
|
70
96
|
this.stats.misses++;
|
|
71
97
|
return null;
|
|
72
98
|
}
|
|
@@ -75,17 +101,24 @@ var _MemoryCache = class _MemoryCache {
|
|
|
75
101
|
this.stats.misses++;
|
|
76
102
|
return null;
|
|
77
103
|
}
|
|
104
|
+
logger.debug("Data retrieved from cache:", {
|
|
105
|
+
key,
|
|
106
|
+
expiry: entry.expireAt ? new Date(entry.expireAt).toISOString() : "no expiry"
|
|
107
|
+
});
|
|
78
108
|
this.stats.hits++;
|
|
79
109
|
return entry.data;
|
|
80
110
|
}
|
|
81
111
|
async delete(key) {
|
|
112
|
+
logger.debug("Deleting data from cache:", { key });
|
|
82
113
|
const entry = this.cache.get(key);
|
|
83
114
|
if (entry) {
|
|
84
115
|
this.stats.size -= entry.size;
|
|
85
116
|
this.cache.delete(key);
|
|
86
117
|
}
|
|
118
|
+
logger.debug("Data deleted from cache:", { key });
|
|
87
119
|
}
|
|
88
120
|
async clear() {
|
|
121
|
+
logger.debug("Clearing cache");
|
|
89
122
|
this.cache.clear();
|
|
90
123
|
this.stats = {
|
|
91
124
|
hits: 0,
|
|
@@ -93,6 +126,7 @@ var _MemoryCache = class _MemoryCache {
|
|
|
93
126
|
size: 0,
|
|
94
127
|
lastCleanup: Date.now()
|
|
95
128
|
};
|
|
129
|
+
logger.debug("Cache cleared");
|
|
96
130
|
}
|
|
97
131
|
async cleanupCache() {
|
|
98
132
|
const now = Date.now();
|
|
@@ -135,7 +169,7 @@ var _ContentLoader = class _ContentLoader {
|
|
|
135
169
|
defaultLocale: "en",
|
|
136
170
|
cache: true,
|
|
137
171
|
ttl: 60 * 1e3,
|
|
138
|
-
// 1
|
|
172
|
+
// 1 minute
|
|
139
173
|
maxCacheSize: 100,
|
|
140
174
|
// 100 MB
|
|
141
175
|
...options
|
|
@@ -169,6 +203,10 @@ var _ContentLoader = class _ContentLoader {
|
|
|
169
203
|
const allMetadata = JSON.parse(metadataContent);
|
|
170
204
|
const modelMetadata = allMetadata.find((m) => m.modelId === model);
|
|
171
205
|
if (!modelMetadata) {
|
|
206
|
+
logger.error("Model metadata not found:", {
|
|
207
|
+
model,
|
|
208
|
+
metadataPath
|
|
209
|
+
});
|
|
172
210
|
throw new Error(`Model metadata not found for ${model}`);
|
|
173
211
|
}
|
|
174
212
|
const modelPath = path.join(this.options.contentDir, "models", `${model}.json`);
|
|
@@ -179,6 +217,10 @@ var _ContentLoader = class _ContentLoader {
|
|
|
179
217
|
fields: modelFields
|
|
180
218
|
};
|
|
181
219
|
} catch (error) {
|
|
220
|
+
logger.error("Failed to load model config:", {
|
|
221
|
+
model,
|
|
222
|
+
error: error?.message || "Unknown error"
|
|
223
|
+
});
|
|
182
224
|
throw new Error(`Failed to load model config for ${model}: ${error?.message || "Unknown error"}`);
|
|
183
225
|
}
|
|
184
226
|
}
|
|
@@ -189,6 +231,9 @@ var _ContentLoader = class _ContentLoader {
|
|
|
189
231
|
if (modelConfig.metadata.localization) {
|
|
190
232
|
if (!locale || locale === "default") {
|
|
191
233
|
if (!this.options.defaultLocale) {
|
|
234
|
+
logger.error("Default locale is required for localized model:", {
|
|
235
|
+
model
|
|
236
|
+
});
|
|
192
237
|
throw new Error(`Default locale is required for localized model "${model}"`);
|
|
193
238
|
}
|
|
194
239
|
locale = this.options.defaultLocale;
|
|
@@ -209,10 +254,19 @@ var _ContentLoader = class _ContentLoader {
|
|
|
209
254
|
data
|
|
210
255
|
};
|
|
211
256
|
} catch {
|
|
257
|
+
logger.error("Failed to load content:", {
|
|
258
|
+
model,
|
|
259
|
+
locale,
|
|
260
|
+
contentPath
|
|
261
|
+
});
|
|
212
262
|
throw new Error(`Failed to load content: Invalid JSON format in ${contentPath}`);
|
|
213
263
|
}
|
|
214
264
|
} catch (error) {
|
|
215
265
|
if (error.message.includes("Invalid JSON format")) {
|
|
266
|
+
logger.error("Failed to load content:", {
|
|
267
|
+
model,
|
|
268
|
+
locale
|
|
269
|
+
});
|
|
216
270
|
throw error;
|
|
217
271
|
}
|
|
218
272
|
throw new Error(
|
|
@@ -297,7 +351,7 @@ var _ContentLoader = class _ContentLoader {
|
|
|
297
351
|
const file = await this.loadContentFile(model);
|
|
298
352
|
content.default = file.data;
|
|
299
353
|
}
|
|
300
|
-
let assets;
|
|
354
|
+
let assets = [];
|
|
301
355
|
try {
|
|
302
356
|
const assetsPath = path.join(this.options.contentDir, "assets.json");
|
|
303
357
|
const assetsContent = await promises.readFile(assetsPath, "utf-8");
|
|
@@ -318,19 +372,65 @@ var _ContentLoader = class _ContentLoader {
|
|
|
318
372
|
}
|
|
319
373
|
async resolveRelation(model, relationField, data, locale) {
|
|
320
374
|
try {
|
|
375
|
+
logger.debug("Debug - Starting relation resolution:", {
|
|
376
|
+
model,
|
|
377
|
+
relationField,
|
|
378
|
+
dataLength: data.length,
|
|
379
|
+
locale
|
|
380
|
+
});
|
|
321
381
|
const relations = this.relations.get(model);
|
|
382
|
+
logger.debug("Debug - Relations:", relations);
|
|
322
383
|
if (!relations)
|
|
323
384
|
throw new Error(`No relations found for model: ${model}`);
|
|
324
385
|
const relation = relations.find((r) => r.foreignKey === relationField);
|
|
386
|
+
logger.debug("Debug - Found relation:", relation);
|
|
325
387
|
if (!relation)
|
|
326
388
|
throw new Error(`No relation found for field: ${String(relationField)}`);
|
|
389
|
+
logger.debug("Debug - Related model loading:", relation.model);
|
|
327
390
|
const relatedContent = await this.load(relation.model);
|
|
328
|
-
|
|
391
|
+
logger.debug("Debug - \u0130li\u015Fkili model y\xFCklendi:", {
|
|
392
|
+
model: relation.model,
|
|
393
|
+
metadata: relatedContent.model.metadata,
|
|
394
|
+
contentKeys: Object.keys(relatedContent.content)
|
|
395
|
+
});
|
|
396
|
+
let relatedData;
|
|
397
|
+
if (relatedContent.model.metadata.localization) {
|
|
398
|
+
logger.debug("Debug - Processing localized model");
|
|
399
|
+
const localizedContent = locale ? relatedContent.content[locale] : relatedContent.content.en;
|
|
400
|
+
logger.debug("Debug - Localized content:", {
|
|
401
|
+
locale: locale || "en",
|
|
402
|
+
contentType: typeof localizedContent,
|
|
403
|
+
isArray: Array.isArray(localizedContent)
|
|
404
|
+
});
|
|
405
|
+
if (!Array.isArray(localizedContent)) {
|
|
406
|
+
throw new TypeError(`Invalid content format for localized model ${relation.model}`);
|
|
407
|
+
}
|
|
408
|
+
relatedData = localizedContent;
|
|
409
|
+
} else {
|
|
410
|
+
logger.debug("Debug - Processing non-localized model");
|
|
411
|
+
const nonLocalizedContent = relatedContent.content.default;
|
|
412
|
+
logger.debug("Debug - Raw content:", {
|
|
413
|
+
contentType: typeof nonLocalizedContent,
|
|
414
|
+
isArray: Array.isArray(nonLocalizedContent),
|
|
415
|
+
content: nonLocalizedContent
|
|
416
|
+
});
|
|
417
|
+
if (!Array.isArray(nonLocalizedContent)) {
|
|
418
|
+
throw new TypeError(`Invalid content format for non-localized model ${relation.model}`);
|
|
419
|
+
}
|
|
420
|
+
relatedData = nonLocalizedContent;
|
|
421
|
+
}
|
|
422
|
+
logger.debug("Debug - Related data ready:", {
|
|
423
|
+
dataLength: relatedData.length,
|
|
424
|
+
firstItem: relatedData[0]
|
|
425
|
+
});
|
|
329
426
|
if (!relatedData) {
|
|
330
427
|
throw new Error(`Failed to resolve relation: No data found for model ${relation.model}`);
|
|
331
428
|
}
|
|
332
429
|
if (relation.type === "one-to-one") {
|
|
333
|
-
|
|
430
|
+
logger.debug("Debug - Processing one-to-one relation");
|
|
431
|
+
const itemsWithRelation = data.filter((item) => item[relationField] !== void 0);
|
|
432
|
+
logger.debug("Debug - Items with relations:", itemsWithRelation.length);
|
|
433
|
+
return itemsWithRelation.map((item) => {
|
|
334
434
|
const relatedItem = relatedData.find((r) => r.ID === item[relationField]);
|
|
335
435
|
if (!relatedItem) {
|
|
336
436
|
throw new Error(`Failed to resolve relation: No matching item found for ID ${String(item[relationField])}`);
|
|
@@ -338,18 +438,22 @@ var _ContentLoader = class _ContentLoader {
|
|
|
338
438
|
return relatedItem;
|
|
339
439
|
});
|
|
340
440
|
} else {
|
|
441
|
+
logger.debug("Debug - Processing one-to-many relation");
|
|
341
442
|
const uniqueIds = new Set(
|
|
342
443
|
data.flatMap(
|
|
343
|
-
(item) => Array.isArray(item[relationField]) ? item[relationField] : [item[relationField]]
|
|
444
|
+
(item) => item[relationField] !== void 0 ? Array.isArray(item[relationField]) ? item[relationField] : [item[relationField]] : []
|
|
344
445
|
)
|
|
345
446
|
);
|
|
447
|
+
logger.debug("Debug - Unique IDs:", Array.from(uniqueIds));
|
|
346
448
|
const items = Array.from(uniqueIds).map((id) => relatedData.find((r) => r.ID === id)).filter(Boolean);
|
|
449
|
+
logger.debug("Debug - Matching items:", items.length);
|
|
347
450
|
if (items.length !== uniqueIds.size) {
|
|
348
451
|
throw new Error("Failed to resolve relation: Some related items not found");
|
|
349
452
|
}
|
|
350
453
|
return items;
|
|
351
454
|
}
|
|
352
455
|
} catch (error) {
|
|
456
|
+
logger.error("Debug - Error occurred:", error);
|
|
353
457
|
throw new Error(`Failed to resolve relation: ${error.message}`);
|
|
354
458
|
}
|
|
355
459
|
}
|
|
@@ -370,6 +474,11 @@ var _ContentrainQueryBuilder = class _ContentrainQueryBuilder {
|
|
|
370
474
|
this.loader = loader;
|
|
371
475
|
}
|
|
372
476
|
where(field, operator, value) {
|
|
477
|
+
logger.debug("Adding filter:", {
|
|
478
|
+
field,
|
|
479
|
+
operator,
|
|
480
|
+
value
|
|
481
|
+
});
|
|
373
482
|
this.filters.push({
|
|
374
483
|
field,
|
|
375
484
|
operator,
|
|
@@ -378,6 +487,7 @@ var _ContentrainQueryBuilder = class _ContentrainQueryBuilder {
|
|
|
378
487
|
return this;
|
|
379
488
|
}
|
|
380
489
|
include(relation) {
|
|
490
|
+
logger.debug("Adding relation:", relation);
|
|
381
491
|
if (typeof relation === "string") {
|
|
382
492
|
this.includes[relation] = {};
|
|
383
493
|
} else if (Array.isArray(relation)) {
|
|
@@ -388,6 +498,10 @@ var _ContentrainQueryBuilder = class _ContentrainQueryBuilder {
|
|
|
388
498
|
return this;
|
|
389
499
|
}
|
|
390
500
|
orderBy(field, direction = "asc") {
|
|
501
|
+
logger.debug("Adding sorting:", {
|
|
502
|
+
field,
|
|
503
|
+
direction
|
|
504
|
+
});
|
|
391
505
|
this.sorting.push({
|
|
392
506
|
field,
|
|
393
507
|
direction
|
|
@@ -395,28 +509,37 @@ var _ContentrainQueryBuilder = class _ContentrainQueryBuilder {
|
|
|
395
509
|
return this;
|
|
396
510
|
}
|
|
397
511
|
limit(count) {
|
|
512
|
+
logger.debug("Adding limit:", count);
|
|
398
513
|
this.pagination.limit = count;
|
|
399
514
|
return this;
|
|
400
515
|
}
|
|
401
516
|
offset(count) {
|
|
517
|
+
logger.debug("Adding offset:", count);
|
|
402
518
|
this.pagination.offset = count;
|
|
403
519
|
return this;
|
|
404
520
|
}
|
|
405
521
|
locale(code) {
|
|
522
|
+
logger.debug("Setting locale:", code);
|
|
406
523
|
this.options.locale = code;
|
|
407
524
|
return this;
|
|
408
525
|
}
|
|
409
526
|
cache(ttl) {
|
|
527
|
+
logger.debug("Setting cache:", {
|
|
528
|
+
enabled: true,
|
|
529
|
+
ttl
|
|
530
|
+
});
|
|
410
531
|
this.options.cache = true;
|
|
411
532
|
if (ttl)
|
|
412
533
|
this.options.ttl = ttl;
|
|
413
534
|
return this;
|
|
414
535
|
}
|
|
415
536
|
noCache() {
|
|
537
|
+
logger.debug("Disabling cache");
|
|
416
538
|
this.options.cache = false;
|
|
417
539
|
return this;
|
|
418
540
|
}
|
|
419
541
|
bypassCache() {
|
|
542
|
+
logger.debug("Bypassing cache");
|
|
420
543
|
this.options.cache = false;
|
|
421
544
|
this.options.ttl = 0;
|
|
422
545
|
return this;
|
|
@@ -432,21 +555,56 @@ var _ContentrainQueryBuilder = class _ContentrainQueryBuilder {
|
|
|
432
555
|
};
|
|
433
556
|
}
|
|
434
557
|
async get() {
|
|
558
|
+
logger.debug("Starting query:", {
|
|
559
|
+
model: this.model,
|
|
560
|
+
filterCount: this.filters.length,
|
|
561
|
+
includeCount: Object.keys(this.includes).length,
|
|
562
|
+
sortingCount: this.sorting.length,
|
|
563
|
+
pagination: this.pagination,
|
|
564
|
+
options: this.options
|
|
565
|
+
});
|
|
435
566
|
const result = await this.loader.load(this.model);
|
|
436
567
|
const modelConfig = result.model;
|
|
568
|
+
logger.debug("Model loaded:", {
|
|
569
|
+
model: this.model,
|
|
570
|
+
metadata: modelConfig.metadata,
|
|
571
|
+
contentKeys: Object.keys(result.content)
|
|
572
|
+
});
|
|
437
573
|
let data;
|
|
438
574
|
if (modelConfig.metadata.localization) {
|
|
439
575
|
const locale = this.options.locale || "en";
|
|
576
|
+
logger.debug("Selecting content for localized model:", {
|
|
577
|
+
model: this.model,
|
|
578
|
+
requestedLocale: locale,
|
|
579
|
+
availableLocales: Object.keys(result.content)
|
|
580
|
+
});
|
|
440
581
|
data = result.content[locale];
|
|
441
582
|
if (!data) {
|
|
583
|
+
logger.error("Content not found:", {
|
|
584
|
+
model: this.model,
|
|
585
|
+
locale,
|
|
586
|
+
availableLocales: Object.keys(result.content)
|
|
587
|
+
});
|
|
442
588
|
throw new Error(`Content not found for locale: ${locale}`);
|
|
443
589
|
}
|
|
444
590
|
} else {
|
|
591
|
+
logger.debug("Selecting content for non-localized model:", {
|
|
592
|
+
model: this.model,
|
|
593
|
+
contentKeys: Object.keys(result.content)
|
|
594
|
+
});
|
|
445
595
|
if (!result.content.default) {
|
|
596
|
+
logger.error("Content not found:", {
|
|
597
|
+
model: this.model,
|
|
598
|
+
contentKeys: Object.keys(result.content)
|
|
599
|
+
});
|
|
446
600
|
throw new Error(`Content not found for model: ${this.model}`);
|
|
447
601
|
}
|
|
448
602
|
data = result.content.default;
|
|
449
603
|
}
|
|
604
|
+
logger.debug("Executing query:", {
|
|
605
|
+
model: this.model,
|
|
606
|
+
dataLength: data.length
|
|
607
|
+
});
|
|
450
608
|
return this.executor.execute({
|
|
451
609
|
model: this.model,
|
|
452
610
|
data,
|
|
@@ -475,11 +633,16 @@ var _QueryExecutor = class _QueryExecutor {
|
|
|
475
633
|
this.loader = loader;
|
|
476
634
|
}
|
|
477
635
|
applyFilters(data, filters) {
|
|
478
|
-
|
|
636
|
+
logger.debug("Starting to apply filters:", {
|
|
637
|
+
dataLength: data.length,
|
|
638
|
+
filters
|
|
639
|
+
});
|
|
640
|
+
const result = data.filter((item) => {
|
|
479
641
|
return filters.every(({ field, operator, value }) => {
|
|
480
642
|
const itemValue = item[field];
|
|
481
643
|
const validOperators = ["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin", "contains", "startsWith", "endsWith"];
|
|
482
644
|
if (!validOperators.includes(operator)) {
|
|
645
|
+
logger.error("Invalid operator:", operator);
|
|
483
646
|
throw new Error(`Invalid operator: ${operator}`);
|
|
484
647
|
}
|
|
485
648
|
if (typeof itemValue === "string" && typeof value === "string") {
|
|
@@ -492,6 +655,7 @@ var _QueryExecutor = class _QueryExecutor {
|
|
|
492
655
|
case "nin":
|
|
493
656
|
return !value.includes(itemValue);
|
|
494
657
|
default:
|
|
658
|
+
logger.error("Invalid array operator:", operator);
|
|
495
659
|
throw new Error(`Invalid array operator: ${operator}`);
|
|
496
660
|
}
|
|
497
661
|
}
|
|
@@ -502,6 +666,7 @@ var _QueryExecutor = class _QueryExecutor {
|
|
|
502
666
|
case "nin":
|
|
503
667
|
return !value.some((v) => itemValue.includes(v));
|
|
504
668
|
default:
|
|
669
|
+
logger.error("Invalid array operator:", operator);
|
|
505
670
|
throw new Error(`Invalid array operator: ${operator}`);
|
|
506
671
|
}
|
|
507
672
|
}
|
|
@@ -524,6 +689,11 @@ var _QueryExecutor = class _QueryExecutor {
|
|
|
524
689
|
return false;
|
|
525
690
|
});
|
|
526
691
|
});
|
|
692
|
+
logger.debug("Filter application completed:", {
|
|
693
|
+
initialCount: data.length,
|
|
694
|
+
resultCount: result.length
|
|
695
|
+
});
|
|
696
|
+
return result;
|
|
527
697
|
}
|
|
528
698
|
applySorting(data, sorting) {
|
|
529
699
|
return [...data].sort((a, b) => {
|
|
@@ -547,15 +717,26 @@ var _QueryExecutor = class _QueryExecutor {
|
|
|
547
717
|
return data.slice(offset, offset + limit);
|
|
548
718
|
}
|
|
549
719
|
async resolveIncludes(model, data, includes, options) {
|
|
720
|
+
logger.debug("Starting to resolve relations:", {
|
|
721
|
+
model,
|
|
722
|
+
dataLength: data.length,
|
|
723
|
+
includes,
|
|
724
|
+
options
|
|
725
|
+
});
|
|
550
726
|
const result = [...data];
|
|
551
727
|
for (const [field, config] of Object.entries(includes)) {
|
|
728
|
+
logger.debug(`Resolving relation "${field}"`);
|
|
552
729
|
const relations = await this.loader.resolveRelation(
|
|
553
730
|
model,
|
|
554
731
|
field,
|
|
555
732
|
result,
|
|
556
733
|
options.locale
|
|
557
734
|
);
|
|
735
|
+
logger.debug(`Relation "${field}" resolved:`, {
|
|
736
|
+
foundRelationsCount: relations.length
|
|
737
|
+
});
|
|
558
738
|
if (config.include && relations.length) {
|
|
739
|
+
logger.debug(`Resolving nested relations for "${field}":`, config.include);
|
|
559
740
|
await this.resolveIncludes(
|
|
560
741
|
field,
|
|
561
742
|
relations,
|
|
@@ -576,6 +757,7 @@ var _QueryExecutor = class _QueryExecutor {
|
|
|
576
757
|
}
|
|
577
758
|
item._relations[field] = Array.isArray(value) ? relatedItems : relatedItems[0];
|
|
578
759
|
});
|
|
760
|
+
logger.debug(`Data added for relation "${field}"`);
|
|
579
761
|
}
|
|
580
762
|
return result;
|
|
581
763
|
}
|
|
@@ -606,17 +788,37 @@ var _QueryExecutor = class _QueryExecutor {
|
|
|
606
788
|
pagination = {},
|
|
607
789
|
options = {}
|
|
608
790
|
}) {
|
|
791
|
+
logger.debug("Starting execution:", {
|
|
792
|
+
model,
|
|
793
|
+
dataLength: data.length,
|
|
794
|
+
filterCount: filters.length,
|
|
795
|
+
includeCount: Object.keys(includes).length,
|
|
796
|
+
sortingCount: sorting.length,
|
|
797
|
+
pagination,
|
|
798
|
+
options
|
|
799
|
+
});
|
|
609
800
|
let result = [...data];
|
|
610
801
|
if (filters.length) {
|
|
802
|
+
logger.debug("Applying filters:", filters);
|
|
611
803
|
result = this.applyFilters(result, filters);
|
|
804
|
+
logger.debug("Remaining items after filtering:", result.length);
|
|
612
805
|
}
|
|
613
806
|
if (Object.keys(includes).length) {
|
|
807
|
+
logger.debug("Resolving relations:", includes);
|
|
614
808
|
result = await this.resolveIncludes(model, result, includes, options);
|
|
809
|
+
logger.debug("Items after relation resolution:", result.length);
|
|
615
810
|
}
|
|
616
811
|
if (sorting.length) {
|
|
812
|
+
logger.debug("Applying sorting:", sorting);
|
|
617
813
|
result = this.applySorting(result, sorting);
|
|
618
814
|
}
|
|
619
815
|
const paginatedData = this.applyPagination(result, pagination.limit, pagination.offset);
|
|
816
|
+
logger.debug("After pagination:", {
|
|
817
|
+
totalCount: result.length,
|
|
818
|
+
pageSize: paginatedData.length,
|
|
819
|
+
offset: pagination.offset || 0,
|
|
820
|
+
hasMore: (pagination.offset || 0) + paginatedData.length < result.length
|
|
821
|
+
});
|
|
620
822
|
return {
|
|
621
823
|
data: paginatedData,
|
|
622
824
|
total: result.length,
|
|
@@ -665,5 +867,6 @@ exports.ContentrainQueryBuilder = ContentrainQueryBuilder;
|
|
|
665
867
|
exports.ContentrainSDK = ContentrainSDK;
|
|
666
868
|
exports.MemoryCache = MemoryCache;
|
|
667
869
|
exports.QueryExecutor = QueryExecutor;
|
|
870
|
+
exports.logger = logger;
|
|
668
871
|
//# sourceMappingURL=index.js.map
|
|
669
872
|
//# sourceMappingURL=index.js.map
|