@flusys/nestjs-localization 7.0.2 → 8.0.0-beta.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.
Files changed (117) hide show
  1. package/config/index.d.ts +3 -3
  2. package/controllers/index.d.ts +3 -3
  3. package/controllers/language.controller.d.ts +4 -4
  4. package/controllers/translation-key.controller.d.ts +3 -3
  5. package/controllers/translation.controller.d.ts +4 -4
  6. package/docs/index.d.ts +1 -1
  7. package/docs/localization-swagger.config.d.ts +1 -1
  8. package/dtos/index.d.ts +3 -3
  9. package/dtos/translation.dto.d.ts +2 -2
  10. package/entities/index.d.ts +6 -6
  11. package/entities/language.entity.d.ts +1 -1
  12. package/entities/translation-key.entity.d.ts +1 -1
  13. package/entities/translation.entity.d.ts +2 -2
  14. package/fesm/349.js +1179 -0
  15. package/fesm/692.js +1205 -0
  16. package/fesm/config/index.js +101 -3
  17. package/fesm/controllers/index.js +15 -3
  18. package/fesm/docs/index.js +126 -1
  19. package/fesm/dtos/index.js +680 -3
  20. package/fesm/entities/index.js +405 -8
  21. package/fesm/index.js +257 -7
  22. package/fesm/interfaces/index.js +18 -4
  23. package/fesm/modules/index.js +152 -1
  24. package/fesm/runtime.js +85 -0
  25. package/fesm/services/index.js +15 -5
  26. package/index.d.ts +7 -7
  27. package/interfaces/index.d.ts +4 -4
  28. package/interfaces/language.interface.d.ts +1 -1
  29. package/interfaces/localization-module-options.interface.d.ts +3 -3
  30. package/interfaces/translation-key.interface.d.ts +1 -1
  31. package/interfaces/translation.interface.d.ts +3 -3
  32. package/modules/index.d.ts +1 -1
  33. package/modules/localization.module.d.ts +2 -2
  34. package/package.json +25 -34
  35. package/services/index.d.ts +5 -5
  36. package/services/language.service.d.ts +6 -6
  37. package/services/localization-config.service.d.ts +3 -3
  38. package/services/localization-datasource.provider.d.ts +3 -3
  39. package/services/translation-key.service.d.ts +6 -6
  40. package/services/translation.service.d.ts +5 -5
  41. package/cjs/config/event-actions.js +0 -33
  42. package/cjs/config/index.js +0 -20
  43. package/cjs/config/localization.constants.js +0 -11
  44. package/cjs/config/message-keys.js +0 -41
  45. package/cjs/controllers/index.js +0 -20
  46. package/cjs/controllers/language.controller.js +0 -188
  47. package/cjs/controllers/language.controller.spec.js +0 -154
  48. package/cjs/controllers/translation-key.controller.js +0 -135
  49. package/cjs/controllers/translation-key.controller.spec.js +0 -70
  50. package/cjs/controllers/translation.controller.js +0 -195
  51. package/cjs/controllers/translation.controller.spec.js +0 -169
  52. package/cjs/docs/index.js +0 -11
  53. package/cjs/docs/localization-swagger.config.js +0 -111
  54. package/cjs/docs/localization-swagger.config.spec.js +0 -30
  55. package/cjs/dtos/index.js +0 -20
  56. package/cjs/dtos/language.dto.js +0 -213
  57. package/cjs/dtos/translation-key.dto.js +0 -215
  58. package/cjs/dtos/translation.dto.js +0 -269
  59. package/cjs/entities/index.js +0 -42
  60. package/cjs/entities/index.spec.js +0 -18
  61. package/cjs/entities/language.entity.js +0 -126
  62. package/cjs/entities/translation-key.entity.js +0 -126
  63. package/cjs/entities/translation.entity.js +0 -120
  64. package/cjs/index.js +0 -24
  65. package/cjs/interfaces/index.js +0 -21
  66. package/cjs/interfaces/language.interface.js +0 -4
  67. package/cjs/interfaces/localization-module-options.interface.js +0 -4
  68. package/cjs/interfaces/translation-key.interface.js +0 -4
  69. package/cjs/interfaces/translation.interface.js +0 -4
  70. package/cjs/modules/index.js +0 -18
  71. package/cjs/modules/localization.module.js +0 -116
  72. package/cjs/modules/localization.module.spec.js +0 -132
  73. package/cjs/services/index.js +0 -22
  74. package/cjs/services/language.service.js +0 -181
  75. package/cjs/services/language.service.spec.js +0 -256
  76. package/cjs/services/localization-config.service.js +0 -66
  77. package/cjs/services/localization-config.service.spec.js +0 -80
  78. package/cjs/services/localization-datasource.provider.js +0 -79
  79. package/cjs/services/localization-datasource.provider.spec.js +0 -85
  80. package/cjs/services/translation-key.service.js +0 -179
  81. package/cjs/services/translation-key.service.spec.js +0 -303
  82. package/cjs/services/translation.service.js +0 -228
  83. package/cjs/services/translation.service.spec.js +0 -530
  84. package/fesm/config/event-actions.js +0 -12
  85. package/fesm/config/localization.constants.js +0 -1
  86. package/fesm/config/message-keys.js +0 -20
  87. package/fesm/controllers/language.controller.js +0 -178
  88. package/fesm/controllers/language.controller.spec.js +0 -150
  89. package/fesm/controllers/translation-key.controller.js +0 -125
  90. package/fesm/controllers/translation-key.controller.spec.js +0 -66
  91. package/fesm/controllers/translation.controller.js +0 -185
  92. package/fesm/controllers/translation.controller.spec.js +0 -165
  93. package/fesm/docs/localization-swagger.config.js +0 -101
  94. package/fesm/docs/localization-swagger.config.spec.js +0 -26
  95. package/fesm/dtos/language.dto.js +0 -192
  96. package/fesm/dtos/translation-key.dto.js +0 -194
  97. package/fesm/dtos/translation.dto.js +0 -239
  98. package/fesm/entities/index.spec.js +0 -14
  99. package/fesm/entities/language.entity.js +0 -116
  100. package/fesm/entities/translation-key.entity.js +0 -116
  101. package/fesm/entities/translation.entity.js +0 -110
  102. package/fesm/interfaces/language.interface.js +0 -1
  103. package/fesm/interfaces/localization-module-options.interface.js +0 -1
  104. package/fesm/interfaces/translation-key.interface.js +0 -1
  105. package/fesm/interfaces/translation.interface.js +0 -1
  106. package/fesm/modules/localization.module.js +0 -106
  107. package/fesm/modules/localization.module.spec.js +0 -128
  108. package/fesm/services/language.service.js +0 -171
  109. package/fesm/services/language.service.spec.js +0 -252
  110. package/fesm/services/localization-config.service.js +0 -56
  111. package/fesm/services/localization-config.service.spec.js +0 -76
  112. package/fesm/services/localization-datasource.provider.js +0 -69
  113. package/fesm/services/localization-datasource.provider.spec.js +0 -81
  114. package/fesm/services/translation-key.service.js +0 -169
  115. package/fesm/services/translation-key.service.spec.js +0 -299
  116. package/fesm/services/translation.service.js +0 -218
  117. package/fesm/services/translation.service.spec.js +0 -526
@@ -1,185 +0,0 @@
1
- function _define_property(obj, key, value) {
2
- if (key in obj) {
3
- Object.defineProperty(obj, key, {
4
- value: value,
5
- enumerable: true,
6
- configurable: true,
7
- writable: true
8
- });
9
- } else {
10
- obj[key] = value;
11
- }
12
- return obj;
13
- }
14
- function _ts_decorate(decorators, target, key, desc) {
15
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
- 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;
18
- return c > 3 && r && Object.defineProperty(target, key, r), r;
19
- }
20
- function _ts_metadata(k, v) {
21
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
- }
23
- function _ts_param(paramIndex, decorator) {
24
- return function(target, key) {
25
- decorator(target, key, paramIndex);
26
- };
27
- }
28
- import { createApiController, TRANSLATION_PERMISSIONS } from '@flusys/nestjs-shared/classes';
29
- import { CurrentUser, RequirePermission } from '@flusys/nestjs-shared/decorators';
30
- import { JwtAuthGuard, PermissionGuard } from '@flusys/nestjs-shared/guards';
31
- import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
32
- import { Body, Controller, Inject, Post, UseGuards } from '@nestjs/common';
33
- import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
34
- import { TRANSLATION_MESSAGES } from '../config';
35
- import { BulkUpdateTranslationsDto, CreateTranslationDto, GetTranslationsByLanguageDto, TranslationResponseDto, UpdateTranslationDto } from '../dtos';
36
- import { TranslationService } from '../services';
37
- export class TranslationController extends createApiController(CreateTranslationDto, UpdateTranslationDto, TranslationResponseDto, {
38
- entityName: 'translation',
39
- security: {
40
- insert: {
41
- level: 'permission',
42
- permissions: [
43
- TRANSLATION_PERMISSIONS.CREATE
44
- ]
45
- },
46
- insertMany: {
47
- level: 'permission',
48
- permissions: [
49
- TRANSLATION_PERMISSIONS.CREATE
50
- ]
51
- },
52
- getById: {
53
- level: 'permission',
54
- permissions: [
55
- TRANSLATION_PERMISSIONS.READ
56
- ]
57
- },
58
- getAll: {
59
- level: 'permission',
60
- permissions: [
61
- TRANSLATION_PERMISSIONS.READ
62
- ]
63
- },
64
- update: {
65
- level: 'permission',
66
- permissions: [
67
- TRANSLATION_PERMISSIONS.UPDATE
68
- ]
69
- },
70
- updateMany: {
71
- level: 'permission',
72
- permissions: [
73
- TRANSLATION_PERMISSIONS.UPDATE
74
- ]
75
- },
76
- delete: {
77
- level: 'permission',
78
- permissions: [
79
- TRANSLATION_PERMISSIONS.DELETE
80
- ]
81
- }
82
- }
83
- }) {
84
- async getByLanguage(body) {
85
- const data = await this.service.getByLanguageCode(body.languageCode, body.modules);
86
- return {
87
- success: true,
88
- message: 'Translations retrieved successfully',
89
- messageKey: TRANSLATION_MESSAGES.BY_LANGUAGE_SUCCESS,
90
- data
91
- };
92
- }
93
- async updateManyValues(body, _user) {
94
- const data = await this.service.bulkUpdate(body.translations);
95
- return {
96
- success: true,
97
- message: `${data.length} translations updated`,
98
- messageKey: TRANSLATION_MESSAGES.UPDATE_MANY_SUCCESS,
99
- messageVariables: {
100
- count: data.length
101
- },
102
- data,
103
- meta: {
104
- count: data.length
105
- }
106
- };
107
- }
108
- async getCounts(_user) {
109
- const data = await this.service.getTranslationCounts();
110
- return {
111
- success: true,
112
- message: 'Translation counts retrieved successfully',
113
- messageKey: TRANSLATION_MESSAGES.GET_ALL_SUCCESS,
114
- data
115
- };
116
- }
117
- constructor(service){
118
- super(service), _define_property(this, "service", void 0), this.service = service;
119
- }
120
- }
121
- _ts_decorate([
122
- Post('get-by-language'),
123
- ApiOperation({
124
- summary: 'Get translations for a language (optionally filtered by modules)'
125
- }),
126
- ApiResponse({
127
- status: 200
128
- }),
129
- _ts_param(0, Body()),
130
- _ts_metadata("design:type", Function),
131
- _ts_metadata("design:paramtypes", [
132
- typeof GetTranslationsByLanguageDto === "undefined" ? Object : GetTranslationsByLanguageDto
133
- ]),
134
- _ts_metadata("design:returntype", Promise)
135
- ], TranslationController.prototype, "getByLanguage", null);
136
- _ts_decorate([
137
- Post('update-many-values'),
138
- UseGuards(JwtAuthGuard, PermissionGuard),
139
- ApiBearerAuth(),
140
- RequirePermission(TRANSLATION_PERMISSIONS.UPDATE),
141
- ApiOperation({
142
- summary: 'Bulk update translation values'
143
- }),
144
- ApiResponse({
145
- status: 200,
146
- type: [
147
- TranslationResponseDto
148
- ]
149
- }),
150
- _ts_param(0, Body()),
151
- _ts_param(1, CurrentUser()),
152
- _ts_metadata("design:type", Function),
153
- _ts_metadata("design:paramtypes", [
154
- typeof BulkUpdateTranslationsDto === "undefined" ? Object : BulkUpdateTranslationsDto,
155
- typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
156
- ]),
157
- _ts_metadata("design:returntype", Promise)
158
- ], TranslationController.prototype, "updateManyValues", null);
159
- _ts_decorate([
160
- Post('get-counts'),
161
- UseGuards(JwtAuthGuard, PermissionGuard),
162
- ApiBearerAuth(),
163
- RequirePermission(TRANSLATION_PERMISSIONS.READ),
164
- ApiOperation({
165
- summary: 'Get translation counts per translation key'
166
- }),
167
- ApiResponse({
168
- status: 200
169
- }),
170
- _ts_param(0, CurrentUser()),
171
- _ts_metadata("design:type", Function),
172
- _ts_metadata("design:paramtypes", [
173
- typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
174
- ]),
175
- _ts_metadata("design:returntype", Promise)
176
- ], TranslationController.prototype, "getCounts", null);
177
- TranslationController = _ts_decorate([
178
- ApiTags('Localization - Translation'),
179
- Controller('localization/translation'),
180
- _ts_param(0, Inject(TranslationService)),
181
- _ts_metadata("design:type", Function),
182
- _ts_metadata("design:paramtypes", [
183
- typeof TranslationService === "undefined" ? Object : TranslationService
184
- ])
185
- ], TranslationController);
@@ -1,165 +0,0 @@
1
- import { Test } from '@nestjs/testing';
2
- import { UtilsService } from '@flusys/nestjs-shared/modules';
3
- import { buildMockUser } from '@test-utils/mocks/logged-user.mock';
4
- import { TranslationController } from './translation.controller';
5
- import { TranslationService } from '../services';
6
- function buildTranslation(overrides = {}) {
7
- return {
8
- id: 'translation-1',
9
- languageId: 'lang-en',
10
- translationKeyId: 'tkey-1',
11
- value: 'Login successful',
12
- isVerified: false,
13
- isActive: true,
14
- createdAt: new Date(),
15
- updatedAt: new Date(),
16
- deletedAt: null,
17
- createdById: null,
18
- updatedById: null,
19
- deletedById: null,
20
- ...overrides
21
- };
22
- }
23
- describe('TranslationController', ()=>{
24
- let controller;
25
- let mockService;
26
- beforeEach(async ()=>{
27
- mockService = {
28
- insert: jest.fn(),
29
- findById: jest.fn(),
30
- getAll: jest.fn(),
31
- update: jest.fn(),
32
- delete: jest.fn(),
33
- getByLanguageCode: jest.fn(),
34
- bulkUpdate: jest.fn(),
35
- getTranslationCounts: jest.fn()
36
- };
37
- const module = await Test.createTestingModule({
38
- controllers: [
39
- TranslationController
40
- ],
41
- providers: [
42
- {
43
- provide: TranslationService,
44
- useValue: mockService
45
- },
46
- {
47
- provide: UtilsService,
48
- useValue: {}
49
- }
50
- ]
51
- }).compile();
52
- controller = module.get(TranslationController);
53
- });
54
- describe('getByLanguage', ()=>{
55
- it('returns the translations map for the requested language and modules', async ()=>{
56
- mockService.getByLanguageCode.mockResolvedValue({
57
- 'auth.login.success': 'Login successful'
58
- });
59
- const result = await controller.getByLanguage({
60
- languageCode: 'en',
61
- modules: [
62
- 'auth'
63
- ]
64
- });
65
- expect(mockService.getByLanguageCode).toHaveBeenCalledWith('en', [
66
- 'auth'
67
- ]);
68
- expect(result).toEqual({
69
- success: true,
70
- message: 'Translations retrieved successfully',
71
- messageKey: 'translation.by.language.success',
72
- data: {
73
- 'auth.login.success': 'Login successful'
74
- }
75
- });
76
- });
77
- it('returns an empty map (fallback) for an unknown language code without throwing', async ()=>{
78
- mockService.getByLanguageCode.mockResolvedValue({});
79
- const result = await controller.getByLanguage({
80
- languageCode: 'xx'
81
- });
82
- expect(result.success).toBe(true);
83
- expect(result.data).toEqual({});
84
- });
85
- it('requests translations for all modules when modules is omitted', async ()=>{
86
- mockService.getByLanguageCode.mockResolvedValue({});
87
- await controller.getByLanguage({
88
- languageCode: 'en'
89
- });
90
- expect(mockService.getByLanguageCode).toHaveBeenCalledWith('en', undefined);
91
- });
92
- });
93
- describe('updateManyValues', ()=>{
94
- it('bulk updates translations and reports the updated count', async ()=>{
95
- const updated = [
96
- buildTranslation(),
97
- buildTranslation({
98
- id: 'translation-2'
99
- })
100
- ];
101
- mockService.bulkUpdate.mockResolvedValue(updated);
102
- const result = await controller.updateManyValues({
103
- translations: [
104
- {
105
- languageId: 'lang-en',
106
- translationKeyId: 'tkey-1',
107
- value: 'Login successful'
108
- }
109
- ]
110
- }, buildMockUser());
111
- expect(result).toEqual({
112
- success: true,
113
- message: '2 translations updated',
114
- messageKey: 'translation.update.many.success',
115
- messageVariables: {
116
- count: 2
117
- },
118
- data: updated,
119
- meta: {
120
- count: 2
121
- }
122
- });
123
- });
124
- it('reports zero updates for an empty batch without calling the service twice', async ()=>{
125
- mockService.bulkUpdate.mockResolvedValue([]);
126
- const result = await controller.updateManyValues({
127
- translations: []
128
- }, buildMockUser());
129
- expect(mockService.bulkUpdate).toHaveBeenCalledTimes(1);
130
- expect(result.meta).toEqual({
131
- count: 0
132
- });
133
- expect(result.message).toBe('0 translations updated');
134
- });
135
- it('propagates errors raised during the bulk transaction (e.g. rollback surfaced as a rejection)', async ()=>{
136
- mockService.bulkUpdate.mockRejectedValue(new Error('transaction rolled back'));
137
- await expect(controller.updateManyValues({
138
- translations: []
139
- }, buildMockUser())).rejects.toThrow('transaction rolled back');
140
- });
141
- });
142
- describe('getCounts', ()=>{
143
- it('returns translation counts keyed by translation key id', async ()=>{
144
- mockService.getTranslationCounts.mockResolvedValue({
145
- 'tkey-1': 3,
146
- 'tkey-2': 1
147
- });
148
- const result = await controller.getCounts(buildMockUser());
149
- expect(result).toEqual({
150
- success: true,
151
- message: 'Translation counts retrieved successfully',
152
- messageKey: 'translation.get.all.success',
153
- data: {
154
- 'tkey-1': 3,
155
- 'tkey-2': 1
156
- }
157
- });
158
- });
159
- it('returns an empty object when there are no translations yet', async ()=>{
160
- mockService.getTranslationCounts.mockResolvedValue({});
161
- const result = await controller.getCounts(buildMockUser());
162
- expect(result.data).toEqual({});
163
- });
164
- });
165
- });
@@ -1,101 +0,0 @@
1
- export function localizationSwaggerConfig(bootstrapConfig) {
2
- const isMultiTenant = bootstrapConfig?.databaseMode === 'multi-tenant';
3
- const multiTenantNote = isMultiTenant ? `\n> **Multi-Tenant Mode**: Include \`x-tenant-id\` header to target a specific tenant database.\n` : '';
4
- return {
5
- title: 'Localization API',
6
- description: `
7
- ## Localization API
8
- ${multiTenantNote}
9
-
10
- Database-driven internationalization system. Manage languages, translation keys, and translations — all stored in the database and served via API.
11
-
12
- ## Features
13
-
14
- ### 🌐 Language Management
15
- - Create and manage languages with LTR/RTL direction support
16
- - Set a default language
17
- - Mark languages as readonly to protect seeded entries
18
-
19
- ### 🔑 Translation Keys
20
- - Organize keys by module for lazy loading (e.g. \`auth\`, \`iam\`, \`common\`)
21
- - Dot-case naming convention: \`auth.login.title\`, \`common.button.save\`
22
- - Support for interpolation variables: \`['count', 'name']\`
23
- - Readonly protection — system keys cannot be deleted or have their key/module changed
24
-
25
- ### 📝 Translations
26
- - Store translated values per language per key
27
- - Mark translations as verified
28
- - Bulk upsert in a single transaction — create or update in one call
29
- - Detect missing translations for a given language
30
- - Track translation counts per key
31
-
32
- ### 🚀 Angular Lazy Loading
33
- - Public endpoints return flat key-value maps: \`{ "auth.login.title": "Sign In" }\`
34
- - Filter by one or multiple modules to load only what is needed
35
- - No authentication required for translation retrieval endpoints
36
-
37
- ## Key Naming Convention
38
-
39
- Translation keys use dot-case and must be unique per module:
40
-
41
- \`\`\`
42
- auth.login.title
43
- auth.login.submit
44
- auth.register.email.placeholder
45
- common.button.save
46
- common.button.cancel
47
- iam.role.create.success
48
- \`\`\`
49
-
50
- ## Module-Based Lazy Loading
51
-
52
- Keys are grouped by \`module\` so the frontend loads translations on demand:
53
-
54
- | Module | Purpose |
55
- |--------|---------|
56
- | auth | Login, register, profile pages |
57
- | iam | Roles, permissions management |
58
- | storage | Files and folders |
59
- | event-manager | Calendar events |
60
- | form-builder | Dynamic form fields |
61
- | notification | Notification titles and messages |
62
- | email | Email template content |
63
- | common | Shared labels used across modules |
64
-
65
- ## Public vs Authenticated Endpoints
66
-
67
- **Public** (no auth required — used by Angular to load translations):
68
- - POST /localization/language/get-active
69
- - POST /localization/language/get-default
70
- - POST /localization/translation/get-by-language
71
- - POST /localization/translation/get-by-module
72
-
73
- **Authenticated** (require JWT + permission):
74
- - All create, update, delete operations
75
- - get-missing, get-counts, update-many-values
76
-
77
- ## Bulk Update
78
-
79
- POST /localization/translation/update-many-values accepts an array of translation objects. Each item is either an upsert (provide **id** to update, omit to create). The entire batch runs in a single database transaction.
80
-
81
- ## Readonly Protection
82
-
83
- Languages and translation keys with \`isReadonly: true\` are protected at the service layer:
84
- - Cannot be deleted
85
- - Key and module fields cannot be modified
86
-
87
- Use \`isReadonly\` to protect entries that are seeded at startup and should not be changed by users.
88
-
89
- ## Getting Started
90
-
91
- 1. **Authenticate**: Obtain JWT token from POST /auth/login
92
- 2. **Create languages**: Add languages via POST /localization/language/insert
93
- 3. **Seed translation keys**: Bulk insert keys via POST /localization/translation-key/insert-many
94
- 4. **Add translations**: Use POST /localization/translation/update-many-values for bulk upsert
95
- 5. **Load in Angular**: Call POST /localization/translation/get-by-language with { languageCode: "en", modules: ["auth"] }
96
- `,
97
- version: '1.0',
98
- path: 'api/docs/localization',
99
- bearerAuth: true
100
- };
101
- }
@@ -1,26 +0,0 @@
1
- import { localizationSwaggerConfig } from './localization-swagger.config';
2
- describe('localizationSwaggerConfig', ()=>{
3
- it('should build a static config with no multi-tenant note by default', ()=>{
4
- const config = localizationSwaggerConfig();
5
- expect(config.title).toBe('Localization API');
6
- expect(config.path).toBe('api/docs/localization');
7
- expect(config.bearerAuth).toBe(true);
8
- expect(config.description).not.toContain('Multi-Tenant Mode');
9
- });
10
- it('should include the multi-tenant note only for multi-tenant database mode', ()=>{
11
- const multiTenant = localizationSwaggerConfig({
12
- databaseMode: 'multi-tenant'
13
- });
14
- const single = localizationSwaggerConfig({
15
- databaseMode: 'single'
16
- });
17
- expect(multiTenant.description).toContain('Multi-Tenant Mode');
18
- expect(single.description).not.toContain('Multi-Tenant Mode');
19
- });
20
- it('should treat any non-"multi-tenant" value as single-database mode', ()=>{
21
- const config = localizationSwaggerConfig({
22
- databaseMode: 'unexpected-value'
23
- });
24
- expect(config.description).not.toContain('Multi-Tenant Mode');
25
- });
26
- });
@@ -1,192 +0,0 @@
1
- function _define_property(obj, key, value) {
2
- if (key in obj) {
3
- Object.defineProperty(obj, key, {
4
- value: value,
5
- enumerable: true,
6
- configurable: true,
7
- writable: true
8
- });
9
- } else {
10
- obj[key] = value;
11
- }
12
- return obj;
13
- }
14
- function _ts_decorate(decorators, target, key, desc) {
15
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
- 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;
18
- return c > 3 && r && Object.defineProperty(target, key, r), r;
19
- }
20
- function _ts_metadata(k, v) {
21
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
- }
23
- import { IdentityResponseDto } from '@flusys/nestjs-shared/dtos';
24
- import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
25
- import { Exclude, Expose, Transform } from 'class-transformer';
26
- import { IsBoolean, IsIn, IsNumber, IsOptional, IsString, IsUUID, MaxLength } from 'class-validator';
27
- export class CreateLanguageDto {
28
- constructor(){
29
- _define_property(this, "code", void 0);
30
- _define_property(this, "name", void 0);
31
- _define_property(this, "nativeName", void 0);
32
- _define_property(this, "direction", void 0);
33
- _define_property(this, "isActive", void 0);
34
- _define_property(this, "isDefault", void 0);
35
- _define_property(this, "serial", void 0);
36
- }
37
- }
38
- _ts_decorate([
39
- IsString(),
40
- MaxLength(10),
41
- Transform(({ value })=>value?.trim()?.toLowerCase()),
42
- ApiProperty({
43
- example: 'en',
44
- description: 'Language code (ISO 639-1)'
45
- }),
46
- _ts_metadata("design:type", String)
47
- ], CreateLanguageDto.prototype, "code", void 0);
48
- _ts_decorate([
49
- IsString(),
50
- MaxLength(100),
51
- Transform(({ value })=>value?.trim()),
52
- ApiProperty({
53
- example: 'English',
54
- description: 'Language name'
55
- }),
56
- _ts_metadata("design:type", String)
57
- ], CreateLanguageDto.prototype, "name", void 0);
58
- _ts_decorate([
59
- IsOptional(),
60
- IsString(),
61
- MaxLength(100),
62
- Transform(({ value })=>value?.trim()),
63
- ApiPropertyOptional({
64
- example: 'English',
65
- description: 'Native name of the language'
66
- }),
67
- _ts_metadata("design:type", String)
68
- ], CreateLanguageDto.prototype, "nativeName", void 0);
69
- _ts_decorate([
70
- IsOptional(),
71
- IsIn([
72
- 'ltr',
73
- 'rtl'
74
- ]),
75
- ApiPropertyOptional({
76
- example: 'ltr',
77
- enum: [
78
- 'ltr',
79
- 'rtl'
80
- ],
81
- description: 'Text direction'
82
- }),
83
- _ts_metadata("design:type", String)
84
- ], CreateLanguageDto.prototype, "direction", void 0);
85
- _ts_decorate([
86
- IsOptional(),
87
- IsBoolean(),
88
- ApiPropertyOptional({
89
- example: true,
90
- description: 'Whether the language is active'
91
- }),
92
- _ts_metadata("design:type", Boolean)
93
- ], CreateLanguageDto.prototype, "isActive", void 0);
94
- _ts_decorate([
95
- IsOptional(),
96
- IsBoolean(),
97
- ApiPropertyOptional({
98
- example: false,
99
- description: 'Whether this is the default language'
100
- }),
101
- _ts_metadata("design:type", Boolean)
102
- ], CreateLanguageDto.prototype, "isDefault", void 0);
103
- _ts_decorate([
104
- IsOptional(),
105
- IsNumber(),
106
- ApiPropertyOptional({
107
- example: 1,
108
- description: 'Display order'
109
- }),
110
- _ts_metadata("design:type", Number)
111
- ], CreateLanguageDto.prototype, "serial", void 0);
112
- export class UpdateLanguageDto extends PartialType(CreateLanguageDto) {
113
- constructor(...args){
114
- super(...args), _define_property(this, "id", void 0);
115
- }
116
- }
117
- _ts_decorate([
118
- IsUUID(),
119
- ApiProperty({
120
- description: 'Language ID'
121
- }),
122
- _ts_metadata("design:type", String)
123
- ], UpdateLanguageDto.prototype, "id", void 0);
124
- export class LanguageResponseDto extends IdentityResponseDto {
125
- constructor(...args){
126
- super(...args), _define_property(this, "code", void 0), _define_property(this, "name", void 0), _define_property(this, "nativeName", void 0), _define_property(this, "direction", void 0), _define_property(this, "isActive", void 0), _define_property(this, "isDefault", void 0), _define_property(this, "isReadonly", void 0), _define_property(this, "serial", void 0);
127
- }
128
- }
129
- _ts_decorate([
130
- ApiProperty({
131
- example: 'en'
132
- }),
133
- Expose(),
134
- _ts_metadata("design:type", String)
135
- ], LanguageResponseDto.prototype, "code", void 0);
136
- _ts_decorate([
137
- ApiProperty({
138
- example: 'English'
139
- }),
140
- Expose(),
141
- _ts_metadata("design:type", String)
142
- ], LanguageResponseDto.prototype, "name", void 0);
143
- _ts_decorate([
144
- ApiPropertyOptional({
145
- example: 'English'
146
- }),
147
- Expose(),
148
- _ts_metadata("design:type", Object)
149
- ], LanguageResponseDto.prototype, "nativeName", void 0);
150
- _ts_decorate([
151
- ApiPropertyOptional({
152
- example: 'ltr',
153
- enum: [
154
- 'ltr',
155
- 'rtl'
156
- ]
157
- }),
158
- Expose(),
159
- _ts_metadata("design:type", Object)
160
- ], LanguageResponseDto.prototype, "direction", void 0);
161
- _ts_decorate([
162
- ApiProperty({
163
- example: true
164
- }),
165
- Expose(),
166
- _ts_metadata("design:type", Boolean)
167
- ], LanguageResponseDto.prototype, "isActive", void 0);
168
- _ts_decorate([
169
- ApiProperty({
170
- example: false
171
- }),
172
- Expose(),
173
- _ts_metadata("design:type", Boolean)
174
- ], LanguageResponseDto.prototype, "isDefault", void 0);
175
- _ts_decorate([
176
- ApiProperty({
177
- example: false,
178
- description: 'System language: cannot be renamed or deleted'
179
- }),
180
- Expose(),
181
- _ts_metadata("design:type", Boolean)
182
- ], LanguageResponseDto.prototype, "isReadonly", void 0);
183
- _ts_decorate([
184
- ApiPropertyOptional({
185
- example: 1
186
- }),
187
- Expose(),
188
- _ts_metadata("design:type", Object)
189
- ], LanguageResponseDto.prototype, "serial", void 0);
190
- LanguageResponseDto = _ts_decorate([
191
- Exclude()
192
- ], LanguageResponseDto);