New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@contentrain/query

Package Overview
Dependencies
Maintainers
0
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@contentrain/query - npm Package Compare versions

Comparing version 3.1.0 to 3.2.0

7

dist/index.d.ts

@@ -275,2 +275,7 @@ interface ContentrainConfig {

declare const logger: {
debug: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
};
declare class ContentrainSDK {

@@ -287,2 +292,2 @@ private loader;

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 };
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 };

@@ -6,5 +6,21 @@ 'use strict';

var tinyLru = require('tiny-lru');
var process = require('process');
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var isDevelopment = process.env.NODE_ENV === "development";
var logger = {
debug: /* @__PURE__ */ __name((...args) => {
if (isDevelopment) {
console.log(...args);
}
}, "debug"),
error: /* @__PURE__ */ __name((...args) => {
if (isDevelopment) {
console.error(...args);
}
}, "error")
};
// src/cache/memory.ts
var _MemoryCache = class _MemoryCache {

@@ -33,2 +49,6 @@ constructor(options = {}) {

async set(key, data, ttl) {
logger.debug("Saving data to cache:", {
key,
ttl
});
await this.cleanupCache();

@@ -56,2 +76,6 @@ const size = this.calculateSize(data);

this.stats.size += size;
logger.debug("Data saved to cache:", {
key,
expiry: expireAt ? new Date(expireAt).toISOString() : "no expiry"
});
}

@@ -71,4 +95,6 @@ findOldestKey() {

async get(key) {
logger.debug("Getting data from cache:", { key });
const entry = this.cache.get(key);
if (!entry) {
logger.debug("Data not found in cache:", { key });
this.stats.misses++;

@@ -82,2 +108,6 @@ return null;

}
logger.debug("Data retrieved from cache:", {
key,
expiry: entry.expireAt ? new Date(entry.expireAt).toISOString() : "no expiry"
});
this.stats.hits++;

@@ -87,2 +117,3 @@ return entry.data;

async delete(key) {
logger.debug("Deleting data from cache:", { key });
const entry = this.cache.get(key);

@@ -93,4 +124,6 @@ if (entry) {

}
logger.debug("Data deleted from cache:", { key });
}
async clear() {
logger.debug("Clearing cache");
this.cache.clear();

@@ -103,2 +136,3 @@ this.stats = {

};
logger.debug("Cache cleared");
}

@@ -146,3 +180,3 @@ async cleanupCache() {

ttl: 60 * 1e3,
// 1 dakika
// 1 minute
maxCacheSize: 100,

@@ -181,2 +215,6 @@ // 100 MB

if (!modelMetadata) {
logger.error("Model metadata not found:", {
model,
metadataPath
});
throw new Error(`Model metadata not found for ${model}`);

@@ -192,2 +230,6 @@ }

} catch (error) {
logger.error("Failed to load model config:", {
model,
error: error?.message || "Unknown error"
});
throw new Error(`Failed to load model config for ${model}: ${error?.message || "Unknown error"}`);

@@ -203,2 +245,5 @@ }

if (!this.options.defaultLocale) {
logger.error("Default locale is required for localized model:", {
model
});
throw new Error(`Default locale is required for localized model "${model}"`);

@@ -224,2 +269,7 @@ }

} catch {
logger.error("Failed to load content:", {
model,
locale,
contentPath
});
throw new Error(`Failed to load content: Invalid JSON format in ${contentPath}`);

@@ -229,2 +279,6 @@ }

if (error.message.includes("Invalid JSON format")) {
logger.error("Failed to load content:", {
model,
locale
});
throw error;

@@ -314,3 +368,3 @@ }

}
let assets;
let assets = [];
try {

@@ -336,10 +390,53 @@ const assetsPath = path.join(this.options.contentDir, "assets.json");

try {
logger.debug("Debug - Starting relation resolution:", {
model,
relationField,
dataLength: data.length,
locale
});
const relations = this.relations.get(model);
logger.debug("Debug - Relations:", relations);
if (!relations)
throw new Error(`No relations found for model: ${model}`);
const relation = relations.find((r) => r.foreignKey === relationField);
logger.debug("Debug - Found relation:", relation);
if (!relation)
throw new Error(`No relation found for field: ${String(relationField)}`);
logger.debug("Debug - Related model loading:", relation.model);
const relatedContent = await this.load(relation.model);
const relatedData = locale ? relatedContent.content[locale] : relatedContent.content.en;
logger.debug("Debug - \u0130li\u015Fkili model y\xFCklendi:", {
model: relation.model,
metadata: relatedContent.model.metadata,
contentKeys: Object.keys(relatedContent.content)
});
let relatedData;
if (relatedContent.model.metadata.localization) {
logger.debug("Debug - Processing localized model");
const localizedContent = locale ? relatedContent.content[locale] : relatedContent.content.en;
logger.debug("Debug - Localized content:", {
locale: locale || "en",
contentType: typeof localizedContent,
isArray: Array.isArray(localizedContent)
});
if (!Array.isArray(localizedContent)) {
throw new TypeError(`Invalid content format for localized model ${relation.model}`);
}
relatedData = localizedContent;
} else {
logger.debug("Debug - Processing non-localized model");
const nonLocalizedContent = relatedContent.content.default;
logger.debug("Debug - Raw content:", {
contentType: typeof nonLocalizedContent,
isArray: Array.isArray(nonLocalizedContent),
content: nonLocalizedContent
});
if (!Array.isArray(nonLocalizedContent)) {
throw new TypeError(`Invalid content format for non-localized model ${relation.model}`);
}
relatedData = nonLocalizedContent;
}
logger.debug("Debug - Related data ready:", {
dataLength: relatedData.length,
firstItem: relatedData[0]
});
if (!relatedData) {

@@ -349,3 +446,6 @@ throw new Error(`Failed to resolve relation: No data found for model ${relation.model}`);

if (relation.type === "one-to-one") {
return data.map((item) => {
logger.debug("Debug - Processing one-to-one relation");
const itemsWithRelation = data.filter((item) => item[relationField] !== void 0);
logger.debug("Debug - Items with relations:", itemsWithRelation.length);
return itemsWithRelation.map((item) => {
const relatedItem = relatedData.find((r) => r.ID === item[relationField]);

@@ -358,8 +458,11 @@ if (!relatedItem) {

} else {
logger.debug("Debug - Processing one-to-many relation");
const uniqueIds = new Set(
data.flatMap(
(item) => Array.isArray(item[relationField]) ? item[relationField] : [item[relationField]]
(item) => item[relationField] !== void 0 ? Array.isArray(item[relationField]) ? item[relationField] : [item[relationField]] : []
)
);
logger.debug("Debug - Unique IDs:", Array.from(uniqueIds));
const items = Array.from(uniqueIds).map((id) => relatedData.find((r) => r.ID === id)).filter(Boolean);
logger.debug("Debug - Matching items:", items.length);
if (items.length !== uniqueIds.size) {

@@ -371,2 +474,3 @@ throw new Error("Failed to resolve relation: Some related items not found");

} catch (error) {
logger.error("Debug - Error occurred:", error);
throw new Error(`Failed to resolve relation: ${error.message}`);

@@ -392,2 +496,7 @@ }

where(field, operator, value) {
logger.debug("Adding filter:", {
field,
operator,
value
});
this.filters.push({

@@ -401,2 +510,3 @@ field,

include(relation) {
logger.debug("Adding relation:", relation);
if (typeof relation === "string") {

@@ -412,2 +522,6 @@ this.includes[relation] = {};

orderBy(field, direction = "asc") {
logger.debug("Adding sorting:", {
field,
direction
});
this.sorting.push({

@@ -420,2 +534,3 @@ field,

limit(count) {
logger.debug("Adding limit:", count);
this.pagination.limit = count;

@@ -425,2 +540,3 @@ return this;

offset(count) {
logger.debug("Adding offset:", count);
this.pagination.offset = count;

@@ -430,2 +546,3 @@ return this;

locale(code) {
logger.debug("Setting locale:", code);
this.options.locale = code;

@@ -435,2 +552,6 @@ return this;

cache(ttl) {
logger.debug("Setting cache:", {
enabled: true,
ttl
});
this.options.cache = true;

@@ -442,2 +563,3 @@ if (ttl)

noCache() {
logger.debug("Disabling cache");
this.options.cache = false;

@@ -447,2 +569,3 @@ return this;

bypassCache() {
logger.debug("Bypassing cache");
this.options.cache = false;

@@ -463,13 +586,44 @@ this.options.ttl = 0;

async get() {
logger.debug("Starting query:", {
model: this.model,
filterCount: this.filters.length,
includeCount: Object.keys(this.includes).length,
sortingCount: this.sorting.length,
pagination: this.pagination,
options: this.options
});
const result = await this.loader.load(this.model);
const modelConfig = result.model;
logger.debug("Model loaded:", {
model: this.model,
metadata: modelConfig.metadata,
contentKeys: Object.keys(result.content)
});
let data;
if (modelConfig.metadata.localization) {
const locale = this.options.locale || "en";
logger.debug("Selecting content for localized model:", {
model: this.model,
requestedLocale: locale,
availableLocales: Object.keys(result.content)
});
data = result.content[locale];
if (!data) {
logger.error("Content not found:", {
model: this.model,
locale,
availableLocales: Object.keys(result.content)
});
throw new Error(`Content not found for locale: ${locale}`);
}
} else {
logger.debug("Selecting content for non-localized model:", {
model: this.model,
contentKeys: Object.keys(result.content)
});
if (!result.content.default) {
logger.error("Content not found:", {
model: this.model,
contentKeys: Object.keys(result.content)
});
throw new Error(`Content not found for model: ${this.model}`);

@@ -479,2 +633,6 @@ }

}
logger.debug("Executing query:", {
model: this.model,
dataLength: data.length
});
return this.executor.execute({

@@ -508,3 +666,7 @@ model: this.model,

applyFilters(data, filters) {
return data.filter((item) => {
logger.debug("Starting to apply filters:", {
dataLength: data.length,
filters
});
const result = data.filter((item) => {
return filters.every(({ field, operator, value }) => {

@@ -514,2 +676,3 @@ const itemValue = item[field];

if (!validOperators.includes(operator)) {
logger.error("Invalid operator:", operator);
throw new Error(`Invalid operator: ${operator}`);

@@ -527,2 +690,3 @@ }

default:
logger.error("Invalid array operator:", operator);
throw new Error(`Invalid array operator: ${operator}`);

@@ -538,2 +702,3 @@ }

default:
logger.error("Invalid array operator:", operator);
throw new Error(`Invalid array operator: ${operator}`);

@@ -561,2 +726,7 @@ }

});
logger.debug("Filter application completed:", {
initialCount: data.length,
resultCount: result.length
});
return result;
}

@@ -585,4 +755,11 @@ applySorting(data, sorting) {

async resolveIncludes(model, data, includes, options) {
logger.debug("Starting to resolve relations:", {
model,
dataLength: data.length,
includes,
options
});
const result = [...data];
for (const [field, config] of Object.entries(includes)) {
logger.debug(`Resolving relation "${field}"`);
const relations = await this.loader.resolveRelation(

@@ -594,3 +771,7 @@ model,

);
logger.debug(`Relation "${field}" resolved:`, {
foundRelationsCount: relations.length
});
if (config.include && relations.length) {
logger.debug(`Resolving nested relations for "${field}":`, config.include);
await this.resolveIncludes(

@@ -616,2 +797,3 @@ field,

});
logger.debug(`Data added for relation "${field}"`);
}

@@ -647,13 +829,33 @@ return result;

}) {
logger.debug("Starting execution:", {
model,
dataLength: data.length,
filterCount: filters.length,
includeCount: Object.keys(includes).length,
sortingCount: sorting.length,
pagination,
options
});
let result = [...data];
if (filters.length) {
logger.debug("Applying filters:", filters);
result = this.applyFilters(result, filters);
logger.debug("Remaining items after filtering:", result.length);
}
if (Object.keys(includes).length) {
logger.debug("Resolving relations:", includes);
result = await this.resolveIncludes(model, result, includes, options);
logger.debug("Items after relation resolution:", result.length);
}
if (sorting.length) {
logger.debug("Applying sorting:", sorting);
result = this.applySorting(result, sorting);
}
const paginatedData = this.applyPagination(result, pagination.limit, pagination.offset);
logger.debug("After pagination:", {
totalCount: result.length,
pageSize: paginatedData.length,
offset: pagination.offset || 0,
hasMore: (pagination.offset || 0) + paginatedData.length < result.length
});
return {

@@ -707,3 +909,4 @@ data: paginatedData,

exports.QueryExecutor = QueryExecutor;
exports.logger = logger;
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map

4

package.json
{
"name": "@contentrain/query",
"version": "3.1.0",
"version": "3.2.0",
"description": "Core package for Contentrain SDK, providing fundamental functionality and types",

@@ -43,4 +43,4 @@ "author": "Contentrain Inc.",

"scripts": {
"dev": "NODE_ENV=development tsup --watch",
"build": "tsup && rm -rf dist/types dist/cache dist/loader dist/query",
"dev": "tsup --watch",
"dev:watch": "tsup --watch",

@@ -47,0 +47,0 @@ "test": "vitest watch",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc