@futdevpro/fsm-dynamo 1.14.11 → 1.14.13
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/.vscode/settings.json +11 -0
- package/build/_collections/utils/json-error-helper.util.d.ts.map +1 -1
- package/build/_collections/utils/json-error-helper.util.js.map +1 -1
- package/build/_collections/utils/stack.util.d.ts.map +1 -1
- package/build/_collections/utils/stack.util.js +3 -2
- package/build/_collections/utils/stack.util.js.map +1 -1
- package/build/_models/control-models/service-endpoint-settings-base.control-model.d.ts +22 -1
- package/build/_models/control-models/service-endpoint-settings-base.control-model.d.ts.map +1 -1
- package/build/_models/control-models/service-endpoint-settings-base.control-model.js +23 -1
- package/build/_models/control-models/service-endpoint-settings-base.control-model.js.map +1 -1
- package/build/_modules/ai/_modules/open-ai/index.d.ts.map +1 -1
- package/build/_modules/ai/_modules/open-ai/index.js +7 -7
- package/build/_modules/ai/_modules/open-ai/index.js.map +1 -1
- package/build/_modules/crypto/_collections/{crypto-2-non-stable.util.d.ts → crypto-v1.util.d.ts} +1 -1
- package/build/_modules/crypto/_collections/crypto-v1.util.d.ts.map +1 -0
- package/build/_modules/crypto/_collections/{crypto-2-non-stable.util.js → crypto-v1.util.js} +1 -1
- package/build/_modules/crypto/_collections/crypto-v1.util.js.map +1 -0
- package/build/_modules/crypto/_collections/{crypto-old.util.d.ts → crypto-v2.util.d.ts} +1 -1
- package/build/_modules/crypto/_collections/crypto-v2.util.d.ts.map +1 -0
- package/build/_modules/crypto/_collections/{crypto-old.util.js → crypto-v2.util.js} +10 -10
- package/build/_modules/crypto/_collections/crypto-v2.util.js.map +1 -0
- package/build/_modules/crypto/_collections/crypto-v4.util.d.ts +165 -0
- package/build/_modules/crypto/_collections/crypto-v4.util.d.ts.map +1 -0
- package/build/_modules/crypto/_collections/crypto-v4.util.js +611 -0
- package/build/_modules/crypto/_collections/crypto-v4.util.js.map +1 -0
- package/build/_modules/crypto/index.d.ts.map +1 -1
- package/build/_modules/crypto/index.js +7 -7
- package/build/_modules/crypto/index.js.map +1 -1
- package/build/_modules/data-handler/_models/data-handler-settings.control-model.d.ts +73 -0
- package/build/_modules/data-handler/_models/data-handler-settings.control-model.d.ts.map +1 -0
- package/build/_modules/data-handler/_models/data-handler-settings.control-model.js +83 -0
- package/build/_modules/data-handler/_models/data-handler-settings.control-model.js.map +1 -0
- package/build/_modules/data-handler/_models/data-handler.control-model.d.ts +136 -0
- package/build/_modules/data-handler/_models/data-handler.control-model.d.ts.map +1 -0
- package/build/_modules/data-handler/_models/data-handler.control-model.js +333 -0
- package/build/_modules/data-handler/_models/data-handler.control-model.js.map +1 -0
- package/build/_modules/data-handler/_models/data-list-handler.control-model.d.ts +111 -0
- package/build/_modules/data-handler/_models/data-list-handler.control-model.d.ts.map +1 -0
- package/build/_modules/data-handler/_models/data-list-handler.control-model.js +217 -0
- package/build/_modules/data-handler/_models/data-list-handler.control-model.js.map +1 -0
- package/build/_modules/data-handler/_models/data-search-handler.control-model.d.ts +172 -0
- package/build/_modules/data-handler/_models/data-search-handler.control-model.d.ts.map +1 -0
- package/build/_modules/data-handler/_models/data-search-handler.control-model.js +325 -0
- package/build/_modules/data-handler/_models/data-search-handler.control-model.js.map +1 -0
- package/build/_modules/data-handler/_models/list-collector-data-handler.control-model.d.ts +116 -0
- package/build/_modules/data-handler/_models/list-collector-data-handler.control-model.d.ts.map +1 -0
- package/build/_modules/data-handler/_models/list-collector-data-handler.control-model.js +245 -0
- package/build/_modules/data-handler/_models/list-collector-data-handler.control-model.js.map +1 -0
- package/build/_modules/data-handler/index.d.ts +6 -0
- package/build/_modules/data-handler/index.d.ts.map +1 -0
- package/build/_modules/data-handler/index.js +10 -0
- package/build/_modules/data-handler/index.js.map +1 -0
- package/eslint.config.js +4 -0
- package/futdevpro-fsm-dynamo-01.14.13.tgz +0 -0
- package/package.json +22 -3
- package/src/_collections/utils/json-error-helper.util.ts +5 -3
- package/src/_collections/utils/stack.util.ts +8 -4
- package/src/_models/control-models/service-endpoint-settings-base.control-model.ts +41 -4
- package/src/_modules/ai/_modules/open-ai/index.ts +4 -3
- package/src/_modules/crypto/_collections/{crypto-old.util.ts → crypto-v2.util.ts} +17 -9
- package/src/_modules/crypto/_collections/crypto-v4.util.ts +702 -0
- package/src/_modules/crypto/index.ts +4 -3
- package/src/_modules/data-handler/_models/data-handler-settings.control-model.ts +110 -0
- package/src/_modules/data-handler/_models/data-handler.control-model.ts +459 -0
- package/src/_modules/data-handler/_models/data-list-handler.control-model.ts +245 -0
- package/src/_modules/data-handler/_models/data-search-handler.control-model.ts +390 -0
- package/src/_modules/data-handler/_models/list-collector-data-handler.control-model.ts +274 -0
- package/src/_modules/data-handler/index.ts +6 -0
- package/src/_modules/usage/_collections/usg-module-settings.const.ts +1 -1
- package/.eslintrc.json +0 -155
- package/build/_modules/crypto/_collections/crypto-2-non-stable.util.d.ts.map +0 -1
- package/build/_modules/crypto/_collections/crypto-2-non-stable.util.js.map +0 -1
- package/build/_modules/crypto/_collections/crypto-old.util.d.ts.map +0 -1
- package/build/_modules/crypto/_collections/crypto-old.util.js.map +0 -1
- package/futdevpro-fsm-dynamo-01.14.11.tgz +0 -0
- /package/src/_modules/crypto/_collections/{crypto-2-non-stable.util.ts → crypto-v1.util.ts} +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyFM_ListCollectorDataHandler = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const data_handler_control_model_1 = require("./data-handler.control-model");
|
|
6
|
+
const error_control_model_1 = require("../../../_models/control-models/error.control-model");
|
|
7
|
+
/**
|
|
8
|
+
* A specialized data handler for managing list collections within a parent data object.
|
|
9
|
+
* Extends DyFM_DataHandler to provide functionality for handling lists within a collector object.
|
|
10
|
+
*
|
|
11
|
+
* @template T_ListCollectorData - The type of the parent collector data object
|
|
12
|
+
* @template T_DataItem - The type of individual items in the list (must extend DyFM_Metadata)
|
|
13
|
+
* @template T_DependencyData - The type of dependency data (defaults to any)
|
|
14
|
+
* @template T_DataLoadBy - The type used to identify how data should be loaded (defaults to string)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* // Create a list collector handler for user's projects
|
|
19
|
+
* const userProjectsHandler = new DyFM_ListCollectorDataHandler<User, Project>({
|
|
20
|
+
* listKey: 'projects',
|
|
21
|
+
* get: async (userId: string): Promise<User> => {
|
|
22
|
+
* return await userService.getUserWithProjects(userId);
|
|
23
|
+
* }
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Access the data list
|
|
27
|
+
* const projects = userProjectsHandler.dataList;
|
|
28
|
+
*
|
|
29
|
+
* // Add a new project
|
|
30
|
+
* userProjectsHandler.addItem(newProject);
|
|
31
|
+
*
|
|
32
|
+
* // Update an existing project
|
|
33
|
+
* userProjectsHandler.updateItem(updatedProject);
|
|
34
|
+
*
|
|
35
|
+
* // Subscribe to changes
|
|
36
|
+
* userProjectsHandler.dataList$.subscribe(projects => {
|
|
37
|
+
* console.log('Projects updated:', projects);
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
class DyFM_ListCollectorDataHandler extends data_handler_control_model_1.DyFM_DataHandler {
|
|
42
|
+
/** this is only for data list handlers,
|
|
43
|
+
* while creating arrow function for this, dont forget to use async n await! */
|
|
44
|
+
setItem;
|
|
45
|
+
/** this is only for data list handlers,
|
|
46
|
+
* while creating arrow function for this, dont forget to use async n await! */
|
|
47
|
+
deleteItem;
|
|
48
|
+
listKey;
|
|
49
|
+
/**
|
|
50
|
+
* BehaviorSubject that holds the current data list.
|
|
51
|
+
* Computed from the base data_BS BehaviorSubject, ensuring it always returns an array.
|
|
52
|
+
*/
|
|
53
|
+
dataList_BS;
|
|
54
|
+
/**
|
|
55
|
+
* Observable that holds the current data list.
|
|
56
|
+
* Computed from the base data$ Observable, ensuring it always returns an array.
|
|
57
|
+
*/
|
|
58
|
+
dataList$;
|
|
59
|
+
/**
|
|
60
|
+
* BehaviorSubject that holds the currently active item.
|
|
61
|
+
*/
|
|
62
|
+
activeItem_BS;
|
|
63
|
+
/**
|
|
64
|
+
* Observable that holds the currently active item.
|
|
65
|
+
*/
|
|
66
|
+
activeItem$;
|
|
67
|
+
/**
|
|
68
|
+
* Gets the current data value.
|
|
69
|
+
* @returns The current data value
|
|
70
|
+
*/
|
|
71
|
+
get data() {
|
|
72
|
+
return this.data_BS.value;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Gets the current data list.
|
|
76
|
+
* Alias for data getter.
|
|
77
|
+
* @returns The current array of data items
|
|
78
|
+
*/
|
|
79
|
+
get dataList() {
|
|
80
|
+
return this.dataList_BS.value;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Creates a new instance of DyFM_ListCollectorDataHandler.
|
|
84
|
+
*
|
|
85
|
+
* @param set - Configuration settings for the data handler
|
|
86
|
+
* @param skipDependencyConnections - Optional flag to skip dependency connections during construction
|
|
87
|
+
*/
|
|
88
|
+
constructor(set,
|
|
89
|
+
/** is in construct?
|
|
90
|
+
* so the dependent data handlers are not added here, but in the extended class */
|
|
91
|
+
skipDependencyConnections) {
|
|
92
|
+
super(set, skipDependencyConnections);
|
|
93
|
+
this.listKey = set.listKey;
|
|
94
|
+
// Initialize dataList BehaviorSubject and Observable
|
|
95
|
+
this.dataList_BS = new rxjs_1.BehaviorSubject([]);
|
|
96
|
+
this.dataList$ = this.dataList_BS.asObservable();
|
|
97
|
+
// Initialize activeItem BehaviorSubject and Observable
|
|
98
|
+
this.activeItem_BS = new rxjs_1.BehaviorSubject(null);
|
|
99
|
+
this.activeItem$ = this.activeItem_BS.asObservable();
|
|
100
|
+
// Subscribe to data changes to update dataList
|
|
101
|
+
this.data$.subscribe(data => {
|
|
102
|
+
const dataList = Array.isArray(data?.[this.listKey]) ? data[this.listKey] : [];
|
|
103
|
+
this.dataList_BS.next(dataList);
|
|
104
|
+
});
|
|
105
|
+
if (set.setItem) {
|
|
106
|
+
this.setItem = set.setItem;
|
|
107
|
+
}
|
|
108
|
+
if (set.deleteItem) {
|
|
109
|
+
this.deleteItem = set.deleteItem;
|
|
110
|
+
}
|
|
111
|
+
this.getPostProcesses.push((data) => {
|
|
112
|
+
// check if data is an array
|
|
113
|
+
if (!Array.isArray(data)) {
|
|
114
|
+
console.error(`DYNAMO DynamoDataHandler (${this.name}) ERROR: ` +
|
|
115
|
+
`\nData is not an array!:` +
|
|
116
|
+
'\n\n', data);
|
|
117
|
+
throw new Error(`Data is not an array! (${this.name})`);
|
|
118
|
+
}
|
|
119
|
+
return data;
|
|
120
|
+
});
|
|
121
|
+
if (!skipDependencyConnections) {
|
|
122
|
+
if (set.dependencyDataHandler) {
|
|
123
|
+
this.addDependencyDataHandler(set.dependencyDataHandler);
|
|
124
|
+
}
|
|
125
|
+
if (set.dependentDataHandlers) {
|
|
126
|
+
this.addDependentDataHandlers(set.dependentDataHandlers, true);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
clear(dontClearDependents) {
|
|
131
|
+
super.clear(dontClearDependents);
|
|
132
|
+
this.activeItem_BS.next(null);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Adds a new item to the data list.
|
|
136
|
+
*
|
|
137
|
+
* @param item - The item to add to the list
|
|
138
|
+
* @param collectorId - Optional collector ID for tracking
|
|
139
|
+
* @param dontSendUpdate - Optional flag to prevent sending update notification
|
|
140
|
+
*/
|
|
141
|
+
async addItem(item, collectorId, dontSendUpdate) {
|
|
142
|
+
if (!this.data) {
|
|
143
|
+
throw new error_control_model_1.DyFM_Error({
|
|
144
|
+
error: new Error(`Data not found! (${this.name})`),
|
|
145
|
+
errorCode: 'DyFM-LCDH-AI1',
|
|
146
|
+
additionalContent: {
|
|
147
|
+
listKey: this.listKey,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
this.data[this.listKey] ??= [];
|
|
152
|
+
this.data[this.listKey].push(item);
|
|
153
|
+
if (this.setItem && !dontSendUpdate) {
|
|
154
|
+
await this.setItem(item, collectorId);
|
|
155
|
+
// dont send update because we already sent it to the setItem function
|
|
156
|
+
await this.updateData(this.data_BS.value, true);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
await this.updateData(this.data_BS.value, dontSendUpdate);
|
|
160
|
+
}
|
|
161
|
+
this.activeItem_BS.next(item);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Removes an item from the data list.
|
|
165
|
+
* The item is identified by its _id property.
|
|
166
|
+
*
|
|
167
|
+
* @param id - The id of the item to remove from the list
|
|
168
|
+
* @param collectorId - Optional collector ID for tracking
|
|
169
|
+
* @param dontSendUpdate - Optional flag to prevent sending update notification
|
|
170
|
+
*/
|
|
171
|
+
async removeItem(id, collectorId, dontSendUpdate) {
|
|
172
|
+
if (!this.data?.[this.listKey]?.length) {
|
|
173
|
+
throw new error_control_model_1.DyFM_Error({
|
|
174
|
+
error: new Error(`List not found! (${this.name})`),
|
|
175
|
+
errorCode: 'DyFM-LCDH-RI1',
|
|
176
|
+
additionalContent: {
|
|
177
|
+
listKey: this.listKey,
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
const index = this.data[this.listKey].findIndex(i => i._id === id);
|
|
182
|
+
if (index !== -1) {
|
|
183
|
+
this.data[this.listKey].splice(index, 1);
|
|
184
|
+
if (this.deleteItem) {
|
|
185
|
+
await this.deleteItem(id, collectorId);
|
|
186
|
+
await this.updateData(this.data_BS.value, true);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
await this.updateData(this.data_BS.value, dontSendUpdate);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (this.activeItem_BS.value?._id === id) {
|
|
193
|
+
this.activeItem_BS.next(null);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Updates an existing item in the data list.
|
|
198
|
+
* The item is identified by its _id property.
|
|
199
|
+
*
|
|
200
|
+
* @param item - The updated item
|
|
201
|
+
* @param collectorId - Optional collector ID for tracking
|
|
202
|
+
* @param dontSendUpdate - Optional flag to prevent sending update notification
|
|
203
|
+
* @throws Error if the item is not found in the list
|
|
204
|
+
*/
|
|
205
|
+
async updateItem(item, collectorId, dontSendUpdate) {
|
|
206
|
+
if (!this.data?.[this.listKey]?.length) {
|
|
207
|
+
throw new error_control_model_1.DyFM_Error({
|
|
208
|
+
error: new Error(`List not found! (${this.name})`),
|
|
209
|
+
errorCode: 'DyFM-LCDH-UI0',
|
|
210
|
+
additionalContent: {
|
|
211
|
+
listKey: this.listKey,
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
// check if item is in the list
|
|
216
|
+
const index = this.data[this.listKey].findIndex(i => i._id === item._id);
|
|
217
|
+
if (index !== -1) {
|
|
218
|
+
// update the item
|
|
219
|
+
this.data[this.listKey][index] = item;
|
|
220
|
+
if (this.setItem) {
|
|
221
|
+
// send update to API
|
|
222
|
+
await this.setItem(item, collectorId);
|
|
223
|
+
await this.updateData(this.data_BS.value, true);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
// send update to API
|
|
227
|
+
await this.updateData(this.data_BS.value, dontSendUpdate);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
throw new error_control_model_1.DyFM_Error({
|
|
232
|
+
error: new Error(`Item not found! (${this.name})`),
|
|
233
|
+
errorCode: 'DyFM-LCDH-UI1',
|
|
234
|
+
additionalContent: {
|
|
235
|
+
item: item,
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
setActiveItem(item) {
|
|
241
|
+
this.activeItem_BS.next(item);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
exports.DyFM_ListCollectorDataHandler = DyFM_ListCollectorDataHandler;
|
|
245
|
+
//# sourceMappingURL=list-collector-data-handler.control-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-collector-data-handler.control-model.js","sourceRoot":"","sources":["../../../../src/_modules/data-handler/_models/list-collector-data-handler.control-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './_models/data-handler.control-model';
|
|
2
|
+
export * from './_models/data-handler-settings.control-model';
|
|
3
|
+
export * from './_models/data-list-handler.control-model';
|
|
4
|
+
export * from './_models/data-search-handler.control-model';
|
|
5
|
+
export * from './_models/list-collector-data-handler.control-model';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/data-handler/index.ts"],"names":[],"mappings":"AACA,cAAc,sCAAsC,CAAC;AACrD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,qDAAqD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
// MODELS
|
|
5
|
+
tslib_1.__exportStar(require("./_models/data-handler.control-model"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./_models/data-handler-settings.control-model"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./_models/data-list-handler.control-model"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./_models/data-search-handler.control-model"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./_models/list-collector-data-handler.control-model"), exports);
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/data-handler/index.ts"],"names":[],"mappings":";;;AAAA,SAAS;AACT,+EAAqD;AACrD,wFAA8D;AAC9D,oFAA0D;AAC1D,sFAA4D;AAC5D,8FAAoE"}
|
package/eslint.config.js
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/fsm-dynamo",
|
|
3
|
-
"version": "01.14.
|
|
3
|
+
"version": "01.14.13",
|
|
4
4
|
"description": "Full Stack Model Collection for Dynamic (NodeJS-Typescript) Framework called Dynamo, by Future Development Ltd.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "full-stack-package",
|
|
@@ -29,7 +29,14 @@
|
|
|
29
29
|
"test": "pnpm run build-base && jasmine",
|
|
30
30
|
"test-clean": "pnpm run build-clean && jasmine",
|
|
31
31
|
"crypto-test": "node ./scripts/crypto/stress-test-crypto.js",
|
|
32
|
-
"crypto-test-clean": "pnpm run build-clean && node ./scripts/crypto/stress-test-crypto.js"
|
|
32
|
+
"crypto-test-clean": "pnpm run build-clean && node ./scripts/crypto/stress-test-crypto.js",
|
|
33
|
+
"lint": "eslint src --ext .ts",
|
|
34
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
35
|
+
"validate:imports": "dynamo-validate-imports",
|
|
36
|
+
"validate:naming": "dynamo-validate-naming",
|
|
37
|
+
"audit:eslintrc": "dynamo-eslintrc-audit",
|
|
38
|
+
"fix": "dynamo-fix",
|
|
39
|
+
"fix:return-types": "dynamo-fix-return-types"
|
|
33
40
|
},
|
|
34
41
|
"main": "./build/index.js",
|
|
35
42
|
"module": "./build/index.js",
|
|
@@ -140,6 +147,12 @@
|
|
|
140
147
|
"module": "./build/_modules/usage/index.js",
|
|
141
148
|
"types": "./build/_modules/usage/index.d.ts",
|
|
142
149
|
"typings": "./build/_modules/usage/index.d.ts"
|
|
150
|
+
},
|
|
151
|
+
"./data-handler": {
|
|
152
|
+
"default": "./build/_modules/data-handler/index.js",
|
|
153
|
+
"module": "./build/_modules/data-handler/index.js",
|
|
154
|
+
"types": "./build/_modules/data-handler/index.d.ts",
|
|
155
|
+
"typings": "./build/_modules/data-handler/index.d.ts"
|
|
143
156
|
}
|
|
144
157
|
},
|
|
145
158
|
"typesVersions": {
|
|
@@ -163,7 +176,8 @@
|
|
|
163
176
|
"pipe": [ "build/_modules/pipe/index.d.ts" ],
|
|
164
177
|
"socket": [ "build/_modules/socket/index.d.ts" ],
|
|
165
178
|
"test": [ "build/_modules/test/index.d.ts" ],
|
|
166
|
-
"usage": [ "build/_modules/usage/index.d.ts" ]
|
|
179
|
+
"usage": [ "build/_modules/usage/index.d.ts" ],
|
|
180
|
+
"data-handler": [ "build/_modules/data-handler/index.d.ts" ]
|
|
167
181
|
}
|
|
168
182
|
},
|
|
169
183
|
"keywords": [],
|
|
@@ -183,14 +197,19 @@
|
|
|
183
197
|
"uuid": "12.0.0"
|
|
184
198
|
},
|
|
185
199
|
"devDependencies": {
|
|
200
|
+
"@futdevpro/dynamo-eslint": "1.14.9",
|
|
186
201
|
"@types/jasmine": "~4.3.5",
|
|
187
202
|
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
|
188
203
|
"@typescript-eslint/parser": "^8.41.0",
|
|
189
204
|
"eslint": "^9.34.0",
|
|
205
|
+
"eslint-plugin-import": "^2.29.0",
|
|
206
|
+
"eslint-plugin-jsdoc": "^48.0.0",
|
|
190
207
|
"eslint-plugin-max-params-no-constructor": "^0.0.4",
|
|
208
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
191
209
|
"eslint-plugin-unused-imports": "^4.1.4",
|
|
192
210
|
"jasmine": "5.10.0",
|
|
193
211
|
"jasmine-spec-reporter": "^7.0.0",
|
|
212
|
+
"prettier": "^3.3.0",
|
|
194
213
|
"crypto-js": "~4.2.0",
|
|
195
214
|
"openai": "^4.93.0"
|
|
196
215
|
}
|
|
@@ -254,6 +254,7 @@ export class DyFM_JsonErrorHelper {
|
|
|
254
254
|
|
|
255
255
|
if (lineInfo) {
|
|
256
256
|
const formattedError = this.formatJsonErrorForLogging(lineInfo, errorMessage);
|
|
257
|
+
|
|
257
258
|
throw new Error(`JSON parsing failed:\n${formattedError.join('\n')}`);
|
|
258
259
|
} else {
|
|
259
260
|
// Fallback to simple error if we can't extract line info
|
|
@@ -286,14 +287,15 @@ export class DyFM_JsonErrorHelper {
|
|
|
286
287
|
.replace(/\[/g, '[\n ')
|
|
287
288
|
.replace(/\]/g, '\n]')
|
|
288
289
|
.replace(/\n\s*\n/g, '\n') // Remove double newlines
|
|
289
|
-
.replace(/^\s+|\s+$/gm, function(match, offset, string) {
|
|
290
|
+
.replace(/^\s+|\s+$/gm, function(match: string, offset: number, string: string): string {
|
|
290
291
|
// Trim but preserve indentation structure
|
|
291
292
|
if (!string || typeof string !== 'string') {
|
|
292
293
|
return match;
|
|
293
294
|
}
|
|
294
|
-
const lines = string.slice(0, offset).split('\n');
|
|
295
|
-
const depth = (string.slice(0, offset).match(/{|\[/g) || []).length -
|
|
295
|
+
const lines: string[] = string.slice(0, offset).split('\n');
|
|
296
|
+
const depth: number = (string.slice(0, offset).match(/{|\[/g) || []).length -
|
|
296
297
|
(string.slice(0, offset).match(/}|\]/g) || []).length;
|
|
298
|
+
|
|
297
299
|
return ' '.repeat(Math.max(0, depth));
|
|
298
300
|
});
|
|
299
301
|
}
|
|
@@ -13,7 +13,7 @@ import { DyFM_Log } from './log.util';
|
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
15
|
export function DyFM_getConstructionStackLocation(level: number = 0): string {
|
|
16
|
-
|
|
16
|
+
const stack: string = new Error().stack;
|
|
17
17
|
|
|
18
18
|
// Split the stack into lines and remove the first line (Error:)
|
|
19
19
|
let stackLines = stack?.split('\n')?.slice(2);
|
|
@@ -134,9 +134,13 @@ export function DyFM_getLocalStackLocation(level: number = 0): string {
|
|
|
134
134
|
|
|
135
135
|
if (!locationLine) {
|
|
136
136
|
DyFM_Log.warn(
|
|
137
|
-
`No location line found outside of node_modules or node: (0)
|
|
138
|
-
stack,
|
|
139
|
-
|
|
137
|
+
`No location line found outside of node_modules or node: (0)` +
|
|
138
|
+
`\n${typeof stack}\n${stack?.slice(0, 300)?.split('\n') + '...'}`,
|
|
139
|
+
{
|
|
140
|
+
stack,
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
|
|
140
144
|
return '';
|
|
141
145
|
}
|
|
142
146
|
}
|
|
@@ -17,7 +17,8 @@ class SomethingElse {
|
|
|
17
17
|
|
|
18
18
|
export interface DyFM_EndpointTypesContainer<
|
|
19
19
|
T_Result,
|
|
20
|
-
T_Inputs extends
|
|
20
|
+
//T_Inputs extends DyFM_API_Input<any>[] = [],
|
|
21
|
+
T_Inputs extends any[] = [],
|
|
21
22
|
T_Body = undefined
|
|
22
23
|
> {
|
|
23
24
|
resultType: T_Result;
|
|
@@ -74,9 +75,45 @@ export class DyFM_Endpoint_SettingsBase<T_Result, I_Inputs, T_Body> {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
export type DyFM_ServiceEndpoint_SettingsBase<T extends DyFM_ServiceEndpointTypesSettings> = {
|
|
77
|
-
[K in keyof T]: DyFM_Endpoint_SettingsBase<
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
[K in keyof T]: DyFM_Endpoint_SettingsBase<T[K]['resultType'], T[K]['inputTypes'], T[K]['bodyType']>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
export class DyFM_ServerRoute_SettingsBase<
|
|
84
|
+
T_Result,
|
|
85
|
+
T_Inputs extends DyFM_API_Input<any>[] = [],
|
|
86
|
+
T_Body = undefined
|
|
87
|
+
> extends DyFM_Endpoint_SettingsBase<T_Result, T_Inputs, T_Body> {
|
|
88
|
+
|
|
89
|
+
preProcesses: ((req: Request, res: Response) => Promise<void>)[];
|
|
90
|
+
/** this is the old way of setting up tasks, it will be deprecated in future (we want)
|
|
91
|
+
* @deprecated use simpleTask instead */
|
|
92
|
+
tasks?: ((req: Request, res: Response, issuer?: string, ...inputs: T_Inputs) => Promise<void>)[];
|
|
93
|
+
/**
|
|
94
|
+
* a simple task that is executed after the preProcesses
|
|
95
|
+
* this will automatically handle the API setup and this will be the TASK that will be executed
|
|
96
|
+
* (result will be sent to the client, error will be caught and sent to the client)
|
|
97
|
+
*/
|
|
98
|
+
simpleTask?: (...inputs: T_Inputs) => Promise<T_Result>;
|
|
99
|
+
|
|
100
|
+
constructor(
|
|
101
|
+
set: DyFM_ServerRoute_SettingsBase<T_Result, T_Inputs, T_Body>
|
|
102
|
+
) {
|
|
103
|
+
super(set);
|
|
104
|
+
|
|
105
|
+
Object.assign(this, set);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface DyFM_API_Input<T_Input> {
|
|
110
|
+
type: DyFM_API_Input_Type;
|
|
111
|
+
value: T_Input;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export enum DyFM_API_Input_Type {
|
|
115
|
+
body = 'body',
|
|
116
|
+
queryParams = 'queryParams',
|
|
80
117
|
}
|
|
81
118
|
|
|
82
119
|
/* asdasd
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
require.resolve('open-ai');
|
|
4
|
+
try {
|
|
5
|
+
/* require.resolve('open-ai'); */
|
|
6
|
+
import('open-ai' as any);
|
|
6
7
|
} catch {
|
|
7
8
|
console.log(
|
|
8
9
|
'❌ OpenAI package not found, please install it with: pnpm add open-ai'
|
|
9
10
|
);
|
|
10
|
-
}
|
|
11
|
+
}
|
|
11
12
|
|
|
12
13
|
// COLLECTIONS
|
|
13
14
|
export * from './_collections/oai-embedding-model-dimensions.const';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as CryptoJS from 'crypto-js';
|
|
2
|
+
|
|
2
3
|
import {
|
|
3
4
|
DyFM_Error,
|
|
4
5
|
DyFM_Error_Settings
|
|
@@ -39,7 +40,7 @@ export class DyFM_Crypto {
|
|
|
39
40
|
ivLength: 16, // 128 bits
|
|
40
41
|
saltLength: 16, // 128 bits
|
|
41
42
|
keyIterations: 1000, // Reduced for better performance and stability
|
|
42
|
-
keySize: 8 // 256 bits (8 * 32)
|
|
43
|
+
keySize: 8, // 256 bits (8 * 32)
|
|
43
44
|
};
|
|
44
45
|
private static readonly defaultErrorUserMsg =
|
|
45
46
|
`We encountered an unhandled Authentication Error, ` +
|
|
@@ -54,7 +55,7 @@ export class DyFM_Crypto {
|
|
|
54
55
|
throw new DyFM_Error({
|
|
55
56
|
...this.getDefaultErrorSettings('validateInput'),
|
|
56
57
|
errorCode: 'DyFM-CRY-IKY',
|
|
57
|
-
message: 'Invalid encryption key'
|
|
58
|
+
message: 'Invalid encryption key',
|
|
58
59
|
});
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -63,7 +64,7 @@ export class DyFM_Crypto {
|
|
|
63
64
|
throw new DyFM_Error({
|
|
64
65
|
...this.getDefaultErrorSettings('validateInput'),
|
|
65
66
|
errorCode: 'DyFM-CRY-IDT',
|
|
66
|
-
message: `Invalid data to encrypt/decrypt (is "${data}")
|
|
67
|
+
message: `Invalid data to encrypt/decrypt (is "${data}")`,
|
|
67
68
|
});
|
|
68
69
|
}
|
|
69
70
|
}
|
|
@@ -79,6 +80,7 @@ export class DyFM_Crypto {
|
|
|
79
80
|
// Use MD5 for better stability - simpler hash algorithm, more consistent across versions
|
|
80
81
|
const combined = data + key;
|
|
81
82
|
const hash = CryptoJS.MD5(combined);
|
|
83
|
+
|
|
82
84
|
// Use slice(0, 4) for 16 bytes - more stable than division operations
|
|
83
85
|
return CryptoJS.lib.WordArray.create(hash.words.slice(0, 4));
|
|
84
86
|
}
|
|
@@ -94,6 +96,7 @@ export class DyFM_Crypto {
|
|
|
94
96
|
// Use MD5 for better stability - simpler hash algorithm, more consistent across versions
|
|
95
97
|
const combined = key + data;
|
|
96
98
|
const hash = CryptoJS.MD5(combined);
|
|
99
|
+
|
|
97
100
|
// Use slice(0, 4) for 16 bytes - more stable than division operations
|
|
98
101
|
return CryptoJS.lib.WordArray.create(hash.words.slice(0, 4));
|
|
99
102
|
}
|
|
@@ -104,7 +107,7 @@ export class DyFM_Crypto {
|
|
|
104
107
|
private static deriveKey(key: string, salt: CryptoJS.lib.WordArray, config: Required<CryptoConfig>): CryptoJS.lib.WordArray {
|
|
105
108
|
return CryptoJS.PBKDF2(key, salt, {
|
|
106
109
|
keySize: config.keySize,
|
|
107
|
-
iterations: config.keyIterations
|
|
110
|
+
iterations: config.keyIterations,
|
|
108
111
|
});
|
|
109
112
|
}
|
|
110
113
|
|
|
@@ -119,7 +122,7 @@ export class DyFM_Crypto {
|
|
|
119
122
|
throw new DyFM_Error({
|
|
120
123
|
...this.getDefaultErrorSettings('safeSerialize', error),
|
|
121
124
|
errorCode: 'DyFM-CRY-SER',
|
|
122
|
-
message: 'Failed to serialize data'
|
|
125
|
+
message: 'Failed to serialize data',
|
|
123
126
|
});
|
|
124
127
|
}
|
|
125
128
|
}
|
|
@@ -134,10 +137,12 @@ export class DyFM_Crypto {
|
|
|
134
137
|
|
|
135
138
|
// Handle double-stringified JSON (or more levels of stringification)
|
|
136
139
|
let maxAttempts = 3; // Prevent infinite loops
|
|
140
|
+
|
|
137
141
|
while (typeof parsed === 'string' && maxAttempts > 0) {
|
|
138
142
|
try {
|
|
139
143
|
//const nextParsed = JSON.parse(parsed);
|
|
140
144
|
const nextParsed = DyFM_Object.failableSafeParseJSON(parsed);
|
|
145
|
+
|
|
141
146
|
// Only continue if parsing actually changed the result
|
|
142
147
|
if (nextParsed !== parsed) {
|
|
143
148
|
parsed = nextParsed;
|
|
@@ -161,7 +166,7 @@ export class DyFM_Crypto {
|
|
|
161
166
|
throw new DyFM_Error({
|
|
162
167
|
...this.getDefaultErrorSettings('safeDeserialize', error),
|
|
163
168
|
errorCode: 'DyFM-CRY-DES',
|
|
164
|
-
message: 'Failed to deserialize data'
|
|
169
|
+
message: 'Failed to deserialize data',
|
|
165
170
|
});
|
|
166
171
|
}
|
|
167
172
|
}
|
|
@@ -205,7 +210,7 @@ export class DyFM_Crypto {
|
|
|
205
210
|
const encrypted = CryptoJS.AES.encrypt(dataStr, derivedKey, {
|
|
206
211
|
iv: iv,
|
|
207
212
|
mode: CryptoJS.mode.CBC,
|
|
208
|
-
padding: CryptoJS.pad.Pkcs7
|
|
213
|
+
padding: CryptoJS.pad.Pkcs7,
|
|
209
214
|
});
|
|
210
215
|
|
|
211
216
|
// Combine IV + Salt + Ciphertext
|
|
@@ -247,6 +252,7 @@ export class DyFM_Crypto {
|
|
|
247
252
|
|
|
248
253
|
// Validate minimum length (IV + Salt + minimum ciphertext)
|
|
249
254
|
const minLength = (finalConfig.ivLength + finalConfig.saltLength + 16) / 4; // 16 bytes minimum for ciphertext
|
|
255
|
+
|
|
250
256
|
if (combined.words.length < minLength) {
|
|
251
257
|
throw new Error('Invalid encrypted data length');
|
|
252
258
|
}
|
|
@@ -273,12 +279,13 @@ export class DyFM_Crypto {
|
|
|
273
279
|
{
|
|
274
280
|
iv: iv,
|
|
275
281
|
mode: CryptoJS.mode.CBC,
|
|
276
|
-
padding: CryptoJS.pad.Pkcs7
|
|
282
|
+
padding: CryptoJS.pad.Pkcs7,
|
|
277
283
|
}
|
|
278
284
|
);
|
|
279
285
|
|
|
280
286
|
// Parse JSON
|
|
281
287
|
const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
|
|
288
|
+
|
|
282
289
|
return this.safeDeserialize<T>(decryptedStr);
|
|
283
290
|
} catch (error) {
|
|
284
291
|
throw new DyFM_Error({
|
|
@@ -306,6 +313,7 @@ export class DyFM_Crypto {
|
|
|
306
313
|
if (!encryptedData || typeof encryptedData !== 'string') {
|
|
307
314
|
return false;
|
|
308
315
|
}
|
|
316
|
+
|
|
309
317
|
return /^[A-Za-z0-9\-_]+$/.test(encryptedData);
|
|
310
318
|
}
|
|
311
319
|
|
|
@@ -317,7 +325,7 @@ export class DyFM_Crypto {
|
|
|
317
325
|
status: (error as DyFM_Error)?.___status ?? (error as any)?.status ?? 401,
|
|
318
326
|
message: `Crypto operation "${operation}" failed`,
|
|
319
327
|
error: error,
|
|
320
|
-
errorCode: 'DyFM-CRY-ERR'
|
|
328
|
+
errorCode: 'DyFM-CRY-ERR',
|
|
321
329
|
};
|
|
322
330
|
}
|
|
323
331
|
}
|