data-primals-engine 1.6.2-rc1 → 1.6.3

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/README.md CHANGED
@@ -153,6 +153,46 @@ The engine includes a pluggable system for user management. For development and
153
153
 
154
154
  For production environments, you should use SSO providers as seen in the page below, or extend the base `UserProvider` class to connect to your actual user database (e.g., another MongoDB collection, a SQL database, or an external authentication service). This allows you to implement your own logic for finding and creating users.
155
155
 
156
+ ### Permission System
157
+
158
+ The engine features a powerful dual-mode permission system, providing both granular, database-driven control and a lightweight, simplified approach.
159
+
160
+ #### 1. The Complete System (for Local Users)
161
+
162
+ This is the full-featured Role-Based Access Control (RBAC) system designed for application users. It relies on three core models:
163
+
164
+ - **`permission`**: Defines a single action (e.g., `API_EDIT_DATA_product`) and can include a JSON-based **filter** to restrict its scope (e.g., only edit products where `status` is `'draft'`).
165
+ - **`role`**: A group of permissions (e.g., an "Editor" role that includes `API_EDIT_DATA_product` and `API_SEARCH_DATA_product`).
166
+ - **`userPermission`**: Manages exceptions for individual users, allowing you to grant or revoke specific permissions, or even override a permission's filter for a single user.
167
+
168
+ When `hasPermission()` is called for a "local user" (a standard user stored in the database), the engine performs a detailed aggregation to compute the final set of active permissions and their corresponding filters.
169
+
170
+ #### 2. The Simplified System (for System/Non-Local Users)
171
+
172
+ For internal processes, system users, or temporary "demo" users, the full database-driven permission system can be overkill. The engine offers an "extremely simplified" mode for these cases.
173
+
174
+ **How it works:**
175
+
176
+ If a user object is not a "local user" (i.e., it does not have `_model: 'user'`), the permission check becomes a simple string comparison. The `hasPermission()` function will just check if the permission name you are testing exists directly in the user's `roles` array.
177
+
178
+ **Use Case:** This is perfect for system-level scripts or internal services that need specific, hard-coded permissions without the overhead of database lookups.
179
+
180
+ **Example:**
181
+
182
+ Consider a system user defined directly in your code:
183
+
184
+ ```javascript
185
+ const systemUser = {
186
+ username: 'internal-service',
187
+ roles: ['API_SEARCH_DATA_product', 'API_ADD_DATA_order']
188
+ };
189
+
190
+ await hasPermission('API_SEARCH_DATA_product', systemUser); // Returns true
191
+ await hasPermission('API_DELETE_DATA_product', systemUser); // Returns false
192
+ ```
193
+
194
+ This dual approach gives you the flexibility to use a robust, granular system for your end-users while maintaining a simple, performant mechanism for internal and system-level tasks.
195
+
156
196
  ### Model generation
157
197
  Models are the way to handle structured data. They organize data and they can be declared in JSON.
158
198
 
@@ -898,26 +938,27 @@ Event.Listen("OnDataAdded", (engine, data) => {
898
938
  }, "event", "system");
899
939
  ```
900
940
 
901
- | Event | Description | Scope | Triggered by | Arguments (Payload) |
902
- |:-----------------|:------------------------------------------------------------------------|:--------------|:---------------------|:-----------------------------------------------------------------------------------------------------------------------------------------|
903
- | OnServerStart | Triggered once the HTTP server is started and listening. | System | engine.start() | engine |
904
- | OnServerStop | Triggered right after the HTTP server is stopped. | System | engine.stop() | engine |
905
- | OnModelsLoaded | Triggered after the initial models are loaded and validated at startup. | System | setupInitialModels() | engine, dbModels |
906
- | OnModelsDeleted | Triggered after all models are deleted via the reset function. | System | engine.resetModels() | engine |
907
- | OnUserDataDumped | Triggered after a user's data has been backed up (dumped). | System | jobDumpUserData() | engine |
908
- | OnDataRestored | Triggered after a user's data has been restored from a backup. | System | loadFromDump() | (none) |
909
- | OnPackInstalled | Triggered after a data pack has been successfully installed. | System | installPack() | pack |
910
- | OnModelEdited | Triggered after a model definition has been modified. | System & User | editModel() | System: engine, newModel (Pipeline*)<br>User: newModel (or the version modified by the system) |
911
- | OnDataAdded | Triggered after new data has been inserted. | System & User | insertData() | System: engine, insertedIds (Pipeline*)<br>User: insertedIds (or the version modified by the system) |
912
- | OnDataDeleted | Triggered just after data is actually deleted. | System & User | deleteData() | System: engine, {model, filter} (Pipeline*)<br>User: {model, filter} |
913
- | OnDataSearched | Triggered after a data search. | System & User | searchData() | System: engine, {data, count} (Pipeline*)<br>User: {data, count} (or the version modified by the system) |
914
- | OnDataExported | Triggered after a data export. | System & User | exportData() | System: engine, exportResults, modelsToExport (Pipeline*)<br>User: exportResults, modelsToExport (or the version modified by the system) |
915
- | OnDataInsert | Triggered just before data insertion. It will use the overrided data. | System | internal | (data) |
916
- | OnDataValidate | Triggered to override validation check. | System | internal | (value, field, data) |
917
- | OnDataFilter | Triggered to override data filtering operation. | System | internal | (filteredValue, field, data) |
918
- | OnEmailTemplate | Triggered to override custom email templates | System | internal | (templateData, lang) |
919
- | OnSystemPrompt | Triggered to override assistant system prompt | User | handleChatRequest | (user) |
920
- | OnChatAction | Triggered when an action is created by the AI | User | handleChatRequest | (action, params, parsedResponse, user) |
941
+ | Event | Description | Scope | Triggered by | Arguments (Payload) |
942
+ |:-----------------|:------------------------------------------------------------------------|:-------|:-------------------------|:---------------------------------------------------------------------|
943
+ | OnServerStart | Triggered once the HTTP server is started and listening. | System | engine.start() | engine |
944
+ | OnServerStop | Triggered right after the HTTP server is stopped. | System | engine.stop() | engine |
945
+ | OnModelsLoaded | Triggered after the initial models are loaded and validated at startup. | System | setupInitialModels() | engine, dbModels |
946
+ | OnModelsDeleted | Triggered after all models are deleted via the reset function. | System | engine.resetModels() | engine |
947
+ | OnUserDataDumped | Triggered after a user's data has been backed up (dumped). | System | jobDumpUserData() | engine |
948
+ | OnDataRestored | Triggered after a user's data has been restored from a backup. | System | loadFromDump() | (none) |
949
+ | OnPackInstalled | Triggered after a data pack has been successfully installed. | System | installPack() | pack |
950
+ | OnModelEdited | Triggered after a model definition has been modified. | System | editModel() | newModel |
951
+ | OnDataAdded | Triggered after new data has been inserted. | System | insertData() | engine, insertedDocs |
952
+ | OnDataEdited | Triggered after data has been edited. | System | editData() / patchData() | engine, {modelName, before, after} |
953
+ | OnDataDeleted | Triggered just after data is actually deleted. | System | deleteData() | engine, {model, filter} |
954
+ | OnDataSearched | Triggered after a data search. | System | searchData() | engine, {data, count} |
955
+ | OnDataExported | Triggered after a data export. | User | exportData() | exportResults, modelsToExport |
956
+ | OnDataInsert | Triggered just before data insertion. It will use the overrided data. | System | internal | data |
957
+ | OnDataValidate | Triggered to override validation check. | System | internal | value, field, data |
958
+ | OnDataFilter | Triggered to override data filtering operation. | System | internal | filteredValue, field, data |
959
+ | OnEmailTemplate | Triggered to override custom email templates | System | internal | templateData, lang |
960
+ | OnSystemPrompt | Triggered to override assistant system prompt | User | handleChatRequest | user |
961
+ | OnChatAction | Triggered when an action is created by the AI | User | handleChatRequest | action, params, parsedResponse, command, llmOptions, user, reqParams |
921
962
 
922
963
  ### Triggering events
923
964
 
@@ -1,6 +1,6 @@
1
1
  import React, {useState, useMemo, useEffect} from 'react';
2
2
  import { Trans, useTranslation } from 'react-i18next';
3
- import {FaPlus, FaSpinner, FaCog} from "react-icons/fa"; // Ajout FaTrash
3
+ import {FaPlus, FaSpinner, FaCog, FaEye} from "react-icons/fa"; // Ajout FaTrash
4
4
 
5
5
  import "./Dashboard.scss"
6
6
  import {useMutation, useQuery, useQueryClient} from "react-query";
@@ -12,6 +12,7 @@ import { useModelContext } from './contexts/ModelContext';
12
12
  import { useAuthContext } from './contexts/AuthContext';
13
13
  import { Trans, useTranslation } from 'react-i18next';
14
14
  import { CodeField } from "./Field.jsx";
15
+ import { useData } from './hooks/data.js';
15
16
  import { useQuery } from 'react-query';
16
17
 
17
18
  import "./WorkflowEditor.scss"
@@ -32,6 +33,23 @@ const WorkflowEditor = ({ workflowId }) => {
32
33
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
33
34
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);
34
35
  const [selectedNode, setSelectedNode] = useState(null);
36
+ const [highlightedElements, setHighlightedElements] = useState({ nodes: new Set(), edges: new Set() });
37
+ const [workflowRuns, setWorkflowRuns] = useState([]);
38
+ const [selectedRun, setSelectedRun] = useState(null);
39
+
40
+ // --- CORRECTION ---
41
+ // On utilise le hook `useData` comme prévu, en lui passant directement les paramètres de la requête.
42
+ // Cela corrige l'erreur "Cannot read properties of undefined (reading 'queryKey')".
43
+ const { data: runsData, refetch: refetchRuns } = useData(
44
+ 'workflowRun', // queryKey
45
+ { model: 'workflowRun', filter: { workflow: workflowId }, sort: 'startedAt:DESC', limit: 10 }, // queryParams
46
+ {
47
+ queryKey: ['workflowRuns', workflowId],
48
+ enabled: !!workflowId,
49
+ // --- CORRECTION ---
50
+ // Le hook `useData` retourne déjà le tableau de données. On utilise donc `data` directement.
51
+ onSuccess: (data) => setWorkflowRuns(data || [])
52
+ });
35
53
  const [panelWidth, setPanelWidth] = useState(300);
36
54
  const resizeData = useRef({ isResizing: false, initialX: 0, initialWidth: 0 });
37
55
 
@@ -157,6 +175,7 @@ const WorkflowEditor = ({ workflowId }) => {
157
175
  const nodePosition = { x: parentPosition.x, y: parentPosition.y + 120 };
158
176
  initialNodes.push({
159
177
  id: step._id,
178
+ // --- NOUVEAU --- Ajout d'une classe de base pour le styling
160
179
  type: 'default',
161
180
  className: 'workflow-step-node',
162
181
  position: nodePosition,
@@ -182,6 +201,7 @@ const WorkflowEditor = ({ workflowId }) => {
182
201
  initialNodes.push({
183
202
  id: action._id,
184
203
  type: 'default',
204
+ // --- NOUVEAU --- Ajout d'une classe de base pour le styling
185
205
  className: 'workflow-action-node',
186
206
  position: actionNodePosition,
187
207
  data: {
@@ -220,6 +240,62 @@ const WorkflowEditor = ({ workflowId }) => {
220
240
  }
221
241
  }, [mainWorkflowData, workflowStepsData, workflowActionsData, setNodes, setEdges, t]);
222
242
 
243
+ // --- NOUVEAU ---
244
+ // Ce `useEffect` est le cœur de la nouvelle fonctionnalité.
245
+ // Il s'exécute chaque fois que l'utilisateur sélectionne un `workflowRun` différent.
246
+ useEffect(() => {
247
+ if (!selectedRun) {
248
+ // Si aucun run n'est sélectionné, on réinitialise tous les styles.
249
+ setNodes((nds) =>
250
+ nds.map((node) => ({
251
+ ...node,
252
+ className: node.className?.split(' ')[0] // Garde seulement la classe de base (ex: 'workflow-step-node')
253
+ }))
254
+ );
255
+ setEdges((eds) =>
256
+ eds.map((edge) => ({
257
+ ...edge,
258
+ animated: false,
259
+ className: ''
260
+ }))
261
+ );
262
+ return;
263
+ }
264
+
265
+ // 1. Identifier tous les IDs des nœuds (étapes et actions) qui ont été exécutés.
266
+ const executedStepIds = new Set(selectedRun.history.map(h => h.stepId));
267
+ const executedActionIds = new Set(selectedRun.history.flatMap(h => h.actions?.map(a => a.actionId) || []));
268
+ const allExecutedNodeIds = new Set([
269
+ `workflow-start-${mainWorkflowData._id}`, // Toujours inclure le nœud de départ
270
+ ...executedStepIds,
271
+ ...executedActionIds
272
+ ]);
273
+
274
+ // 2. Mettre à jour les nœuds pour ajouter une classe 'executed'.
275
+ setNodes((nds) =>
276
+ nds.map((node) => {
277
+ const baseClass = node.className?.split(' ')[0] || '';
278
+ if (allExecutedNodeIds.has(node.id)) {
279
+ return { ...node, className: `${baseClass} executed` };
280
+ }
281
+ return { ...node, className: baseClass }; // Rétablir la classe de base si non exécuté
282
+ })
283
+ );
284
+
285
+ // 3. Mettre à jour les arêtes pour les animer si elles connectent deux nœuds exécutés.
286
+ setEdges((eds) =>
287
+ eds.map((edge) => {
288
+ const isExecuted = allExecutedNodeIds.has(edge.source) && allExecutedNodeIds.has(edge.target);
289
+ return {
290
+ ...edge,
291
+ animated: isExecuted,
292
+ className: isExecuted ? 'executed' : ''
293
+ };
294
+ })
295
+ );
296
+
297
+ }, [selectedRun, setNodes, setEdges, mainWorkflowData]);
298
+
223
299
  const onConnect = useCallback(
224
300
  (params) => setEdges((eds) => addEdge(params, eds)),
225
301
  [setEdges],
@@ -264,6 +340,11 @@ const WorkflowEditor = ({ workflowId }) => {
264
340
  {/* Panneau latéral pour l'édition des propriétés */}
265
341
  {selectedNode && (
266
342
  <div className="properties-panel" style={{ width: `${panelWidth}px`, padding: '10px', borderLeft: '1px solid #ccc' }}>
343
+ <select onChange={(e) => setSelectedRun(workflowRuns.find(r => r._id === e.target.value))} value={selectedRun?._id || ''}>
344
+ <option value="">{t('select_a_run', 'Select a run to debug')}</option>
345
+ {workflowRuns.map(run => <option key={run._id} value={run._id}>{new Date(run.startedAt).toLocaleString()} - {run.status}</option>)}
346
+ </select>
347
+ <button onClick={() => refetchRuns()}>{t('refresh', 'Refresh')}</button>
267
348
  <div
268
349
  className="resizer"
269
350
  onMouseDown={handleMouseDown}
@@ -271,6 +352,26 @@ const WorkflowEditor = ({ workflowId }) => {
271
352
  <h3><Trans i18nKey="properties">Propriétés</Trans></h3>
272
353
  <p><strong>ID:</strong> {selectedNode.id}</p>
273
354
 
355
+ {/* --- NOUVELLE SECTION POUR L'HISTORIQUE --- */}
356
+ {selectedRun && selectedRun.history && selectedRun.history.find(h => h.stepId === selectedNode.id) && (
357
+ <div className="mt-2 p-2 border rounded bg-gray-50">
358
+ <strong><Trans i18nKey="run_history">Run History</Trans> ({selectedRun.status})</strong>
359
+ {selectedRun.history.filter(h => h.stepId === selectedNode.id).map((historyEntry, index) => (
360
+ <div key={index} className="mt-1 text-sm">
361
+ <p><strong><Trans i18nKey="executed_at">Executed at:</Trans></strong> {new Date(historyEntry.executedAt).toLocaleTimeString()}</p>
362
+ <p><strong><Trans i18nKey="status">Status:</Trans></strong> {historyEntry.status}</p>
363
+ {historyEntry.actions?.length > 0 && (
364
+ <ul className="pl-4 list-disc">
365
+ {historyEntry.actions.map((actionHist, aIndex) => (
366
+ <li key={aIndex}>{actionHist.actionName}: {actionHist.status} ({actionHist.result})</li>
367
+ ))}
368
+ </ul>
369
+ )}
370
+ </div>
371
+ ))}
372
+ </div>
373
+ )}
374
+
274
375
  {/* Affiche les conditions pour un workflowStep */}
275
376
  {selectedNode.data.conditions && (
276
377
  <div className="mt-2">
@@ -1,16 +1,41 @@
1
1
 
2
2
  .workflow-step-node {
3
- background-color: #e0e7ff; /* Un bleu clair pour les étapes */
4
- border-color: #a5b4fc;
3
+ background-color: #f3f4f6; /* Gris clair par défaut */
4
+ border-color: #d1d5db;
5
5
  border-width: 2px;
6
6
  font-weight: bold;
7
+ transition: background-color 0.3s ease, border-color 0.3s ease;
7
8
  }
8
9
 
9
10
  .workflow-action-node {
10
- background-color: #f0f9ff; /* Un bleu très clair pour les actions */
11
- border-color: #bae6fd;
11
+ background-color: #f9fafb; /* Gris très clair par défaut */
12
+ border-color: #e5e7eb;
12
13
  border-width: 1px;
13
14
  border-style: dashed;
14
15
  width: auto;
15
16
  min-width: 150px;
17
+ transition: background-color 0.3s ease, border-color 0.3s ease;
18
+ }
19
+
20
+ /* --- NOUVEAU : Styles pour les éléments exécutés --- */
21
+
22
+ /* Style pour les nœuds (étapes et actions) qui ont été exécutés */
23
+ .react-flow__node.executed {
24
+ background-color: #dcfce7; /* Vert clair */
25
+ border-color: #4ade80; /* Vert plus prononcé */
26
+ }
27
+
28
+ /* Style pour les arêtes qui font partie du chemin d'exécution */
29
+ .react-flow__edge.executed .react-flow__edge-path {
30
+ stroke: #2563eb; /* Bleu vif */
31
+ stroke-width: 2.5;
32
+ }
33
+
34
+ /* Style pour l'animation sur les arêtes exécutées */
35
+ .react-flow__edge.executed.animated .react-flow__edge-path {
36
+ animation-duration: 1s;
37
+ }
38
+
39
+ .react-flow__edge-textbg {
40
+ fill: #f9fafb;
16
41
  }
package/package.json CHANGED
@@ -1,142 +1,145 @@
1
- {
2
- "name": "data-primals-engine",
3
- "version": "1.6.2-rc1",
4
- "description": "data-primals-engine is a package responsible from handling large amount of data using MongoDB in a practical and performant way. It can also get workflow models working (for automation), and fully supports internationalisation. It also has integrated AI assistant.",
5
- "main": "src/engine.js",
6
- "type": "module",
7
- "scripts": {
8
- "preinstall": "npx force-resolutions",
9
- "dev": "concurrently \"npm:client\" \"npm:devserver\"",
10
- "prod": "npm run build-server && npm run server",
11
- "client": "cd client && npm run dev",
12
- "build-server": "vite build client --config client/vite.config.js --outDir dist",
13
- "build-client": "cd client && npm run build",
14
- "server": "cross-env NODE_ENV=production node server.js",
15
- "devserver": "npm run build-server && cross-env NODE_ENV=development PORT=7633 node server.js",
16
- "lint": "eslint .",
17
- "format": "prettier --write .",
18
- "clean": "rm -rf node_modules package-lock.json",
19
- "test": "cross-env MONGO_DB_URL=\"mongodb://localhost:27017\" PORT=7635 vitest --no-file-parallelism --no-watch",
20
- "audit": "npm audit --audit-level=high",
21
- "migrate:create": "node src/migrate.js create",
22
- "migrate:up": "node src/migrate.js up",
23
- "migrate:down": "node src/migrate.js down",
24
- "migrate:revert": "node src/migrate.js revert",
25
- "migrate:status": "node src/migrate.js status"
26
- },
27
- "optionalDependencies": {
28
- "@rollup/rollup-linux-x64-gnu": "4.6.1"
29
- },
30
- "resolutions": {
31
- "on-headers": "1.1.0",
32
- "brace-expansion": "2.0.2",
33
- "prismjs": "1.30.0",
34
- "xml2js": ">=0.5.0",
35
- "tar-fs": ">=3.1.1",
36
- "vite": ">=7.0.8"
37
- },
38
- "overrides": {
39
- "react-syntax-highlighter": {
40
- "prismjs": "1.30.0"
41
- },
42
- "react-code-blocks": {
43
- "prismjs": "1.30.0"
44
- },
45
- "refractor": {
46
- "prismjs": "1.30.0"
47
- }
48
- },
49
- "repository": {
50
- "type": "git",
51
- "url": "https://github.com/anonympins/data-primals-engine.git"
52
- },
53
- "exports": {
54
- ".": "./src/index.js",
55
- "./modules/*.js": "./src/modules/*.js",
56
- "./modules/*": "./src/modules/*/index.js",
57
- "./client": "./client/index.js",
58
- "./*": "./src/*.js"
59
- },
60
- "dependencies": {
61
- "@langchain/core": "^0.3.79",
62
- "archiver": "^7.0.1",
63
- "aws-sdk": "^2.1692.0",
64
- "bcrypt": "^6.0.0",
65
- "body-parser": "^2.2.0",
66
- "chalk": "^5.4.1",
67
- "check-disk-space": "^3.4.0",
68
- "compression": "^1.8.1",
69
- "cookie-parser": "^1.4.7",
70
- "cronstrue": "^3.2.0",
71
- "csv-parse": "^6.1.0",
72
- "date-fns": "^4.1.0",
73
- "express-csrf-double-submit-cookie": "^2.0.0",
74
- "express-formidable": "^1.2.0",
75
- "express-mongo-sanitize": "^2.2.0",
76
- "express-rate-limit": "^8.0.1",
77
- "express-session": "^1.18.2",
78
- "handlebars": "^4.7.8",
79
- "i18next-browser-languagedetector": "^8.2.0",
80
- "isolated-vm": "^5.0.0",
81
- "juice": "^11.0.3",
82
- "mathjs": "^15.1.0",
83
- "mongodb": "^6.18.0",
84
- "node-cache": "^5.1.2",
85
- "node-schedule": "^2.1.1",
86
- "nodemailer": "^7.0.10",
87
- "openai": "^6.9.1",
88
- "passport": "^0.7.0",
89
- "passport-saml-encrypted": "^0.1.13",
90
- "process": "^0.11.10",
91
- "prop-types": "^15.8.1",
92
- "randomcolor": "^0.6.2",
93
- "react-markdown": "^10.1.0",
94
- "read-excel-file": "^6.0.1",
95
- "request-ip": "^3.3.0",
96
- "safe-regex": "^2.1.1",
97
- "sanitize-html": "^2.17.0",
98
- "sirv": "^3.0.2",
99
- "stripe": "^20.0.0",
100
- "swagger-ui-express": "^5.0.1",
101
- "tar": "^7.5.2",
102
- "tinycolor2": "^1.6.0",
103
- "uniqid": "^5.4.0",
104
- "vitest": "^3.2.4",
105
- "yaml": "^2.8.1"
106
- },
107
- "peerDependencies": {
108
- "express": "^5.1.0",
109
- "passport-azure-ad": "^4.3.5",
110
- "passport-google-oauth20": "^2.0.0",
111
- "react": "18.3.1",
112
- "react-i18next": "^16.3.4",
113
- "react-query": "^3.39.3",
114
- "@langchain/anthropic": "^0.3.33",
115
- "@langchain/deepseek": "^0.1.0",
116
- "@langchain/google-genai": "^0.2.18",
117
- "@langchain/openai": "^0.6.16"
118
- },
119
- "devDependencies": {
120
- "@eslint/js": "^9.32.0",
121
- "concurrently": "^9.2.0",
122
- "cross-env": "^10.0.0",
123
- "eslint": "^9.32.0",
124
- "globals": "^16.3.0"
125
- },
126
- "subPackages": [
127
- "client"
128
- ],
129
- "keywords": [
130
- "data-driven engine",
131
- "headless CMS",
132
- "backend",
133
- "automation",
134
- "AWS S3",
135
- "MongoDB"
136
- ],
137
- "author": "anonympins",
138
- "license": "MIT",
139
- "engines": {
140
- "node": ">=20.0.0"
141
- }
142
- }
1
+ {
2
+ "name": "data-primals-engine",
3
+ "version": "1.6.3",
4
+ "description": "data-primals-engine is a package responsible from handling large amount of data using MongoDB in a practical and performant way. It can also get workflow models working (for automation), and fully supports internationalisation. It also has integrated AI assistant.",
5
+ "main": "src/engine.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "preinstall": "npx force-resolutions",
9
+ "dev": "concurrently \"npm:client\" \"npm:devserver\"",
10
+ "prod": "npm run build-server && npm run server",
11
+ "client": "cd client && npm run dev",
12
+ "build-server": "vite build client --config client/vite.config.js --outDir dist",
13
+ "build-client": "cd client && npm run build",
14
+ "server": "cross-env NODE_ENV=production node server.js",
15
+ "devserver": "npm run build-server && cross-env NODE_ENV=development PORT=7633 node server.js",
16
+ "lint": "eslint .",
17
+ "format": "prettier --write .",
18
+ "clean": "rm -rf node_modules package-lock.json",
19
+ "test": "cross-env MONGO_DB_URL=\"mongodb://localhost:27017\" PORT=7635 vitest --no-file-parallelism --no-watch",
20
+ "audit": "npm audit --audit-level=high",
21
+ "migrate:create": "node src/migrate.js create",
22
+ "migrate:up": "node src/migrate.js up",
23
+ "migrate:down": "node src/migrate.js down",
24
+ "migrate:revert": "node src/migrate.js revert",
25
+ "migrate:status": "node src/migrate.js status"
26
+ },
27
+ "optionalDependencies": {
28
+ "@rollup/rollup-linux-x64-gnu": "4.6.1"
29
+ },
30
+ "resolutions": {
31
+ "on-headers": "1.1.0",
32
+ "brace-expansion": "2.0.2",
33
+ "prismjs": "1.30.0",
34
+ "xml2js": ">=0.5.0",
35
+ "tar-fs": ">=3.1.1",
36
+ "vite": ">=7.0.8",
37
+ "node-forge": ">=1.3.2",
38
+ "js-yaml": ">=4.1.1"
39
+ },
40
+ "overrides": {
41
+ "react-syntax-highlighter": {
42
+ "prismjs": "1.30.0"
43
+ },
44
+ "react-code-blocks": {
45
+ "prismjs": "1.30.0"
46
+ },
47
+ "refractor": {
48
+ "prismjs": "1.30.0"
49
+ }
50
+ },
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "https://github.com/anonympins/data-primals-engine.git"
54
+ },
55
+ "exports": {
56
+ ".": "./src/index.js",
57
+ "./client-only": "./src/client.js",
58
+ "./modules/*.js": "./src/modules/*.js",
59
+ "./modules/*": "./src/modules/*/index.js",
60
+ "./client": "./client/index.js",
61
+ "./*": "./src/*.js"
62
+ },
63
+ "dependencies": {
64
+ "@langchain/core": "^0.3.79",
65
+ "archiver": "^7.0.1",
66
+ "aws-sdk": "^2.1692.0",
67
+ "bcrypt": "^6.0.0",
68
+ "body-parser": "^2.2.1",
69
+ "chalk": "^5.4.1",
70
+ "check-disk-space": "^3.4.0",
71
+ "compression": "^1.8.1",
72
+ "cookie-parser": "^1.4.7",
73
+ "cronstrue": "^3.2.0",
74
+ "csv-parse": "^6.1.0",
75
+ "date-fns": "^4.1.0",
76
+ "express-csrf-double-submit-cookie": "^2.0.0",
77
+ "express-formidable": "^1.2.0",
78
+ "express-mongo-sanitize": "^2.2.0",
79
+ "express-rate-limit": "^8.0.1",
80
+ "express-session": "^1.18.2",
81
+ "handlebars": "^4.7.8",
82
+ "i18next-browser-languagedetector": "^8.2.0",
83
+ "isolated-vm": "^5.0.4",
84
+ "juice": "^11.0.3",
85
+ "mathjs": "^15.1.0",
86
+ "mongodb": "^6.18.0",
87
+ "node-cache": "^5.1.2",
88
+ "node-schedule": "^2.1.1",
89
+ "nodemailer": "^7.0.10",
90
+ "openai": "^6.9.1",
91
+ "passport": "^0.7.0",
92
+ "passport-saml-encrypted": "^0.1.13",
93
+ "process": "^0.11.10",
94
+ "prop-types": "^15.8.1",
95
+ "randomcolor": "^0.6.2",
96
+ "react-markdown": "^10.1.0",
97
+ "read-excel-file": "^6.0.1",
98
+ "request-ip": "^3.3.0",
99
+ "safe-regex": "^2.1.1",
100
+ "sanitize-html": "^2.17.0",
101
+ "sirv": "^3.0.2",
102
+ "stripe": "^20.0.0",
103
+ "swagger-ui-express": "^5.0.1",
104
+ "tar": "^7.5.2",
105
+ "tinycolor2": "^1.6.0",
106
+ "uniqid": "^5.4.0",
107
+ "vitest": "^3.2.4",
108
+ "yaml": "^2.8.1"
109
+ },
110
+ "peerDependencies": {
111
+ "express": "^5.1.0",
112
+ "passport-azure-ad": "^4.3.5",
113
+ "passport-google-oauth20": "^2.0.0",
114
+ "react": "18.3.1",
115
+ "react-i18next": "^16.3.4",
116
+ "react-query": "^3.39.3",
117
+ "@langchain/anthropic": "^0.3.33",
118
+ "@langchain/deepseek": "^0.1.0",
119
+ "@langchain/google-genai": "^0.2.18",
120
+ "@langchain/openai": "^0.6.16"
121
+ },
122
+ "devDependencies": {
123
+ "@eslint/js": "^9.32.0",
124
+ "concurrently": "^9.2.0",
125
+ "cross-env": "^10.0.0",
126
+ "eslint": "^9.32.0",
127
+ "globals": "^16.3.0"
128
+ },
129
+ "subPackages": [
130
+ "client"
131
+ ],
132
+ "keywords": [
133
+ "data-driven engine",
134
+ "headless CMS",
135
+ "backend",
136
+ "automation",
137
+ "AWS S3",
138
+ "MongoDB"
139
+ ],
140
+ "author": "anonympins",
141
+ "license": "MIT",
142
+ "engines": {
143
+ "node": ">=20.0.0"
144
+ }
145
+ }
package/src/client.js ADDED
@@ -0,0 +1,4 @@
1
+ // data-primals-engine/client
2
+ // Ce fichier sert de point d'entrée pour les modules qui peuvent être utilisés en toute sécurité côté client (navigateur).
3
+
4
+ export { Event } from './events.js';