@flusys/nestjs-localization 6.3.0 → 6.4.1
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/cjs/services/language.service.js +16 -1
- package/cjs/services/language.service.spec.js +31 -1
- package/cjs/services/translation.service.js +6 -1
- package/cjs/services/translation.service.spec.js +28 -5
- package/fesm/services/language.service.js +16 -1
- package/fesm/services/language.service.spec.js +31 -1
- package/fesm/services/translation.service.js +6 -1
- package/fesm/services/translation.service.spec.js +28 -5
- package/package.json +3 -3
|
@@ -66,6 +66,11 @@ let LanguageService = class LanguageService extends _classes.ApiService {
|
|
|
66
66
|
}
|
|
67
67
|
async setAsDefault(id) {
|
|
68
68
|
await this.ensureDataSourceRepository();
|
|
69
|
+
const previousDefaults = await this.repository.find({
|
|
70
|
+
where: {
|
|
71
|
+
isDefault: true
|
|
72
|
+
}
|
|
73
|
+
});
|
|
69
74
|
await this.repository.update({
|
|
70
75
|
isDefault: true
|
|
71
76
|
}, {
|
|
@@ -76,11 +81,21 @@ let LanguageService = class LanguageService extends _classes.ApiService {
|
|
|
76
81
|
}, {
|
|
77
82
|
isDefault: true
|
|
78
83
|
});
|
|
79
|
-
|
|
84
|
+
const language = await this.repository.findOne({
|
|
80
85
|
where: {
|
|
81
86
|
id
|
|
82
87
|
}
|
|
83
88
|
});
|
|
89
|
+
await Promise.all([
|
|
90
|
+
this.clearCacheForAll(),
|
|
91
|
+
this.clearCacheForId([
|
|
92
|
+
...previousDefaults,
|
|
93
|
+
{
|
|
94
|
+
id
|
|
95
|
+
}
|
|
96
|
+
])
|
|
97
|
+
]);
|
|
98
|
+
return language;
|
|
84
99
|
}
|
|
85
100
|
constructor(cacheManager, utilsService, dataSourceProvider){
|
|
86
101
|
super('language', cacheManager, utilsService, LanguageService.name, true, 'localization', _entities.Language, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService;
|
|
@@ -30,6 +30,15 @@ function buildLanguage(overrides = {}) {
|
|
|
30
30
|
describe('LanguageService', ()=>{
|
|
31
31
|
let service;
|
|
32
32
|
let mockRepo;
|
|
33
|
+
const mockUtilsService = {
|
|
34
|
+
clearCache: jest.fn(),
|
|
35
|
+
getCacheKey: jest.fn().mockReturnValue('cache-key'),
|
|
36
|
+
trackCacheKey: jest.fn()
|
|
37
|
+
};
|
|
38
|
+
// Call history is shared across tests in this file; reset it so each cache assertion is exact.
|
|
39
|
+
beforeEach(()=>{
|
|
40
|
+
mockUtilsService.clearCache.mockClear();
|
|
41
|
+
});
|
|
33
42
|
beforeEach(async ()=>{
|
|
34
43
|
mockRepo = (0, _repositorymock.createMockRepository)();
|
|
35
44
|
const mockDataSourceProvider = (0, _repositorymock.createMockDataSourceProvider)(mockRepo);
|
|
@@ -42,7 +51,7 @@ describe('LanguageService', ()=>{
|
|
|
42
51
|
},
|
|
43
52
|
{
|
|
44
53
|
provide: _modules.UtilsService,
|
|
45
|
-
useValue:
|
|
54
|
+
useValue: mockUtilsService
|
|
46
55
|
},
|
|
47
56
|
{
|
|
48
57
|
provide: _localizationdatasourceprovider.LocalizationDataSourceProvider,
|
|
@@ -108,6 +117,9 @@ describe('LanguageService', ()=>{
|
|
|
108
117
|
});
|
|
109
118
|
});
|
|
110
119
|
describe('setAsDefault', ()=>{
|
|
120
|
+
beforeEach(()=>{
|
|
121
|
+
mockRepo.find.mockResolvedValue([]);
|
|
122
|
+
});
|
|
111
123
|
it('unsets the previous default and sets the requested language as default', async ()=>{
|
|
112
124
|
const newDefault = buildLanguage({
|
|
113
125
|
id: 'lang-2',
|
|
@@ -133,6 +145,24 @@ describe('LanguageService', ()=>{
|
|
|
133
145
|
});
|
|
134
146
|
expect(result).toEqual(newDefault);
|
|
135
147
|
});
|
|
148
|
+
it('invalidates the language list cache and both the old and new default entries', async ()=>{
|
|
149
|
+
const previousDefault = buildLanguage({
|
|
150
|
+
id: 'lang-1',
|
|
151
|
+
isDefault: true,
|
|
152
|
+
code: 'en'
|
|
153
|
+
});
|
|
154
|
+
mockRepo.find.mockResolvedValue([
|
|
155
|
+
previousDefault
|
|
156
|
+
]);
|
|
157
|
+
mockRepo.findOne.mockResolvedValue(buildLanguage({
|
|
158
|
+
id: 'lang-2',
|
|
159
|
+
isDefault: true
|
|
160
|
+
}));
|
|
161
|
+
await service.setAsDefault('lang-2');
|
|
162
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('language', expect.anything());
|
|
163
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('language', expect.anything(), 'lang-1');
|
|
164
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('language', expect.anything(), 'lang-2');
|
|
165
|
+
});
|
|
136
166
|
it('returns null when the id does not correspond to any language after the update', async ()=>{
|
|
137
167
|
mockRepo.findOne.mockResolvedValue(null);
|
|
138
168
|
const result = await service.setAsDefault('non-existent-id');
|
|
@@ -132,11 +132,16 @@ let TranslationService = class TranslationService extends _classes.ApiService {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
await queryRunner.commitTransaction();
|
|
135
|
-
|
|
135
|
+
const saved = await this.repository.find({
|
|
136
136
|
where: {
|
|
137
137
|
id: (0, _typeorm.In)(resultIds)
|
|
138
138
|
}
|
|
139
139
|
});
|
|
140
|
+
await Promise.all([
|
|
141
|
+
this.clearCacheForAll(),
|
|
142
|
+
this.clearCacheForId(saved)
|
|
143
|
+
]);
|
|
144
|
+
return saved;
|
|
140
145
|
} catch (error) {
|
|
141
146
|
await queryRunner.rollbackTransaction();
|
|
142
147
|
throw error;
|
|
@@ -66,6 +66,15 @@ function buildTranslation(overrides = {}) {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
describe('TranslationService', ()=>{
|
|
69
|
+
const mockUtilsService = {
|
|
70
|
+
clearCache: jest.fn(),
|
|
71
|
+
getCacheKey: jest.fn().mockReturnValue('cache-key'),
|
|
72
|
+
trackCacheKey: jest.fn()
|
|
73
|
+
};
|
|
74
|
+
// Call history is shared across tests in this file; reset it so each cache assertion is exact.
|
|
75
|
+
beforeEach(()=>{
|
|
76
|
+
mockUtilsService.clearCache.mockClear();
|
|
77
|
+
});
|
|
69
78
|
let service;
|
|
70
79
|
let mockRepo;
|
|
71
80
|
// `TranslationService` uses joins/aggregate query-builder methods (innerJoin, innerJoinAndSelect,
|
|
@@ -98,11 +107,6 @@ describe('TranslationService', ()=>{
|
|
|
98
107
|
createQueryRunner: jest.fn()
|
|
99
108
|
};
|
|
100
109
|
mockDataSourceProvider.getDataSource.mockResolvedValue(fakeDataSource);
|
|
101
|
-
const mockUtilsService = {
|
|
102
|
-
clearCache: jest.fn(),
|
|
103
|
-
getCacheKey: jest.fn().mockReturnValue('cache-key'),
|
|
104
|
-
trackCacheKey: jest.fn()
|
|
105
|
-
};
|
|
106
110
|
const module = await _testing.Test.createTestingModule({
|
|
107
111
|
providers: [
|
|
108
112
|
_translationservice.TranslationService,
|
|
@@ -275,6 +279,25 @@ describe('TranslationService', ()=>{
|
|
|
275
279
|
});
|
|
276
280
|
expect(result).toHaveLength(1);
|
|
277
281
|
});
|
|
282
|
+
it('invalidates the translation list cache and each written entry after committing', async ()=>{
|
|
283
|
+
const queryRunner = buildQueryRunner();
|
|
284
|
+
fakeDataSource.createQueryRunner.mockReturnValue(queryRunner);
|
|
285
|
+
mockRepo.find.mockResolvedValue([
|
|
286
|
+
buildTranslation({
|
|
287
|
+
id: 'translation-1'
|
|
288
|
+
})
|
|
289
|
+
]);
|
|
290
|
+
await service.bulkUpdate([
|
|
291
|
+
{
|
|
292
|
+
id: 'translation-1',
|
|
293
|
+
languageId: 'lang-en',
|
|
294
|
+
translationKeyId: 'tkey-1',
|
|
295
|
+
value: 'Updated'
|
|
296
|
+
}
|
|
297
|
+
]);
|
|
298
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('translation', expect.anything());
|
|
299
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('translation', expect.anything(), 'translation-1');
|
|
300
|
+
});
|
|
278
301
|
it('creates new translations when no id is provided', async ()=>{
|
|
279
302
|
const queryRunner = buildQueryRunner();
|
|
280
303
|
fakeDataSource.createQueryRunner.mockReturnValue(queryRunner);
|
|
@@ -56,6 +56,11 @@ export class LanguageService extends ApiService {
|
|
|
56
56
|
}
|
|
57
57
|
async setAsDefault(id) {
|
|
58
58
|
await this.ensureDataSourceRepository();
|
|
59
|
+
const previousDefaults = await this.repository.find({
|
|
60
|
+
where: {
|
|
61
|
+
isDefault: true
|
|
62
|
+
}
|
|
63
|
+
});
|
|
59
64
|
await this.repository.update({
|
|
60
65
|
isDefault: true
|
|
61
66
|
}, {
|
|
@@ -66,11 +71,21 @@ export class LanguageService extends ApiService {
|
|
|
66
71
|
}, {
|
|
67
72
|
isDefault: true
|
|
68
73
|
});
|
|
69
|
-
|
|
74
|
+
const language = await this.repository.findOne({
|
|
70
75
|
where: {
|
|
71
76
|
id
|
|
72
77
|
}
|
|
73
78
|
});
|
|
79
|
+
await Promise.all([
|
|
80
|
+
this.clearCacheForAll(),
|
|
81
|
+
this.clearCacheForId([
|
|
82
|
+
...previousDefaults,
|
|
83
|
+
{
|
|
84
|
+
id
|
|
85
|
+
}
|
|
86
|
+
])
|
|
87
|
+
]);
|
|
88
|
+
return language;
|
|
74
89
|
}
|
|
75
90
|
constructor(cacheManager, utilsService, dataSourceProvider){
|
|
76
91
|
super('language', cacheManager, utilsService, LanguageService.name, true, 'localization', Language, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService;
|
|
@@ -26,6 +26,15 @@ function buildLanguage(overrides = {}) {
|
|
|
26
26
|
describe('LanguageService', ()=>{
|
|
27
27
|
let service;
|
|
28
28
|
let mockRepo;
|
|
29
|
+
const mockUtilsService = {
|
|
30
|
+
clearCache: jest.fn(),
|
|
31
|
+
getCacheKey: jest.fn().mockReturnValue('cache-key'),
|
|
32
|
+
trackCacheKey: jest.fn()
|
|
33
|
+
};
|
|
34
|
+
// Call history is shared across tests in this file; reset it so each cache assertion is exact.
|
|
35
|
+
beforeEach(()=>{
|
|
36
|
+
mockUtilsService.clearCache.mockClear();
|
|
37
|
+
});
|
|
29
38
|
beforeEach(async ()=>{
|
|
30
39
|
mockRepo = createMockRepository();
|
|
31
40
|
const mockDataSourceProvider = createMockDataSourceProvider(mockRepo);
|
|
@@ -38,7 +47,7 @@ describe('LanguageService', ()=>{
|
|
|
38
47
|
},
|
|
39
48
|
{
|
|
40
49
|
provide: UtilsService,
|
|
41
|
-
useValue:
|
|
50
|
+
useValue: mockUtilsService
|
|
42
51
|
},
|
|
43
52
|
{
|
|
44
53
|
provide: LocalizationDataSourceProvider,
|
|
@@ -104,6 +113,9 @@ describe('LanguageService', ()=>{
|
|
|
104
113
|
});
|
|
105
114
|
});
|
|
106
115
|
describe('setAsDefault', ()=>{
|
|
116
|
+
beforeEach(()=>{
|
|
117
|
+
mockRepo.find.mockResolvedValue([]);
|
|
118
|
+
});
|
|
107
119
|
it('unsets the previous default and sets the requested language as default', async ()=>{
|
|
108
120
|
const newDefault = buildLanguage({
|
|
109
121
|
id: 'lang-2',
|
|
@@ -129,6 +141,24 @@ describe('LanguageService', ()=>{
|
|
|
129
141
|
});
|
|
130
142
|
expect(result).toEqual(newDefault);
|
|
131
143
|
});
|
|
144
|
+
it('invalidates the language list cache and both the old and new default entries', async ()=>{
|
|
145
|
+
const previousDefault = buildLanguage({
|
|
146
|
+
id: 'lang-1',
|
|
147
|
+
isDefault: true,
|
|
148
|
+
code: 'en'
|
|
149
|
+
});
|
|
150
|
+
mockRepo.find.mockResolvedValue([
|
|
151
|
+
previousDefault
|
|
152
|
+
]);
|
|
153
|
+
mockRepo.findOne.mockResolvedValue(buildLanguage({
|
|
154
|
+
id: 'lang-2',
|
|
155
|
+
isDefault: true
|
|
156
|
+
}));
|
|
157
|
+
await service.setAsDefault('lang-2');
|
|
158
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('language', expect.anything());
|
|
159
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('language', expect.anything(), 'lang-1');
|
|
160
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('language', expect.anything(), 'lang-2');
|
|
161
|
+
});
|
|
132
162
|
it('returns null when the id does not correspond to any language after the update', async ()=>{
|
|
133
163
|
mockRepo.findOne.mockResolvedValue(null);
|
|
134
164
|
const result = await service.setAsDefault('non-existent-id');
|
|
@@ -122,11 +122,16 @@ export class TranslationService extends ApiService {
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
await queryRunner.commitTransaction();
|
|
125
|
-
|
|
125
|
+
const saved = await this.repository.find({
|
|
126
126
|
where: {
|
|
127
127
|
id: In(resultIds)
|
|
128
128
|
}
|
|
129
129
|
});
|
|
130
|
+
await Promise.all([
|
|
131
|
+
this.clearCacheForAll(),
|
|
132
|
+
this.clearCacheForId(saved)
|
|
133
|
+
]);
|
|
134
|
+
return saved;
|
|
130
135
|
} catch (error) {
|
|
131
136
|
await queryRunner.rollbackTransaction();
|
|
132
137
|
throw error;
|
|
@@ -62,6 +62,15 @@ function buildTranslation(overrides = {}) {
|
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
describe('TranslationService', ()=>{
|
|
65
|
+
const mockUtilsService = {
|
|
66
|
+
clearCache: jest.fn(),
|
|
67
|
+
getCacheKey: jest.fn().mockReturnValue('cache-key'),
|
|
68
|
+
trackCacheKey: jest.fn()
|
|
69
|
+
};
|
|
70
|
+
// Call history is shared across tests in this file; reset it so each cache assertion is exact.
|
|
71
|
+
beforeEach(()=>{
|
|
72
|
+
mockUtilsService.clearCache.mockClear();
|
|
73
|
+
});
|
|
65
74
|
let service;
|
|
66
75
|
let mockRepo;
|
|
67
76
|
// `TranslationService` uses joins/aggregate query-builder methods (innerJoin, innerJoinAndSelect,
|
|
@@ -94,11 +103,6 @@ describe('TranslationService', ()=>{
|
|
|
94
103
|
createQueryRunner: jest.fn()
|
|
95
104
|
};
|
|
96
105
|
mockDataSourceProvider.getDataSource.mockResolvedValue(fakeDataSource);
|
|
97
|
-
const mockUtilsService = {
|
|
98
|
-
clearCache: jest.fn(),
|
|
99
|
-
getCacheKey: jest.fn().mockReturnValue('cache-key'),
|
|
100
|
-
trackCacheKey: jest.fn()
|
|
101
|
-
};
|
|
102
106
|
const module = await Test.createTestingModule({
|
|
103
107
|
providers: [
|
|
104
108
|
TranslationService,
|
|
@@ -271,6 +275,25 @@ describe('TranslationService', ()=>{
|
|
|
271
275
|
});
|
|
272
276
|
expect(result).toHaveLength(1);
|
|
273
277
|
});
|
|
278
|
+
it('invalidates the translation list cache and each written entry after committing', async ()=>{
|
|
279
|
+
const queryRunner = buildQueryRunner();
|
|
280
|
+
fakeDataSource.createQueryRunner.mockReturnValue(queryRunner);
|
|
281
|
+
mockRepo.find.mockResolvedValue([
|
|
282
|
+
buildTranslation({
|
|
283
|
+
id: 'translation-1'
|
|
284
|
+
})
|
|
285
|
+
]);
|
|
286
|
+
await service.bulkUpdate([
|
|
287
|
+
{
|
|
288
|
+
id: 'translation-1',
|
|
289
|
+
languageId: 'lang-en',
|
|
290
|
+
translationKeyId: 'tkey-1',
|
|
291
|
+
value: 'Updated'
|
|
292
|
+
}
|
|
293
|
+
]);
|
|
294
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('translation', expect.anything());
|
|
295
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('translation', expect.anything(), 'translation-1');
|
|
296
|
+
});
|
|
274
297
|
it('creates new translations when no id is provided', async ()=>{
|
|
275
298
|
const queryRunner = buildQueryRunner();
|
|
276
299
|
fakeDataSource.createQueryRunner.mockReturnValue(queryRunner);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/nestjs-localization",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.1",
|
|
4
4
|
"description": "Localization module for multi-language support",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "fesm/index.js",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"express": "^5.0.0"
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@flusys/nestjs-core": "6.
|
|
84
|
-
"@flusys/nestjs-shared": "6.
|
|
83
|
+
"@flusys/nestjs-core": "6.4.1",
|
|
84
|
+
"@flusys/nestjs-shared": "6.4.1"
|
|
85
85
|
}
|
|
86
86
|
}
|