@nest-omni/core 4.1.3-1 → 4.1.3-11
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/audit/audit.module.d.ts +10 -0
- package/audit/audit.module.js +39 -1
- package/audit/controllers/audit.controller.d.ts +24 -0
- package/audit/controllers/audit.controller.js +24 -0
- package/audit/decorators/audit-controller.decorator.d.ts +9 -1
- package/audit/decorators/audit-controller.decorator.js +11 -2
- package/audit/decorators/audit-operation.decorator.d.ts +45 -0
- package/audit/decorators/audit-operation.decorator.js +49 -0
- package/audit/decorators/entity-audit.decorator.d.ts +76 -1
- package/audit/decorators/entity-audit.decorator.js +135 -3
- package/audit/decorators/index.d.ts +1 -0
- package/audit/decorators/index.js +1 -0
- package/audit/dto/audit-log-query.dto.d.ts +3 -0
- package/audit/dto/audit-log-query.dto.js +3 -0
- package/audit/dto/begin-transaction.dto.d.ts +3 -0
- package/audit/dto/begin-transaction.dto.js +3 -0
- package/audit/dto/compare-entities.dto.d.ts +3 -0
- package/audit/dto/compare-entities.dto.js +3 -0
- package/audit/dto/pre-check-restore.dto.d.ts +3 -0
- package/audit/dto/pre-check-restore.dto.js +3 -0
- package/audit/dto/restore-entity.dto.d.ts +3 -0
- package/audit/dto/restore-entity.dto.js +3 -0
- package/audit/entities/entity-audit-log.entity.d.ts +8 -0
- package/audit/entities/entity-audit-log.entity.js +33 -1
- package/audit/entities/entity-transaction.entity.d.ts +10 -0
- package/audit/entities/entity-transaction.entity.js +33 -1
- package/audit/entities/index.d.ts +2 -0
- package/audit/entities/index.js +2 -0
- package/audit/entities/manual-operation-log.entity.d.ts +4 -0
- package/audit/entities/manual-operation-log.entity.js +4 -0
- package/audit/entities/operation-template.entity.d.ts +4 -0
- package/audit/entities/operation-template.entity.js +4 -0
- package/audit/enums/audit.enums.d.ts +45 -5
- package/audit/enums/audit.enums.js +47 -4
- package/audit/index.d.ts +3 -1
- package/audit/index.js +30 -1
- package/audit/interceptors/audit.interceptor.d.ts +15 -0
- package/audit/interceptors/audit.interceptor.js +23 -1
- package/audit/interfaces/audit.interfaces.d.ts +182 -2
- package/audit/services/audit-context.service.d.ts +15 -0
- package/audit/services/audit-context.service.js +15 -0
- package/audit/services/audit-strategy.service.d.ts +6 -0
- package/audit/services/audit-strategy.service.js +13 -0
- package/audit/services/entity-audit.service.d.ts +129 -3
- package/audit/services/entity-audit.service.js +301 -6
- package/audit/services/index.d.ts +2 -0
- package/audit/services/index.js +2 -0
- package/audit/services/manual-audit-log.service.d.ts +124 -0
- package/audit/services/manual-audit-log.service.js +138 -0
- package/audit/services/multi-database.service.d.ts +12 -0
- package/audit/services/multi-database.service.js +12 -0
- package/audit/services/operation-description.service.d.ts +59 -0
- package/audit/services/operation-description.service.js +76 -2
- package/audit/services/transaction-audit.service.d.ts +30 -0
- package/audit/services/transaction-audit.service.js +47 -0
- package/audit/subscribers/entity-audit.subscriber.d.ts +15 -0
- package/audit/subscribers/entity-audit.subscriber.js +29 -1
- package/cache/cache-metrics.service.d.ts +67 -0
- package/cache/cache-metrics.service.js +68 -4
- package/cache/cache-serialization.service.d.ts +31 -0
- package/cache/cache-serialization.service.js +25 -0
- package/cache/cache.constants.d.ts +9 -0
- package/cache/cache.constants.js +9 -0
- package/cache/cache.health.d.ts +26 -0
- package/cache/cache.health.js +30 -0
- package/cache/cache.module.d.ts +86 -0
- package/cache/cache.module.js +71 -0
- package/cache/cache.service.d.ts +140 -0
- package/cache/cache.service.js +157 -0
- package/cache/cache.warmup.service.d.ts +39 -0
- package/cache/cache.warmup.service.js +32 -0
- package/cache/decorators/cache-evict.decorator.d.ts +47 -0
- package/cache/decorators/cache-evict.decorator.js +56 -0
- package/cache/decorators/cache-put.decorator.d.ts +34 -0
- package/cache/decorators/cache-put.decorator.js +39 -0
- package/cache/decorators/cacheable.decorator.d.ts +40 -0
- package/cache/decorators/cacheable.decorator.js +55 -0
- package/cache/dependencies/callback.dependency.d.ts +33 -0
- package/cache/dependencies/callback.dependency.js +39 -1
- package/cache/dependencies/chain.dependency.d.ts +28 -0
- package/cache/dependencies/chain.dependency.js +34 -0
- package/cache/dependencies/db.dependency.d.ts +45 -0
- package/cache/dependencies/db.dependency.js +48 -1
- package/cache/dependencies/file.dependency.d.ts +32 -0
- package/cache/dependencies/file.dependency.js +34 -0
- package/cache/dependencies/tag.dependency.d.ts +36 -0
- package/cache/dependencies/tag.dependency.js +36 -0
- package/cache/dependencies/time.dependency.d.ts +43 -0
- package/cache/dependencies/time.dependency.js +43 -0
- package/cache/examples/basic-usage.d.ts +15 -0
- package/cache/examples/basic-usage.js +62 -8
- package/cache/index.js +9 -0
- package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
- package/cache/interfaces/cache-options.interface.d.ts +81 -0
- package/cache/interfaces/cache-options.interface.js +6 -0
- package/cache/interfaces/cache-provider.interface.d.ts +78 -0
- package/cache/providers/base-cache.provider.d.ts +14 -0
- package/cache/providers/base-cache.provider.js +16 -0
- package/cache/providers/cls-cache.provider.d.ts +20 -0
- package/cache/providers/cls-cache.provider.js +28 -0
- package/cache/providers/memory-cache.provider.d.ts +23 -0
- package/cache/providers/memory-cache.provider.js +26 -0
- package/cache/providers/redis-cache.provider.d.ts +26 -0
- package/cache/providers/redis-cache.provider.js +29 -0
- package/cache/utils/dependency-manager.util.d.ts +52 -0
- package/cache/utils/dependency-manager.util.js +59 -0
- package/cache/utils/key-generator.util.d.ts +42 -0
- package/cache/utils/key-generator.util.js +53 -1
- package/common/abstract.entity.d.ts +14 -0
- package/common/abstract.entity.js +14 -0
- package/common/boilerplate.polyfill.d.ts +142 -4
- package/common/boilerplate.polyfill.js +24 -100
- package/common/dto/dto-container.d.ts +16 -0
- package/common/dto/dto-container.js +20 -0
- package/common/dto/dto-decorators.d.ts +18 -0
- package/common/dto/dto-decorators.js +14 -0
- package/common/dto/dto-extensions.d.ts +11 -0
- package/common/dto/dto-extensions.js +9 -0
- package/common/dto/dto-service-accessor.d.ts +17 -0
- package/common/dto/dto-service-accessor.js +18 -0
- package/common/dto/dto-transformer.d.ts +12 -0
- package/common/dto/dto-transformer.js +9 -0
- package/common/dto/index.js +2 -0
- package/common/examples/paginate-and-map.example.d.ts +6 -0
- package/common/examples/paginate-and-map.example.js +26 -0
- package/common/utils.d.ts +15 -0
- package/common/utils.js +15 -0
- package/constants/language-code.js +1 -0
- package/decorators/field.decorators.js +8 -1
- package/decorators/property.decorators.js +1 -0
- package/decorators/public-route.decorator.js +1 -0
- package/decorators/transform.decorators.d.ts +27 -0
- package/decorators/transform.decorators.js +29 -0
- package/decorators/translate.decorator.js +1 -0
- package/decorators/user.decorator.js +1 -0
- package/decorators/validator.decorators.d.ts +8 -18
- package/decorators/validator.decorators.js +22 -190
- package/filters/constraint-errors.js +1 -0
- package/helpers/common.helper.d.ts +13 -0
- package/helpers/common.helper.js +13 -0
- package/http-client/config/http-client.config.d.ts +15 -0
- package/http-client/config/http-client.config.js +25 -9
- package/http-client/decorators/http-client.decorators.d.ts +63 -0
- package/http-client/decorators/http-client.decorators.js +71 -3
- package/http-client/entities/http-log.entity.d.ts +229 -0
- package/http-client/entities/http-log.entity.js +6 -1
- package/http-client/errors/http-client.errors.d.ts +57 -0
- package/http-client/errors/http-client.errors.js +58 -0
- package/http-client/examples/advanced-usage.example.d.ts +41 -0
- package/http-client/examples/advanced-usage.example.js +68 -24
- package/http-client/examples/auth-with-waiting-lock.example.d.ts +31 -0
- package/http-client/examples/auth-with-waiting-lock.example.js +52 -5
- package/http-client/examples/basic-usage.example.d.ts +60 -0
- package/http-client/examples/basic-usage.example.js +60 -0
- package/http-client/examples/multi-api-configuration.example.d.ts +60 -0
- package/http-client/examples/multi-api-configuration.example.js +76 -5
- package/http-client/http-client.module.d.ts +13 -0
- package/http-client/http-client.module.js +20 -5
- package/http-client/index.js +8 -0
- package/http-client/interfaces/api-client-config.interface.d.ts +125 -0
- package/http-client/interfaces/api-client-config.interface.js +3 -0
- package/http-client/interfaces/http-client-config.interface.d.ts +60 -0
- package/http-client/services/api-client-registry.service.d.ts +57 -0
- package/http-client/services/api-client-registry.service.js +84 -1
- package/http-client/services/cache.service.d.ts +52 -0
- package/http-client/services/cache.service.js +72 -3
- package/http-client/services/circuit-breaker.service.d.ts +46 -0
- package/http-client/services/circuit-breaker.service.js +52 -0
- package/http-client/services/http-client.service.d.ts +67 -0
- package/http-client/services/http-client.service.js +105 -4
- package/http-client/services/http-log-query.service.d.ts +83 -0
- package/http-client/services/http-log-query.service.js +122 -1
- package/http-client/services/http-replay.service.d.ts +101 -0
- package/http-client/services/http-replay.service.js +86 -0
- package/http-client/services/log-cleanup.service.d.ts +63 -0
- package/http-client/services/log-cleanup.service.js +54 -2
- package/http-client/services/logging.service.d.ts +40 -0
- package/http-client/services/logging.service.js +53 -0
- package/http-client/utils/call-stack-extractor.util.d.ts +37 -0
- package/http-client/utils/call-stack-extractor.util.js +48 -0
- package/http-client/utils/context-extractor.util.d.ts +49 -0
- package/http-client/utils/context-extractor.util.js +52 -0
- package/http-client/utils/curl-generator.util.d.ts +21 -0
- package/http-client/utils/curl-generator.util.js +44 -3
- package/http-client/utils/request-id.util.d.ts +18 -0
- package/http-client/utils/request-id.util.js +20 -0
- package/http-client/utils/retry-recorder.util.d.ts +42 -0
- package/http-client/utils/retry-recorder.util.js +44 -0
- package/i18n/en_US/validation.json +2 -1
- package/i18n/zh_CN/validation.json +2 -1
- package/index.js +8 -0
- package/interceptors/translation-interceptor.service.js +5 -0
- package/package.json +1 -1
- package/providers/context.provider.js +2 -0
- package/providers/generator.provider.d.ts +4 -0
- package/providers/generator.provider.js +4 -0
- package/redis-lock/comprehensive-lock-cleanup.service.d.ts +94 -0
- package/redis-lock/comprehensive-lock-cleanup.service.js +253 -0
- package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
- package/redis-lock/examples/lock-strategy.examples.js +130 -15
- package/redis-lock/index.d.ts +2 -0
- package/redis-lock/index.js +8 -1
- package/redis-lock/lock-heartbeat.service.d.ts +78 -0
- package/redis-lock/lock-heartbeat.service.js +222 -0
- package/redis-lock/redis-lock.decorator.d.ts +101 -0
- package/redis-lock/redis-lock.decorator.js +120 -0
- package/redis-lock/redis-lock.module.d.ts +66 -0
- package/redis-lock/redis-lock.module.js +175 -70
- package/redis-lock/redis-lock.service.d.ts +278 -0
- package/redis-lock/redis-lock.service.js +282 -12
- package/setup/bootstrap.setup.js +20 -0
- package/setup/mode.setup.d.ts +44 -0
- package/setup/mode.setup.js +44 -0
- package/setup/schedule.decorator.d.ts +227 -0
- package/setup/schedule.decorator.js +235 -12
- package/setup/worker.decorator.d.ts +86 -0
- package/setup/worker.decorator.js +88 -0
- package/shared/serviceRegistryModule.js +27 -14
- package/shared/services/api-config.service.d.ts +3 -0
- package/shared/services/api-config.service.js +20 -9
- package/validator-json/decorators.d.ts +17 -0
- package/validator-json/decorators.js +17 -2
- package/validator-json/default.d.ts +6 -0
- package/validator-json/default.js +30 -2
- package/validator-json/defaultConverters.js +1 -0
- package/validator-json/options.d.ts +23 -0
- package/validators/common-validators.d.ts +143 -0
- package/validators/common-validators.js +249 -0
- package/validators/custom-validate.examples.d.ts +96 -0
- package/validators/custom-validate.examples.js +400 -0
- package/validators/custom-validate.validator.d.ts +134 -0
- package/validators/custom-validate.validator.js +214 -0
- package/validators/index.d.ts +2 -0
- package/validators/index.js +2 -0
- package/validators/is-exists.validator.d.ts +18 -4
- package/validators/is-exists.validator.js +67 -6
- package/validators/is-unique.validator.d.ts +32 -5
- package/validators/is-unique.validator.js +99 -17
- package/validators/skip-empty.validator.d.ts +5 -0
- package/validators/skip-empty.validator.js +5 -0
- package/vault/interfaces/vault-options.interface.d.ts +9 -0
- package/vault/vault-config.loader.d.ts +30 -0
- package/vault/vault-config.loader.js +48 -1
- package/vault/vault-config.service.d.ts +53 -0
- package/vault/vault-config.service.js +57 -0
- package/vault/vault.module.d.ts +4 -0
- package/vault/vault.module.js +4 -0
- package/decorators/examples/validation-decorators.example.d.ts +0 -69
- package/decorators/examples/validation-decorators.example.js +0 -331
|
@@ -16,10 +16,6 @@ declare global {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
declare module 'typeorm' {
|
|
19
|
-
interface Repository<Entity extends ObjectLiteral> {
|
|
20
|
-
saveWithPk(this: Repository<Entity>, entity: Entity | Entity[]): Promise<Entity | Entity[]>;
|
|
21
|
-
getPrimaryKeyFields(this: Repository<Entity>): string[];
|
|
22
|
-
}
|
|
23
19
|
interface SelectQueryBuilder<Entity> {
|
|
24
20
|
searchByString(q: string, columnNames: string[], options?: {
|
|
25
21
|
formStart: boolean;
|
|
@@ -29,6 +25,91 @@ declare module 'typeorm' {
|
|
|
29
25
|
takeAll: boolean;
|
|
30
26
|
skipCount: boolean;
|
|
31
27
|
}>): Promise<[Entity[], PageMetaDto]>;
|
|
28
|
+
/**
|
|
29
|
+
* Paginate and automatically map entities to DTOs in a single call.
|
|
30
|
+
* This method combines paginate() and toPageDto() into one convenient method.
|
|
31
|
+
*
|
|
32
|
+
* @param pageOptionsDto Pagination options (page, pageSize, order, etc.)
|
|
33
|
+
* @param options Configuration options
|
|
34
|
+
* @param options.dtoOptions Options to pass to the toDto() method of each entity
|
|
35
|
+
* @param options.skipCount Skip counting total items (improves performance)
|
|
36
|
+
* @param options.takeAll Fetch all items without limit (ignores pageSize)
|
|
37
|
+
* @param options.transform Optional callback to transform items before mapping to DTOs (supports both sync and async)
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* Basic usage - automatically maps entities to DTOs:
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const queryBuilder = userRepository.createQueryBuilder('user');
|
|
43
|
+
* const pageDto = await queryBuilder.paginateAndMap(pageOptionsDto);
|
|
44
|
+
* return pageDto; // Returns PageDto<UserDto>
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* With toDto options:
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const queryBuilder = userRepository.createQueryBuilder('user');
|
|
51
|
+
* const pageDto = await queryBuilder.paginateAndMap(pageOptionsDto, {
|
|
52
|
+
* dtoOptions: { includeRelations: true }
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* With synchronous transform callback:
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const queryBuilder = orderRepository.createQueryBuilder('order');
|
|
60
|
+
* const pageDto = await queryBuilder.paginateAndMap(pageOptionsDto, {
|
|
61
|
+
* transform: (items) => items.filter(order => order.status === 'active')
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* With async transform callback for complex operations:
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const queryBuilder = orderRepository.createQueryBuilder('order');
|
|
69
|
+
* const pageDto = await queryBuilder.paginateAndMap(pageOptionsDto, {
|
|
70
|
+
* transform: async (items) => {
|
|
71
|
+
* // Perform async operations on items
|
|
72
|
+
* const enrichedItems = await Promise.all(
|
|
73
|
+
* items.map(async (order) => {
|
|
74
|
+
* order.additionalData = await externalService.getData(order.id);
|
|
75
|
+
* return order;
|
|
76
|
+
* })
|
|
77
|
+
* );
|
|
78
|
+
* return enrichedItems.filter(order => order.isValid);
|
|
79
|
+
* }
|
|
80
|
+
* });
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* Complete example with all options:
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const queryBuilder = productRepository
|
|
87
|
+
* .createQueryBuilder('product')
|
|
88
|
+
* .leftJoinAndSelect('product.category', 'category')
|
|
89
|
+
* .where('product.isActive = :isActive', { isActive: true });
|
|
90
|
+
*
|
|
91
|
+
* const pageDto = await queryBuilder.paginateAndMap(pageOptionsDto, {
|
|
92
|
+
* dtoOptions: { includeCategory: true },
|
|
93
|
+
* skipCount: false,
|
|
94
|
+
* transform: async (items) => {
|
|
95
|
+
* // Enrich products with external data
|
|
96
|
+
* const enrichedProducts = await Promise.all(
|
|
97
|
+
* items.map(async (product) => {
|
|
98
|
+
* product.reviews = await reviewService.getReviews(product.id);
|
|
99
|
+
* return product;
|
|
100
|
+
* })
|
|
101
|
+
* );
|
|
102
|
+
* // Filter out products with no stock
|
|
103
|
+
* return enrichedProducts.filter(product => product.stock > 0);
|
|
104
|
+
* }
|
|
105
|
+
* });
|
|
106
|
+
*
|
|
107
|
+
* // Returns PageDto<ProductDto> with enriched and filtered data
|
|
108
|
+
* return pageDto;
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @returns Promise resolving to PageDto with mapped DTOs
|
|
112
|
+
*/
|
|
32
113
|
paginateAndMap<Dto extends AbstractDto, DtoOptions = unknown>(this: SelectQueryBuilder<Entity>, pageOptionsDto: PageOptionsDto, options?: Partial<{
|
|
33
114
|
dtoOptions: DtoOptions;
|
|
34
115
|
skipCount: boolean;
|
|
@@ -39,9 +120,66 @@ declare module 'typeorm' {
|
|
|
39
120
|
leftJoin<AliasEntity extends AbstractEntity, A extends string>(this: SelectQueryBuilder<Entity>, property: `${A}.${Exclude<KeyOfType<AliasEntity, AbstractEntity>, symbol>}`, alias: string, condition?: string, parameters?: ObjectLiteral): this;
|
|
40
121
|
innerJoinAndSelect<AliasEntity extends AbstractEntity, A extends string>(this: SelectQueryBuilder<Entity>, property: `${A}.${Exclude<KeyOfType<AliasEntity, AbstractEntity>, symbol>}`, alias: string, condition?: string, parameters?: ObjectLiteral): this;
|
|
41
122
|
innerJoin<AliasEntity extends AbstractEntity, A extends string>(this: SelectQueryBuilder<Entity>, property: `${A}.${Exclude<KeyOfType<AliasEntity, AbstractEntity>, symbol>}`, alias: string, condition?: string, parameters?: ObjectLiteral): this;
|
|
123
|
+
/**
|
|
124
|
+
* Iterate over entity results in batches using async iteration.
|
|
125
|
+
*
|
|
126
|
+
* @param options.batchSize Number of entities to retrieve per batch (default: 1000)
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const queryBuilder = repository.createQueryBuilder('entity');
|
|
131
|
+
*
|
|
132
|
+
* for await (const batch of queryBuilder.iterate({ batchSize: 500 })) {
|
|
133
|
+
* console.log(`Processing batch of ${batch.length} entities`);
|
|
134
|
+
* // Process each batch of entities
|
|
135
|
+
* await processEntities(batch);
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @returns An async iterator that yields arrays of entities
|
|
140
|
+
*/
|
|
42
141
|
iterate(this: SelectQueryBuilder<Entity>, options?: {
|
|
43
142
|
batchSize?: number;
|
|
44
143
|
}): AsyncIterableIterator<Entity[]>;
|
|
144
|
+
/**
|
|
145
|
+
* Process entity results in batches by calling a callback function.
|
|
146
|
+
* The callback can accept either individual entities or batches of entities.
|
|
147
|
+
*
|
|
148
|
+
* @param callback Function to process each entity or batch of entities
|
|
149
|
+
* @param options
|
|
150
|
+
* @param options.batchSize Number of entities to retrieve per batch (default: 1000)
|
|
151
|
+
* @param options.mode Whether to pass entities individually or as batches to the callback (default: 'batch')
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* Processing individual entities:
|
|
155
|
+
* ```typescript
|
|
156
|
+
* const queryBuilder = repository.createQueryBuilder('entity');
|
|
157
|
+
*
|
|
158
|
+
* await queryBuilder.eachBatch(
|
|
159
|
+
* async (entity) => {
|
|
160
|
+
* // Process each individual entity
|
|
161
|
+
* console.log(`Processing entity: ${entity.id}`);
|
|
162
|
+
* await processEntity(entity);
|
|
163
|
+
* },
|
|
164
|
+
* { batchSize: 100, mode: 'single' }
|
|
165
|
+
* );
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* Processing batches of entities:
|
|
170
|
+
* ```typescript
|
|
171
|
+
* const queryBuilder = repository.createQueryBuilder('entity');
|
|
172
|
+
*
|
|
173
|
+
* await queryBuilder.eachBatch(
|
|
174
|
+
* async (batch) => {
|
|
175
|
+
* // Process each batch of entities
|
|
176
|
+
* console.log(`Processing batch of ${batch.length} entities`);
|
|
177
|
+
* await processEntities(batch);
|
|
178
|
+
* },
|
|
179
|
+
* { batchSize: 500, mode: 'batch' }
|
|
180
|
+
* );
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
45
183
|
eachBatch(this: SelectQueryBuilder<Entity>, callback: (item: Entity) => Promise<void> | void, options?: {
|
|
46
184
|
batchSize?: number;
|
|
47
185
|
mode?: 'single';
|
|
@@ -25,30 +25,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
require("source-map-support/register");
|
|
26
26
|
const lodash_1 = require("lodash");
|
|
27
27
|
const typeorm_1 = require("typeorm");
|
|
28
|
-
const typeorm_2 = require("typeorm");
|
|
29
28
|
const page_dto_1 = require("./dto/page.dto");
|
|
30
29
|
const page_meta_dto_1 = require("./dto/page-meta.dto");
|
|
31
30
|
const providers_1 = require("../providers");
|
|
32
31
|
Array.prototype.toDtos = function (options) {
|
|
33
32
|
return (0, lodash_1.compact)((0, lodash_1.map)(this, (item) => {
|
|
33
|
+
// Check if item exists and has toDto method
|
|
34
34
|
if (item && typeof item.toDto === 'function') {
|
|
35
35
|
return item.toDto(options);
|
|
36
36
|
}
|
|
37
|
+
// Skip items that don't have toDto method
|
|
37
38
|
return undefined;
|
|
38
39
|
}));
|
|
39
40
|
};
|
|
40
41
|
Array.prototype.getByLanguage = function (languageCode) {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
41
43
|
return this.find((translation) => languageCode === translation.languageCode)
|
|
42
44
|
.text;
|
|
43
45
|
};
|
|
44
46
|
Array.prototype.toPageDto = function (pageMetaDto, options) {
|
|
45
47
|
return new page_dto_1.PageDto(this.toDtos(options), pageMetaDto);
|
|
46
48
|
};
|
|
47
|
-
|
|
49
|
+
typeorm_1.SelectQueryBuilder.prototype.searchByString = function (q, columnNames, options) {
|
|
48
50
|
if (!q) {
|
|
49
51
|
return this;
|
|
50
52
|
}
|
|
51
|
-
this.andWhere(new
|
|
53
|
+
this.andWhere(new typeorm_1.Brackets((qb) => {
|
|
52
54
|
for (const item of columnNames) {
|
|
53
55
|
qb.orWhere(`${item} ILIKE :q`);
|
|
54
56
|
}
|
|
@@ -61,7 +63,7 @@ typeorm_2.SelectQueryBuilder.prototype.searchByString = function (q, columnNames
|
|
|
61
63
|
}
|
|
62
64
|
return this;
|
|
63
65
|
};
|
|
64
|
-
|
|
66
|
+
typeorm_1.SelectQueryBuilder.prototype.paginate = function (pageOptionsDto, options) {
|
|
65
67
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
68
|
if (!(options === null || options === void 0 ? void 0 : options.takeAll)) {
|
|
67
69
|
this.skip(pageOptionsDto.skip).take(pageOptionsDto.pageSize);
|
|
@@ -78,20 +80,26 @@ typeorm_2.SelectQueryBuilder.prototype.paginate = function (pageOptionsDto, opti
|
|
|
78
80
|
return [entities, pageMetaDto];
|
|
79
81
|
});
|
|
80
82
|
};
|
|
81
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Implementation of paginateAndMap
|
|
85
|
+
*/
|
|
86
|
+
typeorm_1.SelectQueryBuilder.prototype.paginateAndMap = function (pageOptionsDto, options) {
|
|
82
87
|
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
// Call paginate to get entities and meta
|
|
83
89
|
const [entities, pageMetaDto] = yield this.paginate(pageOptionsDto, {
|
|
84
90
|
skipCount: options === null || options === void 0 ? void 0 : options.skipCount,
|
|
85
91
|
takeAll: options === null || options === void 0 ? void 0 : options.takeAll,
|
|
86
92
|
});
|
|
93
|
+
// Apply transform if provided (support both sync and async)
|
|
87
94
|
let transformedEntities = entities;
|
|
88
95
|
if (options === null || options === void 0 ? void 0 : options.transform) {
|
|
89
96
|
transformedEntities = yield options.transform(entities);
|
|
90
97
|
}
|
|
98
|
+
// Convert to DTOs and return PageDto
|
|
91
99
|
return transformedEntities.toPageDto(pageMetaDto, options === null || options === void 0 ? void 0 : options.dtoOptions);
|
|
92
100
|
});
|
|
93
101
|
};
|
|
94
|
-
|
|
102
|
+
typeorm_1.SelectQueryBuilder.prototype.withTenant = function (tenantId, tenantFieldName = 'tenantId') {
|
|
95
103
|
var _a;
|
|
96
104
|
if (!tenantId) {
|
|
97
105
|
tenantId = providers_1.ContextProvider.getTenantId();
|
|
@@ -107,7 +115,10 @@ typeorm_2.SelectQueryBuilder.prototype.withTenant = function (tenantId, tenantFi
|
|
|
107
115
|
}
|
|
108
116
|
return this;
|
|
109
117
|
};
|
|
110
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Implementation for the async iterator method
|
|
120
|
+
*/
|
|
121
|
+
typeorm_1.SelectQueryBuilder.prototype.iterate = function (options) {
|
|
111
122
|
return __asyncGenerator(this, arguments, function* () {
|
|
112
123
|
const batchSize = (options === null || options === void 0 ? void 0 : options.batchSize) || 100;
|
|
113
124
|
let offset = 0;
|
|
@@ -125,7 +136,10 @@ typeorm_2.SelectQueryBuilder.prototype.iterate = function (options) {
|
|
|
125
136
|
}
|
|
126
137
|
});
|
|
127
138
|
};
|
|
128
|
-
|
|
139
|
+
/**
|
|
140
|
+
* Implementation for the callback-based iteration method
|
|
141
|
+
*/
|
|
142
|
+
typeorm_1.SelectQueryBuilder.prototype.eachBatch = function (callback, options) {
|
|
129
143
|
return __awaiter(this, void 0, void 0, function* () {
|
|
130
144
|
const batchSize = (options === null || options === void 0 ? void 0 : options.batchSize) || 100;
|
|
131
145
|
const mode = (options === null || options === void 0 ? void 0 : options.mode) || 'batch';
|
|
@@ -135,11 +149,13 @@ typeorm_2.SelectQueryBuilder.prototype.eachBatch = function (callback, options)
|
|
|
135
149
|
const batch = yield this.clone().skip(offset).take(batchSize).getMany();
|
|
136
150
|
if (batch.length > 0) {
|
|
137
151
|
if (mode === 'single') {
|
|
152
|
+
// Process each entity individually
|
|
138
153
|
for (const item of batch) {
|
|
139
154
|
yield callback(item);
|
|
140
155
|
}
|
|
141
156
|
}
|
|
142
157
|
else {
|
|
158
|
+
// Process the entire batch
|
|
143
159
|
yield callback(batch);
|
|
144
160
|
}
|
|
145
161
|
offset += batchSize;
|
|
@@ -151,95 +167,3 @@ typeorm_2.SelectQueryBuilder.prototype.eachBatch = function (callback, options)
|
|
|
151
167
|
}
|
|
152
168
|
});
|
|
153
169
|
};
|
|
154
|
-
const insertWithPk = function (entity) {
|
|
155
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
156
|
-
if (!this.metadata) {
|
|
157
|
-
throw new Error('Repository metadata is not available. Make sure the repository is properly initialized.');
|
|
158
|
-
}
|
|
159
|
-
const tableName = this.metadata.tableName;
|
|
160
|
-
const columns = this.metadata.columns;
|
|
161
|
-
const columnNames = [];
|
|
162
|
-
const columnValues = [];
|
|
163
|
-
const valuePlaceholders = [];
|
|
164
|
-
for (const column of columns) {
|
|
165
|
-
const propertyName = column.propertyName;
|
|
166
|
-
const value = entity[propertyName];
|
|
167
|
-
if (value === undefined) {
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
const columnName = column.databaseName;
|
|
171
|
-
if (columnName) {
|
|
172
|
-
columnNames.push(columnName);
|
|
173
|
-
columnValues.push(value);
|
|
174
|
-
valuePlaceholders.push(`?`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
const sql = `INSERT INTO ${tableName} (${columnNames.join(', ')}) VALUES (${valuePlaceholders.join(', ')})`;
|
|
178
|
-
try {
|
|
179
|
-
const result = yield this.query(sql, columnValues);
|
|
180
|
-
return result[0];
|
|
181
|
-
}
|
|
182
|
-
catch (error) {
|
|
183
|
-
console.warn(`Native SQL insert failed for ${tableName}, falling back to regular save:`, error);
|
|
184
|
-
return yield this.save(entity);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
};
|
|
188
|
-
typeorm_1.Repository.prototype.getPrimaryKeyFields = function () {
|
|
189
|
-
if (!this.metadata) {
|
|
190
|
-
throw new Error('Repository metadata is not available. Make sure the repository is properly initialized.');
|
|
191
|
-
}
|
|
192
|
-
const primaryKeys = this.metadata.primaryColumns;
|
|
193
|
-
if (!primaryKeys || primaryKeys.length === 0) {
|
|
194
|
-
throw new Error(`Entity ${this.metadata.targetName} does not have any primary key columns defined.`);
|
|
195
|
-
}
|
|
196
|
-
return primaryKeys.map(column => column.propertyName);
|
|
197
|
-
};
|
|
198
|
-
typeorm_1.Repository.prototype.saveWithPk = function (entity) {
|
|
199
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
const isArray = Array.isArray(entity);
|
|
201
|
-
const entities = isArray ? entity : [entity];
|
|
202
|
-
if (entities.length === 0) {
|
|
203
|
-
return isArray ? [] : null;
|
|
204
|
-
}
|
|
205
|
-
const pkFields = this.getPrimaryKeyFields();
|
|
206
|
-
const results = yield Promise.all(entities.map((singleEntity) => __awaiter(this, void 0, void 0, function* () {
|
|
207
|
-
const hasPkValues = pkFields.every(pkField => {
|
|
208
|
-
const value = singleEntity[pkField];
|
|
209
|
-
return value !== undefined && value !== null && value !== '';
|
|
210
|
-
});
|
|
211
|
-
if (hasPkValues) {
|
|
212
|
-
try {
|
|
213
|
-
const existingEntity = yield this.findOne({
|
|
214
|
-
where: pkFields.reduce((acc, pkField) => {
|
|
215
|
-
acc[pkField] = singleEntity[pkField];
|
|
216
|
-
return acc;
|
|
217
|
-
}, {})
|
|
218
|
-
});
|
|
219
|
-
if (existingEntity) {
|
|
220
|
-
yield this.update(pkFields.reduce((acc, pkField) => {
|
|
221
|
-
acc[pkField] = singleEntity[pkField];
|
|
222
|
-
return acc;
|
|
223
|
-
}, {}), singleEntity);
|
|
224
|
-
return yield this.findOne({
|
|
225
|
-
where: pkFields.reduce((acc, pkField) => {
|
|
226
|
-
acc[pkField] = singleEntity[pkField];
|
|
227
|
-
return acc;
|
|
228
|
-
}, {})
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
return yield insertWithPk.call(this, singleEntity);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
catch (error) {
|
|
236
|
-
return yield insertWithPk.call(this, singleEntity);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
return yield this.save(singleEntity);
|
|
241
|
-
}
|
|
242
|
-
})));
|
|
243
|
-
return isArray ? results : results[0];
|
|
244
|
-
});
|
|
245
|
-
};
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DTO容器 - 类似class-validator的useContainer机制
|
|
3
|
+
* 全局存储服务容器,供DTO转换时使用
|
|
4
|
+
*/
|
|
1
5
|
export declare class DtoContainer {
|
|
2
6
|
private static instance;
|
|
3
7
|
private container;
|
|
4
8
|
static getInstance(): DtoContainer;
|
|
9
|
+
/**
|
|
10
|
+
* 设置容器 - 类似useContainer
|
|
11
|
+
*/
|
|
5
12
|
static useContainer(container: any): void;
|
|
13
|
+
/**
|
|
14
|
+
* 获取服务实例
|
|
15
|
+
*/
|
|
6
16
|
static get<T = any>(serviceToken: string | symbol | any): Promise<T | null>;
|
|
17
|
+
/**
|
|
18
|
+
* 检查容器是否已初始化
|
|
19
|
+
*/
|
|
7
20
|
static isInitialized(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* 重置容器 (主要用于测试)
|
|
23
|
+
*/
|
|
8
24
|
static reset(): void;
|
|
9
25
|
}
|
|
@@ -10,6 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.DtoContainer = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* DTO容器 - 类似class-validator的useContainer机制
|
|
15
|
+
* 全局存储服务容器,供DTO转换时使用
|
|
16
|
+
*/
|
|
13
17
|
class DtoContainer {
|
|
14
18
|
constructor() {
|
|
15
19
|
this.container = null;
|
|
@@ -20,9 +24,15 @@ class DtoContainer {
|
|
|
20
24
|
}
|
|
21
25
|
return DtoContainer.instance;
|
|
22
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* 设置容器 - 类似useContainer
|
|
29
|
+
*/
|
|
23
30
|
static useContainer(container) {
|
|
24
31
|
DtoContainer.getInstance().container = container;
|
|
25
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* 获取服务实例
|
|
35
|
+
*/
|
|
26
36
|
static get(serviceToken) {
|
|
27
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
28
38
|
const instance = DtoContainer.getInstance();
|
|
@@ -31,13 +41,17 @@ class DtoContainer {
|
|
|
31
41
|
return null;
|
|
32
42
|
}
|
|
33
43
|
try {
|
|
44
|
+
// 支持多种容器类型
|
|
34
45
|
if (typeof instance.container.get === 'function') {
|
|
46
|
+
// NestJS容器
|
|
35
47
|
return yield instance.container.get(serviceToken);
|
|
36
48
|
}
|
|
37
49
|
else if (typeof instance.container.resolve === 'function') {
|
|
50
|
+
// ModuleRef
|
|
38
51
|
return yield instance.container.resolve(serviceToken);
|
|
39
52
|
}
|
|
40
53
|
else if (typeof instance.container[serviceToken] === 'function') {
|
|
54
|
+
// 直接的服务实例
|
|
41
55
|
return instance.container[serviceToken];
|
|
42
56
|
}
|
|
43
57
|
console.warn(`Unable to resolve service: ${String(serviceToken)}`);
|
|
@@ -49,9 +63,15 @@ class DtoContainer {
|
|
|
49
63
|
}
|
|
50
64
|
});
|
|
51
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* 检查容器是否已初始化
|
|
68
|
+
*/
|
|
52
69
|
static isInitialized() {
|
|
53
70
|
return DtoContainer.getInstance().container !== null;
|
|
54
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* 重置容器 (主要用于测试)
|
|
74
|
+
*/
|
|
55
75
|
static reset() {
|
|
56
76
|
DtoContainer.getInstance().container = null;
|
|
57
77
|
}
|
|
@@ -1,18 +1,36 @@
|
|
|
1
1
|
import { Constructor } from '../types';
|
|
2
2
|
import { TransformFnParams } from 'class-transformer';
|
|
3
|
+
/**
|
|
4
|
+
* 扩展的TransformFnParams,包含context
|
|
5
|
+
*/
|
|
3
6
|
export interface ExtendedTransformFnParams extends TransformFnParams {
|
|
4
7
|
context?: any;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* DTO服务装饰器 - 标记可以在DTO中使用的服务
|
|
11
|
+
*/
|
|
6
12
|
export declare const DTO_SERVICE_KEY = "dto:service-name";
|
|
7
13
|
export declare function DtoService(serviceName?: string): ClassDecorator;
|
|
14
|
+
/**
|
|
15
|
+
* 使用服务装饰器 - 在DTO类中声明需要的服务
|
|
16
|
+
*/
|
|
8
17
|
export declare const DTO_REQUIRED_SERVICES_KEY = "dto:required-services";
|
|
9
18
|
export declare function UseServices(...serviceTokens: Array<string | Constructor<any>>): ClassDecorator;
|
|
19
|
+
/**
|
|
20
|
+
* DTO类装饰器 - 标记这是一个DTO类并关联到Entity
|
|
21
|
+
*/
|
|
10
22
|
export declare const DTO_ENTITY_KEY = "dto:entity";
|
|
11
23
|
export declare function Dto(entityClass: Constructor<any>): ClassDecorator;
|
|
24
|
+
/**
|
|
25
|
+
* DTO字段装饰器 - 类似@Column,用于DTO类
|
|
26
|
+
*/
|
|
12
27
|
export interface DtoFieldOptions {
|
|
13
28
|
source?: string;
|
|
14
29
|
transform?: (value: any) => any;
|
|
15
30
|
}
|
|
16
31
|
export declare function DtoField(source?: string, transform?: (value: any) => any): PropertyDecorator;
|
|
17
32
|
export declare function DtoField(options?: DtoFieldOptions): PropertyDecorator;
|
|
33
|
+
/**
|
|
34
|
+
* DTO计算字段装饰器 - 用于需要计算的复杂字段
|
|
35
|
+
*/
|
|
18
36
|
export declare function DtoComputed(computeFn: (entity: any, context?: any) => any): PropertyDecorator;
|
|
@@ -7,6 +7,9 @@ exports.Dto = Dto;
|
|
|
7
7
|
exports.DtoField = DtoField;
|
|
8
8
|
exports.DtoComputed = DtoComputed;
|
|
9
9
|
const common_1 = require("@nestjs/common");
|
|
10
|
+
/**
|
|
11
|
+
* DTO服务装饰器 - 标记可以在DTO中使用的服务
|
|
12
|
+
*/
|
|
10
13
|
exports.DTO_SERVICE_KEY = 'dto:service-name';
|
|
11
14
|
function DtoService(serviceName) {
|
|
12
15
|
return function (target) {
|
|
@@ -14,18 +17,26 @@ function DtoService(serviceName) {
|
|
|
14
17
|
(0, common_1.SetMetadata)(exports.DTO_SERVICE_KEY, name)(target);
|
|
15
18
|
};
|
|
16
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* 使用服务装饰器 - 在DTO类中声明需要的服务
|
|
22
|
+
*/
|
|
17
23
|
exports.DTO_REQUIRED_SERVICES_KEY = 'dto:required-services';
|
|
18
24
|
function UseServices(...serviceTokens) {
|
|
19
25
|
return function (target) {
|
|
26
|
+
// 将Constructor转换为服务名
|
|
20
27
|
const tokens = serviceTokens.map(token => {
|
|
21
28
|
if (typeof token === 'string') {
|
|
22
29
|
return token;
|
|
23
30
|
}
|
|
31
|
+
// 假设服务名就是类名的小写版本
|
|
24
32
|
return token.name.charAt(0).toLowerCase() + token.name.slice(1);
|
|
25
33
|
});
|
|
26
34
|
(0, common_1.SetMetadata)(exports.DTO_REQUIRED_SERVICES_KEY, tokens)(target);
|
|
27
35
|
};
|
|
28
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* DTO类装饰器 - 标记这是一个DTO类并关联到Entity
|
|
39
|
+
*/
|
|
29
40
|
exports.DTO_ENTITY_KEY = 'dto:entity';
|
|
30
41
|
function Dto(entityClass) {
|
|
31
42
|
return function (target) {
|
|
@@ -46,6 +57,9 @@ function DtoField(sourceOrOptions, transform) {
|
|
|
46
57
|
Reflect.defineMetadata('dto:fields', fields, target.constructor);
|
|
47
58
|
};
|
|
48
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* DTO计算字段装饰器 - 用于需要计算的复杂字段
|
|
62
|
+
*/
|
|
49
63
|
function DtoComputed(computeFn) {
|
|
50
64
|
return function (target, propertyKey) {
|
|
51
65
|
const fields = Reflect.getMetadata('dto:fields', target.constructor) || [];
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { Constructor } from '../types';
|
|
2
2
|
declare global {
|
|
3
3
|
interface Array<T> {
|
|
4
|
+
/**
|
|
5
|
+
* 将实体数组转换为DTO数组
|
|
6
|
+
* @param dtoClass DTO类
|
|
7
|
+
* @param context 转换上下文
|
|
8
|
+
*/
|
|
4
9
|
toDto<DtoType>(dtoClass: Constructor<DtoType>, context?: any): Promise<DtoType[]>;
|
|
5
10
|
}
|
|
6
11
|
}
|
|
7
12
|
declare module 'typeorm' {
|
|
8
13
|
interface SelectQueryBuilder<Entity> {
|
|
14
|
+
/**
|
|
15
|
+
* 执行分页查询并转换为DTO页面
|
|
16
|
+
* @param pageOptionsDto 分页选项
|
|
17
|
+
* @param dtoClass DTO类
|
|
18
|
+
* @param context 转换上下文
|
|
19
|
+
*/
|
|
9
20
|
toDtoPage<DtoType>(pageOptionsDto: any, dtoClass: Constructor<DtoType>, context?: any): Promise<any>;
|
|
10
21
|
}
|
|
11
22
|
}
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.transformEntityToDto = transformEntityToDto;
|
|
13
13
|
const typeorm_1 = require("typeorm");
|
|
14
14
|
const dto_transformer_1 = require("./dto-transformer");
|
|
15
|
+
// 实现Array.toDto方法
|
|
15
16
|
Array.prototype.toDto = function (dtoClass, context) {
|
|
16
17
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17
18
|
if (!this || this.length === 0) {
|
|
@@ -20,6 +21,7 @@ Array.prototype.toDto = function (dtoClass, context) {
|
|
|
20
21
|
return yield dto_transformer_1.DtoTransformer.transformArray(this, dtoClass, context);
|
|
21
22
|
});
|
|
22
23
|
};
|
|
24
|
+
// 避免直接修改Object原型,改为使用独立的函数
|
|
23
25
|
function transformEntityToDto(entity, dtoClass, context) {
|
|
24
26
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
27
|
if (!entity) {
|
|
@@ -28,21 +30,28 @@ function transformEntityToDto(entity, dtoClass, context) {
|
|
|
28
30
|
return yield dto_transformer_1.DtoTransformer.transform(entity, dtoClass, context);
|
|
29
31
|
});
|
|
30
32
|
}
|
|
33
|
+
// 实现QueryBuilder.toDtoPage方法
|
|
31
34
|
typeorm_1.SelectQueryBuilder.prototype.toDtoPage = function (pageOptionsDto, dtoClass, context) {
|
|
32
35
|
return __awaiter(this, void 0, void 0, function* () {
|
|
33
36
|
const page = pageOptionsDto.page || 1;
|
|
34
37
|
const pageSize = pageOptionsDto.pageSize || 10;
|
|
35
38
|
const skip = (page - 1) * pageSize;
|
|
39
|
+
// 获取总数
|
|
36
40
|
const total = yield this.getCount();
|
|
41
|
+
// 应用分页
|
|
37
42
|
const entities = yield this.skip(skip).take(pageSize).getMany();
|
|
38
43
|
const count = entities.length;
|
|
44
|
+
// 调试:输出原始实体数据
|
|
39
45
|
if (count) {
|
|
40
46
|
console.log('Raw entity sample:', JSON.stringify(entities[0], null, 2));
|
|
41
47
|
}
|
|
48
|
+
// 转换为DTO
|
|
42
49
|
const data = yield entities.toDto(dtoClass, context);
|
|
50
|
+
// 调试:输出转换后的DTO数据
|
|
43
51
|
if (data.length > 0) {
|
|
44
52
|
console.log('Converted DTO sample:', JSON.stringify(data[0], null, 2));
|
|
45
53
|
}
|
|
54
|
+
// 计算分页信息
|
|
46
55
|
const pageCount = Math.ceil(total / pageSize);
|
|
47
56
|
const hasPreviousPage = page > 1;
|
|
48
57
|
const hasNextPage = page < pageCount;
|
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import { Constructor } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* DTO服务访问器 - 使用全局容器获取服务
|
|
4
|
+
* 类似class-validator的useContainer机制
|
|
5
|
+
*/
|
|
2
6
|
export declare class DtoServiceAccessor {
|
|
7
|
+
/**
|
|
8
|
+
* 获取服务实例
|
|
9
|
+
*/
|
|
3
10
|
static getService<T = any>(serviceToken: string | symbol | Constructor<any>): Promise<T | null>;
|
|
11
|
+
/**
|
|
12
|
+
* 批量获取服务
|
|
13
|
+
*/
|
|
4
14
|
static getServices<T = any>(serviceTokens: Array<string | symbol | Constructor<any>>): Promise<Record<string, T>>;
|
|
15
|
+
/**
|
|
16
|
+
* 为特定DTO类获取所需服务
|
|
17
|
+
* 基于预定义的服务依赖列表
|
|
18
|
+
*/
|
|
5
19
|
static getServicesForDto(dtoClass: Constructor<any>): Promise<Record<string, any>>;
|
|
20
|
+
/**
|
|
21
|
+
* 检查是否已初始化
|
|
22
|
+
*/
|
|
6
23
|
static isInitialized(): boolean;
|
|
7
24
|
}
|