data-primals-engine 1.2.3 → 1.2.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/CONTRIBUTING.md +91 -0
- package/README.md +33 -17
- package/client/src/App.jsx +0 -5
- package/client/src/ConditionBuilder.scss +34 -1
- package/client/src/ConditionBuilder2.jsx +179 -53
- package/client/src/ContentView.jsx +0 -3
- package/client/src/CronBuilder.jsx +0 -1
- package/client/src/CronPartBuilder.jsx +0 -2
- package/client/src/DashboardView.jsx +0 -5
- package/client/src/DataEditor.jsx +8 -10
- package/client/src/DataLayout.jsx +0 -1
- package/client/src/DataTable.jsx +1 -3
- package/client/src/Field.jsx +0 -5
- package/client/src/FlexBuilder.jsx +1 -1
- package/client/src/ModelCreatorField.jsx +1 -5
- package/client/src/RTE.jsx +1 -6
- package/client/src/RTETrans.jsx +0 -2
- package/client/src/RelationField.jsx +1 -1
- package/client/src/RelationValue.jsx +1 -2
- package/client/src/TourSpotlight.jsx +0 -2
- package/client/src/filter.js +87 -0
- package/client/src/hooks/data.js +1 -3
- package/client/src/hooks/useTutorials.jsx +0 -1
- package/package.json +3 -3
- package/server.js +2 -2
- package/src/email.js +2 -2
- package/src/engine.js +59 -20
- package/src/index.js +1 -1
- package/src/middlewares/middleware-mongodb.js +0 -1
- package/src/modules/assistant.js +1 -3
- package/src/modules/bucket.js +3 -4
- package/src/modules/{data.js → data/data.js} +34 -51
- package/src/modules/data/index.js +1 -0
- package/src/modules/file.js +1 -1
- package/src/modules/mongodb.js +0 -1
- package/src/modules/user.js +1 -1
- package/src/modules/workflow.js +38 -38
- package/src/packs.js +4 -1
- package/test/data.backup.integration.test.js +4 -5
- package/test/data.integration.test.js +2 -6
- package/test/events.test.js +1 -1
- package/test/file.test.js +1 -4
- package/test/import_export.integration.test.js +20 -13
- package/test/model.integration.test.js +8 -10
- package/test/user.test.js +2 -2
- package/test/vm.test.js +1 -1
- package/test/workflow.integration.test.js +17 -14
- package/test/workflow.robustness.test.js +15 -10
- package/src/modules/test +0 -147
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {expect, describe, it, beforeEach, beforeAll, afterAll, vi} from 'vitest';
|
|
1
|
+
import {expect, describe, it, beforeEach, beforeAll, afterAll, vi, afterEach} from 'vitest';
|
|
2
2
|
|
|
3
3
|
// --- Importations des modules de votre application ---
|
|
4
4
|
import {
|
|
@@ -10,12 +10,11 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
modelsCollection as getAppModelsCollection,
|
|
12
12
|
getCollectionForUser as getAppUserCollection, getCollectionForUser
|
|
13
|
-
} from '
|
|
13
|
+
} from '../src/modules/mongodb.js';
|
|
14
14
|
import {sleep} from "data-primals-engine/core";
|
|
15
15
|
import fs from "node:fs";
|
|
16
|
-
import {
|
|
16
|
+
import {initEngine} from "../src/setenv.js";
|
|
17
17
|
import {Config} from "../src/index.js";
|
|
18
|
-
import {ObjectId} from "mongodb";
|
|
19
18
|
|
|
20
19
|
// --- Données Mock ---
|
|
21
20
|
const mockUser = {
|
|
@@ -38,13 +37,9 @@ const impexTestModel = {
|
|
|
38
37
|
};
|
|
39
38
|
|
|
40
39
|
// --- Setup de l'environnement de test ---
|
|
41
|
-
let mongod;
|
|
42
|
-
let testDbUri;
|
|
43
|
-
const testDbName = 'testIntegrationDbHO_Impex';
|
|
44
40
|
let testModelsColInstance;
|
|
45
41
|
let testDatasColInstance;
|
|
46
|
-
|
|
47
|
-
const port = getUniquePort(); // Port unique pour cette suite de tests
|
|
42
|
+
|
|
48
43
|
function blobToFile(theBlob, fileName){
|
|
49
44
|
//A Blob() is almost a File() - it's just missing the two properties below which we will add
|
|
50
45
|
theBlob.lastModifiedDate = new Date();
|
|
@@ -56,6 +51,17 @@ beforeAll(async () =>{
|
|
|
56
51
|
Config.Set("modules", ["mongodb", "data", "file", "bucket", "workflow","user", "assistant"]);
|
|
57
52
|
await initEngine();
|
|
58
53
|
})
|
|
54
|
+
|
|
55
|
+
beforeEach(async() =>{
|
|
56
|
+
// tell vitest we use mocked time
|
|
57
|
+
vi.useFakeTimers({ shouldAdvanceTime: true })
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
afterEach(() => {
|
|
61
|
+
vi.runOnlyPendingTimers();
|
|
62
|
+
// restoring date after each test run
|
|
63
|
+
vi.useRealTimers()
|
|
64
|
+
})
|
|
59
65
|
afterAll(async () => {
|
|
60
66
|
const coll = await getCollectionForUser(mockUser);
|
|
61
67
|
await coll.drop();
|
|
@@ -84,6 +90,7 @@ describe('Intégration des fonctions d\'Import/Export', () => {
|
|
|
84
90
|
|
|
85
91
|
describe('Export de données', () => {
|
|
86
92
|
it('devrait exporter les données en format JSON', async () => {
|
|
93
|
+
|
|
87
94
|
const res= await exportData({
|
|
88
95
|
models: [impexTestModel.name],
|
|
89
96
|
depth: 1
|
|
@@ -107,6 +114,7 @@ describe('Intégration des fonctions d\'Import/Export', () => {
|
|
|
107
114
|
|
|
108
115
|
describe('Import de données', () => {
|
|
109
116
|
it('devrait importer des données depuis une chaîne JSON', async () => {
|
|
117
|
+
|
|
110
118
|
const jsonDataToImport = [
|
|
111
119
|
{ name: 'Produit D', sku: 'SKU-D', price: 1.00, inStock: true },
|
|
112
120
|
{ name: 'Produit E', sku: 'SKU-E', price: 2.00 } // inStock utilisera la valeur par défaut
|
|
@@ -124,7 +132,7 @@ describe('Intégration des fonctions d\'Import/Export', () => {
|
|
|
124
132
|
expect(result.success).toBe(true);
|
|
125
133
|
expect(result.job.jobId).not.toBeNull();
|
|
126
134
|
|
|
127
|
-
await sleep(
|
|
135
|
+
await sleep(5000);
|
|
128
136
|
|
|
129
137
|
// Vérification directe en base de données
|
|
130
138
|
const importedDocs = await testDatasColInstance.find({
|
|
@@ -158,7 +166,7 @@ describe('Intégration des fonctions d\'Import/Export', () => {
|
|
|
158
166
|
expect(result.success).toBe(true);
|
|
159
167
|
expect(result.job.jobId).not.toBeNull();
|
|
160
168
|
|
|
161
|
-
await sleep(
|
|
169
|
+
await sleep(5000);
|
|
162
170
|
// Vérification en base de données
|
|
163
171
|
const importedDocs = await testDatasColInstance.find({
|
|
164
172
|
_model: impexTestModel.name,
|
|
@@ -194,8 +202,7 @@ Valide K,SKU-A,40,true`;
|
|
|
194
202
|
expect(result.success).toBe(true);
|
|
195
203
|
expect(result.job.jobId).not.toBeNull();
|
|
196
204
|
|
|
197
|
-
await sleep(
|
|
198
|
-
|
|
205
|
+
await sleep(5000);
|
|
199
206
|
// Vérifier que seule les données valides sont en BDD
|
|
200
207
|
const count = await testDatasColInstance.countDocuments({ _model: impexTestModel.name, sku: 'SKU-H' });
|
|
201
208
|
expect(count).toBe(1); // Seule la ligne valide 'SKU-H' doit être insérée.
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
// __tests__/data.integration.test.js
|
|
2
2
|
import { ObjectId } from 'mongodb';
|
|
3
|
-
import {expect, describe, it,
|
|
3
|
+
import {expect, describe, it, beforeAll} from 'vitest';
|
|
4
4
|
import { Config } from '../src/config.js';
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {getCollectionForUser, getUserCollectionName} from "../src/modules/mongodb.js";
|
|
7
|
+
getCollection // Accès direct pour vérifications
|
|
8
|
+
} from '../src/modules/mongodb.js';
|
|
9
|
+
import {generateUniqueName, initEngine} from "../src/setenv.js";
|
|
10
|
+
import {editModel} from "../src/index.js";
|
|
11
|
+
import {getCollectionForUser} from "../src/modules/mongodb.js";
|
|
13
12
|
|
|
14
13
|
let testModelsColInstance;
|
|
15
14
|
let testModelId;
|
|
16
|
-
let lastUser;
|
|
17
15
|
// Cette fonction va remplacer la logique de votre beforeEach pour la création de contexte
|
|
18
16
|
async function setupTestContext() {
|
|
19
17
|
|
|
@@ -24,7 +22,7 @@ async function setupTestContext() {
|
|
|
24
22
|
// Créer un utilisateur unique pour ce test
|
|
25
23
|
const currentTestUser = {
|
|
26
24
|
username: generateUniqueName('testuserModelIntegration'),
|
|
27
|
-
userPlan: '
|
|
25
|
+
userPlan: 'free',
|
|
28
26
|
email: generateUniqueName('test') + '@example.com'
|
|
29
27
|
};
|
|
30
28
|
|
|
@@ -125,7 +123,7 @@ describe('CRUD on model definitions and integrity tests', () => {
|
|
|
125
123
|
|
|
126
124
|
describe('editModel unit tests', () => {
|
|
127
125
|
|
|
128
|
-
it
|
|
126
|
+
it('should create and drop index when field.index is toggled (premium user)', async () => {
|
|
129
127
|
// --- SETUP ---
|
|
130
128
|
const { coll, currentTestUser, comprehensiveTestModelDefinition } = await setupTestContext();
|
|
131
129
|
const fieldToIndex = 'stringUnique'; // Utiliser un champ qui existe vraiment dans le modèle
|
package/test/user.test.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { expect, describe, it, beforeEach, beforeAll, afterAll } from 'vitest';
|
|
2
2
|
import { hasPermission, getUserActivePermissions } from '../src/modules/user.js';
|
|
3
|
-
import {initEngine} from "
|
|
3
|
+
import {initEngine} from "../src/setenv";
|
|
4
4
|
import {generateUniqueName} from "../src/setenv.js";
|
|
5
5
|
import {
|
|
6
6
|
getCollectionForUser as getAppUserCollection,
|
|
7
7
|
modelsCollection as getAppModelsCollection
|
|
8
|
-
} from "
|
|
8
|
+
} from "../src/modules/mongodb.js";
|
|
9
9
|
import {Config} from "../src/index.js";
|
|
10
10
|
let permRead, permWrite, permDelete, permManage;
|
|
11
11
|
let roleEditor;
|
package/test/vm.test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {expect, describe, it, beforeEach, afterEach, beforeAll, afterAll, vi, vitest} from 'vitest';
|
|
2
2
|
import ivm from "isolated-vm";
|
|
3
|
-
import {sleep} from "
|
|
3
|
+
import {sleep} from "../src/core";
|
|
4
4
|
|
|
5
5
|
vi.stubEnv('ENCRYPTION_KEY', '12345678901234567890123456789012');
|
|
6
6
|
|
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
// __tests__/workflow.integration.test.js
|
|
2
1
|
import { expect, describe, it, beforeEach,afterEach, beforeAll, afterAll, vi } from 'vitest';
|
|
3
|
-
import { Config } from "
|
|
4
|
-
|
|
5
|
-
import {insertData, editData, deleteData, patchData} from 'data-primals-engine/modules/data';
|
|
6
|
-
import { modelsCollection as getAppModelsCollection, getCollectionForUser } from 'data-primals-engine/modules/mongodb';
|
|
7
|
-
import * as workflowModule from 'data-primals-engine/modules/workflow';
|
|
8
|
-
import {getUniquePort, initEngine} from "../src/setenv.js";
|
|
9
|
-
import process from "process";
|
|
10
|
-
import {getUserCollectionName} from "../src/modules/mongodb.js";
|
|
2
|
+
import { Config } from "../src/config";
|
|
11
3
|
|
|
4
|
+
import {insertData, editData, deleteData, patchData} from '../src/index.js';
|
|
5
|
+
import { modelsCollection as getAppModelsCollection, getCollectionForUser } from '../src/modules/mongodb.js';
|
|
6
|
+
import * as workflowModule from '../src/modules/workflow.js';
|
|
7
|
+
import {initEngine} from "../src/setenv.js";
|
|
12
8
|
|
|
13
9
|
beforeAll(async () =>{
|
|
14
10
|
Config.Set("modules", ["mongodb", "data", "file", "bucket", "workflow","user", "assistant"]);
|
|
15
11
|
await initEngine();
|
|
16
12
|
})
|
|
17
|
-
vi.mock('
|
|
13
|
+
vi.mock('../src/modules/workflow.js', { spy: true })
|
|
18
14
|
// --- Données Mock pour les tests ---
|
|
19
15
|
const mockUser = {
|
|
20
16
|
username: 'testuserWorkflow',
|
|
@@ -139,8 +135,6 @@ const processWorkflowRunSpy = vi.spyOn(workflowModule, 'processWorkflowRun');
|
|
|
139
135
|
beforeEach(async () => {
|
|
140
136
|
testModelsColInstance = getAppModelsCollection;
|
|
141
137
|
testDatasColInstance = await getCollectionForUser(mockUser);
|
|
142
|
-
// Nettoyer les données avant chaque test
|
|
143
|
-
await testDatasColInstance.deleteMany({_user: "testuserWorkflow"});
|
|
144
138
|
|
|
145
139
|
// Réinitialiser l'espion
|
|
146
140
|
processWorkflowRunSpy.mockClear();
|
|
@@ -153,9 +147,15 @@ beforeEach(async () => {
|
|
|
153
147
|
...workflowMetaModels.map(m => ({...m})) // Copie pour éviter les mutations
|
|
154
148
|
]);
|
|
155
149
|
}
|
|
156
|
-
|
|
157
|
-
})
|
|
150
|
+
// tell vitest we use mocked time
|
|
151
|
+
vi.useFakeTimers({ shouldAdvanceTime: true })
|
|
152
|
+
})
|
|
158
153
|
|
|
154
|
+
afterEach(() => {
|
|
155
|
+
vi.runOnlyPendingTimers();
|
|
156
|
+
// restoring date after each test run
|
|
157
|
+
vi.useRealTimers()
|
|
158
|
+
})
|
|
159
159
|
afterAll(async () => {
|
|
160
160
|
const coll = await getCollectionForUser(mockUser);
|
|
161
161
|
await coll.drop();
|
|
@@ -167,6 +167,9 @@ describe('Intégration des Workflows - triggerWorkflows', () => {
|
|
|
167
167
|
|
|
168
168
|
// Avant chaque test de ce bloc, on crée un workflow et une étape de base
|
|
169
169
|
const initTest = async () => {
|
|
170
|
+
// Nettoyer les données avant chaque test
|
|
171
|
+
await testDatasColInstance.deleteMany({_user: "testuserWorkflow"});
|
|
172
|
+
|
|
170
173
|
const workflowInsertResult = await insertData('workflow', { name: 'Test Workflow' }, {}, mockUser, false);
|
|
171
174
|
testWorkflow = { _id: workflowInsertResult.insertedIds[0] };
|
|
172
175
|
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { ObjectId } from 'mongodb';
|
|
2
|
-
import {expect, describe, it, beforeEach, beforeAll, vi, afterAll} from 'vitest';
|
|
3
|
-
import { Config } from "
|
|
4
|
-
|
|
5
|
-
import { insertData, editData } from '
|
|
6
|
-
import { modelsCollection as getAppModelsCollection, getCollectionForUser, getCollection } from '
|
|
7
|
-
import * as workflowModule from '
|
|
2
|
+
import {expect, describe, it, beforeEach, beforeAll, vi, afterAll, afterEach} from 'vitest';
|
|
3
|
+
import { Config } from "../src/config";
|
|
4
|
+
|
|
5
|
+
import { insertData, editData } from '../src/index.js';
|
|
6
|
+
import { modelsCollection as getAppModelsCollection, getCollectionForUser, getCollection } from '../src/modules/mongodb.js';
|
|
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 {getUserCollectionName} from "../src/modules/mongodb.js";
|
|
11
10
|
|
|
12
|
-
vi.mock('
|
|
11
|
+
vi.mock('../src/modules/workflow.js', { spy: true })
|
|
13
12
|
|
|
14
13
|
const mockUser = {
|
|
15
14
|
username: 'robustnessUser',
|
|
@@ -42,12 +41,18 @@ beforeEach(async () => {
|
|
|
42
41
|
await testDatasColInstance.deleteMany({ _user: mockUser.username });
|
|
43
42
|
await getCollection('job_locks').deleteMany({}); // Nettoyer les verrous
|
|
44
43
|
const mods = await testModelsColInstance.find({ $and: [{_user: mockUser.username}, {$or: [{name: targetDataModel.name}, ...workflowMetaModels.map(m =>({name: m.name}))] }]}).toArray();
|
|
45
|
-
console.log({mods})
|
|
46
44
|
if( mods.length === 0){
|
|
47
45
|
await testModelsColInstance.insertMany([targetDataModel, ...workflowMetaModels]);
|
|
48
46
|
}
|
|
49
|
-
|
|
47
|
+
// tell vitest we use mocked time
|
|
48
|
+
vi.useFakeTimers({ shouldAdvanceTime: true })
|
|
49
|
+
})
|
|
50
50
|
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
vi.runOnlyPendingTimers();
|
|
53
|
+
// restoring date after each test run
|
|
54
|
+
vi.useRealTimers()
|
|
55
|
+
})
|
|
51
56
|
afterAll(async () => {
|
|
52
57
|
const coll = await getCollectionForUser(mockUser);
|
|
53
58
|
await coll.drop();
|
package/src/modules/test
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
// src/modules/file.js
|
|
2
|
-
import { getCollection } from "./mongodb.js";
|
|
3
|
-
import { uuidv4, getFileExtension } from "../core.js";
|
|
4
|
-
import { getUserS3Config, uploadToS3, deleteFromS3 } from "./bucket.js";
|
|
5
|
-
import { maxFileSize } from "../constants.js";
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
import fs from "node:fs";
|
|
8
|
-
import { promises as fsPromises } from "node:fs";
|
|
9
|
-
import { Logger } from "../gameObject.js";
|
|
10
|
-
|
|
11
|
-
let logger;
|
|
12
|
-
|
|
13
|
-
const getLogger = () => {
|
|
14
|
-
if (!logger) {
|
|
15
|
-
logger = new Logger();
|
|
16
|
-
}
|
|
17
|
-
return logger;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Ajoute un fichier au système. Le téléverse sur S3 si configuré, sinon le sauvegarde localement.
|
|
22
|
-
* @param {object} file - L'objet fichier provenant de express-formidable.
|
|
23
|
-
* @param {object} user - L'objet utilisateur.
|
|
24
|
-
* @returns {Promise<string>} Le GUID du fichier nouvellement ajouté.
|
|
25
|
-
*/
|
|
26
|
-
export const addFile = async (file, user) => {
|
|
27
|
-
if (!file) {
|
|
28
|
-
throw new Error("Aucun fichier fourni.");
|
|
29
|
-
}
|
|
30
|
-
if (file.size > maxFileSize) {
|
|
31
|
-
throw new Error(`La taille du fichier dépasse la limite de ${maxFileSize / 1024 / 1024} Mo.`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const guid = uuidv4();
|
|
35
|
-
const extension = getFileExtension(file.name);
|
|
36
|
-
const newFilename = `${guid}.${extension}`;
|
|
37
|
-
const s3Config = await getUserS3Config(user);
|
|
38
|
-
|
|
39
|
-
const fileData = {
|
|
40
|
-
_id: guid,
|
|
41
|
-
guid: guid,
|
|
42
|
-
originalFilename: file.name,
|
|
43
|
-
size: file.size,
|
|
44
|
-
mimetype: file.type,
|
|
45
|
-
createdAt: new Date(),
|
|
46
|
-
user: user.username // Bonne pratique : garder une trace de l'uploader
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
if (s3Config && s3Config.bucketName) { // Correction: bucketName au lieu de bucket
|
|
50
|
-
try {
|
|
51
|
-
// Correction: Appel manquant à la fonction de téléversement
|
|
52
|
-
await uploadToS3(s3Config, file.path, newFilename);
|
|
53
|
-
|
|
54
|
-
fileData.storage = 's3';
|
|
55
|
-
fileData.filename = newFilename; // Le nom sur S3
|
|
56
|
-
getLogger().log(`Fichier ${newFilename} téléversé sur le bucket S3 ${s3Config.bucketName}.`);
|
|
57
|
-
} catch (error) {
|
|
58
|
-
getLogger().log(`Le téléversement S3 a échoué pour ${file.name}: ${error.message}`, 'error');
|
|
59
|
-
throw new Error("Le téléversement S3 a échoué.");
|
|
60
|
-
} finally {
|
|
61
|
-
// Nettoyer le fichier temporaire uploadé par express-formidable
|
|
62
|
-
await fsPromises.unlink(file.path).catch(e => getLogger().log(`Échec de la suppression du fichier temporaire ${file.path}: ${e.message}`, 'error'));
|
|
63
|
-
}
|
|
64
|
-
} else {
|
|
65
|
-
// Sauvegarde locale
|
|
66
|
-
const uploadDir = path.join(process.cwd(), "uploads");
|
|
67
|
-
if (!fs.existsSync(uploadDir)) {
|
|
68
|
-
fs.mkdirSync(uploadDir, { recursive: true });
|
|
69
|
-
}
|
|
70
|
-
const newPath = path.join(uploadDir, newFilename);
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
// express-formidable place déjà le fichier dans un répertoire temporaire. Nous n'avons qu'éplacer.
|
|
74
|
-
await fsPromises.rename(file.path, newPath);
|
|
75
|
-
fileData.storage = 'local';
|
|
76
|
-
fileData.filename = newFilename; // Le nom dans le dossier uploads
|
|
77
|
-
fileData.path = newPath; // Le chemin complet pour les fichiers locaux
|
|
78
|
-
getLogger().log(`Fichier ${newFilename} sauvegardé localement dans ${newPath}.`);
|
|
79
|
-
} catch (error) {
|
|
80
|
-
getLogger().log(`Le déplacement du fichier local a échoué pour ${file.name}: ${error.message}`, 'error');
|
|
81
|
-
// Essayer de nettoyer le fichier temporaire même si le renommage échoue
|
|
82
|
-
await fsPromises.unlink(file.path).catch(e => getLogger().log(`Échec de la suppression du fichier temporaire ${file.path}: ${e.message}`, 'error'));
|
|
83
|
-
throw new Error("Le stockage du fichier local a échoué.");
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const filesCollection = await getCollection("files");
|
|
88
|
-
await filesCollection.insertOne(fileData);
|
|
89
|
-
|
|
90
|
-
return guid;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Récupère les métadonnées d'un fichier depuis la base de données.
|
|
95
|
-
* @param {string} guid - Le GUID du fichier.
|
|
96
|
-
* @returns {Promise<object|null>} L'objet de métadonnées du fichier ou null si non trouvé.
|
|
97
|
-
*/
|
|
98
|
-
export const getFile = async (guid) => {
|
|
99
|
-
const filesCollection = await getCollection("files");
|
|
100
|
-
return await filesCollection.findOne({ guid });
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Supprime un fichier du système (S3 ou local) et son enregistrement en base de données.
|
|
105
|
-
* @param {string} guid - Le GUID du fichier à supprimer.
|
|
106
|
-
* @param {object} user - L'objet utilisateur.
|
|
107
|
-
* @returns {Promise<void>}
|
|
108
|
-
*/
|
|
109
|
-
export const deleteFile = async (guid, user) => {
|
|
110
|
-
const fileData = await getFile(guid);
|
|
111
|
-
if (!fileData) {
|
|
112
|
-
getLogger().log(`Tentative de suppression d'un fichier inexistant avec le GUID : ${guid}`, 'warn');
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (fileData.storage === 's3') {
|
|
117
|
-
const s3Config = await getUserS3Config(user);
|
|
118
|
-
if (s3Config && s3Config.bucketName) { // Correction: bucketName au lieu de bucket
|
|
119
|
-
try {
|
|
120
|
-
await deleteFromS3(s3Config, fileData.filename);
|
|
121
|
-
getLogger().log(`Fichier ${fileData.filename} supprimé du bucket S3 ${s3Config.bucketName}.`);
|
|
122
|
-
} catch (error) {
|
|
123
|
-
getLogger().log(`La suppression S3 a échoué pour ${fileData.filename}: ${error.message}`, 'error');
|
|
124
|
-
throw new Error("La suppression S3 a échoué.");
|
|
125
|
-
}
|
|
126
|
-
} else {
|
|
127
|
-
getLogger().log(`Configuration S3 non trouvée pour l'utilisateur, impossible de supprimer le fichier ${fileData.filename} de S3.`, 'error');
|
|
128
|
-
throw new Error("Configuration S3 non trouvée, impossible de supprimer le fichier.");
|
|
129
|
-
}
|
|
130
|
-
} else if (fileData.storage === 'local') {
|
|
131
|
-
try {
|
|
132
|
-
if (fileData.path && fs.existsSync(fileData.path)) {
|
|
133
|
-
await fsPromises.unlink(fileData.path);
|
|
134
|
-
getLogger().log(`Fichier local ${fileData.path} supprimé.`);
|
|
135
|
-
} else {
|
|
136
|
-
getLogger().log(`Fichier local non trouvé au chemin ${fileData.path}, mais suppression de l'enregistrement en BDD.`, 'warn');
|
|
137
|
-
}
|
|
138
|
-
} catch (error) {
|
|
139
|
-
getLogger().log(`La suppression du fichier local a échoué pour ${fileData.path}: ${error.message}`, 'error');
|
|
140
|
-
throw new Error("La suppression du fichier local a échoué.");
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const filesCollection = await getCollection("files");
|
|
145
|
-
await filesCollection.deleteOne({ guid });
|
|
146
|
-
getLogger().log(`Enregistrement du fichier ${guid} supprimé de la base de données.`);
|
|
147
|
-
};
|