@fjell/lib-sequelize 4.4.80 → 4.4.82
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/QueryBuilder.d.ts.map +1 -1
- package/dist/errors/sequelizeErrorHandler.d.ts.map +1 -1
- package/dist/index.js +250 -95
- package/dist/index.js.map +3 -3
- package/dist/ops/create.d.ts.map +1 -1
- package/dist/ops/find.d.ts.map +1 -1
- package/dist/ops/upsert.d.ts.map +1 -1
- package/dist/processing/ReferenceBuilder.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -941,12 +941,30 @@ var buildSequelizeReference = async (item, referenceDefinition, registry, contex
|
|
|
941
941
|
);
|
|
942
942
|
}
|
|
943
943
|
if (!registry) {
|
|
944
|
+
libLogger3.error("Registry not provided for reference processing", {
|
|
945
|
+
component: "lib-sequelize",
|
|
946
|
+
subcomponent: "ReferenceBuilder",
|
|
947
|
+
operation: "buildSequelizeReference",
|
|
948
|
+
property: referenceDefinition.property,
|
|
949
|
+
kta: referenceDefinition.kta,
|
|
950
|
+
column: referenceDefinition.column,
|
|
951
|
+
suggestion: "Ensure registry is passed to library configuration"
|
|
952
|
+
});
|
|
944
953
|
throw new Error(
|
|
945
|
-
`This model definition has a reference definition, but the registry is not present. Reference property: '${referenceDefinition.property}', key types: [${referenceDefinition.kta.join(", ")}], column: '${referenceDefinition.column}'
|
|
954
|
+
`This model definition has a reference definition, but the registry is not present. Reference property: '${referenceDefinition.property}', key types: [${referenceDefinition.kta.join(", ")}], column: '${referenceDefinition.column}'. Suggestion: Pass registry to library initialization.`
|
|
946
955
|
);
|
|
947
956
|
}
|
|
948
957
|
const library = registry.get(referenceDefinition.kta);
|
|
949
958
|
if (!library) {
|
|
959
|
+
libLogger3.error("Referenced library not found in registry", {
|
|
960
|
+
component: "lib-sequelize",
|
|
961
|
+
subcomponent: "ReferenceBuilder",
|
|
962
|
+
operation: "buildSequelizeReference",
|
|
963
|
+
property: referenceDefinition.property,
|
|
964
|
+
kta: referenceDefinition.kta,
|
|
965
|
+
column: referenceDefinition.column,
|
|
966
|
+
suggestion: `Register a library for [${referenceDefinition.kta.join(", ")}] in the registry`
|
|
967
|
+
});
|
|
950
968
|
throw new Error(
|
|
951
969
|
`This model definition has a reference definition, but the dependency is not present in registry. Reference property: '${referenceDefinition.property}', missing key type: '${primaryKeyType}', column: '${referenceDefinition.column}'`
|
|
952
970
|
);
|
|
@@ -1037,6 +1055,18 @@ var buildSequelizeReference = async (item, referenceDefinition, registry, contex
|
|
|
1037
1055
|
referencedItem = await library.operations.get(itemKey);
|
|
1038
1056
|
context.setCached(itemKey, referencedItem);
|
|
1039
1057
|
} catch (error) {
|
|
1058
|
+
libLogger3.error("Failed to load reference", {
|
|
1059
|
+
component: "lib-sequelize",
|
|
1060
|
+
subcomponent: "ReferenceBuilder",
|
|
1061
|
+
operation: "buildSequelizeReference",
|
|
1062
|
+
property: referenceDefinition.property,
|
|
1063
|
+
referenceKey: JSON.stringify(itemKey),
|
|
1064
|
+
referencedItemType: primaryKeyType,
|
|
1065
|
+
errorType: error?.constructor?.name,
|
|
1066
|
+
errorMessage: error?.message,
|
|
1067
|
+
errorCode: error?.code || error?.errorInfo?.code,
|
|
1068
|
+
suggestion: "Check referenced item exists, registry is configured, and database connectivity"
|
|
1069
|
+
});
|
|
1040
1070
|
throw error;
|
|
1041
1071
|
} finally {
|
|
1042
1072
|
context.markComplete(itemKey);
|
|
@@ -1305,6 +1335,7 @@ import {
|
|
|
1305
1335
|
DuplicateError,
|
|
1306
1336
|
ValidationError
|
|
1307
1337
|
} from "@fjell/core";
|
|
1338
|
+
var logger7 = logger_default.get("sequelize", "errors", "errorHandler");
|
|
1308
1339
|
function transformSequelizeError(error, itemType, key, modelName, itemData) {
|
|
1309
1340
|
if (error.code === "23505" || error.original?.code === "23505") {
|
|
1310
1341
|
const constraint = error.original?.constraint;
|
|
@@ -1318,6 +1349,16 @@ function transformSequelizeError(error, itemType, key, modelName, itemData) {
|
|
|
1318
1349
|
message = `${itemType} already exists`;
|
|
1319
1350
|
}
|
|
1320
1351
|
const field = error.fields ? Object.keys(error.fields)[0] : "unique constraint";
|
|
1352
|
+
logger7.debug("Transformed PostgreSQL unique constraint error to DuplicateError", {
|
|
1353
|
+
component: "lib-sequelize",
|
|
1354
|
+
transformation: "sequelizeErrorHandler",
|
|
1355
|
+
originalError: "PostgreSQL 23505",
|
|
1356
|
+
transformedError: "DuplicateError",
|
|
1357
|
+
itemType,
|
|
1358
|
+
constraint,
|
|
1359
|
+
field,
|
|
1360
|
+
model: modelName
|
|
1361
|
+
});
|
|
1321
1362
|
return new DuplicateError(message, key, field);
|
|
1322
1363
|
}
|
|
1323
1364
|
if (error.name === "SequelizeUniqueConstraintError" || error.code === "ER_DUP_ENTRY") {
|
|
@@ -1458,6 +1499,16 @@ function transformSequelizeError(error, itemType, key, modelName, itemData) {
|
|
|
1458
1499
|
);
|
|
1459
1500
|
}
|
|
1460
1501
|
if (error.name === "SequelizeConnectionError" || error.name === "SequelizeConnectionRefusedError") {
|
|
1502
|
+
logger7.error("Transformed database connection error to BusinessLogicError", {
|
|
1503
|
+
component: "lib-sequelize",
|
|
1504
|
+
transformation: "sequelizeErrorHandler",
|
|
1505
|
+
originalError: error.name,
|
|
1506
|
+
transformedError: "BusinessLogicError",
|
|
1507
|
+
itemType,
|
|
1508
|
+
retryable: true,
|
|
1509
|
+
model: modelName,
|
|
1510
|
+
suggestion: "Check database is running, connection string is correct, and network connectivity"
|
|
1511
|
+
});
|
|
1461
1512
|
return new BusinessLogicError(
|
|
1462
1513
|
"Database connection failed",
|
|
1463
1514
|
"Check database connectivity and try again",
|
|
@@ -1466,6 +1517,16 @@ function transformSequelizeError(error, itemType, key, modelName, itemData) {
|
|
|
1466
1517
|
);
|
|
1467
1518
|
}
|
|
1468
1519
|
if (error.name === "SequelizeTimeoutError") {
|
|
1520
|
+
logger7.error("Transformed database timeout error to BusinessLogicError", {
|
|
1521
|
+
component: "lib-sequelize",
|
|
1522
|
+
transformation: "sequelizeErrorHandler",
|
|
1523
|
+
originalError: "SequelizeTimeoutError",
|
|
1524
|
+
transformedError: "BusinessLogicError",
|
|
1525
|
+
itemType,
|
|
1526
|
+
retryable: true,
|
|
1527
|
+
model: modelName,
|
|
1528
|
+
suggestion: "Reduce query complexity, add indexes, or increase timeout limits"
|
|
1529
|
+
});
|
|
1469
1530
|
return new BusinessLogicError(
|
|
1470
1531
|
"Database operation timed out",
|
|
1471
1532
|
"Try again or simplify the operation",
|
|
@@ -1489,7 +1550,7 @@ function transformSequelizeError(error, itemType, key, modelName, itemData) {
|
|
|
1489
1550
|
}
|
|
1490
1551
|
|
|
1491
1552
|
// src/metrics/QueryMetrics.ts
|
|
1492
|
-
var
|
|
1553
|
+
var logger8 = logger_default.get("sequelize", "metrics", "QueryMetrics");
|
|
1493
1554
|
var QueryMetrics = class {
|
|
1494
1555
|
totalQueryCount = 0;
|
|
1495
1556
|
queriesByModel = /* @__PURE__ */ new Map();
|
|
@@ -1504,7 +1565,7 @@ var QueryMetrics = class {
|
|
|
1504
1565
|
this.queriesByModel.set(modelName, currentCount + 1);
|
|
1505
1566
|
if (this.totalQueryCount % this.LOG_INTERVAL === 0) {
|
|
1506
1567
|
const modelBreakdown = Array.from(this.queriesByModel.entries()).map(([model, count]) => `${model}: ${count}`).join(", ");
|
|
1507
|
-
|
|
1568
|
+
logger8.debug(
|
|
1508
1569
|
`Query execution count: ${this.totalQueryCount} total queries. Breakdown by model: ${modelBreakdown || "none"}`
|
|
1509
1570
|
);
|
|
1510
1571
|
}
|
|
@@ -1538,7 +1599,7 @@ var QueryMetrics = class {
|
|
|
1538
1599
|
var queryMetrics = new QueryMetrics();
|
|
1539
1600
|
|
|
1540
1601
|
// src/ops/all.ts
|
|
1541
|
-
var
|
|
1602
|
+
var logger9 = logger_default.get("sequelize", "ops", "all");
|
|
1542
1603
|
var mergeIncludes = (existingIncludes, newIncludes) => {
|
|
1543
1604
|
const mergedIncludes = [...existingIncludes];
|
|
1544
1605
|
for (const newInclude of newIncludes) {
|
|
@@ -1565,7 +1626,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1565
1626
|
async (itemQuery, locations, allOptions) => {
|
|
1566
1627
|
try {
|
|
1567
1628
|
const locs = locations ?? [];
|
|
1568
|
-
|
|
1629
|
+
logger9.debug(`ALL operation called on ${models[0].name} with ${locs.length} location filters: ${locs.map((loc2) => `${loc2.kt}=${loc2.lk}`).join(", ") || "none"}`);
|
|
1569
1630
|
const loc = locs;
|
|
1570
1631
|
const model = models[0];
|
|
1571
1632
|
let options = buildQuery(itemQuery ?? {}, model, references, registry);
|
|
@@ -1590,7 +1651,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1590
1651
|
const relationshipInfo = buildRelationshipPath(model, locKey.kt, kta, true);
|
|
1591
1652
|
if (!relationshipInfo.found) {
|
|
1592
1653
|
const errorMessage = `Location key '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
1593
|
-
|
|
1654
|
+
logger9.error(errorMessage, { locations: loc, kta });
|
|
1594
1655
|
throw new Error(errorMessage);
|
|
1595
1656
|
}
|
|
1596
1657
|
if (relationshipInfo.isDirect) {
|
|
@@ -1601,31 +1662,31 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1601
1662
|
}
|
|
1602
1663
|
for (const locKey of directLocations) {
|
|
1603
1664
|
if (locKey.lk === void 0 || locKey.lk == null || locKey.lk === "" || typeof locKey.lk === "object" && Object.keys(locKey.lk).length === 0) {
|
|
1604
|
-
|
|
1665
|
+
logger9.error(`Location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`, { locKey, locations: loc });
|
|
1605
1666
|
throw new Error(`Location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`);
|
|
1606
1667
|
}
|
|
1607
1668
|
const foreignKeyField = locKey.kt + "Id";
|
|
1608
1669
|
if (options.where[foreignKeyField]) {
|
|
1609
|
-
|
|
1670
|
+
logger9.debug(`[ALL] Field ${foreignKeyField} already constrained by itemQuery, skipping location constraint to avoid conflicts`);
|
|
1610
1671
|
continue;
|
|
1611
1672
|
}
|
|
1612
|
-
|
|
1673
|
+
logger9.trace(`[ALL] Setting direct location where clause: ${foreignKeyField} = ${stringifyJSON(locKey.lk)} (type: ${typeof locKey.lk})`);
|
|
1613
1674
|
options.where[foreignKeyField] = {
|
|
1614
1675
|
[Op2.eq]: locKey.lk
|
|
1615
1676
|
};
|
|
1616
1677
|
}
|
|
1617
1678
|
for (const locKey of hierarchicalLocations) {
|
|
1618
1679
|
if (locKey.lk === void 0 || locKey.lk == null || locKey.lk === "" || typeof locKey.lk === "object" && Object.keys(locKey.lk).length === 0) {
|
|
1619
|
-
|
|
1680
|
+
logger9.error(`Hierarchical location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`, { locKey, locations: loc });
|
|
1620
1681
|
throw new Error(`Hierarchical location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`);
|
|
1621
1682
|
}
|
|
1622
1683
|
const relationshipInfo = buildRelationshipPath(model, locKey.kt, kta);
|
|
1623
1684
|
if (relationshipInfo.found && relationshipInfo.path) {
|
|
1624
1685
|
if (options.where[relationshipInfo.path]) {
|
|
1625
|
-
|
|
1686
|
+
logger9.debug(`[ALL] Field ${relationshipInfo.path} already constrained by itemQuery, skipping hierarchical location constraint to avoid conflicts`);
|
|
1626
1687
|
continue;
|
|
1627
1688
|
}
|
|
1628
|
-
|
|
1689
|
+
logger9.trace(`[ALL] Setting hierarchical location where clause: ${relationshipInfo.path} = ${stringifyJSON(locKey.lk)} (type: ${typeof locKey.lk})`);
|
|
1629
1690
|
options.where[relationshipInfo.path] = {
|
|
1630
1691
|
[Op2.eq]: locKey.lk
|
|
1631
1692
|
};
|
|
@@ -1643,7 +1704,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1643
1704
|
const effectiveOffset = allOptions?.offset ?? itemQuery?.offset ?? 0;
|
|
1644
1705
|
const whereFields = options.where ? Object.keys(options.where).join(", ") : "none";
|
|
1645
1706
|
const includeCount = options.include?.length || 0;
|
|
1646
|
-
|
|
1707
|
+
logger9.default(
|
|
1647
1708
|
`All query configured for ${model.name} with where fields: ${whereFields}, includes: ${includeCount}, limit: ${effectiveLimit}, offset: ${effectiveOffset}`
|
|
1648
1709
|
);
|
|
1649
1710
|
const countOptions = {
|
|
@@ -1656,7 +1717,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1656
1717
|
queryMetrics.recordQuery(model.name);
|
|
1657
1718
|
const countResult = await model.count(countOptions);
|
|
1658
1719
|
const total = Array.isArray(countResult) ? countResult.length : countResult;
|
|
1659
|
-
|
|
1720
|
+
logger9.debug(`[ALL] Total count for ${model.name}: ${total}`);
|
|
1660
1721
|
delete options.limit;
|
|
1661
1722
|
delete options.offset;
|
|
1662
1723
|
if (effectiveLimit !== void 0) {
|
|
@@ -1666,9 +1727,9 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1666
1727
|
options.offset = effectiveOffset;
|
|
1667
1728
|
}
|
|
1668
1729
|
try {
|
|
1669
|
-
|
|
1730
|
+
logger9.trace(`[ALL] Executing ${model.name}.findAll() with options: ${JSON.stringify(options, null, 2)}`);
|
|
1670
1731
|
} catch {
|
|
1671
|
-
|
|
1732
|
+
logger9.trace(`[ALL] Executing ${model.name}.findAll() with options containing non-serializable operators (${Object.keys(options.where || {}).length} where conditions)`);
|
|
1672
1733
|
}
|
|
1673
1734
|
queryMetrics.recordQuery(model.name);
|
|
1674
1735
|
const matchingItems = await model.findAll(options);
|
|
@@ -1686,7 +1747,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1686
1747
|
);
|
|
1687
1748
|
return validateKeys(processedRow, coordinate.kta);
|
|
1688
1749
|
}));
|
|
1689
|
-
|
|
1750
|
+
logger9.debug(`[ALL] Returning ${items.length} of ${total} ${model.name} records`);
|
|
1690
1751
|
return {
|
|
1691
1752
|
items,
|
|
1692
1753
|
metadata: {
|
|
@@ -1707,7 +1768,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1707
1768
|
// src/ops/create.ts
|
|
1708
1769
|
import { createCreateWrapper, isComKey as isComKey3, isPriKey as isPriKey3 } from "@fjell/core";
|
|
1709
1770
|
import { validateKeys as validateKeys2 } from "@fjell/core/validation";
|
|
1710
|
-
var
|
|
1771
|
+
var logger10 = logger_default.get("sequelize", "ops", "create");
|
|
1711
1772
|
async function validateHierarchicalChain(models, locKey, kta) {
|
|
1712
1773
|
const locatorIndex = kta.indexOf(locKey.kt);
|
|
1713
1774
|
if (locatorIndex === -1) {
|
|
@@ -1749,8 +1810,8 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1749
1810
|
coordinate,
|
|
1750
1811
|
async (item, options) => {
|
|
1751
1812
|
const constraints = options?.key ? `key: pk=${options.key.pk}, loc=[${isComKey3(options.key) ? options.key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ") : ""}]` : options?.locations ? `locations: ${options.locations.map((loc) => `${loc.kt}=${loc.lk}`).join(", ")}` : "no constraints";
|
|
1752
|
-
|
|
1753
|
-
|
|
1813
|
+
logger10.debug(`CREATE operation called on ${models[0].name} with ${constraints}`);
|
|
1814
|
+
logger10.default(`Create configured for ${models[0].name} with ${Object.keys(item).length} item fields`);
|
|
1754
1815
|
const model = models[0];
|
|
1755
1816
|
const modelAttributes = model.getAttributes();
|
|
1756
1817
|
let itemData = { ...item };
|
|
@@ -1770,9 +1831,18 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1770
1831
|
}
|
|
1771
1832
|
if (invalidAttributes.length > 0) {
|
|
1772
1833
|
const availableAttributes = Object.keys(modelAttributes).join(", ");
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1834
|
+
const errorMessage = `Invalid attributes for model '${model.name}': [${invalidAttributes.join(", ")}]. Available attributes: [${availableAttributes}].`;
|
|
1835
|
+
logger10.error("Create operation failed - invalid attributes", {
|
|
1836
|
+
operation: "create",
|
|
1837
|
+
model: model.name,
|
|
1838
|
+
invalidAttributes,
|
|
1839
|
+
availableAttributes: Object.keys(modelAttributes),
|
|
1840
|
+
providedAttributes: Object.keys(itemData),
|
|
1841
|
+
itemData: JSON.stringify(itemData, null, 2),
|
|
1842
|
+
suggestion: `Remove invalid attributes or add them to the model definition. Valid attributes are: ${availableAttributes}`,
|
|
1843
|
+
coordinate: JSON.stringify(definition.coordinate)
|
|
1844
|
+
});
|
|
1845
|
+
throw new Error(errorMessage + ` Item data: ${JSON.stringify(itemData, null, 2)}`);
|
|
1776
1846
|
}
|
|
1777
1847
|
if (options?.key) {
|
|
1778
1848
|
const key = options.key;
|
|
@@ -1788,7 +1858,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1788
1858
|
if (!relationshipInfo.found) {
|
|
1789
1859
|
const associations = model.associations ? Object.keys(model.associations) : [];
|
|
1790
1860
|
const errorMessage = `Composite key locator '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships. Available associations: [${associations.join(", ")}]. KTA: [${kta.join(", ")}]. Composite key: ${JSON.stringify(comKey, null, 2)}`;
|
|
1791
|
-
|
|
1861
|
+
logger10.error(errorMessage, { key: comKey, kta, associations });
|
|
1792
1862
|
throw new Error(errorMessage);
|
|
1793
1863
|
}
|
|
1794
1864
|
if (relationshipInfo.isDirect) {
|
|
@@ -1799,7 +1869,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1799
1869
|
}
|
|
1800
1870
|
for (const locKey of directLocations) {
|
|
1801
1871
|
if (locKey.lk == null || locKey.lk === "") {
|
|
1802
|
-
|
|
1872
|
+
logger10.error(`Composite key location '${locKey.kt}' has undefined/null lk value`, { locKey, key: comKey });
|
|
1803
1873
|
throw new Error(`Composite key location '${locKey.kt}' has undefined/null lk value`);
|
|
1804
1874
|
}
|
|
1805
1875
|
const foreignKeyField = locKey.kt + "Id";
|
|
@@ -1818,7 +1888,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1818
1888
|
if (!relationshipInfo.found) {
|
|
1819
1889
|
const associations = model.associations ? Object.keys(model.associations) : [];
|
|
1820
1890
|
const errorMessage = `Location key '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships. Available associations: [${associations.join(", ")}]. KTA: [${kta.join(", ")}]. Locations: ${JSON.stringify(options.locations, null, 2)}`;
|
|
1821
|
-
|
|
1891
|
+
logger10.error(errorMessage, { locations: options.locations, kta, associations });
|
|
1822
1892
|
throw new Error(errorMessage);
|
|
1823
1893
|
}
|
|
1824
1894
|
if (relationshipInfo.isDirect) {
|
|
@@ -1829,7 +1899,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1829
1899
|
}
|
|
1830
1900
|
for (const locKey of directLocations) {
|
|
1831
1901
|
if (locKey.lk == null || locKey.lk === "") {
|
|
1832
|
-
|
|
1902
|
+
logger10.error(`Location option '${locKey.kt}' has undefined/null lk value`, { locKey, locations: options.locations });
|
|
1833
1903
|
throw new Error(`Location option '${locKey.kt}' has undefined/null lk value`);
|
|
1834
1904
|
}
|
|
1835
1905
|
const foreignKeyField = locKey.kt + "Id";
|
|
@@ -1840,14 +1910,64 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1840
1910
|
}
|
|
1841
1911
|
}
|
|
1842
1912
|
try {
|
|
1843
|
-
|
|
1913
|
+
logger10.trace(`[CREATE] Executing ${model.name}.create() with data: ${stringifyJSON(itemData)}`);
|
|
1844
1914
|
queryMetrics.recordQuery(model.name);
|
|
1845
1915
|
const createdRecord = await model.create(itemData);
|
|
1846
|
-
|
|
1916
|
+
let recordToProcess = createdRecord;
|
|
1917
|
+
if (kta.length > 1) {
|
|
1918
|
+
const includesForKey = [];
|
|
1919
|
+
let currentInclude = null;
|
|
1920
|
+
for (let i = kta.length - 1; i > 0; i--) {
|
|
1921
|
+
const relationshipType = kta[i];
|
|
1922
|
+
const relationshipInfo = buildRelationshipPath(model, relationshipType, kta, true);
|
|
1923
|
+
if (relationshipInfo.found && !relationshipInfo.isDirect) {
|
|
1924
|
+
const intermediateType = kta[i - 1];
|
|
1925
|
+
const newInclude = {
|
|
1926
|
+
association: intermediateType,
|
|
1927
|
+
required: false
|
|
1928
|
+
};
|
|
1929
|
+
if (currentInclude) {
|
|
1930
|
+
newInclude.include = [currentInclude];
|
|
1931
|
+
}
|
|
1932
|
+
currentInclude = newInclude;
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
if (currentInclude) {
|
|
1936
|
+
includesForKey.push(currentInclude);
|
|
1937
|
+
}
|
|
1938
|
+
if (includesForKey.length > 0) {
|
|
1939
|
+
logger10.debug(`[CREATE] Reloading ${model.name} with includes for key construction`, { includes: includesForKey });
|
|
1940
|
+
queryMetrics.recordQuery(model.name);
|
|
1941
|
+
const reloadedRecord = await model.findByPk(createdRecord.get("id"), {
|
|
1942
|
+
include: includesForKey
|
|
1943
|
+
});
|
|
1944
|
+
if (reloadedRecord) {
|
|
1945
|
+
recordToProcess = reloadedRecord;
|
|
1946
|
+
} else {
|
|
1947
|
+
logger10.warning(`[CREATE] Failed to reload ${model.name} after creation, using original record`);
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
const processedRecord = await processRow(recordToProcess, kta, references || [], aggregations || [], registry, void 0, void 0);
|
|
1847
1952
|
const result = validateKeys2(processedRecord, kta);
|
|
1848
|
-
|
|
1953
|
+
logger10.debug(`[CREATE] Created ${model.name} with key: ${result.key ? JSON.stringify(result.key) : `id=${createdRecord.id}`}`);
|
|
1849
1954
|
return result;
|
|
1850
1955
|
} catch (error) {
|
|
1956
|
+
logger10.error("Create operation failed", {
|
|
1957
|
+
operation: "create",
|
|
1958
|
+
model: model.name,
|
|
1959
|
+
itemData: JSON.stringify(itemData, null, 2),
|
|
1960
|
+
options: JSON.stringify(options),
|
|
1961
|
+
errorType: error?.constructor?.name || typeof error,
|
|
1962
|
+
errorMessage: error?.message,
|
|
1963
|
+
errorName: error?.name,
|
|
1964
|
+
sqlError: error?.original?.message,
|
|
1965
|
+
sqlCode: error?.original?.code,
|
|
1966
|
+
constraint: error?.original?.constraint,
|
|
1967
|
+
detail: error?.original?.detail,
|
|
1968
|
+
suggestion: "Check validation rules, unique constraints, foreign keys, required fields, and data types",
|
|
1969
|
+
coordinate: JSON.stringify(definition.coordinate)
|
|
1970
|
+
});
|
|
1851
1971
|
throw transformSequelizeError(error, kta[0], options?.key, model.name, itemData);
|
|
1852
1972
|
}
|
|
1853
1973
|
}
|
|
@@ -1857,7 +1977,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1857
1977
|
// src/ops/find.ts
|
|
1858
1978
|
import { createFindWrapper } from "@fjell/core";
|
|
1859
1979
|
import { validateKeys as validateKeys3 } from "@fjell/core/validation";
|
|
1860
|
-
var
|
|
1980
|
+
var logger11 = logger_default.get("sequelize", "ops", "find");
|
|
1861
1981
|
var getFindOperation = (models, definition, registry) => {
|
|
1862
1982
|
const { options: { finders, references, aggregations } } = definition;
|
|
1863
1983
|
return createFindWrapper(
|
|
@@ -1867,20 +1987,36 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1867
1987
|
const locs = locations ?? [];
|
|
1868
1988
|
const params = finderParams ?? {};
|
|
1869
1989
|
const locationFilters = locs.map((loc) => `${loc.kt}=${loc.lk}`).join(", ") || "none";
|
|
1870
|
-
|
|
1990
|
+
logger11.debug(
|
|
1871
1991
|
`FIND operation called on ${models[0].name} with finder '${finder}' and ${locs.length} location filters: ${locationFilters}`
|
|
1872
1992
|
);
|
|
1873
|
-
|
|
1993
|
+
logger11.default(`Find configured for ${models[0].name} using finder '${finder}' with ${Object.keys(params).length} params`);
|
|
1874
1994
|
if (!finders || !finders[finder]) {
|
|
1875
|
-
|
|
1876
|
-
|
|
1995
|
+
const availableFinders = finders ? Object.keys(finders) : [];
|
|
1996
|
+
logger11.error(`No finders defined for library`, {
|
|
1997
|
+
operation: "find",
|
|
1998
|
+
model: models[0]?.name,
|
|
1999
|
+
requestedFinder: finder,
|
|
2000
|
+
availableFinders,
|
|
2001
|
+
suggestion: availableFinders.length > 0 ? `Use one of the available finders: ${availableFinders.join(", ")}` : "Define finders in your library configuration",
|
|
2002
|
+
coordinate: JSON.stringify(definition.coordinate)
|
|
2003
|
+
});
|
|
2004
|
+
throw new Error(`No finders found. ${availableFinders.length > 0 ? `Available finders: ${availableFinders.join(", ")}` : "No finders defined."}`);
|
|
1877
2005
|
}
|
|
1878
2006
|
const finderMethod = finders[finder];
|
|
1879
2007
|
if (!finderMethod) {
|
|
1880
|
-
|
|
1881
|
-
|
|
2008
|
+
const availableFinders = Object.keys(finders);
|
|
2009
|
+
logger11.error(`Finder not found`, {
|
|
2010
|
+
operation: "find",
|
|
2011
|
+
model: models[0]?.name,
|
|
2012
|
+
requestedFinder: finder,
|
|
2013
|
+
availableFinders,
|
|
2014
|
+
suggestion: `Use one of: ${availableFinders.join(", ")}`,
|
|
2015
|
+
coordinate: JSON.stringify(definition.coordinate)
|
|
2016
|
+
});
|
|
2017
|
+
throw new Error(`Finder '${finder}' not found. Available finders: ${availableFinders.join(", ")}`);
|
|
1882
2018
|
}
|
|
1883
|
-
|
|
2019
|
+
logger11.trace(`[FIND] Executing finder '${finder}' on ${models[0].name} with params: ${stringifyJSON(params)}, locations: ${stringifyJSON(locs)}, options: ${stringifyJSON(findOptions)}`);
|
|
1884
2020
|
const finderResult = await finderMethod(params, locs, findOptions);
|
|
1885
2021
|
const processItems = async (items) => {
|
|
1886
2022
|
return await Promise.all(items.map(async (row) => {
|
|
@@ -1892,7 +2028,7 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1892
2028
|
if (isOptInResult) {
|
|
1893
2029
|
const optInResult = finderResult;
|
|
1894
2030
|
const processedResults2 = optInResult.items && optInResult.items.length > 0 ? await processItems(optInResult.items) : [];
|
|
1895
|
-
|
|
2031
|
+
logger11.debug(`[FIND] Finder opted-in, found ${processedResults2.length} ${models[0].name} records using finder '${finder}' (total: ${optInResult.metadata.total})`);
|
|
1896
2032
|
return {
|
|
1897
2033
|
items: processedResults2,
|
|
1898
2034
|
metadata: optInResult.metadata
|
|
@@ -1900,7 +2036,7 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1900
2036
|
}
|
|
1901
2037
|
const results = finderResult;
|
|
1902
2038
|
const processedResults = results && results.length > 0 ? await processItems(results) : [];
|
|
1903
|
-
|
|
2039
|
+
logger11.debug(`[FIND] Legacy finder, found ${processedResults.length} ${models[0].name} records using finder '${finder}'`);
|
|
1904
2040
|
return {
|
|
1905
2041
|
items: processedResults,
|
|
1906
2042
|
metadata: {
|
|
@@ -1911,7 +2047,7 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1911
2047
|
}
|
|
1912
2048
|
};
|
|
1913
2049
|
} catch (error) {
|
|
1914
|
-
|
|
2050
|
+
logger11.error("Error in find operation", {
|
|
1915
2051
|
finder,
|
|
1916
2052
|
finderParams,
|
|
1917
2053
|
locations,
|
|
@@ -1943,7 +2079,7 @@ import {
|
|
|
1943
2079
|
validateKeys as validateKeys4
|
|
1944
2080
|
} from "@fjell/core";
|
|
1945
2081
|
import { NotFoundError } from "@fjell/core";
|
|
1946
|
-
var
|
|
2082
|
+
var logger12 = logger_default.get("sequelize", "ops", "get");
|
|
1947
2083
|
var processCompositeKey = (comKey, model, kta) => {
|
|
1948
2084
|
const where = { id: comKey.pk };
|
|
1949
2085
|
const includes = [];
|
|
@@ -1951,7 +2087,7 @@ var processCompositeKey = (comKey, model, kta) => {
|
|
|
1951
2087
|
const relationshipInfo = buildRelationshipPath(model, locator.kt, kta);
|
|
1952
2088
|
if (!relationshipInfo.found) {
|
|
1953
2089
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships. Key type array: [${kta.join(", ")}], Composite key: ${stringifyJSON(comKey)}, Available associations: [${Object.keys(model.associations || {}).join(", ")}]`;
|
|
1954
|
-
|
|
2090
|
+
logger12.error(errorMessage, { key: comKey, kta });
|
|
1955
2091
|
throw new Error(errorMessage);
|
|
1956
2092
|
}
|
|
1957
2093
|
if (relationshipInfo.path) {
|
|
@@ -1978,12 +2114,12 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
1978
2114
|
async (key) => {
|
|
1979
2115
|
try {
|
|
1980
2116
|
if (!isValidItemKey(key)) {
|
|
1981
|
-
|
|
2117
|
+
logger12.error("Key for Get is not a valid ItemKey: %j", key);
|
|
1982
2118
|
throw new Error("Key for Get is not a valid ItemKey");
|
|
1983
2119
|
}
|
|
1984
2120
|
const keyDescription = isPriKey4(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
1985
|
-
|
|
1986
|
-
|
|
2121
|
+
logger12.debug(`GET operation called on ${models[0].name} with ${keyDescription}`);
|
|
2122
|
+
logger12.default(`Get configured for ${models[0].name} with ${isPriKey4(key) ? "primary" : "composite"} key`);
|
|
1987
2123
|
const itemKey = key;
|
|
1988
2124
|
const model = models[0];
|
|
1989
2125
|
let item;
|
|
@@ -1997,7 +2133,7 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
1997
2133
|
const aggResult = addAggregationIncludes(options, model, aggregations || []);
|
|
1998
2134
|
includedAggregations = aggResult.includedAggregations;
|
|
1999
2135
|
options = aggResult.options;
|
|
2000
|
-
|
|
2136
|
+
logger12.trace(`[GET] Executing ${model.name}.findByPk() with pk: ${itemKey.pk}, ${includedReferences.length} reference includes, and ${includedAggregations.length} aggregation includes`);
|
|
2001
2137
|
queryMetrics.recordQuery(model.name);
|
|
2002
2138
|
item = options.include && options.include.length > 0 ? await model.findByPk(itemKey.pk, { include: options.include }) : await model.findByPk(itemKey.pk);
|
|
2003
2139
|
} else if (isComKey4(itemKey)) {
|
|
@@ -2010,8 +2146,8 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
2010
2146
|
const aggResult = addAggregationIncludes(options, model, aggregations || []);
|
|
2011
2147
|
includedAggregations = aggResult.includedAggregations;
|
|
2012
2148
|
options = aggResult.options;
|
|
2013
|
-
|
|
2014
|
-
|
|
2149
|
+
logger12.debug(`[GET] Empty loc array detected - finding by primary key across all locations: ${comKey.pk}`);
|
|
2150
|
+
logger12.trace(`[GET] Executing ${model.name}.findByPk() with pk: ${comKey.pk}, ${includedReferences.length} reference includes, and ${includedAggregations.length} aggregation includes`);
|
|
2015
2151
|
queryMetrics.recordQuery(model.name);
|
|
2016
2152
|
item = options.include && options.include.length > 0 ? await model.findByPk(comKey.pk, { include: options.include }) : await model.findByPk(comKey.pk);
|
|
2017
2153
|
} else {
|
|
@@ -2022,8 +2158,8 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
2022
2158
|
const aggResult = addAggregationIncludes(queryOptions, model, aggregations || []);
|
|
2023
2159
|
includedAggregations = aggResult.includedAggregations;
|
|
2024
2160
|
queryOptions = aggResult.options;
|
|
2025
|
-
|
|
2026
|
-
|
|
2161
|
+
logger12.default("Composite key query", { queryOptions });
|
|
2162
|
+
logger12.trace(`[GET] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}, ${includedReferences.length} reference includes, and ${includedAggregations.length} aggregation includes`);
|
|
2027
2163
|
queryMetrics.recordQuery(model.name);
|
|
2028
2164
|
item = await model.findOne(queryOptions);
|
|
2029
2165
|
}
|
|
@@ -2037,7 +2173,7 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
2037
2173
|
}
|
|
2038
2174
|
const currentContext = contextManager.getCurrentContext();
|
|
2039
2175
|
const result = validateKeys4(await processRow(item, kta, references || [], aggregations || [], registry, currentContext, includedAggregations, includedReferences), kta);
|
|
2040
|
-
|
|
2176
|
+
logger12.debug(`[GET] Retrieved ${model.name} with key: ${result.key ? JSON.stringify(result.key) : `id=${item.id}`}`);
|
|
2041
2177
|
return result;
|
|
2042
2178
|
} catch (error) {
|
|
2043
2179
|
if (error instanceof NotFoundError) throw error;
|
|
@@ -2049,21 +2185,21 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
2049
2185
|
|
|
2050
2186
|
// src/ops/one.ts
|
|
2051
2187
|
import { createOneWrapper } from "@fjell/core";
|
|
2052
|
-
var
|
|
2188
|
+
var logger13 = logger_default.get("sequelize", "ops", "one");
|
|
2053
2189
|
var getOneOperation = (models, definition, registry) => {
|
|
2054
2190
|
return createOneWrapper(
|
|
2055
2191
|
definition.coordinate,
|
|
2056
2192
|
async (itemQuery, locations) => {
|
|
2057
2193
|
const locs = locations ?? [];
|
|
2058
|
-
|
|
2059
|
-
|
|
2194
|
+
logger13.debug(`ONE operation called on ${models[0].name} with ${locs.length} location filters: ${locs.map((loc) => `${loc.kt}=${loc.lk}`).join(", ") || "none"}`);
|
|
2195
|
+
logger13.default(`One configured for ${models[0].name} delegating to all operation`);
|
|
2060
2196
|
const result = await getAllOperation(models, definition, registry)(itemQuery ?? {}, locs, { limit: 1 });
|
|
2061
2197
|
if (result.items.length > 0) {
|
|
2062
2198
|
const item = result.items[0];
|
|
2063
|
-
|
|
2199
|
+
logger13.debug(`[ONE] Found ${models[0].name} record with key: ${item.key ? JSON.stringify(item.key) : "unknown"}`);
|
|
2064
2200
|
return item;
|
|
2065
2201
|
} else {
|
|
2066
|
-
|
|
2202
|
+
logger13.debug(`[ONE] No ${models[0].name} record found`);
|
|
2067
2203
|
return null;
|
|
2068
2204
|
}
|
|
2069
2205
|
}
|
|
@@ -2073,7 +2209,7 @@ var getOneOperation = (models, definition, registry) => {
|
|
|
2073
2209
|
// src/ops/remove.ts
|
|
2074
2210
|
import { abbrevIK, isComKey as isComKey5, isPriKey as isPriKey5, isValidItemKey as isValidItemKey2, createRemoveWrapper } from "@fjell/core";
|
|
2075
2211
|
import { NotFoundError as NotFoundError2 } from "@fjell/core";
|
|
2076
|
-
var
|
|
2212
|
+
var logger14 = logger_default.get("sequelize", "ops", "remove");
|
|
2077
2213
|
var processCompositeKey2 = (comKey, model, kta) => {
|
|
2078
2214
|
const where = { id: comKey.pk };
|
|
2079
2215
|
const includes = [];
|
|
@@ -2081,7 +2217,7 @@ var processCompositeKey2 = (comKey, model, kta) => {
|
|
|
2081
2217
|
const relationshipInfo = buildRelationshipPath(model, locator.kt, kta);
|
|
2082
2218
|
if (!relationshipInfo.found) {
|
|
2083
2219
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
2084
|
-
|
|
2220
|
+
logger14.error(errorMessage, { key: comKey, kta });
|
|
2085
2221
|
throw new Error(errorMessage);
|
|
2086
2222
|
}
|
|
2087
2223
|
if (relationshipInfo.path) {
|
|
@@ -2108,25 +2244,25 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
2108
2244
|
async (key) => {
|
|
2109
2245
|
try {
|
|
2110
2246
|
if (!isValidItemKey2(key)) {
|
|
2111
|
-
|
|
2247
|
+
logger14.error("Key for Remove is not a valid ItemKey: %j", key);
|
|
2112
2248
|
throw new Error("Key for Remove is not a valid ItemKey");
|
|
2113
2249
|
}
|
|
2114
2250
|
const keyDescription = isPriKey5(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
2115
|
-
|
|
2116
|
-
|
|
2251
|
+
logger14.debug(`REMOVE operation called on ${models[0].name} with ${keyDescription}`);
|
|
2252
|
+
logger14.default(`Remove configured for ${models[0].name} with ${isPriKey5(key) ? "primary" : "composite"} key`);
|
|
2117
2253
|
const model = models[0];
|
|
2118
2254
|
let item;
|
|
2119
2255
|
let returnItem;
|
|
2120
|
-
|
|
2256
|
+
logger14.debug("remove: %s", abbrevIK(key));
|
|
2121
2257
|
if (isPriKey5(key)) {
|
|
2122
|
-
|
|
2258
|
+
logger14.debug(`[REMOVE] Executing ${model.name}.findByPk() with pk: ${key.pk}`);
|
|
2123
2259
|
queryMetrics.recordQuery(model.name);
|
|
2124
2260
|
item = await model.findByPk(key.pk);
|
|
2125
2261
|
} else if (isComKey5(key)) {
|
|
2126
2262
|
const comKey = key;
|
|
2127
2263
|
const queryOptions = processCompositeKey2(comKey, model, kta);
|
|
2128
|
-
|
|
2129
|
-
|
|
2264
|
+
logger14.default(`Remove composite key query for ${model.name} with where fields: ${queryOptions.where ? Object.keys(queryOptions.where).join(", ") : "none"}`);
|
|
2265
|
+
logger14.debug(`[REMOVE] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}`);
|
|
2130
2266
|
queryMetrics.recordQuery(model.name);
|
|
2131
2267
|
item = await model.findOne(queryOptions);
|
|
2132
2268
|
}
|
|
@@ -2146,14 +2282,14 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
2146
2282
|
if (model.getAttributes().deletedAt) {
|
|
2147
2283
|
item.deletedAt = /* @__PURE__ */ new Date();
|
|
2148
2284
|
}
|
|
2149
|
-
|
|
2285
|
+
logger14.debug(`[REMOVE] Executing ${model.name}.save() for soft delete`);
|
|
2150
2286
|
queryMetrics.recordQuery(model.name);
|
|
2151
2287
|
await item?.save();
|
|
2152
2288
|
returnItem = item?.get({ plain: true });
|
|
2153
2289
|
returnItem = addKey(item, returnItem, kta);
|
|
2154
2290
|
returnItem = populateEvents(returnItem);
|
|
2155
2291
|
} else if (options.deleteOnRemove) {
|
|
2156
|
-
|
|
2292
|
+
logger14.debug(`[REMOVE] Executing ${model.name}.destroy() for hard delete`);
|
|
2157
2293
|
queryMetrics.recordQuery(model.name);
|
|
2158
2294
|
await item?.destroy();
|
|
2159
2295
|
returnItem = item?.get({ plain: true });
|
|
@@ -2162,7 +2298,7 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
2162
2298
|
} else {
|
|
2163
2299
|
throw new Error("No deletedAt or isDeleted attribute found in model, and deleteOnRemove is not set");
|
|
2164
2300
|
}
|
|
2165
|
-
|
|
2301
|
+
logger14.debug(`[REMOVE] Removed ${model.name} with key: ${returnItem.key ? JSON.stringify(returnItem.key) : `id=${item.id}`}`);
|
|
2166
2302
|
const { references } = options;
|
|
2167
2303
|
if (references && references.length > 0) {
|
|
2168
2304
|
returnItem = addRefsToSequelizeItem(returnItem, references);
|
|
@@ -2186,7 +2322,7 @@ import {
|
|
|
2186
2322
|
import { validateKeys as validateKeys5 } from "@fjell/core/validation";
|
|
2187
2323
|
import { NotFoundError as NotFoundError3 } from "@fjell/core";
|
|
2188
2324
|
import { Op as Op3 } from "sequelize";
|
|
2189
|
-
var
|
|
2325
|
+
var logger15 = logger_default.get("sequelize", "ops", "update");
|
|
2190
2326
|
var mergeIncludes2 = (existingIncludes, newIncludes) => {
|
|
2191
2327
|
const mergedIncludes = [...existingIncludes];
|
|
2192
2328
|
for (const newInclude of newIncludes) {
|
|
@@ -2218,15 +2354,15 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
2218
2354
|
);
|
|
2219
2355
|
}
|
|
2220
2356
|
const keyDescription = isPriKey6(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
2221
|
-
|
|
2357
|
+
logger15.debug(`UPDATE operation called on ${models[0].name} with ${keyDescription}`, { options });
|
|
2222
2358
|
const { coordinate } = definition;
|
|
2223
2359
|
const { kta } = coordinate;
|
|
2224
|
-
|
|
2360
|
+
logger15.debug("update: %s, %j", abbrevIK2(key), item);
|
|
2225
2361
|
const model = models[0];
|
|
2226
2362
|
let response;
|
|
2227
2363
|
if (isPriKey6(key)) {
|
|
2228
2364
|
const priKey = key;
|
|
2229
|
-
|
|
2365
|
+
logger15.trace(`[UPDATE] Executing ${model.name}.findByPk() with pk: ${priKey.pk}`);
|
|
2230
2366
|
queryMetrics.recordQuery(model.name);
|
|
2231
2367
|
response = await model.findByPk(priKey.pk);
|
|
2232
2368
|
} else if (isComKey6(key)) {
|
|
@@ -2237,7 +2373,7 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
2237
2373
|
const relationshipInfo = buildRelationshipPath(model, locator.kt, kta, true);
|
|
2238
2374
|
if (!relationshipInfo.found) {
|
|
2239
2375
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
2240
|
-
|
|
2376
|
+
logger15.error(errorMessage, { key: comKey, kta });
|
|
2241
2377
|
throw new Error(errorMessage);
|
|
2242
2378
|
}
|
|
2243
2379
|
if (relationshipInfo.isDirect) {
|
|
@@ -2256,8 +2392,8 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
2256
2392
|
if (additionalIncludes.length > 0) {
|
|
2257
2393
|
queryOptions.include = mergeIncludes2([], additionalIncludes);
|
|
2258
2394
|
}
|
|
2259
|
-
|
|
2260
|
-
|
|
2395
|
+
logger15.default(`Update composite key query for ${model.name} with where fields: ${queryOptions.where ? Object.keys(queryOptions.where).join(", ") : "none"}`);
|
|
2396
|
+
logger15.trace(`[UPDATE] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}`);
|
|
2261
2397
|
queryMetrics.recordQuery(model.name);
|
|
2262
2398
|
response = await model.findOne(queryOptions);
|
|
2263
2399
|
}
|
|
@@ -2277,14 +2413,14 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
2277
2413
|
if (aggregations && aggregations.length > 0) {
|
|
2278
2414
|
updateProps = removeAggsFromItem(updateProps, aggregations);
|
|
2279
2415
|
}
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2416
|
+
logger15.default(`Update found ${model.name} record to modify`);
|
|
2417
|
+
logger15.default(`Update properties configured: ${Object.keys(updateProps).join(", ")}`);
|
|
2418
|
+
logger15.trace(`[UPDATE] Executing ${model.name}.update() with properties: ${stringifyJSON(updateProps)}`);
|
|
2283
2419
|
queryMetrics.recordQuery(model.name);
|
|
2284
2420
|
response = await response.update(updateProps);
|
|
2285
2421
|
const processedItem = await processRow(response, kta, references || [], aggregations || [], registry, void 0, void 0);
|
|
2286
2422
|
const returnItem = validateKeys5(processedItem, kta);
|
|
2287
|
-
|
|
2423
|
+
logger15.debug(`[UPDATE] Updated ${model.name} with key: ${returnItem.key ? JSON.stringify(returnItem.key) : `id=${response.id}`}`);
|
|
2288
2424
|
return returnItem;
|
|
2289
2425
|
} catch (error) {
|
|
2290
2426
|
if (error instanceof NotFoundError3) throw error;
|
|
@@ -2296,7 +2432,7 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
2296
2432
|
|
|
2297
2433
|
// src/ops/upsert.ts
|
|
2298
2434
|
import { createUpsertWrapper, isValidItemKey as isValidItemKey3, NotFoundError as NotFoundError4 } from "@fjell/core";
|
|
2299
|
-
var
|
|
2435
|
+
var logger16 = logger_default.get("sequelize", "ops", "upsert");
|
|
2300
2436
|
var getUpsertOperation = (models, definition, registry) => {
|
|
2301
2437
|
const get = getGetOperation(models, definition, registry);
|
|
2302
2438
|
const update = getUpdateOperation(models, definition, registry);
|
|
@@ -2305,31 +2441,50 @@ var getUpsertOperation = (models, definition, registry) => {
|
|
|
2305
2441
|
definition.coordinate,
|
|
2306
2442
|
async (key, item, locations, options) => {
|
|
2307
2443
|
if (!isValidItemKey3(key)) {
|
|
2308
|
-
|
|
2309
|
-
|
|
2444
|
+
logger16.error("Invalid key for upsert operation", {
|
|
2445
|
+
operation: "upsert",
|
|
2446
|
+
model: models[0]?.name,
|
|
2447
|
+
key: stringifyJSON(key),
|
|
2448
|
+
keyType: typeof key,
|
|
2449
|
+
reason: "Key validation failed",
|
|
2450
|
+
suggestion: "Ensure key has valid PriKey or ComKey structure",
|
|
2451
|
+
coordinate: JSON.stringify(definition.coordinate)
|
|
2452
|
+
});
|
|
2453
|
+
throw new Error(`Invalid key for upsert operation: ${stringifyJSON(key)}. Expected valid PriKey or ComKey structure.`);
|
|
2310
2454
|
}
|
|
2311
|
-
|
|
2455
|
+
logger16.debug(`[UPSERT] Attempting upsert with key: ${stringifyJSON(key)}`, { options });
|
|
2312
2456
|
let resultItem = null;
|
|
2313
2457
|
try {
|
|
2314
|
-
|
|
2458
|
+
logger16.debug(`[UPSERT] Retrieving item by key: ${stringifyJSON(key)}`);
|
|
2315
2459
|
resultItem = await get(key);
|
|
2316
2460
|
} catch (error) {
|
|
2317
2461
|
const isNotFound = error instanceof NotFoundError4 || error?.name === "NotFoundError" || error?.errorInfo?.code === "NOT_FOUND";
|
|
2318
2462
|
if (isNotFound) {
|
|
2319
|
-
|
|
2463
|
+
logger16.debug(`[UPSERT] Item not found, creating new item with key: ${stringifyJSON(key)}, errorType: ${error?.name}, errorCode: ${error?.errorInfo?.code}`);
|
|
2320
2464
|
const createOptions3 = locations ? { locations } : { key };
|
|
2321
2465
|
resultItem = await create(item, createOptions3);
|
|
2322
2466
|
} else {
|
|
2323
|
-
|
|
2467
|
+
logger16.error(`[UPSERT] Unexpected error during get operation`, {
|
|
2468
|
+
operation: "upsert",
|
|
2469
|
+
phase: "get-existing",
|
|
2470
|
+
model: models[0]?.name,
|
|
2471
|
+
key: stringifyJSON(key),
|
|
2472
|
+
errorType: error?.constructor?.name || typeof error,
|
|
2473
|
+
errorMessage: error?.message,
|
|
2474
|
+
errorName: error?.name,
|
|
2475
|
+
errorCode: error?.errorInfo?.code,
|
|
2476
|
+
suggestion: "Check database connectivity, permissions, and key validity",
|
|
2477
|
+
coordinate: JSON.stringify(definition.coordinate)
|
|
2478
|
+
});
|
|
2324
2479
|
throw error;
|
|
2325
2480
|
}
|
|
2326
2481
|
}
|
|
2327
2482
|
if (!resultItem) {
|
|
2328
2483
|
throw new Error(`Failed to retrieve or create item for key: ${stringifyJSON(key)}`);
|
|
2329
2484
|
}
|
|
2330
|
-
|
|
2485
|
+
logger16.debug(`[UPSERT] Updating item with properties, key: ${stringifyJSON(key)}`, { options });
|
|
2331
2486
|
resultItem = await update(resultItem.key, item, options);
|
|
2332
|
-
|
|
2487
|
+
logger16.debug(`[UPSERT] Item upserted successfully: ${stringifyJSON(resultItem)}`);
|
|
2333
2488
|
return resultItem;
|
|
2334
2489
|
}
|
|
2335
2490
|
);
|
|
@@ -2358,9 +2513,9 @@ var createOperations = (models, coordinate, registry, options) => {
|
|
|
2358
2513
|
};
|
|
2359
2514
|
|
|
2360
2515
|
// src/SequelizeLibrary.ts
|
|
2361
|
-
var
|
|
2516
|
+
var logger17 = logger_default.get("SequelizeLibrary");
|
|
2362
2517
|
var createSequelizeLibrary = (registry, coordinate, models, options) => {
|
|
2363
|
-
|
|
2518
|
+
logger17.debug("createSequelizeLibrary", { coordinate, models, registry, options });
|
|
2364
2519
|
const operations = createOperations(models, coordinate, registry, options);
|
|
2365
2520
|
const wrappedOperations = Library3.wrapOperations(operations, options, coordinate, registry);
|
|
2366
2521
|
const libLibrary = Library3.createLibrary(registry, coordinate, wrappedOperations, options);
|
|
@@ -2374,10 +2529,10 @@ var isSequelizeLibrary = (library) => {
|
|
|
2374
2529
|
};
|
|
2375
2530
|
|
|
2376
2531
|
// src/SequelizeLibraryFactory.ts
|
|
2377
|
-
var
|
|
2532
|
+
var logger18 = logger_default.get("InstanceFactory");
|
|
2378
2533
|
var createSequelizeLibraryFactory = (models, options) => {
|
|
2379
2534
|
return (coordinate, context) => {
|
|
2380
|
-
|
|
2535
|
+
logger18.debug("Creating Sequelize instance", {
|
|
2381
2536
|
coordinate,
|
|
2382
2537
|
registry: context.registry,
|
|
2383
2538
|
models: models.map((m) => m.name),
|
|
@@ -2422,9 +2577,9 @@ __export(primary_exports, {
|
|
|
2422
2577
|
|
|
2423
2578
|
// src/primary/SequelizeLibrary.ts
|
|
2424
2579
|
import { Primary } from "@fjell/lib";
|
|
2425
|
-
var
|
|
2580
|
+
var logger19 = logger_default.get("lib-sequelize", "primary", "library");
|
|
2426
2581
|
function createSequelizeLibrary3(keyType, models, libOptions = {}, scopes = [], registry) {
|
|
2427
|
-
|
|
2582
|
+
logger19.debug("createSequelizeLibrary", { keyType, models, libOptions, scopes });
|
|
2428
2583
|
const coordinate = createCoordinate([keyType], scopes);
|
|
2429
2584
|
const options = createOptions2(libOptions);
|
|
2430
2585
|
const operations = createOperations(models, coordinate, registry, options);
|