@flusys/nestjs-localization 7.1.0 → 8.0.0
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/config/index.d.ts +3 -3
- package/controllers/index.d.ts +3 -3
- package/controllers/language.controller.d.ts +4 -4
- package/controllers/translation-key.controller.d.ts +3 -3
- package/controllers/translation.controller.d.ts +4 -4
- package/docs/index.d.ts +1 -1
- package/docs/localization-swagger.config.d.ts +1 -1
- package/dtos/index.d.ts +3 -3
- package/dtos/translation.dto.d.ts +2 -2
- package/entities/index.d.ts +6 -6
- package/entities/language.entity.d.ts +1 -1
- package/entities/translation-key.entity.d.ts +1 -1
- package/entities/translation.entity.d.ts +2 -2
- package/fesm/349.js +1179 -0
- package/fesm/692.js +1205 -0
- package/fesm/config/index.js +101 -3
- package/fesm/controllers/index.js +15 -3
- package/fesm/docs/index.js +126 -1
- package/fesm/dtos/index.js +680 -3
- package/fesm/entities/index.js +405 -8
- package/fesm/index.js +257 -7
- package/fesm/interfaces/index.js +18 -4
- package/fesm/modules/index.js +152 -1
- package/fesm/runtime.js +85 -0
- package/fesm/services/index.js +15 -5
- package/index.d.ts +7 -7
- package/interfaces/index.d.ts +4 -4
- package/interfaces/language.interface.d.ts +1 -1
- package/interfaces/localization-module-options.interface.d.ts +3 -3
- package/interfaces/translation-key.interface.d.ts +1 -1
- package/interfaces/translation.interface.d.ts +3 -3
- package/modules/index.d.ts +1 -1
- package/modules/localization.module.d.ts +2 -2
- package/package.json +25 -34
- package/services/index.d.ts +5 -5
- package/services/language.service.d.ts +6 -6
- package/services/localization-config.service.d.ts +3 -3
- package/services/localization-datasource.provider.d.ts +3 -3
- package/services/translation-key.service.d.ts +6 -6
- package/services/translation.service.d.ts +5 -5
- package/cjs/config/event-actions.js +0 -33
- package/cjs/config/index.js +0 -20
- package/cjs/config/localization.constants.js +0 -11
- package/cjs/config/message-keys.js +0 -41
- package/cjs/controllers/index.js +0 -20
- package/cjs/controllers/language.controller.js +0 -188
- package/cjs/controllers/language.controller.spec.js +0 -154
- package/cjs/controllers/translation-key.controller.js +0 -135
- package/cjs/controllers/translation-key.controller.spec.js +0 -70
- package/cjs/controllers/translation.controller.js +0 -195
- package/cjs/controllers/translation.controller.spec.js +0 -169
- package/cjs/docs/index.js +0 -11
- package/cjs/docs/localization-swagger.config.js +0 -111
- package/cjs/docs/localization-swagger.config.spec.js +0 -30
- package/cjs/dtos/index.js +0 -20
- package/cjs/dtos/language.dto.js +0 -213
- package/cjs/dtos/translation-key.dto.js +0 -215
- package/cjs/dtos/translation.dto.js +0 -269
- package/cjs/entities/index.js +0 -42
- package/cjs/entities/index.spec.js +0 -18
- package/cjs/entities/language.entity.js +0 -126
- package/cjs/entities/translation-key.entity.js +0 -126
- package/cjs/entities/translation.entity.js +0 -120
- package/cjs/index.js +0 -24
- package/cjs/interfaces/index.js +0 -21
- package/cjs/interfaces/language.interface.js +0 -4
- package/cjs/interfaces/localization-module-options.interface.js +0 -4
- package/cjs/interfaces/translation-key.interface.js +0 -4
- package/cjs/interfaces/translation.interface.js +0 -4
- package/cjs/modules/index.js +0 -18
- package/cjs/modules/localization.module.js +0 -116
- package/cjs/modules/localization.module.spec.js +0 -132
- package/cjs/services/index.js +0 -22
- package/cjs/services/language.service.js +0 -181
- package/cjs/services/language.service.spec.js +0 -256
- package/cjs/services/localization-config.service.js +0 -66
- package/cjs/services/localization-config.service.spec.js +0 -80
- package/cjs/services/localization-datasource.provider.js +0 -79
- package/cjs/services/localization-datasource.provider.spec.js +0 -85
- package/cjs/services/translation-key.service.js +0 -179
- package/cjs/services/translation-key.service.spec.js +0 -303
- package/cjs/services/translation.service.js +0 -228
- package/cjs/services/translation.service.spec.js +0 -530
- package/fesm/config/event-actions.js +0 -12
- package/fesm/config/localization.constants.js +0 -1
- package/fesm/config/message-keys.js +0 -20
- package/fesm/controllers/language.controller.js +0 -178
- package/fesm/controllers/language.controller.spec.js +0 -150
- package/fesm/controllers/translation-key.controller.js +0 -125
- package/fesm/controllers/translation-key.controller.spec.js +0 -66
- package/fesm/controllers/translation.controller.js +0 -185
- package/fesm/controllers/translation.controller.spec.js +0 -165
- package/fesm/docs/localization-swagger.config.js +0 -101
- package/fesm/docs/localization-swagger.config.spec.js +0 -26
- package/fesm/dtos/language.dto.js +0 -192
- package/fesm/dtos/translation-key.dto.js +0 -194
- package/fesm/dtos/translation.dto.js +0 -239
- package/fesm/entities/index.spec.js +0 -14
- package/fesm/entities/language.entity.js +0 -116
- package/fesm/entities/translation-key.entity.js +0 -116
- package/fesm/entities/translation.entity.js +0 -110
- package/fesm/interfaces/language.interface.js +0 -1
- package/fesm/interfaces/localization-module-options.interface.js +0 -1
- package/fesm/interfaces/translation-key.interface.js +0 -1
- package/fesm/interfaces/translation.interface.js +0 -1
- package/fesm/modules/localization.module.js +0 -106
- package/fesm/modules/localization.module.spec.js +0 -128
- package/fesm/services/language.service.js +0 -171
- package/fesm/services/language.service.spec.js +0 -252
- package/fesm/services/localization-config.service.js +0 -56
- package/fesm/services/localization-config.service.spec.js +0 -76
- package/fesm/services/localization-datasource.provider.js +0 -69
- package/fesm/services/localization-datasource.provider.spec.js +0 -81
- package/fesm/services/translation-key.service.js +0 -169
- package/fesm/services/translation-key.service.spec.js +0 -299
- package/fesm/services/translation.service.js +0 -218
- package/fesm/services/translation.service.spec.js +0 -526
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
const _localizationconfigservice = require("./localization-config.service");
|
|
6
|
-
function buildOptions(overrides = {}) {
|
|
7
|
-
return {
|
|
8
|
-
bootstrapAppConfig: undefined,
|
|
9
|
-
config: undefined,
|
|
10
|
-
...overrides
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
describe('LocalizationConfigService', ()=>{
|
|
14
|
-
describe('isCompanyFeatureEnabled', ()=>{
|
|
15
|
-
it('always returns false — localization module has no company scoping', ()=>{
|
|
16
|
-
const service = new _localizationconfigservice.LocalizationConfigService(buildOptions());
|
|
17
|
-
expect(service.isCompanyFeatureEnabled()).toBe(false);
|
|
18
|
-
});
|
|
19
|
-
it('returns false even when bootstrapAppConfig enables the company feature elsewhere', ()=>{
|
|
20
|
-
const service = new _localizationconfigservice.LocalizationConfigService(buildOptions({
|
|
21
|
-
bootstrapAppConfig: {
|
|
22
|
-
databaseMode: 'single',
|
|
23
|
-
enableCompanyFeature: true
|
|
24
|
-
}
|
|
25
|
-
}));
|
|
26
|
-
expect(service.isCompanyFeatureEnabled()).toBe(false);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
describe('getDatabaseMode', ()=>{
|
|
30
|
-
it('returns the configured database mode', ()=>{
|
|
31
|
-
const service = new _localizationconfigservice.LocalizationConfigService(buildOptions({
|
|
32
|
-
bootstrapAppConfig: {
|
|
33
|
-
databaseMode: 'multi-tenant'
|
|
34
|
-
}
|
|
35
|
-
}));
|
|
36
|
-
expect(service.getDatabaseMode()).toBe('multi-tenant');
|
|
37
|
-
});
|
|
38
|
-
it('defaults to "single" when bootstrapAppConfig is missing', ()=>{
|
|
39
|
-
const service = new _localizationconfigservice.LocalizationConfigService(buildOptions({
|
|
40
|
-
bootstrapAppConfig: undefined
|
|
41
|
-
}));
|
|
42
|
-
expect(service.getDatabaseMode()).toBe('single');
|
|
43
|
-
});
|
|
44
|
-
it('defaults to "single" when databaseMode is not set on bootstrapAppConfig', ()=>{
|
|
45
|
-
const service = new _localizationconfigservice.LocalizationConfigService(buildOptions({
|
|
46
|
-
bootstrapAppConfig: {}
|
|
47
|
-
}));
|
|
48
|
-
expect(service.getDatabaseMode()).toBe('single');
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
describe('isMultiTenant', ()=>{
|
|
52
|
-
it('returns true when database mode is multi-tenant', ()=>{
|
|
53
|
-
const service = new _localizationconfigservice.LocalizationConfigService(buildOptions({
|
|
54
|
-
bootstrapAppConfig: {
|
|
55
|
-
databaseMode: 'multi-tenant'
|
|
56
|
-
}
|
|
57
|
-
}));
|
|
58
|
-
expect(service.isMultiTenant()).toBe(true);
|
|
59
|
-
});
|
|
60
|
-
it('returns false when database mode is single', ()=>{
|
|
61
|
-
const service = new _localizationconfigservice.LocalizationConfigService(buildOptions({
|
|
62
|
-
bootstrapAppConfig: {
|
|
63
|
-
databaseMode: 'single'
|
|
64
|
-
}
|
|
65
|
-
}));
|
|
66
|
-
expect(service.isMultiTenant()).toBe(false);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
describe('getOptions', ()=>{
|
|
70
|
-
it('returns the exact options object it was constructed with', ()=>{
|
|
71
|
-
const options = buildOptions({
|
|
72
|
-
config: {
|
|
73
|
-
defaultLanguageCode: 'en'
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
const service = new _localizationconfigservice.LocalizationConfigService(options);
|
|
77
|
-
expect(service.getOptions()).toBe(options);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
});
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "LocalizationDataSourceProvider", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return LocalizationDataSourceProvider;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
const _modules = require("@flusys/nestjs-shared/modules");
|
|
12
|
-
const _common = require("@nestjs/common");
|
|
13
|
-
const _core = require("@nestjs/core");
|
|
14
|
-
const _express = require("express");
|
|
15
|
-
const _entities = require("../entities");
|
|
16
|
-
const _localizationconfigservice = require("./localization-config.service");
|
|
17
|
-
function _define_property(obj, key, value) {
|
|
18
|
-
if (key in obj) {
|
|
19
|
-
Object.defineProperty(obj, key, {
|
|
20
|
-
value: value,
|
|
21
|
-
enumerable: true,
|
|
22
|
-
configurable: true,
|
|
23
|
-
writable: true
|
|
24
|
-
});
|
|
25
|
-
} else {
|
|
26
|
-
obj[key] = value;
|
|
27
|
-
}
|
|
28
|
-
return obj;
|
|
29
|
-
}
|
|
30
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
31
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
32
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
33
|
-
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
34
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
35
|
-
}
|
|
36
|
-
function _ts_metadata(k, v) {
|
|
37
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
38
|
-
}
|
|
39
|
-
function _ts_param(paramIndex, decorator) {
|
|
40
|
-
return function(target, key) {
|
|
41
|
-
decorator(target, key, paramIndex);
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
let LocalizationDataSourceProvider = class LocalizationDataSourceProvider extends _modules.MultiTenantDataSourceService {
|
|
45
|
-
static buildParentOptions(options) {
|
|
46
|
-
return {
|
|
47
|
-
bootstrapAppConfig: options.bootstrapAppConfig,
|
|
48
|
-
defaultDatabaseConfig: options.config?.defaultDatabaseConfig,
|
|
49
|
-
tenantDefaultDatabaseConfig: options.config?.tenantDefaultDatabaseConfig,
|
|
50
|
-
tenants: options.config?.tenants
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
async createDataSourceFromConfig(config) {
|
|
54
|
-
const entities = (0, _entities.getLocalizationEntities)();
|
|
55
|
-
return super.createDataSourceFromConfig(config, entities);
|
|
56
|
-
}
|
|
57
|
-
constructor(configService, request){
|
|
58
|
-
super(LocalizationDataSourceProvider.buildParentOptions(configService.getOptions()), request);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
_define_property(LocalizationDataSourceProvider, "tenantConnections", new Map());
|
|
62
|
-
_define_property(LocalizationDataSourceProvider, "singleDataSource", null);
|
|
63
|
-
_define_property(LocalizationDataSourceProvider, "tenantsRegistry", new Map());
|
|
64
|
-
_define_property(LocalizationDataSourceProvider, "initialized", false);
|
|
65
|
-
_define_property(LocalizationDataSourceProvider, "connectionLocks", new Map());
|
|
66
|
-
_define_property(LocalizationDataSourceProvider, "singleConnectionLock", null);
|
|
67
|
-
LocalizationDataSourceProvider = _ts_decorate([
|
|
68
|
-
(0, _common.Injectable)({
|
|
69
|
-
scope: _common.Scope.REQUEST
|
|
70
|
-
}),
|
|
71
|
-
_ts_param(0, (0, _common.Inject)(_localizationconfigservice.LocalizationConfigService)),
|
|
72
|
-
_ts_param(1, (0, _common.Optional)()),
|
|
73
|
-
_ts_param(1, (0, _common.Inject)(_core.REQUEST)),
|
|
74
|
-
_ts_metadata("design:type", Function),
|
|
75
|
-
_ts_metadata("design:paramtypes", [
|
|
76
|
-
typeof _localizationconfigservice.LocalizationConfigService === "undefined" ? Object : _localizationconfigservice.LocalizationConfigService,
|
|
77
|
-
typeof _express.Request === "undefined" ? Object : _express.Request
|
|
78
|
-
])
|
|
79
|
-
], LocalizationDataSourceProvider);
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
const _localizationdatasourceprovider = require("./localization-datasource.provider");
|
|
6
|
-
const _entities = require("../entities");
|
|
7
|
-
function buildConfigService(overrides = {}) {
|
|
8
|
-
const options = {
|
|
9
|
-
bootstrapAppConfig: {
|
|
10
|
-
databaseMode: 'single'
|
|
11
|
-
},
|
|
12
|
-
config: {
|
|
13
|
-
defaultDatabaseConfig: {
|
|
14
|
-
type: 'mysql',
|
|
15
|
-
host: 'localhost',
|
|
16
|
-
port: 3306,
|
|
17
|
-
username: 'root',
|
|
18
|
-
password: 'password',
|
|
19
|
-
database: 'flusys_test'
|
|
20
|
-
},
|
|
21
|
-
tenantDefaultDatabaseConfig: undefined,
|
|
22
|
-
tenants: []
|
|
23
|
-
},
|
|
24
|
-
...overrides
|
|
25
|
-
};
|
|
26
|
-
return {
|
|
27
|
-
getOptions: jest.fn().mockReturnValue(options)
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
describe('LocalizationDataSourceProvider', ()=>{
|
|
31
|
-
afterEach(()=>{
|
|
32
|
-
// Reset the isolated static caches this provider owns so tests don't leak state between runs.
|
|
33
|
-
_localizationdatasourceprovider.LocalizationDataSourceProvider.tenantConnections = new Map();
|
|
34
|
-
_localizationdatasourceprovider.LocalizationDataSourceProvider.singleDataSource = null;
|
|
35
|
-
_localizationdatasourceprovider.LocalizationDataSourceProvider.tenantsRegistry = new Map();
|
|
36
|
-
_localizationdatasourceprovider.LocalizationDataSourceProvider.initialized = false;
|
|
37
|
-
_localizationdatasourceprovider.LocalizationDataSourceProvider.connectionLocks = new Map();
|
|
38
|
-
_localizationdatasourceprovider.LocalizationDataSourceProvider.singleConnectionLock = null;
|
|
39
|
-
});
|
|
40
|
-
it('constructs and forwards bootstrap/database config to the base class', ()=>{
|
|
41
|
-
const configService = buildConfigService();
|
|
42
|
-
const provider = new _localizationdatasourceprovider.LocalizationDataSourceProvider(configService, undefined);
|
|
43
|
-
expect(configService.getOptions).toHaveBeenCalled();
|
|
44
|
-
expect(provider.getDatabaseMode()).toBe('single');
|
|
45
|
-
expect(provider.isMultiTenant()).toBe(false);
|
|
46
|
-
});
|
|
47
|
-
it('reflects multi-tenant mode from bootstrapAppConfig', ()=>{
|
|
48
|
-
const configService = buildConfigService({
|
|
49
|
-
bootstrapAppConfig: {
|
|
50
|
-
databaseMode: 'multi-tenant'
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
const provider = new _localizationdatasourceprovider.LocalizationDataSourceProvider(configService, undefined);
|
|
54
|
-
expect(provider.isMultiTenant()).toBe(true);
|
|
55
|
-
});
|
|
56
|
-
it('owns isolated static caches, separate from the base MultiTenantDataSourceService', ()=>{
|
|
57
|
-
// Each DataSource Provider must override BOTH static cache properties and the
|
|
58
|
-
// methods that read them — otherwise modules would share connections (see FLUSYS_NEST/CLAUDE.md).
|
|
59
|
-
expect(_localizationdatasourceprovider.LocalizationDataSourceProvider.tenantConnections).not.toBe(Object.getPrototypeOf(_localizationdatasourceprovider.LocalizationDataSourceProvider).tenantConnections);
|
|
60
|
-
});
|
|
61
|
-
it('createDataSourceFromConfig builds a DataSource using all localization entities', async ()=>{
|
|
62
|
-
const configService = buildConfigService();
|
|
63
|
-
const provider = new _localizationdatasourceprovider.LocalizationDataSourceProvider(configService, undefined);
|
|
64
|
-
const fakeDataSource = {
|
|
65
|
-
isInitialized: true
|
|
66
|
-
};
|
|
67
|
-
const superSpy = jest.spyOn(Object.getPrototypeOf(Object.getPrototypeOf(provider)), 'createDataSourceFromConfig').mockResolvedValue(fakeDataSource);
|
|
68
|
-
const config = {
|
|
69
|
-
type: 'mysql',
|
|
70
|
-
host: 'localhost',
|
|
71
|
-
port: 3306,
|
|
72
|
-
username: 'root',
|
|
73
|
-
password: 'password',
|
|
74
|
-
database: 'flusys_test'
|
|
75
|
-
};
|
|
76
|
-
const result = await provider.createDataSourceFromConfig(config);
|
|
77
|
-
expect(superSpy).toHaveBeenCalledWith(config, [
|
|
78
|
-
_entities.Language,
|
|
79
|
-
_entities.TranslationKey,
|
|
80
|
-
_entities.Translation
|
|
81
|
-
]);
|
|
82
|
-
expect(result).toBe(fakeDataSource);
|
|
83
|
-
superSpy.mockRestore();
|
|
84
|
-
});
|
|
85
|
-
});
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "TranslationKeyService", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return TranslationKeyService;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
const _classes = require("@flusys/nestjs-shared/classes");
|
|
12
|
-
const _modules = require("@flusys/nestjs-shared/modules");
|
|
13
|
-
const _common = require("@nestjs/common");
|
|
14
|
-
const _typeorm = require("typeorm");
|
|
15
|
-
const _config = require("../config");
|
|
16
|
-
const _entities = require("../entities");
|
|
17
|
-
const _localizationdatasourceprovider = require("./localization-datasource.provider");
|
|
18
|
-
function _define_property(obj, key, value) {
|
|
19
|
-
if (key in obj) {
|
|
20
|
-
Object.defineProperty(obj, key, {
|
|
21
|
-
value: value,
|
|
22
|
-
enumerable: true,
|
|
23
|
-
configurable: true,
|
|
24
|
-
writable: true
|
|
25
|
-
});
|
|
26
|
-
} else {
|
|
27
|
-
obj[key] = value;
|
|
28
|
-
}
|
|
29
|
-
return obj;
|
|
30
|
-
}
|
|
31
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
32
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
33
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
34
|
-
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
35
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
36
|
-
}
|
|
37
|
-
function _ts_metadata(k, v) {
|
|
38
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
39
|
-
}
|
|
40
|
-
function _ts_param(paramIndex, decorator) {
|
|
41
|
-
return function(target, key) {
|
|
42
|
-
decorator(target, key, paramIndex);
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
let TranslationKeyService = class TranslationKeyService extends _classes.ApiService {
|
|
46
|
-
async beforeInsertOperation(dto, _user, _queryRunner) {
|
|
47
|
-
const dtos = Array.isArray(dto) ? dto : [
|
|
48
|
-
dto
|
|
49
|
-
];
|
|
50
|
-
await this.validateNoDuplicateKeys(dtos.map((d)=>({
|
|
51
|
-
module: d.module,
|
|
52
|
-
key: d.key
|
|
53
|
-
})));
|
|
54
|
-
}
|
|
55
|
-
async beforeUpdateOperation(dto, _user, _queryRunner) {
|
|
56
|
-
const dtos = Array.isArray(dto) ? dto : [
|
|
57
|
-
dto
|
|
58
|
-
];
|
|
59
|
-
const ids = dtos.map((d)=>d.id);
|
|
60
|
-
await this.ensureDataSourceRepository();
|
|
61
|
-
const existingKeys = await this.repository.find({
|
|
62
|
-
where: {
|
|
63
|
-
id: (0, _typeorm.In)(ids),
|
|
64
|
-
deletedAt: (0, _typeorm.IsNull)()
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
// Check if any readonly keys are being updated with key/module changes
|
|
68
|
-
for (const d of dtos){
|
|
69
|
-
const existing = existingKeys.find((e)=>e.id === d.id);
|
|
70
|
-
const changesIdentity = d.key !== undefined && d.key !== existing?.key || d.module !== undefined && d.module !== existing?.module;
|
|
71
|
-
if (existing?.isReadonly && changesIdentity) {
|
|
72
|
-
throw new _common.ForbiddenException({
|
|
73
|
-
message: `Cannot modify key or module of readonly translation key "${existing.key}"`,
|
|
74
|
-
messageKey: _config.TRANSLATION_KEY_MESSAGES.READONLY_UPDATE_FORBIDDEN,
|
|
75
|
-
messageVariables: {
|
|
76
|
-
key: existing.key
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// Validate no duplicates for keys being changed
|
|
82
|
-
const keysToValidate = dtos.filter((d)=>d.key || d.module).map((d)=>{
|
|
83
|
-
const existing = existingKeys.find((e)=>e.id === d.id);
|
|
84
|
-
return {
|
|
85
|
-
module: d.module ?? existing?.module ?? '',
|
|
86
|
-
key: d.key ?? existing?.key ?? '',
|
|
87
|
-
excludeId: d.id
|
|
88
|
-
};
|
|
89
|
-
});
|
|
90
|
-
if (keysToValidate.length > 0) {
|
|
91
|
-
await this.validateNoDuplicateKeys(keysToValidate);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
async beforeDeleteOperation(option, _user, _queryRunner) {
|
|
95
|
-
const ids = Array.isArray(option.id) ? option.id : [
|
|
96
|
-
option.id
|
|
97
|
-
];
|
|
98
|
-
await this.ensureDataSourceRepository();
|
|
99
|
-
const readonlyKeys = await this.repository.find({
|
|
100
|
-
where: {
|
|
101
|
-
id: (0, _typeorm.In)(ids),
|
|
102
|
-
isReadonly: true,
|
|
103
|
-
deletedAt: (0, _typeorm.IsNull)()
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
if (readonlyKeys.length > 0) {
|
|
107
|
-
const keys = readonlyKeys.map((k)=>k.key).join(', ');
|
|
108
|
-
throw new _common.ForbiddenException({
|
|
109
|
-
message: `Cannot delete readonly translation keys: ${keys}`,
|
|
110
|
-
messageKey: _config.TRANSLATION_KEY_MESSAGES.READONLY_DELETE_FORBIDDEN,
|
|
111
|
-
messageVariables: {
|
|
112
|
-
keys
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
async findByModule(module) {
|
|
118
|
-
await this.ensureDataSourceRepository();
|
|
119
|
-
return this.repository.find({
|
|
120
|
-
where: {
|
|
121
|
-
module,
|
|
122
|
-
isActive: true,
|
|
123
|
-
deletedAt: (0, _typeorm.IsNull)()
|
|
124
|
-
},
|
|
125
|
-
order: {
|
|
126
|
-
serial: 'ASC',
|
|
127
|
-
key: 'ASC'
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
async getModules() {
|
|
132
|
-
await this.ensureDataSourceRepository();
|
|
133
|
-
const result = await this.repository.createQueryBuilder('tk').select('DISTINCT tk.module', 'module').where('tk.deleted_at IS NULL').getRawMany();
|
|
134
|
-
return result.map((r)=>r.module);
|
|
135
|
-
}
|
|
136
|
-
async validateNoDuplicateKeys(keys) {
|
|
137
|
-
await this.ensureDataSourceRepository();
|
|
138
|
-
for (const { module, key, excludeId } of keys){
|
|
139
|
-
const query = this.repository.createQueryBuilder('tk').where('tk.module = :module', {
|
|
140
|
-
module
|
|
141
|
-
}).andWhere('tk.key = :key', {
|
|
142
|
-
key
|
|
143
|
-
}).andWhere('tk.deleted_at IS NULL');
|
|
144
|
-
if (excludeId) {
|
|
145
|
-
query.andWhere('tk.id != :excludeId', {
|
|
146
|
-
excludeId
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
const existing = await query.getOne();
|
|
150
|
-
if (existing) {
|
|
151
|
-
throw new _common.BadRequestException({
|
|
152
|
-
message: `Translation key "${key}" already exists in module "${module}"`,
|
|
153
|
-
messageKey: _config.TRANSLATION_KEY_MESSAGES.DUPLICATE_KEY_IN_MODULE,
|
|
154
|
-
messageVariables: {
|
|
155
|
-
key,
|
|
156
|
-
module
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
constructor(cacheManager, utilsService, dataSourceProvider){
|
|
163
|
-
super(_config.LOCALIZATION_EVENT_ENTITIES.TRANSLATION_KEY, cacheManager, utilsService, TranslationKeyService.name, true, _config.LOCALIZATION_EVENT_MODULE, dataSourceProvider, _entities.TranslationKey), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService;
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
TranslationKeyService = _ts_decorate([
|
|
167
|
-
(0, _common.Injectable)({
|
|
168
|
-
scope: _common.Scope.REQUEST
|
|
169
|
-
}),
|
|
170
|
-
_ts_param(0, (0, _common.Inject)('CACHE_INSTANCE')),
|
|
171
|
-
_ts_param(1, (0, _common.Inject)(_modules.UtilsService)),
|
|
172
|
-
_ts_param(2, (0, _common.Inject)(_localizationdatasourceprovider.LocalizationDataSourceProvider)),
|
|
173
|
-
_ts_metadata("design:type", Function),
|
|
174
|
-
_ts_metadata("design:paramtypes", [
|
|
175
|
-
typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
|
|
176
|
-
typeof _modules.UtilsService === "undefined" ? Object : _modules.UtilsService,
|
|
177
|
-
typeof _localizationdatasourceprovider.LocalizationDataSourceProvider === "undefined" ? Object : _localizationdatasourceprovider.LocalizationDataSourceProvider
|
|
178
|
-
])
|
|
179
|
-
], TranslationKeyService);
|