data-primals-engine 1.2.6 → 1.3.1
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/CHANGELOG.md +440 -0
- package/README.md +782 -712
- package/client/src/App.jsx +13 -20
- package/client/src/App.scss +4 -0
- package/client/src/AssistantChat.jsx +5 -4
- package/client/src/DataEditor.jsx +1 -1
- package/client/src/DataLayout.jsx +2 -2
- package/client/src/DataTable.jsx +66 -5
- package/client/src/ExportDialog.jsx +2 -2
- package/client/src/Field.jsx +5 -4
- package/client/src/HistoryDialog.jsx +96 -0
- package/client/src/HistoryDialog.scss +73 -0
- package/client/src/KanbanCard.jsx +4 -2
- package/client/src/KanbanConfigModal.jsx +5 -7
- package/client/src/ModelCreator.jsx +36 -15
- package/client/src/ModelCreatorField.jsx +14 -15
- package/client/src/PackGallery.jsx +89 -9
- package/client/src/PackGallery.scss +58 -4
- package/client/src/RTETrans.jsx +11 -0
- package/client/src/RelationValue.jsx +3 -4
- package/client/src/constants.js +1 -1
- package/client/src/core/data.js +2 -1
- package/client/src/hooks/useTutorials.jsx +1 -1
- package/client/src/translations.js +217 -0
- package/package.json +9 -2
- package/server.js +4 -4
- package/src/HistoryDialog.jsx +86 -0
- package/src/HistoryDialog.scss +77 -0
- package/src/constants.js +6 -0
- package/src/defaultModels.js +23 -10
- package/src/email.js +1 -1
- package/src/engine.js +6 -6
- package/src/events.js +15 -5
- package/src/gameObject.js +0 -29
- package/src/i18n.js +1 -1
- package/src/modules/{assistant.js → assistant/assistant.js} +42 -27
- package/src/modules/assistant/constants.js +16 -0
- package/src/modules/data/data.history.js +304 -0
- package/src/modules/data/data.js +306 -238
- package/src/modules/data/data.routes.js +33 -7
- package/src/modules/mongodb.js +17 -1
- package/src/modules/user.js +21 -4
- package/src/modules/workflow.js +133 -48
- package/src/packs.js +1016 -9
- package/src/services/index.js +11 -0
- package/src/services/stripe.js +195 -0
- package/src/workers/crypto-worker.js +3 -3
- package/test/data.backup.integration.test.js +5 -0
- package/test/data.history.integration.test.js +193 -0
- package/test/data.integration.test.js +144 -41
- package/test/events.test.js +27 -27
- package/test/globalTeardown.js +1 -0
- package/test/model.integration.test.js +5 -0
- package/test/workflow.actions.integration.test.js +4 -2
- package/test/workflow.integration.test.js +3 -1
- package/test/workflow.robustness.test.js +2 -0
package/test/events.test.js
CHANGED
|
@@ -17,29 +17,29 @@ describe('Event System', () => {
|
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
it('should allow listening for and triggering an event', () => {
|
|
20
|
+
it('should allow listening for and triggering an event', async() => {
|
|
21
21
|
const mockCallback = vitest.fn();
|
|
22
22
|
const eventName = 'testEvent';
|
|
23
23
|
|
|
24
24
|
Event.Listen(eventName, mockCallback);
|
|
25
|
-
Event.Trigger(eventName);
|
|
25
|
+
await Event.Trigger(eventName);
|
|
26
26
|
|
|
27
27
|
expect(mockCallback).toHaveBeenCalledTimes(1);
|
|
28
28
|
});
|
|
29
|
-
it('should pass arguments to the event callback', () => {
|
|
29
|
+
it('should pass arguments to the event callback', async() => {
|
|
30
30
|
const mockCallback = vitest.fn();
|
|
31
31
|
const eventName = 'testEventWithArgs';
|
|
32
32
|
const arg1 = 'hello';
|
|
33
33
|
const arg2 = 123;
|
|
34
34
|
|
|
35
35
|
Event.Listen(eventName, mockCallback, "priority", "medium");
|
|
36
|
-
Event.Trigger(eventName, "priority", "medium", arg1, arg2);
|
|
36
|
+
await Event.Trigger(eventName, "priority", "medium", arg1, arg2);
|
|
37
37
|
|
|
38
38
|
expect(mockCallback).toHaveBeenCalledTimes(1);
|
|
39
39
|
expect(mockCallback).toHaveBeenCalledWith(arg1, arg2);
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
it('should allow removing a specific callback', () => {
|
|
42
|
+
it('should allow removing a specific callback', async() => {
|
|
43
43
|
const mockCallback1 = vitest.fn();
|
|
44
44
|
const mockCallback2 = vitest.fn();
|
|
45
45
|
const eventName = 'testEventRemoveCallback';
|
|
@@ -47,22 +47,22 @@ describe('Event System', () => {
|
|
|
47
47
|
Event.Listen(eventName, mockCallback1);
|
|
48
48
|
Event.Listen(eventName, mockCallback2);
|
|
49
49
|
Event.RemoveCallback(eventName, mockCallback1);
|
|
50
|
-
Event.Trigger(eventName);
|
|
50
|
+
await Event.Trigger(eventName);
|
|
51
51
|
|
|
52
52
|
expect(mockCallback1).not.toHaveBeenCalled();
|
|
53
53
|
expect(mockCallback2).toHaveBeenCalledTimes(1);
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
it('should not trigger a callback if the event is not listened to', () => {
|
|
56
|
+
it('should not trigger a callback if the event is not listened to', async() => {
|
|
57
57
|
const mockCallback = vitest.fn();
|
|
58
58
|
const eventName = 'nonExistentEvent';
|
|
59
59
|
|
|
60
|
-
Event.Trigger(eventName);
|
|
60
|
+
await Event.Trigger(eventName);
|
|
61
61
|
|
|
62
62
|
expect(mockCallback).not.toHaveBeenCalled();
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
it('should handle different systems and layers', () => {
|
|
65
|
+
it('should handle different systems and layers', async() => {
|
|
66
66
|
const mockCallbackPriority = vitest.fn();
|
|
67
67
|
const mockCallbackLog = vitest.fn();
|
|
68
68
|
const eventName = 'testEventMultiSystem';
|
|
@@ -70,13 +70,13 @@ describe('Event System', () => {
|
|
|
70
70
|
Event.Listen(eventName, mockCallbackPriority, 'priority', 'high');
|
|
71
71
|
Event.Listen(eventName, mockCallbackLog, 'log', 'info');
|
|
72
72
|
|
|
73
|
-
Event.Trigger(eventName, 'priority', 'high');
|
|
73
|
+
await Event.Trigger(eventName, 'priority', 'high');
|
|
74
74
|
expect(mockCallbackPriority).toHaveBeenCalledTimes(1);
|
|
75
75
|
expect(mockCallbackLog).not.toHaveBeenCalled();
|
|
76
76
|
|
|
77
77
|
vitest.clearAllMocks(); // Reset mock counts
|
|
78
78
|
|
|
79
|
-
Event.Trigger(eventName, 'log', 'info');
|
|
79
|
+
await Event.Trigger(eventName, 'log', 'info');
|
|
80
80
|
expect(mockCallbackPriority).not.toHaveBeenCalled();
|
|
81
81
|
expect(mockCallbackLog).toHaveBeenCalledTimes(1);
|
|
82
82
|
});
|
|
@@ -92,7 +92,7 @@ describe('Event System', () => {
|
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
describe('Event.Trigger result merging', () => {
|
|
95
|
-
it('should merge objects from multiple callbacks using spread operator', () => {
|
|
95
|
+
it('should merge objects from multiple callbacks using spread operator', async() => {
|
|
96
96
|
const eventName = 'mergeObjectEvent';
|
|
97
97
|
const callback1 = vitest.fn().mockReturnValue({ a: 1, b: 2 });
|
|
98
98
|
const callback2 = vitest.fn().mockReturnValue({ b: 3, c: 4 }); // b will be overwritten
|
|
@@ -100,12 +100,12 @@ describe('Event System', () => {
|
|
|
100
100
|
Event.Listen(eventName, callback1);
|
|
101
101
|
Event.Listen(eventName, callback2);
|
|
102
102
|
|
|
103
|
-
const result = Event.Trigger(eventName);
|
|
103
|
+
const result = await Event.Trigger(eventName);
|
|
104
104
|
|
|
105
105
|
expect(result).toEqual({ a: 1, b: 3, c: 4 });
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
-
it('should concatenate arrays from multiple callbacks', () => {
|
|
108
|
+
it('should concatenate arrays from multiple callbacks', async() => {
|
|
109
109
|
const eventName = 'mergeArrayEvent';
|
|
110
110
|
const callback1 = vitest.fn().mockReturnValue([1, 2]);
|
|
111
111
|
const callback2 = vitest.fn().mockReturnValue([3, 4]);
|
|
@@ -113,12 +113,12 @@ describe('Event System', () => {
|
|
|
113
113
|
Event.Listen(eventName, callback1);
|
|
114
114
|
Event.Listen(eventName, callback2);
|
|
115
115
|
|
|
116
|
-
const result = Event.Trigger(eventName);
|
|
116
|
+
const result = await Event.Trigger(eventName);
|
|
117
117
|
|
|
118
118
|
expect(result).toEqual([1, 2, 3, 4]);
|
|
119
119
|
});
|
|
120
120
|
|
|
121
|
-
it('should concatenate strings from multiple callbacks', () => {
|
|
121
|
+
it('should concatenate strings from multiple callbacks', async() => {
|
|
122
122
|
const eventName = 'mergeStringEvent';
|
|
123
123
|
const callback1 = vitest.fn().mockReturnValue('Hello ');
|
|
124
124
|
const callback2 = vitest.fn().mockReturnValue('World');
|
|
@@ -126,12 +126,12 @@ describe('Event System', () => {
|
|
|
126
126
|
Event.Listen(eventName, callback1);
|
|
127
127
|
Event.Listen(eventName, callback2);
|
|
128
128
|
|
|
129
|
-
const result = Event.Trigger(eventName);
|
|
129
|
+
const result = await Event.Trigger(eventName);
|
|
130
130
|
|
|
131
131
|
expect(result).toBe('Hello World');
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
-
it('should add numbers from multiple callbacks', () => {
|
|
134
|
+
it('should add numbers from multiple callbacks', async() => {
|
|
135
135
|
const eventName = 'mergeNumberEvent';
|
|
136
136
|
const callback1 = vitest.fn().mockReturnValue(10);
|
|
137
137
|
const callback2 = vitest.fn().mockReturnValue(20);
|
|
@@ -139,12 +139,12 @@ describe('Event System', () => {
|
|
|
139
139
|
Event.Listen(eventName, callback1);
|
|
140
140
|
Event.Listen(eventName, callback2);
|
|
141
141
|
|
|
142
|
-
const result = Event.Trigger(eventName);
|
|
142
|
+
const result = await Event.Trigger(eventName);
|
|
143
143
|
|
|
144
144
|
expect(result).toBe(30);
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
-
it('should perform a logical AND on booleans from multiple callbacks', () => {
|
|
147
|
+
it('should perform a logical AND on booleans from multiple callbacks', async() => {
|
|
148
148
|
const eventName = 'mergeBooleanEvent';
|
|
149
149
|
|
|
150
150
|
// Case 1: true && true -> true
|
|
@@ -152,23 +152,23 @@ describe('Event System', () => {
|
|
|
152
152
|
const cb_true2 = vitest.fn().mockReturnValue(true);
|
|
153
153
|
Event.Listen(eventName, cb_true1);
|
|
154
154
|
Event.Listen(eventName, cb_true2);
|
|
155
|
-
expect(Event.Trigger(eventName)).toBe(true);
|
|
155
|
+
expect(await Event.Trigger(eventName)).toBe(true);
|
|
156
156
|
Event.RemoveAllCallbacks(eventName); // Clean up for next case
|
|
157
157
|
|
|
158
158
|
// Case 2: true && false -> false
|
|
159
159
|
const cb_false1 = vitest.fn().mockReturnValue(false);
|
|
160
160
|
Event.Listen(eventName, cb_true1);
|
|
161
161
|
Event.Listen(eventName, cb_false1);
|
|
162
|
-
expect(Event.Trigger(eventName)).toBe(false);
|
|
162
|
+
expect(await Event.Trigger(eventName)).toBe(false);
|
|
163
163
|
Event.RemoveAllCallbacks(eventName);
|
|
164
164
|
|
|
165
165
|
// Case 3: false && true -> false
|
|
166
166
|
Event.Listen(eventName, cb_false1);
|
|
167
167
|
Event.Listen(eventName, cb_true1);
|
|
168
|
-
expect(Event.Trigger(eventName)).toBe(false);
|
|
168
|
+
expect(await Event.Trigger(eventName)).toBe(false);
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
-
it('should handle mixed-type return values', () => {
|
|
171
|
+
it('should handle mixed-type return values', async() => {
|
|
172
172
|
const eventName = 'mergeMixedEvent';
|
|
173
173
|
const callback1 = vitest.fn().mockReturnValue(100); // number
|
|
174
174
|
const callback2 = vitest.fn().mockReturnValue({ a: 1 }); // object
|
|
@@ -176,7 +176,7 @@ describe('Event System', () => {
|
|
|
176
176
|
Event.Listen(eventName, callback1);
|
|
177
177
|
Event.Listen(eventName, callback2);
|
|
178
178
|
|
|
179
|
-
const result = Event.Trigger(eventName);
|
|
179
|
+
const result = await Event.Trigger(eventName);
|
|
180
180
|
|
|
181
181
|
// The logic initializes `ret` with the first value (100).
|
|
182
182
|
// When the second callback returns an object, it re-initializes `ret` to {}
|
|
@@ -184,7 +184,7 @@ describe('Event System', () => {
|
|
|
184
184
|
expect(result).toEqual({ a: 1 });
|
|
185
185
|
});
|
|
186
186
|
|
|
187
|
-
it('should ignore null and undefined return values while merging', () => {
|
|
187
|
+
it('should ignore null and undefined return values while merging', async() => {
|
|
188
188
|
const eventName = 'ignoreNullsEvent';
|
|
189
189
|
const callback1 = vitest.fn().mockReturnValue(null);
|
|
190
190
|
const callback2 = vitest.fn().mockReturnValue({ data: 'important' });
|
|
@@ -194,7 +194,7 @@ describe('Event System', () => {
|
|
|
194
194
|
Event.Listen(eventName, callback2);
|
|
195
195
|
Event.Listen(eventName, callback3);
|
|
196
196
|
|
|
197
|
-
const result = Event.Trigger(eventName);
|
|
197
|
+
const result = await Event.Trigger(eventName);
|
|
198
198
|
|
|
199
199
|
expect(result).toEqual({ data: 'important' });
|
|
200
200
|
});
|
package/test/globalTeardown.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import {generateUniqueName, initEngine} from "../src/setenv.js";
|
|
10
10
|
import {editModel} from "../src/index.js";
|
|
11
11
|
import {getCollectionForUser} from "../src/modules/mongodb.js";
|
|
12
|
+
import {purgeData} from "../src/modules/data/data.history.js";
|
|
12
13
|
|
|
13
14
|
let testModelsColInstance;
|
|
14
15
|
let testModelId;
|
|
@@ -101,6 +102,10 @@ async function setupTestContext() {
|
|
|
101
102
|
]);
|
|
102
103
|
|
|
103
104
|
testModelId = result.insertedIds[0];
|
|
105
|
+
|
|
106
|
+
await purgeData(currentTestUser, comprehensiveTestModelDefinition.name);
|
|
107
|
+
await purgeData(currentTestUser, relatedModelDefinition.name);
|
|
108
|
+
|
|
104
109
|
await testDatasColInstance.deleteMany({ _user: currentTestUser.username });
|
|
105
110
|
await testDatasColInstance.deleteMany({ _model: { $in: [comprehensiveTestModelDefinition.name, 'renamedTestModel'] } });
|
|
106
111
|
// Retourner toutes les variables nécessaires pour un test
|
|
@@ -11,6 +11,7 @@ import { initEngine } from "../src/setenv.js";
|
|
|
11
11
|
import * as emailModule from '../src/email.js';
|
|
12
12
|
import { ChatOpenAI } from "@langchain/openai";
|
|
13
13
|
import {ObjectId} from "mongodb";
|
|
14
|
+
import {purgeData} from "../src/modules/data/data.history.js";
|
|
14
15
|
|
|
15
16
|
let testModelsColInstance;
|
|
16
17
|
let testDatasColInstance;
|
|
@@ -142,6 +143,7 @@ afterEach(() => {
|
|
|
142
143
|
});
|
|
143
144
|
|
|
144
145
|
afterAll(async () => {
|
|
146
|
+
await purgeData(mockUser);
|
|
145
147
|
const coll = await getCollectionForUser(mockUser);
|
|
146
148
|
await coll.drop();
|
|
147
149
|
});
|
|
@@ -251,7 +253,7 @@ describe('Intégration des Actions de Workflow', () => {
|
|
|
251
253
|
expect(deletedTask).toBeNull();
|
|
252
254
|
});
|
|
253
255
|
|
|
254
|
-
it('Action
|
|
256
|
+
it('Action HttpRequest: devrait appeler fetch avec les bonnes informations substituées', async () => {
|
|
255
257
|
global.fetch.mockResolvedValue({
|
|
256
258
|
ok: true,
|
|
257
259
|
status: 200,
|
|
@@ -261,7 +263,7 @@ describe('Intégration des Actions de Workflow', () => {
|
|
|
261
263
|
|
|
262
264
|
const { workflowId } = await setupWorkflow({
|
|
263
265
|
name: 'Notify External System',
|
|
264
|
-
type: '
|
|
266
|
+
type: 'HttpRequest',
|
|
265
267
|
method: 'POST',
|
|
266
268
|
url: 'https://api.example.com/notify/{triggerData.status}',
|
|
267
269
|
headers: { "Authorization": "Bearer {env.API_KEY}" },
|
|
@@ -5,6 +5,7 @@ import {insertData, editData, deleteData, patchData} from '../src/index.js';
|
|
|
5
5
|
import { modelsCollection as getAppModelsCollection, getCollectionForUser } from '../src/modules/mongodb.js';
|
|
6
6
|
import * as workflowModule from '../src/modules/workflow.js';
|
|
7
7
|
import {initEngine} from "../src/setenv.js";
|
|
8
|
+
import {purgeData} from "../src/modules/data/data.history.js";
|
|
8
9
|
|
|
9
10
|
beforeAll(async () =>{
|
|
10
11
|
Config.Set("modules", ["mongodb", "data", "file", "bucket", "workflow","user", "assistant"]);
|
|
@@ -113,7 +114,7 @@ const workflowMetaModels = [
|
|
|
113
114
|
{ name: 'updateMultiple', type: 'boolean' },
|
|
114
115
|
{ name: 'deleteMultiple', type: 'boolean' },
|
|
115
116
|
// GenerateAIContent
|
|
116
|
-
{ name: 'aiProvider', type: 'enum', items: ['OpenAI', '
|
|
117
|
+
{ name: 'aiProvider', type: 'enum', items: ['OpenAI', 'Google', 'Anthropic', 'DeepSeek'] },
|
|
117
118
|
{ name: 'aiModel', type: 'string' },
|
|
118
119
|
{ name: 'prompt', type: 'richtext' },
|
|
119
120
|
// SendEmail
|
|
@@ -157,6 +158,7 @@ afterEach(() => {
|
|
|
157
158
|
vi.useRealTimers()
|
|
158
159
|
})
|
|
159
160
|
afterAll(async () => {
|
|
161
|
+
await purgeData(mockUser);
|
|
160
162
|
const coll = await getCollectionForUser(mockUser);
|
|
161
163
|
await coll.drop();
|
|
162
164
|
})
|
|
@@ -7,6 +7,7 @@ import { modelsCollection as getAppModelsCollection, getCollectionForUser, getCo
|
|
|
7
7
|
import * as workflowModule from '../src/modules/workflow.js';
|
|
8
8
|
import {initEngine} from "../src/setenv.js";
|
|
9
9
|
import {maxExecutionsByStep} from "../src/constants.js";
|
|
10
|
+
import {purgeData} from "../src/modules/data/data.history.js";
|
|
10
11
|
|
|
11
12
|
vi.mock('../src/modules/workflow.js', { spy: true })
|
|
12
13
|
|
|
@@ -54,6 +55,7 @@ afterEach(() => {
|
|
|
54
55
|
vi.useRealTimers()
|
|
55
56
|
})
|
|
56
57
|
afterAll(async () => {
|
|
58
|
+
await purgeData(mockUser);
|
|
57
59
|
const coll = await getCollectionForUser(mockUser);
|
|
58
60
|
await coll.drop();
|
|
59
61
|
})
|