@solidstarters/solid-core 1.2.143 → 1.2.145
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/dist/config/common.config.d.ts +2 -0
- package/dist/config/common.config.d.ts.map +1 -1
- package/dist/config/common.config.js +3 -2
- package/dist/config/common.config.js.map +1 -1
- package/dist/constants/error-messages.d.ts +83 -0
- package/dist/constants/error-messages.d.ts.map +1 -0
- package/dist/constants/error-messages.js +86 -0
- package/dist/constants/error-messages.js.map +1 -0
- package/dist/constants/success-messages.d.ts +11 -0
- package/dist/constants/success-messages.d.ts.map +1 -0
- package/dist/constants/success-messages.js +14 -0
- package/dist/constants/success-messages.js.map +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/api-email-subscriber.service.d.ts +1 -1
- package/dist/jobs/api-email-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/api-email-subscriber.service.js +2 -2
- package/dist/jobs/api-email-subscriber.service.js.map +1 -1
- package/dist/jobs/database/api-email-subscriber-database.service.d.ts +1 -1
- package/dist/jobs/database/api-email-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/api-email-subscriber-database.service.js +2 -2
- package/dist/jobs/database/api-email-subscriber-database.service.js.map +1 -1
- package/dist/jobs/database/email-subscriber-database.service.d.ts +1 -1
- package/dist/jobs/database/email-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/email-subscriber-database.service.js +2 -2
- package/dist/jobs/database/email-subscriber-database.service.js.map +1 -1
- package/dist/jobs/email-subscriber.service.d.ts +1 -1
- package/dist/jobs/email-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/email-subscriber.service.js +2 -2
- package/dist/jobs/email-subscriber.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +12 -12
- package/dist/services/ai-interaction.service.d.ts.map +1 -1
- package/dist/services/ai-interaction.service.js +4 -3
- package/dist/services/ai-interaction.service.js.map +1 -1
- package/dist/services/authentication.service.d.ts +1 -1
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +68 -66
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +3 -2
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +23 -21
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/csv.service.d.ts.map +1 -1
- package/dist/services/csv.service.js +3 -2
- package/dist/services/csv.service.js.map +1 -1
- package/dist/services/excel.service.d.ts.map +1 -1
- package/dist/services/excel.service.js +3 -2
- package/dist/services/excel.service.js.map +1 -1
- package/dist/services/export-transaction.service.d.ts.map +1 -1
- package/dist/services/export-transaction.service.js +2 -1
- package/dist/services/export-transaction.service.js.map +1 -1
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +9 -8
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/file.service.d.ts.map +1 -1
- package/dist/services/file.service.js +5 -4
- package/dist/services/file.service.js.map +1 -1
- package/dist/services/import-transaction.service.d.ts.map +1 -1
- package/dist/services/import-transaction.service.js +11 -9
- package/dist/services/import-transaction.service.js.map +1 -1
- package/dist/services/mail/{ElasticEmailService.d.ts → elastic-email.service.d.ts} +1 -1
- package/dist/services/mail/elastic-email.service.d.ts.map +1 -0
- package/dist/services/mail/{ElasticEmailService.js → elastic-email.service.js} +1 -1
- package/dist/services/mail/elastic-email.service.js.map +1 -0
- package/dist/services/mail/{SMTPEmailService.d.ts → smtp-email.service.d.ts} +3 -3
- package/dist/services/mail/smtp-email.service.d.ts.map +1 -0
- package/dist/services/mail/{SMTPEmailService.js → smtp-email.service.js} +8 -6
- package/dist/services/mail/smtp-email.service.js.map +1 -0
- package/dist/services/media-storage-provider-metadata.service.d.ts.map +1 -1
- package/dist/services/media-storage-provider-metadata.service.js +4 -3
- package/dist/services/media-storage-provider-metadata.service.js.map +1 -1
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/media.service.js +2 -1
- package/dist/services/media.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +11 -10
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata.service.d.ts.map +1 -1
- package/dist/services/module-metadata.service.js +11 -10
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/role-metadata.service.d.ts.map +1 -1
- package/dist/services/role-metadata.service.js +3 -2
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/services/sql-expression-resolver.service.d.ts.map +1 -1
- package/dist/services/sql-expression-resolver.service.js +2 -1
- package/dist/services/sql-expression-resolver.service.js.map +1 -1
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +11 -10
- package/dist/services/user.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +9 -7
- package/dist/solid-core.module.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/config/common.config.ts +3 -2
- package/src/constants/error-messages.ts +123 -0
- package/src/constants/success-messages.ts +13 -0
- package/src/index.ts +10 -4
- package/src/interfaces.ts +3 -3
- package/src/jobs/api-email-subscriber.service.ts +1 -1
- package/src/jobs/database/api-email-subscriber-database.service.ts +1 -1
- package/src/jobs/database/email-subscriber-database.service.ts +1 -1
- package/src/jobs/email-subscriber.service.ts +1 -1
- package/src/seeders/seed-data/solid-core-metadata.json +12 -12
- package/src/services/ai-interaction.service.ts +4 -3
- package/src/services/authentication.service.ts +67 -65
- package/src/services/crud-helper.service.ts +3 -2
- package/src/services/crud.service.ts +23 -23
- package/src/services/csv.service.ts +3 -2
- package/src/services/excel.service.ts +3 -2
- package/src/services/export-transaction.service.ts +2 -1
- package/src/services/field-metadata.service.ts +9 -8
- package/src/services/file.service.ts +5 -4
- package/src/services/import-transaction.service.ts +11 -9
- package/src/services/mail/{SMTPEmailService.ts → smtp-email.service.ts} +7 -5
- package/src/services/media-storage-provider-metadata.service.ts +4 -3
- package/src/services/media.service.ts +2 -1
- package/src/services/model-metadata.service.ts +11 -10
- package/src/services/module-metadata.service.ts +11 -10
- package/src/services/role-metadata.service.ts +3 -2
- package/src/services/sql-expression-resolver.service.ts +2 -1
- package/src/services/user.service.ts +11 -10
- package/src/solid-core.module.ts +5 -3
- package/dist/services/mail/ElasticEmailService.d.ts.map +0 -1
- package/dist/services/mail/ElasticEmailService.js.map +0 -1
- package/dist/services/mail/SMTPEmailService.d.ts.map +0 -1
- package/dist/services/mail/SMTPEmailService.js.map +0 -1
- /package/src/services/mail/{ElasticEmailService.ts → elastic-email.service.ts} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Injectable, Logger } from '@nestjs/common';
|
|
2
2
|
import { format, parse } from 'fast-csv';
|
|
3
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
3
4
|
import { PassThrough, Readable } from 'stream';
|
|
4
5
|
|
|
5
6
|
export interface CsvReadOptions {
|
|
@@ -24,12 +25,12 @@ export class CsvService {
|
|
|
24
25
|
// Validations
|
|
25
26
|
// If neither headers nor data records function is provided, throw an error
|
|
26
27
|
if (headers.length === 0 && typeof getDataRecords !== 'function') {
|
|
27
|
-
throw new Error(
|
|
28
|
+
throw new Error(ERROR_MESSAGES.MISSING_HEADERS_OR_FUNCTION);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
// If data records function is provided, chunkSize must be greater than 0
|
|
31
32
|
if (getDataRecords && chunkSize <= 0) {
|
|
32
|
-
throw new Error(
|
|
33
|
+
throw new Error(ERROR_MESSAGES.INVALID_CHUNK_SIZE);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
const passThrough = new PassThrough(); // ✅ Create a streaming pipe
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Injectable, Logger } from '@nestjs/common';
|
|
2
2
|
import * as ExcelJS from 'exceljs';
|
|
3
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
3
4
|
import { PassThrough, Readable } from 'stream';
|
|
4
5
|
|
|
5
6
|
|
|
@@ -28,12 +29,12 @@ export class ExcelService {
|
|
|
28
29
|
// Validations
|
|
29
30
|
// If neither headers nor data records function is provided, throw an error
|
|
30
31
|
if (headers.length === 0 && typeof getDataRecords !== 'function') {
|
|
31
|
-
throw new Error(
|
|
32
|
+
throw new Error(ERROR_MESSAGES.MISSING_HEADERS_OR_FUNCTION);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
// If data records function is provided, chunkSize must be greater than 0
|
|
35
36
|
if (getDataRecords && chunkSize <= 0) {
|
|
36
|
-
throw new Error(
|
|
37
|
+
throw new Error(ERROR_MESSAGES.INVALID_CHUNK_SIZE);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
const passThrough = new PassThrough(); // Create streaming pipe
|
|
@@ -28,6 +28,7 @@ import { getMediaStorageProvider } from './mediaStorageProviders';
|
|
|
28
28
|
import { SolidIntrospectService } from './solid-introspect.service';
|
|
29
29
|
import { ModelMetadata } from 'src/entities/model-metadata.entity';
|
|
30
30
|
import { UpdateExportTemplateDto } from 'src/dtos/update-export-template.dto';
|
|
31
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
31
32
|
|
|
32
33
|
const EXPORT_CHUNK_SIZE = 100;
|
|
33
34
|
enum ExportStatus {
|
|
@@ -170,7 +171,7 @@ export class ExportTransactionService extends CRUDService<ExportTransaction> {
|
|
|
170
171
|
exportStream = await this.csvService.createCsvStream(dataRecordsFunc, EXPORT_CHUNK_SIZE);
|
|
171
172
|
break;
|
|
172
173
|
default:
|
|
173
|
-
throw new Error('
|
|
174
|
+
throw new Error(ERROR_MESSAGES.INVALID_FORMAT('export' + templateFormat));
|
|
174
175
|
}
|
|
175
176
|
return exportStream;
|
|
176
177
|
}
|
|
@@ -14,6 +14,7 @@ import { FieldMetadata } from '../entities/field-metadata.entity';
|
|
|
14
14
|
import { ModelMetadata } from '../entities/model-metadata.entity';
|
|
15
15
|
import { ISelectionProviderValues } from '../interfaces';
|
|
16
16
|
import { CrudHelperService } from './crud-helper.service';
|
|
17
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
@Injectable()
|
|
@@ -61,7 +62,7 @@ export class FieldMetadataService implements OnApplicationBootstrap {
|
|
|
61
62
|
|
|
62
63
|
async updateInverseField(field: FieldMetadata, fieldRepository: Repository<FieldMetadata>, modelRepository: Repository<ModelMetadata>) {
|
|
63
64
|
if (!field.model || !field.model.module) {
|
|
64
|
-
throw new Error(
|
|
65
|
+
throw new Error(ERROR_MESSAGES.MODEL_AND_MODULE_REQUIRED_TO_UPDATE_INVERSE_FIELD);
|
|
65
66
|
}
|
|
66
67
|
// Update the inverse field in the db
|
|
67
68
|
const savedInverseField = await this.updateInverseFieldInDb(field, fieldRepository, modelRepository);
|
|
@@ -202,13 +203,13 @@ export class FieldMetadataService implements OnApplicationBootstrap {
|
|
|
202
203
|
|
|
203
204
|
private validateForInverseField(field: FieldMetadata) {
|
|
204
205
|
if (field.type !== SolidFieldType.relation) {
|
|
205
|
-
throw new Error(
|
|
206
|
+
throw new Error(ERROR_MESSAGES.INVALID_INVERSE_FIELD_TYPE);
|
|
206
207
|
}
|
|
207
208
|
const modelName = field.model.singularName;
|
|
208
209
|
const moduleName = field.model.module.name;
|
|
209
210
|
|
|
210
211
|
if (!modelName || !moduleName) {
|
|
211
|
-
throw new Error(
|
|
212
|
+
throw new Error(ERROR_MESSAGES.MODEL_NAME_AND_MODULE_NAME_REQUIRED_TO_CREATE_INVERSE_FIELD);
|
|
212
213
|
}
|
|
213
214
|
return { moduleName, modelName };
|
|
214
215
|
}
|
|
@@ -1037,7 +1038,7 @@ export class FieldMetadataService implements OnApplicationBootstrap {
|
|
|
1037
1038
|
},
|
|
1038
1039
|
});
|
|
1039
1040
|
if (!entity) {
|
|
1040
|
-
throw new NotFoundException(
|
|
1041
|
+
throw new NotFoundException(ERROR_MESSAGES.FIELD_NOT_FOUND(query.fieldId));
|
|
1041
1042
|
}
|
|
1042
1043
|
|
|
1043
1044
|
// 2. use the field metadata to identify the provider.
|
|
@@ -1049,7 +1050,7 @@ export class FieldMetadataService implements OnApplicationBootstrap {
|
|
|
1049
1050
|
// 3. get hold of the provider instance from the SolidRegistry
|
|
1050
1051
|
const selectionProviderInstance = this.solidRegistry.getSelectionProviderInstance(selectionDynamicProvider);
|
|
1051
1052
|
if (!selectionProviderInstance) {
|
|
1052
|
-
throw new NotFoundException(
|
|
1053
|
+
throw new NotFoundException(ERROR_MESSAGES.PROVIDER_NOT_FOUND(selectionDynamicProvider));
|
|
1053
1054
|
}
|
|
1054
1055
|
|
|
1055
1056
|
// 4. use the provider to fetch the dynamic values, pass the query string received from the UI..
|
|
@@ -1064,7 +1065,7 @@ export class FieldMetadataService implements OnApplicationBootstrap {
|
|
|
1064
1065
|
},
|
|
1065
1066
|
});
|
|
1066
1067
|
if (!entity) {
|
|
1067
|
-
throw new NotFoundException(
|
|
1068
|
+
throw new NotFoundException(ERROR_MESSAGES.FIELD_NOT_FOUND(query.fieldId));
|
|
1068
1069
|
}
|
|
1069
1070
|
|
|
1070
1071
|
// 2. use the field metadata to identify the provider.
|
|
@@ -1076,7 +1077,7 @@ export class FieldMetadataService implements OnApplicationBootstrap {
|
|
|
1076
1077
|
// 3. get hold of the provider instance from the SolidRegistry
|
|
1077
1078
|
const selectionProviderInstance = this.solidRegistry.getSelectionProviderInstance(selectionDynamicProvider);
|
|
1078
1079
|
if (!selectionProviderInstance) {
|
|
1079
|
-
throw new NotFoundException(
|
|
1080
|
+
throw new NotFoundException(ERROR_MESSAGES.PROVIDER_NOT_FOUND(selectionDynamicProvider));
|
|
1080
1081
|
}
|
|
1081
1082
|
|
|
1082
1083
|
// 4. use the provider to fetch the dynamic values, pass the query string received from the UI..
|
|
@@ -1108,7 +1109,7 @@ export class FieldMetadataService implements OnApplicationBootstrap {
|
|
|
1108
1109
|
await fs.writeFile(filePath, updatedContent);
|
|
1109
1110
|
} catch (error) {
|
|
1110
1111
|
this.logger.error('File creation failed:', error);
|
|
1111
|
-
throw new Error(
|
|
1112
|
+
throw new Error(ERROR_MESSAGES.FILE_WRITE_FAILED); // Trigger rollback
|
|
1112
1113
|
}
|
|
1113
1114
|
}
|
|
1114
1115
|
|
|
@@ -7,6 +7,7 @@ import commonConfig, { AwsS3Config } from '../config/common.config';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { Readable } from 'stream';
|
|
9
9
|
import { getSignedUrl as awsGetSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
10
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
10
11
|
|
|
11
12
|
@Injectable()
|
|
12
13
|
export class FileService {
|
|
@@ -69,7 +70,7 @@ export class FileService {
|
|
|
69
70
|
await this.createDirectoryIfNotExists(destinationPath);
|
|
70
71
|
await this.writeFile(destinationPath, data);
|
|
71
72
|
} catch (error) {
|
|
72
|
-
throw new Error(
|
|
73
|
+
throw new Error(`${ERROR_MESSAGES.FILE_COPY_ERROR}: ${error.message}`);
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -114,12 +115,12 @@ export class FileService {
|
|
|
114
115
|
return fileName
|
|
115
116
|
|
|
116
117
|
} catch (error) {
|
|
117
|
-
throw new Error(
|
|
118
|
+
throw new Error(`${ERROR_MESSAGES.FILE_COPY_ERROR}: ${error.message}`);
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
private checkIfS3ClientExists() {
|
|
122
|
-
if (!this.s3Client) { throw new Error(
|
|
123
|
+
if (!this.s3Client) { throw new Error(ERROR_MESSAGES.S3_CLIENT_NOT_INITIALIZED); }
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
async copyToS3WithPublic(filePath: string, ContentType: string, fileName: string, bucketName: string): Promise<string> {
|
|
@@ -145,7 +146,7 @@ export class FileService {
|
|
|
145
146
|
return fileName
|
|
146
147
|
|
|
147
148
|
} catch (error) {
|
|
148
|
-
throw new Error(
|
|
149
|
+
throw new Error(`${ERROR_MESSAGES.FILE_COPY_ERROR}: ${error.message}`);
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
|
|
@@ -25,6 +25,7 @@ import { ImportTransaction } from '../entities/import-transaction.entity';
|
|
|
25
25
|
import { CsvService } from './csv.service';
|
|
26
26
|
import { ExcelService } from './excel.service';
|
|
27
27
|
import { SolidIntrospectService } from './solid-introspect.service';
|
|
28
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
28
29
|
|
|
29
30
|
interface ImportTemplateFileInfo {
|
|
30
31
|
stream: NodeJS.ReadableStream;
|
|
@@ -120,7 +121,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
120
121
|
populate: ['fields'],
|
|
121
122
|
});
|
|
122
123
|
if (!modelMetadata) {
|
|
123
|
-
throw new Error(
|
|
124
|
+
throw new Error(ERROR_MESSAGES.MODEL_METADATA_NOT_FOUND(modelMetadataId));
|
|
124
125
|
}
|
|
125
126
|
// Create a header row with the display names of the fields, excluding the media fields,computed fields
|
|
126
127
|
const headers = this.fieldsAllowedForImport(modelMetadata.fields)
|
|
@@ -147,7 +148,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
147
148
|
mimeType,
|
|
148
149
|
};
|
|
149
150
|
} else {
|
|
150
|
-
throw new Error(
|
|
151
|
+
throw new Error(ERROR_MESSAGES.INVALID_FORMAT('import' + format));
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
}
|
|
@@ -158,7 +159,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
158
159
|
populate: ['fields'],
|
|
159
160
|
});
|
|
160
161
|
if (!modelMetadata) {
|
|
161
|
-
throw new Error(
|
|
162
|
+
throw new Error(ERROR_MESSAGES.MODEL_METADATA_NOT_FOUND(modelMetadataId));
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
// Create the standard import instructions
|
|
@@ -294,7 +295,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
294
295
|
});
|
|
295
296
|
|
|
296
297
|
if (!firstErrorLogEntry) {
|
|
297
|
-
throw new BadRequestException(
|
|
298
|
+
throw new BadRequestException(ERROR_MESSAGES.NO_ERROR_LOG_FOR_IMPORT(importTransactionId));
|
|
298
299
|
}
|
|
299
300
|
|
|
300
301
|
// Create the headers for the export file
|
|
@@ -384,6 +385,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
384
385
|
field.type !== SolidFieldType.password &&
|
|
385
386
|
field.type !== SolidFieldType.richText &&
|
|
386
387
|
field.type !== SolidFieldType.uuid &&
|
|
388
|
+
field.relationType !== RelationType.oneToMany &&
|
|
387
389
|
field.isSystem !== true // Exclude system fields
|
|
388
390
|
);
|
|
389
391
|
}
|
|
@@ -402,7 +404,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
402
404
|
return firstRecord.value;
|
|
403
405
|
}
|
|
404
406
|
else { // If the file is neither CSV nor Excel, throw an error
|
|
405
|
-
throw new Error(
|
|
407
|
+
throw new Error(ERROR_MESSAGES.INVALID_FORMAT(mimeType));
|
|
406
408
|
}
|
|
407
409
|
}
|
|
408
410
|
|
|
@@ -426,7 +428,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
426
428
|
});
|
|
427
429
|
|
|
428
430
|
if (!fileUrlResponse || !fileUrlResponse.data) {
|
|
429
|
-
throw new Error(
|
|
431
|
+
throw new Error(ERROR_MESSAGES.FILE_READ_FAILED_FROM_URL(fileUrl));
|
|
430
432
|
}
|
|
431
433
|
// fileUrlResponse.data is a Node.js Readable stream
|
|
432
434
|
return fileUrlResponse.data;
|
|
@@ -462,7 +464,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
462
464
|
createdErrorLogIds.push(...errorLogIds);
|
|
463
465
|
}
|
|
464
466
|
} else { // If the file is neither CSV nor Excel, throw an error
|
|
465
|
-
throw new Error(
|
|
467
|
+
throw new Error(ERROR_MESSAGES.INVALID_FORMAT(mimeType));
|
|
466
468
|
}
|
|
467
469
|
|
|
468
470
|
return {
|
|
@@ -529,7 +531,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
529
531
|
const modelServiceWrapper = this.introspectService.getProvider(`${classify(modelSingularName)}Service`);
|
|
530
532
|
const modelService = modelServiceWrapper.instance as CRUDService<any>;
|
|
531
533
|
if (!modelService) {
|
|
532
|
-
throw new Error(
|
|
534
|
+
throw new Error(ERROR_MESSAGES.MODEL_SERVICE_NOT_FOUND(modelSingularName));
|
|
533
535
|
}
|
|
534
536
|
return modelService;
|
|
535
537
|
}
|
|
@@ -639,7 +641,7 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
639
641
|
|
|
640
642
|
private async populateDtoForRelations(fieldMetadata: FieldMetadata, record: Record<string, any>, key: string, dtoRecord: Record<string, any>) {
|
|
641
643
|
if (!fieldMetadata.relationCoModelSingularName) {
|
|
642
|
-
throw new Error(
|
|
644
|
+
throw new Error(ERROR_MESSAGES.RELATION_CO_MODEL_NOT_DEFINED_FOR_FIELD(fieldMetadata.name));
|
|
643
645
|
}
|
|
644
646
|
|
|
645
647
|
const relatedRecordsIds = await this.getRelatedEntityIdsFromUserKeys(fieldMetadata, record, key);
|
|
@@ -33,7 +33,7 @@ export class SMTPEMailService implements IMail {
|
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
async sendEmailUsingTemplate(to: string, templateName: string, templateParams: any, shouldQueueEmails = false, parentEntity = null, parentEntityId = null, attachments: MailAttachment[] = [], cc: string[] = []): Promise<void> {
|
|
36
|
+
async sendEmailUsingTemplate(to: string, templateName: string, templateParams: any, shouldQueueEmails = false, parentEntity = null, parentEntityId = null, attachments: MailAttachment[] = [], cc: string[] = [], bcc: string[] = [], from: string = null): Promise<void> {
|
|
37
37
|
// Load template and evaluate it.
|
|
38
38
|
const emailTemplate = await this.emailTemplateService.findOneByName(templateName);
|
|
39
39
|
if (!emailTemplate) {
|
|
@@ -49,18 +49,19 @@ export class SMTPEMailService implements IMail {
|
|
|
49
49
|
const subject = subjectTemplate(templateParams);
|
|
50
50
|
|
|
51
51
|
// Finally send the email.
|
|
52
|
-
await this.sendEmail(to, subject, body, shouldQueueEmails, parentEntity, parentEntityId, attachments);
|
|
52
|
+
await this.sendEmail(to, subject, body, shouldQueueEmails, parentEntity, parentEntityId, attachments, cc, bcc, from);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
async sendEmail(to: string, subject: string, body: string, shouldQueueEmails = false, parentEntity = null, parentEntityId = null, attachments: MailAttachment[] = [], cc: string[] = []): Promise<void> {
|
|
55
|
+
async sendEmail(to: string, subject: string, body: string, shouldQueueEmails = false, parentEntity = null, parentEntityId = null, attachments: MailAttachment[] = [], cc: string[] = [], bcc: string[] = [], from: string = null): Promise<void> {
|
|
56
56
|
const message = {
|
|
57
57
|
payload: {
|
|
58
|
-
from: this.commonConfiguration.smtpMail.from,
|
|
58
|
+
from: from || this.commonConfiguration.smtpMail.from,
|
|
59
59
|
to: to,
|
|
60
60
|
subject: subject,
|
|
61
61
|
body: body,
|
|
62
62
|
attachments: attachments,
|
|
63
63
|
cc: cc,
|
|
64
|
+
bcc: bcc,
|
|
64
65
|
},
|
|
65
66
|
parentEntity: parentEntity,
|
|
66
67
|
parentEntityId: parentEntityId,
|
|
@@ -92,7 +93,7 @@ export class SMTPEMailService implements IMail {
|
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
async sendEmailSynchronously(message: QueueMessage<any>): Promise<void> {
|
|
95
|
-
const { from, to, subject, body, attachments, cc } = message.payload;
|
|
96
|
+
const { from, to, subject, body, attachments, cc, bcc } = message.payload;
|
|
96
97
|
|
|
97
98
|
const attachmentsList = attachments.map((attachment: MailAttachment) => {
|
|
98
99
|
const attachmentEntry = {
|
|
@@ -113,6 +114,7 @@ export class SMTPEMailService implements IMail {
|
|
|
113
114
|
from: from,
|
|
114
115
|
to: to,
|
|
115
116
|
cc: cc,
|
|
117
|
+
bcc: bcc,
|
|
116
118
|
subject: subject,
|
|
117
119
|
html: body,
|
|
118
120
|
attachments: attachmentsList,
|
|
@@ -5,6 +5,7 @@ import { MediaStorageProviderMetadata } from "../entities/media-storage-provider
|
|
|
5
5
|
import { BasicFilterDto } from "../dtos/basic-filters.dto";
|
|
6
6
|
import { CrudHelperService } from "./crud-helper.service";
|
|
7
7
|
import { UpdateMediaStorageProviderMetadataDto } from "../dtos/update-media-storage-provider.dto";
|
|
8
|
+
import { ERROR_MESSAGES } from "src/constants/error-messages";
|
|
8
9
|
|
|
9
10
|
@Injectable()
|
|
10
11
|
export class MediaStorageProviderMetadataService {
|
|
@@ -80,7 +81,7 @@ export class MediaStorageProviderMetadataService {
|
|
|
80
81
|
relations: relations,
|
|
81
82
|
});
|
|
82
83
|
if (!lov) {
|
|
83
|
-
throw new NotFoundException(
|
|
84
|
+
throw new NotFoundException(ERROR_MESSAGES.MEDIA_STORAGE_PROVIDER_ID_NOT_FOUND(type));
|
|
84
85
|
}
|
|
85
86
|
return lov;
|
|
86
87
|
}
|
|
@@ -118,14 +119,14 @@ export class MediaStorageProviderMetadataService {
|
|
|
118
119
|
});
|
|
119
120
|
|
|
120
121
|
if (!entity) {
|
|
121
|
-
throw new NotFoundException(
|
|
122
|
+
throw new NotFoundException(ERROR_MESSAGES.MODULE_ID_NOT_FOUND(id));
|
|
122
123
|
}
|
|
123
124
|
return this.mediaStorageProviderRepo.save(entity);
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
async deleteMany(ids: number[]): Promise<any> {
|
|
127
128
|
if (!ids || ids.length === 0) {
|
|
128
|
-
throw new Error(
|
|
129
|
+
throw new Error(ERROR_MESSAGES.DELETE_IDS_REQUIRED);
|
|
129
130
|
}
|
|
130
131
|
const removedEntities = [];
|
|
131
132
|
for (let i = 0; i < ids.length; i++) {
|
|
@@ -18,6 +18,7 @@ import { Media } from 'src/entities/media.entity';
|
|
|
18
18
|
import { ModelMetadata } from 'src/entities/model-metadata.entity';
|
|
19
19
|
import { getMediaStorageProvider } from "./mediaStorageProviders";
|
|
20
20
|
import { BasicFilterDto } from 'src/dtos/basic-filters.dto';
|
|
21
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
@Injectable()
|
|
@@ -77,7 +78,7 @@ export class MediaService extends CRUDService<Media> {
|
|
|
77
78
|
async upload(createDto: any, files: Array<Express.Multer.File>) {
|
|
78
79
|
|
|
79
80
|
if (!files) {
|
|
80
|
-
throw new NotFoundException(
|
|
81
|
+
throw new NotFoundException(ERROR_MESSAGES.FILE_NOT_FOUND);
|
|
81
82
|
|
|
82
83
|
}
|
|
83
84
|
const savedMedias = [];
|
|
@@ -27,6 +27,7 @@ import { RoleMetadataService } from './role-metadata.service';
|
|
|
27
27
|
import { PermissionMetadata } from 'src/entities/permission-metadata.entity';
|
|
28
28
|
import { classify, dasherize } from '@angular-devkit/core/src/utils/strings';
|
|
29
29
|
import { DisallowInProduction } from 'src/decorators/disallow-in-production.decorator';
|
|
30
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
30
31
|
|
|
31
32
|
@Injectable()
|
|
32
33
|
export class ModelMetadataService {
|
|
@@ -89,7 +90,7 @@ export class ModelMetadataService {
|
|
|
89
90
|
relations: query?.populate, //FIXME: Check with jenender and change to relations to avoid confusion
|
|
90
91
|
});
|
|
91
92
|
if (!entity) {
|
|
92
|
-
throw new NotFoundException(
|
|
93
|
+
throw new NotFoundException(ERROR_MESSAGES.ENTITY_NOT_FOUND(`#${id}`));
|
|
93
94
|
}
|
|
94
95
|
return entity;
|
|
95
96
|
}
|
|
@@ -102,7 +103,7 @@ export class ModelMetadataService {
|
|
|
102
103
|
relations: relations,
|
|
103
104
|
});
|
|
104
105
|
if (!entity) {
|
|
105
|
-
throw new NotFoundException(
|
|
106
|
+
throw new NotFoundException(ERROR_MESSAGES.ENTITY_NOT_FOUND(singularName));
|
|
106
107
|
}
|
|
107
108
|
return entity;
|
|
108
109
|
}
|
|
@@ -115,7 +116,7 @@ export class ModelMetadataService {
|
|
|
115
116
|
relations: relations,
|
|
116
117
|
});
|
|
117
118
|
if (!entity) {
|
|
118
|
-
throw new NotFoundException(
|
|
119
|
+
throw new NotFoundException(ERROR_MESSAGES.ENTITY_NOT_FOUND(singularName));
|
|
119
120
|
}
|
|
120
121
|
return entity;
|
|
121
122
|
}
|
|
@@ -289,7 +290,7 @@ export class ModelMetadataService {
|
|
|
289
290
|
} catch (error) {
|
|
290
291
|
// console.error('File creation failed:', error);
|
|
291
292
|
this.logger.error('File creation failed:', error);
|
|
292
|
-
throw new Error(
|
|
293
|
+
throw new Error(ERROR_MESSAGES.FILE_WRITE_FAILED); // Trigger rollback
|
|
293
294
|
}
|
|
294
295
|
}
|
|
295
296
|
|
|
@@ -307,7 +308,7 @@ export class ModelMetadataService {
|
|
|
307
308
|
});
|
|
308
309
|
|
|
309
310
|
if (!existingModel) {
|
|
310
|
-
throw new Error(
|
|
311
|
+
throw new Error(ERROR_MESSAGES.MODEL_NOT_FOUND(updateModelMetaDataDto.singularName));
|
|
311
312
|
}
|
|
312
313
|
|
|
313
314
|
const updatedModel = modelRepo.merge(existingModel, modelMetaDataWithoutFields);
|
|
@@ -470,7 +471,7 @@ export class ModelMetadataService {
|
|
|
470
471
|
} catch (error) {
|
|
471
472
|
// console.error('File creation failed:', error);
|
|
472
473
|
this.logger.error('File creation failed:', error);
|
|
473
|
-
throw new Error(
|
|
474
|
+
throw new Error(ERROR_MESSAGES.FILE_WRITE_FAILED); // Trigger rollback
|
|
474
475
|
}
|
|
475
476
|
}
|
|
476
477
|
|
|
@@ -507,7 +508,7 @@ export class ModelMetadataService {
|
|
|
507
508
|
|
|
508
509
|
async deleteMany(ids: number[]): Promise<any> {
|
|
509
510
|
if (!ids || ids.length === 0) {
|
|
510
|
-
throw new Error(
|
|
511
|
+
throw new Error(ERROR_MESSAGES.DELETE_IDS_REQUIRED);
|
|
511
512
|
}
|
|
512
513
|
const removedEntities = [];
|
|
513
514
|
for (let i = 0; i < ids.length; i++) {
|
|
@@ -909,7 +910,7 @@ export class ModelMetadataService {
|
|
|
909
910
|
metaData.menus.push(menu);
|
|
910
911
|
}
|
|
911
912
|
|
|
912
|
-
if (notExists(metaData.actions,
|
|
913
|
+
if (notExists(metaData.actions, actionName)) {
|
|
913
914
|
metaData.actions.push(action);
|
|
914
915
|
}
|
|
915
916
|
|
|
@@ -1088,7 +1089,7 @@ export class ModelMetadataService {
|
|
|
1088
1089
|
|
|
1089
1090
|
async generateRemoveFieldsCode(options: CodeGenerationOptions): Promise<string> {
|
|
1090
1091
|
if (!options.modelId && !options.modelUserKey) {
|
|
1091
|
-
throw new BadRequestException(
|
|
1092
|
+
throw new BadRequestException(ERROR_MESSAGES.MODEL_REQUIRED_FOR_CODE_GENERATION);
|
|
1092
1093
|
}
|
|
1093
1094
|
|
|
1094
1095
|
if (!options.fieldIdsForRemoval || options.fieldIdsForRemoval.length === 0) {
|
|
@@ -1143,7 +1144,7 @@ export class ModelMetadataService {
|
|
|
1143
1144
|
|
|
1144
1145
|
async generateModelCode(options: CodeGenerationOptions): Promise<string> {
|
|
1145
1146
|
if (!options.modelId && !options.modelUserKey) {
|
|
1146
|
-
throw new BadRequestException(
|
|
1147
|
+
throw new BadRequestException(ERROR_MESSAGES.MODEL_REQUIRED_FOR_CODE_GENERATION);
|
|
1147
1148
|
}
|
|
1148
1149
|
|
|
1149
1150
|
const query = {
|
|
@@ -22,6 +22,7 @@ import { CrudHelperService } from './crud-helper.service';
|
|
|
22
22
|
import { ModelMetadataService } from './model-metadata.service';
|
|
23
23
|
import { ModuleMetadataHelperService } from 'src/helpers/module-metadata-helper.service';
|
|
24
24
|
import { DisallowInProduction } from 'src/decorators/disallow-in-production.decorator';
|
|
25
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
25
26
|
|
|
26
27
|
@Injectable()
|
|
27
28
|
export class ModuleMetadataService {
|
|
@@ -77,7 +78,7 @@ export class ModuleMetadataService {
|
|
|
77
78
|
|
|
78
79
|
async findOneByUserKey(name: string, relations = {}) {
|
|
79
80
|
if (!name) {
|
|
80
|
-
throw new BadRequestException(
|
|
81
|
+
throw new BadRequestException(ERROR_MESSAGES.ENTITY_NAME_REQUIRED);
|
|
81
82
|
}
|
|
82
83
|
const entity = await this.moduleMetadataRepo.findOne({
|
|
83
84
|
where: {
|
|
@@ -90,7 +91,7 @@ export class ModuleMetadataService {
|
|
|
90
91
|
|
|
91
92
|
async findOne(id: number, relations = {}) {
|
|
92
93
|
if (!id) {
|
|
93
|
-
throw new BadRequestException(
|
|
94
|
+
throw new BadRequestException(ERROR_MESSAGES.ENTITY_ID_REQUIRED);
|
|
94
95
|
}
|
|
95
96
|
const entity = await this.moduleMetadataRepo.findOne({
|
|
96
97
|
where: {
|
|
@@ -99,7 +100,7 @@ export class ModuleMetadataService {
|
|
|
99
100
|
relations: relations,
|
|
100
101
|
});
|
|
101
102
|
if (!entity) {
|
|
102
|
-
throw new NotFoundException(
|
|
103
|
+
throw new NotFoundException(ERROR_MESSAGES.ENTITY_NOT_FOUND());
|
|
103
104
|
}
|
|
104
105
|
return entity;
|
|
105
106
|
}
|
|
@@ -194,7 +195,7 @@ export class ModuleMetadataService {
|
|
|
194
195
|
} catch (error) {
|
|
195
196
|
// console.error('File creation failed:', error);
|
|
196
197
|
this.logger.error('File creation failed:', error);
|
|
197
|
-
throw new Error(
|
|
198
|
+
throw new Error(ERROR_MESSAGES.FILE_WRITE_FAILED); // Trigger rollback
|
|
198
199
|
}
|
|
199
200
|
}
|
|
200
201
|
|
|
@@ -221,7 +222,7 @@ export class ModuleMetadataService {
|
|
|
221
222
|
});
|
|
222
223
|
|
|
223
224
|
if (!module) {
|
|
224
|
-
throw new NotFoundException(
|
|
225
|
+
throw new NotFoundException(ERROR_MESSAGES.MODULE_ID_NOT_FOUND(id));
|
|
225
226
|
}
|
|
226
227
|
if (files.length > 0) {
|
|
227
228
|
|
|
@@ -281,7 +282,7 @@ export class ModuleMetadataService {
|
|
|
281
282
|
} catch (error) {
|
|
282
283
|
// console.error('File creation failed:', error);
|
|
283
284
|
this.logger.error('File creation failed:', error);
|
|
284
|
-
throw new Error(
|
|
285
|
+
throw new Error(ERROR_MESSAGES.FILE_WRITE_FAILED); // Trigger rollback
|
|
285
286
|
}
|
|
286
287
|
}
|
|
287
288
|
|
|
@@ -320,7 +321,7 @@ export class ModuleMetadataService {
|
|
|
320
321
|
|
|
321
322
|
async deleteMany(ids: number[]): Promise<any> {
|
|
322
323
|
if (!ids || ids.length === 0) {
|
|
323
|
-
throw new Error(
|
|
324
|
+
throw new Error(ERROR_MESSAGES.DELETE_IDS_REQUIRED);
|
|
324
325
|
}
|
|
325
326
|
const removedEntities = [];
|
|
326
327
|
for (let i = 0; i < ids.length; i++) {
|
|
@@ -348,13 +349,13 @@ export class ModuleMetadataService {
|
|
|
348
349
|
@DisallowInProduction()
|
|
349
350
|
async generateCode(options: CodeGenerationOptions): Promise<string> {
|
|
350
351
|
if (!options.moduleId && !options.moduleUserKey) {
|
|
351
|
-
throw new BadRequestException(
|
|
352
|
+
throw new BadRequestException(ERROR_MESSAGES.MODEL_REQUIRED_FOR_CODE_GENERATION);
|
|
352
353
|
}
|
|
353
354
|
const module = options.moduleId ? await this.findOne(options.moduleId) : await this.findOneByUserKey(options.moduleUserKey);
|
|
354
355
|
|
|
355
356
|
// Check if the module exists
|
|
356
357
|
if (!module) {
|
|
357
|
-
throw new NotFoundException(
|
|
358
|
+
throw new NotFoundException(ERROR_MESSAGES.MODULE_ID_NOT_FOUND(options.moduleId));
|
|
358
359
|
}
|
|
359
360
|
|
|
360
361
|
// Check if the module name already exists and is loaded
|
|
@@ -371,7 +372,7 @@ export class ModuleMetadataService {
|
|
|
371
372
|
|
|
372
373
|
private async generateAddModuleCode(options: CodeGenerationOptions = { dryRun: false }): Promise<string> {
|
|
373
374
|
if (!options.moduleId && !options.moduleUserKey) {
|
|
374
|
-
throw new BadRequestException(
|
|
375
|
+
throw new BadRequestException(ERROR_MESSAGES.MODEL_REQUIRED_FOR_CODE_GENERATION);
|
|
375
376
|
}
|
|
376
377
|
const module = options.moduleId ? await this.findOne(options.moduleId) : await this.findOneByUserKey(options.moduleUserKey);
|
|
377
378
|
|
|
@@ -12,6 +12,7 @@ import { CrudHelperService } from "src/services/crud-helper.service";
|
|
|
12
12
|
import { RoleMetadata } from '../entities/role-metadata.entity';
|
|
13
13
|
import { PermissionMetadata } from '../entities/permission-metadata.entity';
|
|
14
14
|
import { CreateRoleMetadataDto } from '../dtos/create-role-metadata.dto';
|
|
15
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
15
16
|
|
|
16
17
|
@Injectable()
|
|
17
18
|
export class RoleMetadataService extends CRUDService<RoleMetadata> {
|
|
@@ -180,7 +181,7 @@ export class RoleMetadataService extends CRUDService<RoleMetadata> {
|
|
|
180
181
|
});
|
|
181
182
|
|
|
182
183
|
if (!role) {
|
|
183
|
-
throw new Error(
|
|
184
|
+
throw new Error(ERROR_MESSAGES.ROLE_NOT_FOUND(roleName));
|
|
184
185
|
}
|
|
185
186
|
|
|
186
187
|
// modify the permissions array.
|
|
@@ -194,7 +195,7 @@ export class RoleMetadataService extends CRUDService<RoleMetadata> {
|
|
|
194
195
|
where: { name },
|
|
195
196
|
});
|
|
196
197
|
if (!existingPermission) {
|
|
197
|
-
throw new NotFoundException(
|
|
198
|
+
throw new NotFoundException(ERROR_MESSAGES.PERMISSION_NOT_EXIST(name));
|
|
198
199
|
}
|
|
199
200
|
return existingPermission;
|
|
200
201
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Injectable } from "@nestjs/common";
|
|
2
2
|
import { SqlExpression, SqlExpressionOperator } from "./question-data-providers/chartjs-sql-data-provider.service";
|
|
3
3
|
import { RequestContextService } from "./request-context.service";
|
|
4
|
+
import { ERROR_MESSAGES } from "src/constants/error-messages";
|
|
4
5
|
|
|
5
6
|
export interface SqlReplacementResult {
|
|
6
7
|
rawSql: string;
|
|
@@ -117,7 +118,7 @@ export class SqlExpressionResolverService {
|
|
|
117
118
|
break;
|
|
118
119
|
|
|
119
120
|
default:
|
|
120
|
-
throw new Error(
|
|
121
|
+
throw new Error(ERROR_MESSAGES.UNSUPPORTED_SQL_OPERATOR(expr.operator));
|
|
121
122
|
}
|
|
122
123
|
simplifiedSql = simplifiedSql.replace(placeholder, sqlFragment);
|
|
123
124
|
}
|