data-primals-engine 1.3.3-rc.1 → 1.3.4
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/client/package-lock.json +7 -6
- package/client/package.json +1 -1
- package/client/src/App.scss +37 -0
- package/client/src/DataLayout.jsx +38 -9
- package/client/src/Dialog.scss +0 -3
- package/client/src/Field.jsx +75 -2
- package/client/src/ModelCreator.jsx +23 -1
- package/client/src/ModelList.jsx +19 -1
- package/client/src/contexts/UIContext.jsx +19 -10
- package/client/src/translations.js +24 -0
- package/package.json +2 -1
- package/server.js +1 -0
- package/src/core.js +9 -0
- package/src/defaultModels.js +52 -0
- package/src/filter.js +50 -40
- package/src/i18n.js +2 -2
- package/src/modules/data/data.js +6 -3
- package/src/modules/data/data.routes.js +3 -2
- package/src/modules/workflow.js +60 -12
- package/src/packs.js +5461 -5062
package/src/modules/workflow.js
CHANGED
|
@@ -23,6 +23,7 @@ import {getHost} from "../constants.js";
|
|
|
23
23
|
import {providers} from "./assistant/constants.js";
|
|
24
24
|
import {ChatAnthropic} from "@langchain/anthropic";
|
|
25
25
|
import {getAIProvider} from "./assistant/assistant.js";
|
|
26
|
+
import {escapeRegex} from "../core.js";
|
|
26
27
|
|
|
27
28
|
let logger = null;
|
|
28
29
|
export async function onInit(defaultEngine) {
|
|
@@ -32,7 +33,6 @@ export async function onInit(defaultEngine) {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
|
|
36
36
|
/**
|
|
37
37
|
* Déclenche un workflow par son nom et lui passe des données de contexte.
|
|
38
38
|
* C'est la fonction clé à exposer aux endpoints pour lancer des processus métier.
|
|
@@ -284,8 +284,14 @@ export async function executeSafeJavascript(actionDef, context, user) {
|
|
|
284
284
|
await jail.set('_db_find', new ivm.Reference(find));
|
|
285
285
|
await jail.set('_db_findOne', new ivm.Reference(findOne));
|
|
286
286
|
|
|
287
|
-
await jail.set('_db_update', new ivm.Reference(async (modelName, filter, updateObject) =>
|
|
288
|
-
|
|
287
|
+
await jail.set('_db_update', new ivm.Reference(async (modelName, filter, updateObject) => {
|
|
288
|
+
const result = await patchData(modelName, JSON.parse(filter), JSON.parse(updateObject), {}, user, false);
|
|
289
|
+
return new ivm.ExternalCopy(result).copyInto();
|
|
290
|
+
}));
|
|
291
|
+
await jail.set('_db_delete', new ivm.Reference(async (modelName, filter) => {
|
|
292
|
+
const result = await deleteData(modelName, JSON.parse(filter), user, false);
|
|
293
|
+
return new ivm.ExternalCopy(result).copyInto();
|
|
294
|
+
}));
|
|
289
295
|
|
|
290
296
|
const createLoggerMethod = (level) => {
|
|
291
297
|
return (...args) => {
|
|
@@ -311,9 +317,29 @@ export async function executeSafeJavascript(actionDef, context, user) {
|
|
|
311
317
|
const result = await getEnv(user);
|
|
312
318
|
return new ivm.ExternalCopy(result).copyInto();
|
|
313
319
|
}));
|
|
320
|
+
await jail.set('_http_request', new ivm.Reference(async (method, url, optionsStr) => {
|
|
321
|
+
try {
|
|
322
|
+
const options = optionsStr ? JSON.parse(optionsStr) : {};
|
|
323
|
+
const fetchOptions = {
|
|
324
|
+
method: method.toUpperCase(),
|
|
325
|
+
headers: options.headers || {},
|
|
326
|
+
body: options.body ? (typeof options.body === 'object' ? JSON.stringify(options.body) : options.body) : undefined
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const response = await fetch(url, fetchOptions);
|
|
330
|
+
const responseBody = await response.json().catch(() => response.text());
|
|
331
|
+
|
|
332
|
+
const result = { success: response.ok, status: response.status, body: responseBody };
|
|
333
|
+
return new ivm.ExternalCopy(result).copyInto();
|
|
334
|
+
} catch (error) {
|
|
335
|
+
logger.error(`[VM http_request] Error: ${error.message}`);
|
|
336
|
+
return new ivm.ExternalCopy({ success: false, message: error.message }).copyInto();
|
|
337
|
+
}
|
|
338
|
+
}));
|
|
314
339
|
|
|
315
340
|
// Contexte sécurisé
|
|
316
341
|
const safeContext = JSON.parse(JSON.stringify(context));
|
|
342
|
+
|
|
317
343
|
await jail.set('context', new ivm.ExternalCopy(safeContext).copyInto());
|
|
318
344
|
|
|
319
345
|
// Exécution
|
|
@@ -347,6 +373,10 @@ export async function executeSafeJavascript(actionDef, context, user) {
|
|
|
347
373
|
getAll: _env_get_all
|
|
348
374
|
};
|
|
349
375
|
|
|
376
|
+
const http = {
|
|
377
|
+
request: (...args) => _http_request.applySyncPromise(null, normalizeArgs(args))
|
|
378
|
+
};
|
|
379
|
+
|
|
350
380
|
(async function() {
|
|
351
381
|
${code}
|
|
352
382
|
})();
|
|
@@ -360,13 +390,22 @@ export async function executeSafeJavascript(actionDef, context, user) {
|
|
|
360
390
|
copy: true // Copie automatique du résultat
|
|
361
391
|
});
|
|
362
392
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
393
|
+
// Vérifier si le script lui-même a signalé un échec.
|
|
394
|
+
if (result && typeof result === 'object' && result.success === false) {
|
|
395
|
+
const scriptMessage = result.message || 'Le script a signalé un échec sans message.';
|
|
396
|
+
collectedLogs.push({
|
|
397
|
+
level: 'warn',
|
|
398
|
+
message: `Script reported failure: ${scriptMessage}`,
|
|
399
|
+
timestamp: new Date().toISOString()
|
|
400
|
+
});
|
|
401
|
+
return {
|
|
402
|
+
success: false,
|
|
403
|
+
message: scriptMessage,
|
|
404
|
+
logs: collectedLogs
|
|
405
|
+
};
|
|
406
|
+
}
|
|
369
407
|
|
|
408
|
+
return { success: true, data: result, logs: collectedLogs, updatedContext: { result } };
|
|
370
409
|
} catch (error) {
|
|
371
410
|
const errorMessage = `Script execution failed: ${error.message}`;
|
|
372
411
|
const finalErrorMessage = logger.trace('critical', `[VM Script] ${errorMessage}\n${error.stack}`);
|
|
@@ -1445,9 +1484,18 @@ export async function processWorkflowRun(workflowRunId, user) {
|
|
|
1445
1484
|
// --- 7. Évaluation des conditions de l'étape ---
|
|
1446
1485
|
if (currentStepDef.conditions && Object.keys(currentStepDef.conditions).length > 0) {
|
|
1447
1486
|
const substitutedConditions = await substituteVariables(currentStepDef.conditions, contextData, user);
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1487
|
+
// Si un modèle est spécifié dans le contexte, la condition est une requête sur la base de données.
|
|
1488
|
+
if (contextData.triggerDataModel) {
|
|
1489
|
+
const searchResult = await searchData({ model: contextData.triggerDataModel, filter: substitutedConditions, limit: 1 }, user);
|
|
1490
|
+
conditionsMet = searchResult && searchResult.count > 0;
|
|
1491
|
+
logger.info(`[processWorkflowRun] Run ID: ${runId}, Step ID: ${currentStepId}: DB condition evaluated. Found ${searchResult ? searchResult.count : 0} match(es). Result: ${conditionsMet}`);
|
|
1492
|
+
} else {
|
|
1493
|
+
console.log({substitutedConditions, c:contextData['triggerData']['event']['type']});
|
|
1494
|
+
// Si aucun modèle n'est spécifié (ex: webhook), la condition est évaluée sur l'objet de contexte lui-même.
|
|
1495
|
+
conditionsMet = isConditionMet(null, substitutedConditions, contextData, [], user);
|
|
1496
|
+
|
|
1497
|
+
logger.info(`[processWorkflowRun] Run ID: ${runId}, Step ID: ${currentStepId}: Context condition evaluated. Operator: ${JSON.stringify(substitutedConditions)}, Result: ${conditionsMet}`);
|
|
1498
|
+
}
|
|
1451
1499
|
}
|
|
1452
1500
|
|
|
1453
1501
|
// --- 8. Exécution des actions si les conditions sont remplies ---
|