@fjell/lib-sequelize 4.4.14 → 4.4.16
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/{types/Operations.d.ts → Operations.d.ts} +5 -5
- package/dist/{types/SequelizeLibraryFactory.d.ts → SequelizeLibraryFactory.d.ts} +4 -4
- package/dist/{types/contained → contained}/SequelizeLibrary.d.ts +4 -4
- package/dist/index.js +1488 -0
- package/dist/index.js.map +7 -0
- package/dist/logger.d.ts +2 -0
- package/dist/{types/ops → ops}/all.d.ts +3 -3
- package/dist/{types/ops → ops}/create.d.ts +3 -3
- package/dist/{types/ops → ops}/find.d.ts +3 -3
- package/dist/{types/ops → ops}/get.d.ts +1 -1
- package/dist/{types/ops → ops}/one.d.ts +3 -3
- package/dist/{types/ops → ops}/remove.d.ts +4 -3
- package/dist/{types/ops → ops}/update.d.ts +3 -3
- package/dist/{types/primary → primary}/SequelizeLibrary.d.ts +4 -4
- package/package.json +17 -20
- package/dist/cjs/AggregationBuilder.cjs +0 -65
- package/dist/cjs/Coordinate.cjs +0 -24
- package/dist/cjs/Definition.cjs +0 -25
- package/dist/cjs/EventCoordinator.cjs +0 -54
- package/dist/cjs/KeyMaster.cjs +0 -151
- package/dist/cjs/OperationContext.cjs +0 -161
- package/dist/cjs/Operations.cjs +0 -34
- package/dist/cjs/Options.cjs +0 -46
- package/dist/cjs/QueryBuilder.cjs +0 -296
- package/dist/cjs/ReferenceBuilder.cjs +0 -76
- package/dist/cjs/RowProcessor.cjs +0 -56
- package/dist/cjs/SequelizeLibrary.cjs +0 -56
- package/dist/cjs/SequelizeLibraryFactory.cjs +0 -25
- package/dist/cjs/contained/SequelizeLibrary.cjs +0 -31
- package/dist/cjs/contained/index.cjs +0 -11
- package/dist/cjs/index.cjs +0 -26
- package/dist/cjs/logger.cjs +0 -10
- package/dist/cjs/ops/all.cjs +0 -145
- package/dist/cjs/ops/create.cjs +0 -252
- package/dist/cjs/ops/find.cjs +0 -47
- package/dist/cjs/ops/get.cjs +0 -92
- package/dist/cjs/ops/one.cjs +0 -27
- package/dist/cjs/ops/remove.cjs +0 -114
- package/dist/cjs/ops/update.cjs +0 -120
- package/dist/cjs/primary/SequelizeLibrary.cjs +0 -41
- package/dist/cjs/primary/index.cjs +0 -11
- package/dist/cjs/util/general.cjs +0 -48
- package/dist/cjs/util/relationshipUtils.cjs +0 -117
- package/dist/es/AggregationBuilder.js +0 -61
- package/dist/es/Coordinate.js +0 -19
- package/dist/es/Definition.js +0 -21
- package/dist/es/EventCoordinator.js +0 -48
- package/dist/es/KeyMaster.js +0 -146
- package/dist/es/OperationContext.js +0 -155
- package/dist/es/Operations.js +0 -30
- package/dist/es/Options.js +0 -23
- package/dist/es/QueryBuilder.js +0 -290
- package/dist/es/ReferenceBuilder.js +0 -72
- package/dist/es/RowProcessor.js +0 -52
- package/dist/es/SequelizeLibrary.js +0 -32
- package/dist/es/SequelizeLibraryFactory.js +0 -21
- package/dist/es/contained/SequelizeLibrary.js +0 -26
- package/dist/es/contained/index.js +0 -2
- package/dist/es/index.js +0 -11
- package/dist/es/logger.js +0 -6
- package/dist/es/ops/all.js +0 -141
- package/dist/es/ops/create.js +0 -248
- package/dist/es/ops/find.js +0 -43
- package/dist/es/ops/get.js +0 -88
- package/dist/es/ops/one.js +0 -23
- package/dist/es/ops/remove.js +0 -110
- package/dist/es/ops/update.js +0 -116
- package/dist/es/primary/SequelizeLibrary.js +0 -36
- package/dist/es/primary/index.js +0 -2
- package/dist/es/util/general.js +0 -44
- package/dist/es/util/relationshipUtils.js +0 -112
- package/dist/index.cjs +0 -1853
- package/dist/index.cjs.map +0 -1
- package/dist/types/AggregationBuilder.d.ts +0 -5
- package/dist/types/EventCoordinator.d.ts +0 -6
- package/dist/types/KeyMaster.d.ts +0 -4
- package/dist/types/OperationContext.d.ts +0 -72
- package/dist/types/QueryBuilder.d.ts +0 -12
- package/dist/types/ReferenceBuilder.d.ts +0 -4
- package/dist/types/RowProcessor.d.ts +0 -6
- package/dist/types/logger.d.ts +0 -2
- package/dist/types/util/general.d.ts +0 -4
- package/dist/types/util/relationshipUtils.d.ts +0 -21
- package/dist/{types/Coordinate.d.ts → Coordinate.d.ts} +0 -0
- package/dist/{types/Definition.d.ts → Definition.d.ts} +0 -0
- package/dist/{types/Options.d.ts → Options.d.ts} +1 -1
- package/dist/{types/Registry.d.ts → Registry.d.ts} +0 -0
- package/dist/{types/SequelizeLibrary.d.ts → SequelizeLibrary.d.ts} +1 -1
- /package/dist/{types/contained → contained}/index.d.ts +0 -0
- /package/dist/{types/index.d.ts → index.d.ts} +0 -0
- /package/dist/{types/primary → primary}/index.d.ts +0 -0
package/dist/es/KeyMaster.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import LibLogger from './logger.js';
|
|
2
|
-
import { buildRelationshipPath } from './util/relationshipUtils.js';
|
|
3
|
-
|
|
4
|
-
const logger = LibLogger.get('sequelize', 'KeyMaster');
|
|
5
|
-
// Helper function to extract location key value from item
|
|
6
|
-
const extractLocationKeyValue = (model, item, locatorType, kta)=>{
|
|
7
|
-
logger.default('Extracting location key value', {
|
|
8
|
-
locatorType,
|
|
9
|
-
kta
|
|
10
|
-
});
|
|
11
|
-
const relationshipInfo = buildRelationshipPath(model, locatorType, kta, true);
|
|
12
|
-
if (!relationshipInfo.found) {
|
|
13
|
-
throw new Error(`Location key '${locatorType}' cannot be resolved on model '${model.name}' or through its relationships.`);
|
|
14
|
-
}
|
|
15
|
-
if (relationshipInfo.isDirect) {
|
|
16
|
-
// Direct foreign key field
|
|
17
|
-
const foreignKeyField = `${locatorType}Id`;
|
|
18
|
-
const value = item[foreignKeyField];
|
|
19
|
-
if (typeof value === 'undefined' || value === null) {
|
|
20
|
-
throw new Error(`Direct foreign key field '${foreignKeyField}' is missing or null in item`);
|
|
21
|
-
}
|
|
22
|
-
return value;
|
|
23
|
-
} else {
|
|
24
|
-
// Need to traverse relationship hierarchy
|
|
25
|
-
// Find the path through the key type array
|
|
26
|
-
const locatorIndex = kta.indexOf(locatorType);
|
|
27
|
-
if (locatorIndex === -1) {
|
|
28
|
-
throw new Error(`Locator type '${locatorType}' not found in key type array`);
|
|
29
|
-
}
|
|
30
|
-
// Start from the current item (index 0 in kta)
|
|
31
|
-
let currentObject = item;
|
|
32
|
-
// Traverse through each intermediate relationship to reach the target
|
|
33
|
-
for(let i = 1; i < locatorIndex; i++){
|
|
34
|
-
const intermediateType = kta[i];
|
|
35
|
-
// Check if the intermediate relationship object is loaded
|
|
36
|
-
if (currentObject[intermediateType] && typeof currentObject[intermediateType] === 'object') {
|
|
37
|
-
currentObject = currentObject[intermediateType];
|
|
38
|
-
} else {
|
|
39
|
-
// Try the foreign key approach if the relationship object isn't loaded
|
|
40
|
-
const foreignKeyField = `${intermediateType}Id`;
|
|
41
|
-
if (typeof currentObject[foreignKeyField] !== 'undefined' && currentObject[foreignKeyField] !== null) {
|
|
42
|
-
// We have the foreign key but not the loaded object, we can't traverse further
|
|
43
|
-
throw new Error(`Intermediate relationship '${intermediateType}' is not loaded. Cannot traverse to '${locatorType}'. Either include the relationship in your query or ensure it's loaded.`);
|
|
44
|
-
}
|
|
45
|
-
throw new Error(`Intermediate relationship '${intermediateType}' is missing in the relationship chain. Expected path: ${kta.slice(0, locatorIndex + 1).join(' → ')}`);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// Now extract the target locator value from the current object
|
|
49
|
-
// First try to get it from the loaded relationship object
|
|
50
|
-
if (currentObject[locatorType] && typeof currentObject[locatorType] === 'object' && typeof currentObject[locatorType].id !== 'undefined') {
|
|
51
|
-
return currentObject[locatorType].id;
|
|
52
|
-
}
|
|
53
|
-
// If the relationship object isn't loaded, try the foreign key field
|
|
54
|
-
const foreignKeyField = `${locatorType}Id`;
|
|
55
|
-
if (typeof currentObject[foreignKeyField] !== 'undefined' && currentObject[foreignKeyField] !== null) {
|
|
56
|
-
return currentObject[foreignKeyField];
|
|
57
|
-
}
|
|
58
|
-
throw new Error(`Unable to extract location key for '${locatorType}'. Neither the relationship object nor direct foreign key is available. Traversal path: ${kta.slice(0, locatorIndex + 1).join(' → ')}`);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
const removeKey = (item)=>{
|
|
62
|
-
logger.default('Removing Key', {
|
|
63
|
-
item
|
|
64
|
-
});
|
|
65
|
-
delete item.key;
|
|
66
|
-
return item;
|
|
67
|
-
};
|
|
68
|
-
// export const populateKey = <
|
|
69
|
-
// S extends string,
|
|
70
|
-
// L1 extends string = never,
|
|
71
|
-
// L2 extends string = never,
|
|
72
|
-
// L3 extends string = never,
|
|
73
|
-
// L4 extends string = never,
|
|
74
|
-
// L5 extends string = never
|
|
75
|
-
// >(
|
|
76
|
-
// item: ItemProperties<S, L1, L2, L3, L4, L5>,
|
|
77
|
-
// keyTypes: AllItemTypeArrays<S, L1, L2, L3, L4, L5>
|
|
78
|
-
// ): ItemProperties<S, L1, L2, L3, L4, L5> => {
|
|
79
|
-
// if (keyTypes.length === 1) {
|
|
80
|
-
// item.key = { kt: keyTypes[0], pk: item.id };
|
|
81
|
-
// delete item.id;
|
|
82
|
-
// } else if (keyTypes.length === 2) {
|
|
83
|
-
// item.key = {
|
|
84
|
-
// kt: keyTypes[0], pk: item.id,
|
|
85
|
-
// // TODO: Shouldn't this be inspecting the model to get the primary key type?
|
|
86
|
-
// loc: [{ kt: keyTypes[1], lk: item[keyTypes[1] + 'Id'] }],
|
|
87
|
-
// };
|
|
88
|
-
// delete item.id;
|
|
89
|
-
// delete item[keyTypes[1] + 'Id'];
|
|
90
|
-
// } else {
|
|
91
|
-
// throw new Error('Not implemented');
|
|
92
|
-
// }
|
|
93
|
-
// return item;
|
|
94
|
-
// }
|
|
95
|
-
const addKey = (model, item, keyTypes)=>{
|
|
96
|
-
logger.default('Adding Key', {
|
|
97
|
-
item
|
|
98
|
-
});
|
|
99
|
-
const key = {};
|
|
100
|
-
const modelClass = model.constructor;
|
|
101
|
-
const primaryKeyAttr = modelClass.primaryKeyAttribute;
|
|
102
|
-
if (Array.isArray(keyTypes) && keyTypes.length > 1) {
|
|
103
|
-
const type = [
|
|
104
|
-
...keyTypes
|
|
105
|
-
];
|
|
106
|
-
const pkType = type.shift();
|
|
107
|
-
Object.assign(key, {
|
|
108
|
-
kt: pkType,
|
|
109
|
-
pk: item[primaryKeyAttr]
|
|
110
|
-
});
|
|
111
|
-
// Build location keys for composite key
|
|
112
|
-
const locationKeys = [];
|
|
113
|
-
for (const locatorType of type){
|
|
114
|
-
try {
|
|
115
|
-
const lk = extractLocationKeyValue(modelClass, item, locatorType, keyTypes);
|
|
116
|
-
locationKeys.push({
|
|
117
|
-
kt: locatorType,
|
|
118
|
-
lk
|
|
119
|
-
});
|
|
120
|
-
} catch (error) {
|
|
121
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
122
|
-
logger.error(`Failed to extract location key for '${locatorType}'`, {
|
|
123
|
-
error: errorMessage,
|
|
124
|
-
item,
|
|
125
|
-
keyTypes
|
|
126
|
-
});
|
|
127
|
-
throw error;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
Object.assign(key, {
|
|
131
|
-
loc: locationKeys
|
|
132
|
-
});
|
|
133
|
-
} else {
|
|
134
|
-
Object.assign(key, {
|
|
135
|
-
kt: keyTypes[0],
|
|
136
|
-
pk: item[primaryKeyAttr]
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
Object.assign(item, {
|
|
140
|
-
key
|
|
141
|
-
});
|
|
142
|
-
return item;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
export { addKey, removeKey };
|
|
146
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2V5TWFzdGVyLmpzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import LibLogger from './logger.js';
|
|
2
|
-
|
|
3
|
-
function _define_property(obj, key, value) {
|
|
4
|
-
if (key in obj) {
|
|
5
|
-
Object.defineProperty(obj, key, {
|
|
6
|
-
value: value,
|
|
7
|
-
enumerable: true,
|
|
8
|
-
configurable: true,
|
|
9
|
-
writable: true
|
|
10
|
-
});
|
|
11
|
-
} else {
|
|
12
|
-
obj[key] = value;
|
|
13
|
-
}
|
|
14
|
-
return obj;
|
|
15
|
-
}
|
|
16
|
-
const logger = LibLogger.get('sequelize', 'OperationContext');
|
|
17
|
-
/**
|
|
18
|
-
* Serialize an ItemKey to a string for use in sets and maps
|
|
19
|
-
*/ const serializeKey = (key)=>{
|
|
20
|
-
if ('pk' in key && 'kt' in key && !('loc' in key)) {
|
|
21
|
-
// PriKey
|
|
22
|
-
return `${key.kt}:${key.pk}`;
|
|
23
|
-
} else if ('pk' in key && 'kt' in key && 'loc' in key) {
|
|
24
|
-
// ComKey
|
|
25
|
-
const locStr = key.loc.map((l)=>`${l.kt}:${l.lk}`).join(',');
|
|
26
|
-
return `${key.kt}:${key.pk}|${locStr}`;
|
|
27
|
-
}
|
|
28
|
-
throw new Error(`Unsupported key type: ${JSON.stringify(key)}`);
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Create a new OperationContext
|
|
32
|
-
*/ const createOperationContext = ()=>{
|
|
33
|
-
const inProgress = new Set();
|
|
34
|
-
const cache = new Map();
|
|
35
|
-
return {
|
|
36
|
-
inProgress,
|
|
37
|
-
cache,
|
|
38
|
-
markInProgress (key) {
|
|
39
|
-
const serialized = serializeKey(key);
|
|
40
|
-
logger.default('Marking key as in progress', {
|
|
41
|
-
key,
|
|
42
|
-
serialized
|
|
43
|
-
});
|
|
44
|
-
inProgress.add(serialized);
|
|
45
|
-
},
|
|
46
|
-
markComplete (key) {
|
|
47
|
-
const serialized = serializeKey(key);
|
|
48
|
-
logger.default('Marking key as complete', {
|
|
49
|
-
key,
|
|
50
|
-
serialized
|
|
51
|
-
});
|
|
52
|
-
inProgress.delete(serialized);
|
|
53
|
-
},
|
|
54
|
-
isInProgress (key) {
|
|
55
|
-
const serialized = serializeKey(key);
|
|
56
|
-
const result = inProgress.has(serialized);
|
|
57
|
-
logger.default('Checking if key is in progress', {
|
|
58
|
-
key,
|
|
59
|
-
serialized,
|
|
60
|
-
result
|
|
61
|
-
});
|
|
62
|
-
return result;
|
|
63
|
-
},
|
|
64
|
-
getCached (key) {
|
|
65
|
-
const serialized = serializeKey(key);
|
|
66
|
-
const result = cache.get(serialized);
|
|
67
|
-
logger.default('Getting cached item', {
|
|
68
|
-
key,
|
|
69
|
-
serialized,
|
|
70
|
-
found: !!result
|
|
71
|
-
});
|
|
72
|
-
return result;
|
|
73
|
-
},
|
|
74
|
-
setCached (key, item) {
|
|
75
|
-
const serialized = serializeKey(key);
|
|
76
|
-
logger.default('Caching item', {
|
|
77
|
-
key,
|
|
78
|
-
serialized
|
|
79
|
-
});
|
|
80
|
-
cache.set(serialized, item);
|
|
81
|
-
},
|
|
82
|
-
isCached (key) {
|
|
83
|
-
const serialized = serializeKey(key);
|
|
84
|
-
const result = cache.has(serialized);
|
|
85
|
-
logger.default('Checking if key is cached', {
|
|
86
|
-
key,
|
|
87
|
-
serialized,
|
|
88
|
-
result
|
|
89
|
-
});
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
/**
|
|
95
|
-
* Context Manager for sharing context across operations without changing public interfaces
|
|
96
|
-
*/ class ContextManager {
|
|
97
|
-
/**
|
|
98
|
-
* Set the current context for the current operation chain
|
|
99
|
-
*/ setCurrentContext(context) {
|
|
100
|
-
const contextId = Math.random().toString(36).substring(7);
|
|
101
|
-
this.contexts.set(contextId, context);
|
|
102
|
-
this.currentContextId = contextId;
|
|
103
|
-
logger.default('Set current context', {
|
|
104
|
-
contextId
|
|
105
|
-
});
|
|
106
|
-
return contextId;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Get the current context if one is set
|
|
110
|
-
*/ getCurrentContext() {
|
|
111
|
-
if (this.currentContextId) {
|
|
112
|
-
const context = this.contexts.get(this.currentContextId);
|
|
113
|
-
logger.default('Got current context', {
|
|
114
|
-
contextId: this.currentContextId,
|
|
115
|
-
found: !!context
|
|
116
|
-
});
|
|
117
|
-
return context;
|
|
118
|
-
}
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Clear the current context
|
|
123
|
-
*/ clearCurrentContext() {
|
|
124
|
-
if (this.currentContextId) {
|
|
125
|
-
logger.default('Clearing current context', {
|
|
126
|
-
contextId: this.currentContextId
|
|
127
|
-
});
|
|
128
|
-
this.contexts.delete(this.currentContextId);
|
|
129
|
-
this.currentContextId = null;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Execute a function with a specific context set as current
|
|
134
|
-
*/ async withContext(context, fn) {
|
|
135
|
-
const previousContextId = this.currentContextId;
|
|
136
|
-
this.setCurrentContext(context);
|
|
137
|
-
try {
|
|
138
|
-
return await fn();
|
|
139
|
-
} finally{
|
|
140
|
-
this.clearCurrentContext();
|
|
141
|
-
if (previousContextId) {
|
|
142
|
-
this.currentContextId = previousContextId;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
constructor(){
|
|
147
|
-
_define_property(this, "contexts", new Map());
|
|
148
|
-
_define_property(this, "currentContextId", null);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
// Global context manager instance
|
|
152
|
-
const contextManager = new ContextManager();
|
|
153
|
-
|
|
154
|
-
export { contextManager, createOperationContext, serializeKey };
|
|
155
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3BlcmF0aW9uQ29udGV4dC5qcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
|
package/dist/es/Operations.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { getAllOperation } from './ops/all.js';
|
|
2
|
-
import { getCreateOperation } from './ops/create.js';
|
|
3
|
-
import { getFindOperation } from './ops/find.js';
|
|
4
|
-
import { getGetOperation } from './ops/get.js';
|
|
5
|
-
import { getOneOperation } from './ops/one.js';
|
|
6
|
-
import { getRemoveOperation } from './ops/remove.js';
|
|
7
|
-
import { getUpdateOperation } from './ops/update.js';
|
|
8
|
-
|
|
9
|
-
const createOperations = (models, coordinate, registry, options)=>{
|
|
10
|
-
const operations = {};
|
|
11
|
-
// Create a definition-like object for backward compatibility with existing operation functions
|
|
12
|
-
const definition = {
|
|
13
|
-
coordinate,
|
|
14
|
-
options
|
|
15
|
-
};
|
|
16
|
-
operations.all = getAllOperation(models, definition, registry);
|
|
17
|
-
operations.one = getOneOperation(models, definition, registry);
|
|
18
|
-
operations.create = getCreateOperation(models, definition, registry);
|
|
19
|
-
operations.update = getUpdateOperation(models, definition, registry);
|
|
20
|
-
operations.get = getGetOperation(models, definition, registry);
|
|
21
|
-
operations.remove = getRemoveOperation(models, definition);
|
|
22
|
-
operations.find = getFindOperation(models, definition, registry);
|
|
23
|
-
operations.upsert = async ()=>{
|
|
24
|
-
throw new Error('Not implemented');
|
|
25
|
-
};
|
|
26
|
-
return operations;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export { createOperations };
|
|
30
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3BlcmF0aW9ucy5qcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==
|
package/dist/es/Options.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import * as Library from '@fjell/lib';
|
|
2
|
-
|
|
3
|
-
const DEFAULT_SEQUELIZE_OPTIONS = {
|
|
4
|
-
deleteOnRemove: false,
|
|
5
|
-
references: [],
|
|
6
|
-
aggregations: []
|
|
7
|
-
};
|
|
8
|
-
const createOptions = (sequelizeOptions)=>{
|
|
9
|
-
// Create the base lib options
|
|
10
|
-
const baseOptions = Library.createOptions(sequelizeOptions);
|
|
11
|
-
var _sequelizeOptions_deleteOnRemove, _sequelizeOptions_references, _sequelizeOptions_aggregations;
|
|
12
|
-
// Add Sequelize-specific defaults
|
|
13
|
-
const result = {
|
|
14
|
-
...baseOptions,
|
|
15
|
-
deleteOnRemove: (_sequelizeOptions_deleteOnRemove = sequelizeOptions === null || sequelizeOptions === void 0 ? void 0 : sequelizeOptions.deleteOnRemove) !== null && _sequelizeOptions_deleteOnRemove !== void 0 ? _sequelizeOptions_deleteOnRemove : DEFAULT_SEQUELIZE_OPTIONS.deleteOnRemove,
|
|
16
|
-
references: (_sequelizeOptions_references = sequelizeOptions === null || sequelizeOptions === void 0 ? void 0 : sequelizeOptions.references) !== null && _sequelizeOptions_references !== void 0 ? _sequelizeOptions_references : DEFAULT_SEQUELIZE_OPTIONS.references,
|
|
17
|
-
aggregations: (_sequelizeOptions_aggregations = sequelizeOptions === null || sequelizeOptions === void 0 ? void 0 : sequelizeOptions.aggregations) !== null && _sequelizeOptions_aggregations !== void 0 ? _sequelizeOptions_aggregations : DEFAULT_SEQUELIZE_OPTIONS.aggregations
|
|
18
|
-
};
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export { createOptions };
|
|
23
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3B0aW9ucy5qcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
|
package/dist/es/QueryBuilder.js
DELETED
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import { isCondition, isPriKey, isComKey } from '@fjell/core';
|
|
2
|
-
import { Op } from 'sequelize';
|
|
3
|
-
import LibLogger from './logger.js';
|
|
4
|
-
import { stringifyJSON } from './util/general.js';
|
|
5
|
-
|
|
6
|
-
const logger = LibLogger.get('sequelize', 'QueryBuilder');
|
|
7
|
-
const addDeleteQuery = (options, model)=>{
|
|
8
|
-
logger.default(`QueryBuilder adding delete query with options: ${stringifyJSON(options)}`);
|
|
9
|
-
if (model.getAttributes().deletedAt) {
|
|
10
|
-
options.where['deletedAt'] = {
|
|
11
|
-
[Op.eq]: null
|
|
12
|
-
};
|
|
13
|
-
} else if (model.getAttributes().isDeleted) {
|
|
14
|
-
options.where['isDeleted'] = {
|
|
15
|
-
[Op.eq]: false
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
return options;
|
|
19
|
-
};
|
|
20
|
-
const addEventQueries = (options, events, model)=>{
|
|
21
|
-
logger.default(`QueryBuilder adding event queries with options: ${stringifyJSON(options)}, events: ${stringifyJSON(events)}`);
|
|
22
|
-
Object.keys(events).forEach((key)=>{
|
|
23
|
-
if (!model.getAttributes()[`${key}At`]) {
|
|
24
|
-
throw new Error(`Event ${key} is not supported on this model, column ${key}At not found`);
|
|
25
|
-
}
|
|
26
|
-
let whereClauses = {};
|
|
27
|
-
const event = events[key];
|
|
28
|
-
if (event.start) {
|
|
29
|
-
whereClauses = {
|
|
30
|
-
...whereClauses,
|
|
31
|
-
[Op.gte]: new Date(event.start)
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
if (event.end) {
|
|
35
|
-
whereClauses = {
|
|
36
|
-
...whereClauses,
|
|
37
|
-
[Op.lt]: new Date(event.end)
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
if (event.by) {
|
|
41
|
-
if (!model.getAttributes()[`${key}By`]) {
|
|
42
|
-
throw new Error(`Event ${key} is not supported on this model, column ${key}By not found`);
|
|
43
|
-
}
|
|
44
|
-
whereClauses = {
|
|
45
|
-
...whereClauses,
|
|
46
|
-
[Op.eq]: event.by
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
options.where[`${key}At`] = whereClauses;
|
|
50
|
-
});
|
|
51
|
-
return options;
|
|
52
|
-
};
|
|
53
|
-
// Add the references to the query
|
|
54
|
-
const addReferenceQueries = (options, references, model)=>{
|
|
55
|
-
logger.default(`QueryBuilder adding reference queries with options: ${stringifyJSON(options)}, references: ${stringifyJSON(references)}`);
|
|
56
|
-
Object.keys(references).forEach((key)=>{
|
|
57
|
-
logger.default(`QueryBuilder adding reference query for key: ${key}, references: ${stringifyJSON(references)}`);
|
|
58
|
-
if (!model.getAttributes()[`${key}Id`]) {
|
|
59
|
-
throw new Error(`Reference ${key} is not supported on this model, column ${key}Id not found`);
|
|
60
|
-
}
|
|
61
|
-
if (isPriKey(references[key])) {
|
|
62
|
-
const priKey = references[key];
|
|
63
|
-
if (priKey.pk == null || priKey.pk === '' || typeof priKey.pk === 'object' && Object.keys(priKey.pk).length === 0) {
|
|
64
|
-
logger.error(`Reference key '${key}' has invalid pk value: ${stringifyJSON(priKey.pk)}`, {
|
|
65
|
-
priKey,
|
|
66
|
-
references
|
|
67
|
-
});
|
|
68
|
-
throw new Error(`Reference key '${key}' has invalid pk value: ${stringifyJSON(priKey.pk)}`);
|
|
69
|
-
}
|
|
70
|
-
logger.trace(`[QueryBuilder] Setting reference where clause: ${key}Id = ${stringifyJSON(priKey.pk)} (type: ${typeof priKey.pk})`);
|
|
71
|
-
options.where[`${key}Id`] = {
|
|
72
|
-
[Op.eq]: priKey.pk
|
|
73
|
-
};
|
|
74
|
-
} else if (isComKey(references[key])) {
|
|
75
|
-
throw new Error('ComKeys are not supported in Sequelize');
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
return options;
|
|
79
|
-
};
|
|
80
|
-
const addCompoundCondition = (options, compoundCondition, model)=>{
|
|
81
|
-
// Ensure options.where exists
|
|
82
|
-
options.where = options.where || {};
|
|
83
|
-
let compoundOp;
|
|
84
|
-
const compoundType = compoundCondition.compoundType;
|
|
85
|
-
if (compoundType === "AND") {
|
|
86
|
-
compoundOp = Op.and;
|
|
87
|
-
} else {
|
|
88
|
-
compoundOp = Op.or;
|
|
89
|
-
}
|
|
90
|
-
let conditions = {};
|
|
91
|
-
compoundCondition.conditions.forEach((condition)=>{
|
|
92
|
-
if (isCondition(condition)) {
|
|
93
|
-
conditions = addCondition(conditions, condition, model);
|
|
94
|
-
} else {
|
|
95
|
-
throw new Error('Nest Compound conditions not supported');
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
// Merge with existing where conditions instead of replacing
|
|
99
|
-
if (Object.keys(options.where).length > 0) {
|
|
100
|
-
// If there are existing conditions, wrap everything in an AND
|
|
101
|
-
options.where = {
|
|
102
|
-
[Op.and]: [
|
|
103
|
-
options.where,
|
|
104
|
-
{
|
|
105
|
-
[compoundOp]: conditions
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
};
|
|
109
|
-
} else {
|
|
110
|
-
// If no existing conditions, just set the compound condition
|
|
111
|
-
options.where[compoundOp] = conditions;
|
|
112
|
-
}
|
|
113
|
-
return options;
|
|
114
|
-
};
|
|
115
|
-
const getSequelizeOperator = (operator)=>{
|
|
116
|
-
if (operator === '==') {
|
|
117
|
-
return Op.eq;
|
|
118
|
-
} else if (operator === '<') {
|
|
119
|
-
return Op.lt;
|
|
120
|
-
} else if (operator === '>') {
|
|
121
|
-
return Op.gt;
|
|
122
|
-
} else if (operator === '<=') {
|
|
123
|
-
return Op.lte;
|
|
124
|
-
} else if (operator === '>=') {
|
|
125
|
-
return Op.gte;
|
|
126
|
-
} else if (operator === 'in') {
|
|
127
|
-
return Op.in;
|
|
128
|
-
} else {
|
|
129
|
-
throw new Error(`Operator ${operator} not supported`);
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
const addAssociationCondition = (conditions, condition, model)=>{
|
|
133
|
-
const [associationName, attributeName] = condition.column.split('.', 2);
|
|
134
|
-
// Check if the association exists on the model
|
|
135
|
-
if (!model.associations || !model.associations[associationName]) {
|
|
136
|
-
throw new Error(`Association ${associationName} not found on model ${model.name}`);
|
|
137
|
-
}
|
|
138
|
-
const association = model.associations[associationName];
|
|
139
|
-
const associatedModel = association.target;
|
|
140
|
-
// Check if the attribute exists on the associated model
|
|
141
|
-
if (!associatedModel.getAttributes()[attributeName]) {
|
|
142
|
-
throw new Error(`Attribute ${attributeName} not found on associated model ${associatedModel.name} for association ${associationName}`);
|
|
143
|
-
}
|
|
144
|
-
// Use Sequelize's $association.attribute$ syntax for querying associated models
|
|
145
|
-
const sequelizeAssociationColumn = `$${associationName}.${attributeName}$`;
|
|
146
|
-
const conditionOp = getSequelizeOperator(condition.operator);
|
|
147
|
-
if (condition.value == null && condition.operator !== '==' && condition.operator !== 'in') {
|
|
148
|
-
logger.error(`Association condition for '${associationName}.${attributeName}' has undefined/null value`, {
|
|
149
|
-
condition
|
|
150
|
-
});
|
|
151
|
-
throw new Error(`Association condition for '${associationName}.${attributeName}' has undefined/null value`);
|
|
152
|
-
}
|
|
153
|
-
logger.trace(`[QueryBuilder] Setting association condition: ${sequelizeAssociationColumn} = ${stringifyJSON(condition.value)} (type: ${typeof condition.value})`);
|
|
154
|
-
conditions[sequelizeAssociationColumn] = {
|
|
155
|
-
[conditionOp]: condition.value
|
|
156
|
-
};
|
|
157
|
-
return conditions;
|
|
158
|
-
};
|
|
159
|
-
const addAttributeCondition = (conditions, condition, model)=>{
|
|
160
|
-
const conditionColumn = condition.column;
|
|
161
|
-
if (!model.getAttributes()[conditionColumn]) {
|
|
162
|
-
throw new Error(`Condition column ${conditionColumn} not found on model ${model.name}`);
|
|
163
|
-
}
|
|
164
|
-
const conditionOp = getSequelizeOperator(condition.operator);
|
|
165
|
-
if (condition.value == null && condition.operator !== '==' && condition.operator !== 'in') {
|
|
166
|
-
logger.error(`Attribute condition for '${conditionColumn}' has undefined/null value`, {
|
|
167
|
-
condition
|
|
168
|
-
});
|
|
169
|
-
throw new Error(`Attribute condition for '${conditionColumn}' has undefined/null value`);
|
|
170
|
-
}
|
|
171
|
-
logger.trace(`[QueryBuilder] Setting attribute condition: ${conditionColumn} = ${stringifyJSON(condition.value)} (type: ${typeof condition.value})`);
|
|
172
|
-
conditions[conditionColumn] = {
|
|
173
|
-
[conditionOp]: condition.value
|
|
174
|
-
};
|
|
175
|
-
return conditions;
|
|
176
|
-
};
|
|
177
|
-
const addCondition = (conditions, condition, model)=>{
|
|
178
|
-
const conditionColumn = condition.column;
|
|
179
|
-
// Check if this is an association query (contains a dot)
|
|
180
|
-
if (conditionColumn.includes('.')) {
|
|
181
|
-
return addAssociationCondition(conditions, condition, model);
|
|
182
|
-
}
|
|
183
|
-
// Handle regular column queries
|
|
184
|
-
return addAttributeCondition(conditions, condition, model);
|
|
185
|
-
};
|
|
186
|
-
const collectAssociationsFromConditions = (conditions)=>{
|
|
187
|
-
const associations = new Set();
|
|
188
|
-
const processObject = (obj)=>{
|
|
189
|
-
if (typeof obj === 'object' && obj !== null) {
|
|
190
|
-
// Check string keys
|
|
191
|
-
Object.keys(obj).forEach((key)=>{
|
|
192
|
-
// Check if this is an association reference ($association.attribute$)
|
|
193
|
-
if (typeof key === 'string' && key.startsWith('$') && key.endsWith('$') && key.includes('.')) {
|
|
194
|
-
const associationName = key.substring(1, key.indexOf('.'));
|
|
195
|
-
associations.add(associationName);
|
|
196
|
-
}
|
|
197
|
-
// Recursively process nested objects
|
|
198
|
-
if (typeof obj[key] === 'object') {
|
|
199
|
-
processObject(obj[key]);
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
// Also check Symbol keys (for compound conditions like Op.and, Op.or)
|
|
203
|
-
Object.getOwnPropertySymbols(obj).forEach((symbol)=>{
|
|
204
|
-
if (typeof obj[symbol] === 'object') {
|
|
205
|
-
processObject(obj[symbol]);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
// Handle arrays (for compound conditions that might be arrays)
|
|
210
|
-
if (Array.isArray(obj)) {
|
|
211
|
-
obj.forEach((item)=>{
|
|
212
|
-
if (typeof item === 'object') {
|
|
213
|
-
processObject(item);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
processObject(conditions);
|
|
219
|
-
return associations;
|
|
220
|
-
};
|
|
221
|
-
const addAssociationIncludes = (options, model)=>{
|
|
222
|
-
// Collect all association names used in conditions
|
|
223
|
-
const referencedAssociations = collectAssociationsFromConditions(options.where);
|
|
224
|
-
if (referencedAssociations.size > 0) {
|
|
225
|
-
options.include = options.include || [];
|
|
226
|
-
// Add each referenced association to the include array
|
|
227
|
-
referencedAssociations.forEach((associationName)=>{
|
|
228
|
-
// Check if this association is already included
|
|
229
|
-
const alreadyIncluded = options.include.some((inc)=>typeof inc === 'string' && inc === associationName || typeof inc === 'object' && inc.association === associationName);
|
|
230
|
-
if (!alreadyIncluded && model.associations && model.associations[associationName]) {
|
|
231
|
-
options.include.push({
|
|
232
|
-
model: model.associations[associationName].target,
|
|
233
|
-
as: associationName,
|
|
234
|
-
required: false // Use LEFT JOIN so records without associations are still returned
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
return options;
|
|
240
|
-
};
|
|
241
|
-
const buildQuery = (itemQuery, model)=>{
|
|
242
|
-
logger.default(`QueryBuilder build called with itemQuery: ${stringifyJSON(itemQuery)}`);
|
|
243
|
-
let options = {
|
|
244
|
-
where: {}
|
|
245
|
-
};
|
|
246
|
-
if (itemQuery.compoundCondition) {
|
|
247
|
-
logger.default(`QueryBuilder adding conditions: ${stringifyJSON(itemQuery.compoundCondition)}`);
|
|
248
|
-
options = addCompoundCondition(options, itemQuery.compoundCondition, model);
|
|
249
|
-
}
|
|
250
|
-
// If the model has a deletedAt column, we need to add a delete query
|
|
251
|
-
if (model.getAttributes().deletedAt || model.getAttributes().isDeleted) {
|
|
252
|
-
options = addDeleteQuery(options, model);
|
|
253
|
-
}
|
|
254
|
-
if (itemQuery.refs) {
|
|
255
|
-
options = addReferenceQueries(options, itemQuery.refs, model);
|
|
256
|
-
}
|
|
257
|
-
if (itemQuery.events) {
|
|
258
|
-
options = addEventQueries(options, itemQuery.events, model);
|
|
259
|
-
}
|
|
260
|
-
// TODO: Once we start to support Aggs on the server-side, we'll need to parse agg queries
|
|
261
|
-
// Apply a limit to the result set
|
|
262
|
-
if (itemQuery.limit) {
|
|
263
|
-
logger.default(`QueryBuilder applying limit: ${itemQuery.limit}`);
|
|
264
|
-
options.limit = itemQuery.limit;
|
|
265
|
-
}
|
|
266
|
-
// Apply an offset to the result set
|
|
267
|
-
if (itemQuery.offset) {
|
|
268
|
-
options.offset = itemQuery.offset;
|
|
269
|
-
}
|
|
270
|
-
// Add orderBy to the query
|
|
271
|
-
if (itemQuery.orderBy) {
|
|
272
|
-
itemQuery.orderBy.forEach((orderBy)=>{
|
|
273
|
-
if (!model.getAttributes()[orderBy.field]) {
|
|
274
|
-
throw new Error(`Order by field ${orderBy.field} not found on model ${model.name}`);
|
|
275
|
-
}
|
|
276
|
-
options.order = [
|
|
277
|
-
[
|
|
278
|
-
orderBy.field,
|
|
279
|
-
orderBy.direction
|
|
280
|
-
]
|
|
281
|
-
];
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
// Add includes for any associations referenced in conditions
|
|
285
|
-
options = addAssociationIncludes(options, model);
|
|
286
|
-
return options;
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
export { addCompoundCondition, addCondition, buildQuery };
|
|
290
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUXVlcnlCdWlsZGVyLmpzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
|