@nest-omni/core 4.1.3-12 → 4.1.3-14

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 (72) hide show
  1. package/cache/dependencies/db.dependency.d.ts +55 -6
  2. package/cache/dependencies/db.dependency.js +64 -13
  3. package/common/boilerplate.polyfill.js +1 -1
  4. package/file-upload/decorators/column.decorator.d.ts +151 -0
  5. package/file-upload/decorators/column.decorator.js +273 -0
  6. package/file-upload/decorators/csv-data.decorator.d.ts +17 -31
  7. package/file-upload/decorators/csv-data.decorator.js +45 -91
  8. package/file-upload/decorators/csv-import.decorator.d.ts +34 -0
  9. package/file-upload/decorators/csv-import.decorator.js +24 -0
  10. package/file-upload/decorators/examples/column-mapping.example.d.ts +76 -0
  11. package/file-upload/decorators/examples/column-mapping.example.js +122 -0
  12. package/file-upload/decorators/excel-data.decorator.d.ts +15 -29
  13. package/file-upload/decorators/excel-data.decorator.js +42 -82
  14. package/file-upload/decorators/index.d.ts +3 -2
  15. package/file-upload/decorators/index.js +20 -2
  16. package/file-upload/decorators/validate-data.decorator.d.ts +91 -0
  17. package/file-upload/decorators/validate-data.decorator.js +39 -0
  18. package/file-upload/dto/update-file.dto.d.ts +0 -1
  19. package/file-upload/dto/update-file.dto.js +0 -4
  20. package/file-upload/entities/file-metadata.entity.d.ts +6 -3
  21. package/file-upload/entities/file-metadata.entity.js +2 -10
  22. package/file-upload/entities/file.entity.d.ts +3 -18
  23. package/file-upload/entities/file.entity.js +0 -34
  24. package/file-upload/file-upload.module.d.ts +1 -1
  25. package/file-upload/file-upload.module.js +44 -16
  26. package/file-upload/index.d.ts +13 -2
  27. package/file-upload/index.js +21 -3
  28. package/file-upload/interceptors/file-upload.interceptor.d.ts +61 -8
  29. package/file-upload/interceptors/file-upload.interceptor.js +417 -257
  30. package/file-upload/interfaces/file-processor.interface.d.ts +93 -0
  31. package/file-upload/interfaces/file-processor.interface.js +2 -0
  32. package/file-upload/interfaces/file-upload-options.interface.d.ts +3 -46
  33. package/file-upload/interfaces/file-upload-options.interface.js +3 -0
  34. package/file-upload/interfaces/processor-options.interface.d.ts +102 -0
  35. package/file-upload/interfaces/processor-options.interface.js +2 -0
  36. package/file-upload/processors/csv.processor.d.ts +98 -0
  37. package/file-upload/processors/csv.processor.js +391 -0
  38. package/file-upload/processors/excel.processor.d.ts +130 -0
  39. package/file-upload/processors/excel.processor.js +547 -0
  40. package/file-upload/processors/image.processor.d.ts +199 -0
  41. package/file-upload/processors/image.processor.js +377 -0
  42. package/file-upload/services/file.service.d.ts +3 -0
  43. package/file-upload/services/file.service.js +39 -10
  44. package/file-upload/services/malicious-file-detector.service.d.ts +29 -3
  45. package/file-upload/services/malicious-file-detector.service.js +256 -57
  46. package/file-upload/utils/dynamic-import.util.d.ts +6 -2
  47. package/file-upload/utils/dynamic-import.util.js +17 -5
  48. package/http-client/decorators/http-client.decorators.d.ts +4 -2
  49. package/http-client/decorators/http-client.decorators.js +2 -1
  50. package/http-client/entities/http-log.entity.js +1 -9
  51. package/http-client/examples/proxy-from-environment.example.d.ts +133 -0
  52. package/http-client/examples/proxy-from-environment.example.js +410 -0
  53. package/http-client/http-client.module.js +65 -6
  54. package/http-client/interfaces/http-client-config.interface.d.ts +6 -0
  55. package/http-client/services/http-client.service.d.ts +8 -0
  56. package/http-client/services/http-client.service.js +61 -17
  57. package/http-client/services/logging.service.d.ts +1 -1
  58. package/http-client/services/logging.service.js +74 -58
  59. package/http-client/utils/index.d.ts +1 -0
  60. package/http-client/utils/index.js +1 -0
  61. package/http-client/utils/proxy-environment.util.d.ts +42 -0
  62. package/http-client/utils/proxy-environment.util.js +148 -0
  63. package/package.json +9 -5
  64. package/shared/service-registry.module.js +18 -0
  65. package/transaction/data-source.util.d.ts +142 -0
  66. package/transaction/data-source.util.js +330 -0
  67. package/transaction/index.d.ts +1 -0
  68. package/transaction/index.js +12 -1
  69. package/validators/is-exists.validator.d.ts +19 -2
  70. package/validators/is-exists.validator.js +27 -2
  71. package/validators/is-unique.validator.d.ts +12 -1
  72. package/validators/is-unique.validator.js +26 -1
@@ -1,44 +1,30 @@
1
- import { CsvDataOptions } from '../interfaces/file-upload-options.interface';
1
+ import 'reflect-metadata';
2
2
  /**
3
- * CSV 列映射元数据键
4
- */
5
- export declare const CSV_COLUMN_METADATA = "csv:column";
6
- /**
7
- * CSV 列名映射装饰器
3
+ * CSV 列映射装饰器
4
+ * 用于标记 DTO 类的属性对应的 CSV 列名
5
+ *
8
6
  * @example
9
7
  * ```typescript
10
- * export class OrderImportDto {
11
- * @CsvColumn('订单号')
12
- * @IsString()
13
- * orderNo: string;
8
+ * class UserDto {
9
+ * @CsvColumn('姓名')
10
+ * name: string;
11
+ *
12
+ * @CsvColumn('邮箱')
13
+ * email: string;
14
14
  * }
15
15
  * ```
16
16
  */
17
17
  export declare function CsvColumn(columnName: string): PropertyDecorator;
18
18
  /**
19
- * CSV 数据参数装饰器
20
- * @example
21
- * ```typescript
22
- * @Post('import/csv')
23
- * @FileUpload({ types: [FileType.CSV] })
24
- * async importCsv(@CsvData(OrderImportDto) orders: OrderImportDto[]) {
25
- * await this.orderService.batchCreate(orders);
26
- * return { count: orders.length };
27
- * }
28
- * ```
29
- */
30
- export declare const CsvData: (...dataOrPipes: (import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>> | {
31
- dto: any;
32
- options?: CsvDataOptions;
33
- })[]) => ParameterDecorator;
34
- /**
35
- * 辅助函数:获取 DTO 的 CSV 列映射
19
+ * 获取 CSV 列映射
36
20
  */
37
- export declare function getCsvColumnMapping(dto: any): Map<string, string>;
21
+ export declare function getCsvColumnMapping(dto: any): Record<string, string>;
38
22
  /**
39
- * 辅助函数:解析和验证 CSV 数据
23
+ * 解析并验证 CSV 数据
40
24
  */
41
- export declare function parseAndValidateCsvData<T extends object>(rawData: any[], dtoClass: new () => T, options?: CsvDataOptions): Promise<{
42
- data: T[];
25
+ export declare function parseAndValidateCsvData(data: any[], dto: any, options?: {
26
+ skipValidation?: boolean;
27
+ }): Promise<{
28
+ data: any[];
43
29
  errors: any[];
44
30
  }>;
@@ -9,123 +9,77 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.CsvData = exports.CSV_COLUMN_METADATA = void 0;
13
12
  exports.CsvColumn = CsvColumn;
14
13
  exports.getCsvColumnMapping = getCsvColumnMapping;
15
14
  exports.parseAndValidateCsvData = parseAndValidateCsvData;
16
- const common_1 = require("@nestjs/common");
15
+ require("reflect-metadata");
17
16
  const class_transformer_1 = require("class-transformer");
18
17
  const class_validator_1 = require("class-validator");
18
+ const CSV_COLUMN_METADATA_KEY = Symbol('csv:column');
19
19
  /**
20
- * CSV 列映射元数据键
21
- */
22
- exports.CSV_COLUMN_METADATA = 'csv:column';
23
- /**
24
- * CSV 列名映射装饰器
20
+ * CSV 列映射装饰器
21
+ * 用于标记 DTO 类的属性对应的 CSV 列名
22
+ *
25
23
  * @example
26
24
  * ```typescript
27
- * export class OrderImportDto {
28
- * @CsvColumn('订单号')
29
- * @IsString()
30
- * orderNo: string;
25
+ * class UserDto {
26
+ * @CsvColumn('姓名')
27
+ * name: string;
28
+ *
29
+ * @CsvColumn('邮箱')
30
+ * email: string;
31
31
  * }
32
32
  * ```
33
33
  */
34
34
  function CsvColumn(columnName) {
35
35
  return (target, propertyKey) => {
36
- Reflect.defineMetadata(exports.CSV_COLUMN_METADATA, columnName, target, propertyKey);
36
+ const existingColumns = Reflect.getMetadata(CSV_COLUMN_METADATA_KEY, target.constructor) || {};
37
+ existingColumns[columnName] = propertyKey;
38
+ Reflect.defineMetadata(CSV_COLUMN_METADATA_KEY, existingColumns, target.constructor);
37
39
  };
38
40
  }
39
41
  /**
40
- * CSV 数据参数装饰器
41
- * @example
42
- * ```typescript
43
- * @Post('import/csv')
44
- * @FileUpload({ types: [FileType.CSV] })
45
- * async importCsv(@CsvData(OrderImportDto) orders: OrderImportDto[]) {
46
- * await this.orderService.batchCreate(orders);
47
- * return { count: orders.length };
48
- * }
49
- * ```
50
- */
51
- exports.CsvData = (0, common_1.createParamDecorator)((data, ctx) => __awaiter(void 0, void 0, void 0, function* () {
52
- const request = ctx.switchToHttp().getRequest();
53
- const file = request.file;
54
- if (!file) {
55
- throw new Error('No file uploaded');
56
- }
57
- // 这里将在 interceptor 中处理 CSV 解析
58
- // 当前只返回文件信息,实际解析逻辑在 FileUploadInterceptor 中
59
- return {
60
- _csvData: true,
61
- dto: data,
62
- file,
63
- options: data === null || data === void 0 ? void 0 : data['options'],
64
- };
65
- }));
66
- /**
67
- * 辅助函数:获取 DTO 的 CSV 列映射
42
+ * 获取 CSV 列映射
68
43
  */
69
44
  function getCsvColumnMapping(dto) {
70
- const mapping = new Map();
71
- const prototype = dto.prototype;
72
- if (!prototype) {
73
- return mapping;
74
- }
75
- const propertyKeys = Object.getOwnPropertyNames(prototype);
76
- for (const propertyKey of propertyKeys) {
77
- const columnName = Reflect.getMetadata(exports.CSV_COLUMN_METADATA, prototype, propertyKey);
78
- if (columnName) {
79
- mapping.set(columnName, propertyKey);
80
- }
81
- }
82
- return mapping;
45
+ return Reflect.getMetadata(CSV_COLUMN_METADATA_KEY, dto) || {};
83
46
  }
84
47
  /**
85
- * 辅助函数:解析和验证 CSV 数据
48
+ * 解析并验证 CSV 数据
86
49
  */
87
- function parseAndValidateCsvData(rawData_1, dtoClass_1) {
88
- return __awaiter(this, arguments, void 0, function* (rawData, dtoClass, options = {}) {
89
- const { skipEmptyLines = true, skipHeader = false } = options;
90
- const data = [];
50
+ function parseAndValidateCsvData(data, dto, options) {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ const columnMapping = getCsvColumnMapping(dto);
53
+ const results = [];
91
54
  const errors = [];
92
- const mapping = getCsvColumnMapping(dtoClass);
93
- const startIndex = skipHeader ? 1 : 0;
94
- for (let i = startIndex; i < rawData.length; i++) {
95
- const row = rawData[i];
96
- // 跳过空行
97
- if (skipEmptyLines && isEmptyRow(row)) {
98
- continue;
99
- }
100
- const obj = {};
101
- // 映射列名到属性名
102
- for (const [columnName, propertyKey] of mapping.entries()) {
103
- obj[propertyKey] = row[columnName];
55
+ for (let i = 0; i < data.length; i++) {
56
+ const row = data[i];
57
+ const mappedData = {};
58
+ // 映射列名
59
+ for (const [csvColumn, dtoProperty] of Object.entries(columnMapping)) {
60
+ if (row.hasOwnProperty(csvColumn)) {
61
+ mappedData[dtoProperty] = row[csvColumn];
62
+ }
104
63
  }
105
64
  // 转换为 DTO 实例
106
- const instance = (0, class_transformer_1.plainToInstance)(dtoClass, obj);
65
+ const instance = (0, class_transformer_1.plainToInstance)(dto, mappedData);
107
66
  // 验证
108
- const validationErrors = yield (0, class_validator_1.validate)(instance);
109
- if (validationErrors.length > 0) {
110
- errors.push({
111
- row: i + 1,
112
- data: obj,
113
- errors: validationErrors,
114
- });
115
- }
116
- else {
117
- data.push(instance);
67
+ if (!(options === null || options === void 0 ? void 0 : options.skipValidation)) {
68
+ const validationErrors = yield (0, class_validator_1.validate)(instance);
69
+ if (validationErrors.length > 0) {
70
+ errors.push({
71
+ row: i + 1,
72
+ data: row,
73
+ errors: validationErrors.map((e) => ({
74
+ property: e.property,
75
+ constraints: e.constraints,
76
+ })),
77
+ });
78
+ continue;
79
+ }
118
80
  }
81
+ results.push(instance);
119
82
  }
120
- return { data, errors };
83
+ return { data: results, errors };
121
84
  });
122
85
  }
123
- /**
124
- * 检查是否为空行
125
- */
126
- function isEmptyRow(row) {
127
- if (!row)
128
- return true;
129
- const values = Object.values(row);
130
- return values.every((val) => !val || String(val).trim() === '');
131
- }
@@ -0,0 +1,34 @@
1
+ import { CsvProcessorOptions } from '../processors/csv.processor';
2
+ import { ValidateDataOptions } from './validate-data.decorator';
3
+ /**
4
+ * CSV 处理装饰器元数据键
5
+ */
6
+ export declare const CSV_PROCESS_KEY = "csv:process";
7
+ /**
8
+ * CSV 数据处理选项
9
+ */
10
+ export interface CsvDataOptions extends CsvProcessorOptions {
11
+ /** 验证类(使用 class-validator) */
12
+ validateClass?: any;
13
+ /** 验证选项 */
14
+ validation?: ValidateDataOptions;
15
+ /** 批处理大小 */
16
+ batchSize?: number;
17
+ /** 是否异步处理 */
18
+ async?: boolean;
19
+ }
20
+ /**
21
+ * CSV 数据处理装饰器
22
+ * 用于标记方法处理 CSV 文件数据
23
+ */
24
+ export declare const CsvData: (options?: CsvDataOptions) => import("@nestjs/common").CustomDecorator<string>;
25
+ /**
26
+ * CSV 批量导入装饰器
27
+ * 专门用于批量导入场景
28
+ */
29
+ export declare const CsvImport: (validateClass: any, options?: Omit<CsvDataOptions, "validateClass"> & {
30
+ /** 目标服务名 */
31
+ service?: string;
32
+ /** 目标方法名 */
33
+ method?: string;
34
+ }) => import("@nestjs/common").CustomDecorator<string>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CsvImport = exports.CsvData = exports.CSV_PROCESS_KEY = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ /**
6
+ * CSV 处理装饰器元数据键
7
+ */
8
+ exports.CSV_PROCESS_KEY = 'csv:process';
9
+ /**
10
+ * CSV 数据处理装饰器
11
+ * 用于标记方法处理 CSV 文件数据
12
+ */
13
+ const CsvData = (options = {}) => {
14
+ return (0, common_1.SetMetadata)(exports.CSV_PROCESS_KEY, options);
15
+ };
16
+ exports.CsvData = CsvData;
17
+ /**
18
+ * CSV 批量导入装饰器
19
+ * 专门用于批量导入场景
20
+ */
21
+ const CsvImport = (validateClass, options = {}) => {
22
+ return (0, common_1.SetMetadata)(exports.CSV_PROCESS_KEY, Object.assign(Object.assign({}, options), { validateClass, type: 'import' }));
23
+ };
24
+ exports.CsvImport = CsvImport;
@@ -0,0 +1,76 @@
1
+ /**
2
+ * 用户导入DTO示例
3
+ * 展示如何使用列序号、列名和Excel列名进行映射
4
+ */
5
+ export declare class UserImportDto {
6
+ /**
7
+ * 使用列名映射(推荐,更易读)
8
+ * CSV: 通过表头"姓名"找到列
9
+ * Excel: 通过表头"姓名"或列名"A"找到列
10
+ */
11
+ name: string;
12
+ /**
13
+ * 使用列序号映射(从0开始)
14
+ * CSV: 第2列(索引为1)
15
+ * Excel: 第2列(B列)
16
+ */
17
+ age: number;
18
+ /**
19
+ * 使用Excel列名映射
20
+ * CSV: 如果没有表头,需要使用数字索引
21
+ * Excel: 可以直接使用列名"C"
22
+ */
23
+ email: string;
24
+ /**
25
+ * 混合使用不同的映射方式
26
+ */
27
+ phone?: string;
28
+ /**
29
+ * 使用较大的列索引
30
+ */
31
+ address?: string;
32
+ /**
33
+ * 使用更大的Excel列名(如AA, AB等)
34
+ */
35
+ notes?: string;
36
+ }
37
+ /**
38
+ * 产品导入DTO示例
39
+ */
40
+ export declare class ProductImportDto {
41
+ /**
42
+ * 产品名称 - 第1列
43
+ */
44
+ name: string;
45
+ /**
46
+ * 价格 - 第2列
47
+ */
48
+ price: number;
49
+ /**
50
+ * 库存 - 第3列
51
+ */
52
+ stock: number;
53
+ /**
54
+ * 描述 - 第4列(可选)
55
+ */
56
+ description?: string;
57
+ }
58
+ /**
59
+ * 使用说明:
60
+ *
61
+ * 1. CSV文件:
62
+ * - 如果CSV有表头,建议使用列名(如 @CSVColumn('姓名'))
63
+ * - 如果CSV没有表头,使用数字索引(如 @CSVColumn(0) 表示第1列)
64
+ *
65
+ * 2. Excel文件:
66
+ * - 可以使用列名(如 @ExcelColumn('姓名'))
67
+ * - 可以使用数字索引(如 @ExcelColumn(0) 表示第1列)
68
+ * - 可以使用Excel列名(如 @ExcelColumn('A') 表示A列)
69
+ * - 数字索引会自动转换为对应的Excel列名(0 -> A, 1 -> B, 26 -> AA)
70
+ *
71
+ * 3. 最佳实践:
72
+ * - 优先使用列名,代码更易读
73
+ * - 对于无表头的CSV文件,使用数字索引
74
+ * - 对于Excel文件,推荐使用Excel列名(A, B, C)或数字索引
75
+ * - 可以混合使用不同的映射方式
76
+ */
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ProductImportDto = exports.UserImportDto = void 0;
13
+ const column_decorator_1 = require("../column.decorator");
14
+ const class_validator_1 = require("class-validator");
15
+ /**
16
+ * 用户导入DTO示例
17
+ * 展示如何使用列序号、列名和Excel列名进行映射
18
+ */
19
+ class UserImportDto {
20
+ }
21
+ exports.UserImportDto = UserImportDto;
22
+ __decorate([
23
+ (0, column_decorator_1.CSVColumn)('姓名'),
24
+ (0, column_decorator_1.ExcelColumn)('姓名'),
25
+ (0, class_validator_1.IsString)(),
26
+ __metadata("design:type", String)
27
+ ], UserImportDto.prototype, "name", void 0);
28
+ __decorate([
29
+ (0, column_decorator_1.CSVColumn)(1),
30
+ (0, column_decorator_1.ExcelColumn)(1),
31
+ (0, class_validator_1.IsNumber)(),
32
+ (0, class_validator_1.Min)(0),
33
+ (0, class_validator_1.Max)(150),
34
+ __metadata("design:type", Number)
35
+ ], UserImportDto.prototype, "age", void 0);
36
+ __decorate([
37
+ (0, column_decorator_1.CSVColumn)(2) // CSV使用数字索引
38
+ ,
39
+ (0, column_decorator_1.ExcelColumn)('C') // Excel使用列名
40
+ ,
41
+ (0, class_validator_1.IsEmail)(),
42
+ __metadata("design:type", String)
43
+ ], UserImportDto.prototype, "email", void 0);
44
+ __decorate([
45
+ (0, column_decorator_1.CSVColumn)('电话') // CSV使用列名
46
+ ,
47
+ (0, column_decorator_1.ExcelColumn)('D') // Excel使用列名
48
+ ,
49
+ (0, class_validator_1.IsOptional)(),
50
+ (0, class_validator_1.IsString)(),
51
+ __metadata("design:type", String)
52
+ ], UserImportDto.prototype, "phone", void 0);
53
+ __decorate([
54
+ (0, column_decorator_1.CSVColumn)(4) // 第5列
55
+ ,
56
+ (0, column_decorator_1.ExcelColumn)('E') // 或使用Excel列名
57
+ ,
58
+ (0, class_validator_1.IsOptional)(),
59
+ (0, class_validator_1.IsString)(),
60
+ __metadata("design:type", String)
61
+ ], UserImportDto.prototype, "address", void 0);
62
+ __decorate([
63
+ (0, column_decorator_1.CSVColumn)(26) // 第27列
64
+ ,
65
+ (0, column_decorator_1.ExcelColumn)('AA') // Excel列AA
66
+ ,
67
+ (0, class_validator_1.IsOptional)(),
68
+ (0, class_validator_1.IsString)(),
69
+ __metadata("design:type", String)
70
+ ], UserImportDto.prototype, "notes", void 0);
71
+ /**
72
+ * 产品导入DTO示例
73
+ */
74
+ class ProductImportDto {
75
+ }
76
+ exports.ProductImportDto = ProductImportDto;
77
+ __decorate([
78
+ (0, column_decorator_1.CSVColumn)('产品名称'),
79
+ (0, column_decorator_1.ExcelColumn)(0),
80
+ (0, class_validator_1.IsString)(),
81
+ __metadata("design:type", String)
82
+ ], ProductImportDto.prototype, "name", void 0);
83
+ __decorate([
84
+ (0, column_decorator_1.CSVColumn)('价格'),
85
+ (0, column_decorator_1.ExcelColumn)('B'),
86
+ (0, class_validator_1.IsNumber)(),
87
+ (0, class_validator_1.Min)(0),
88
+ __metadata("design:type", Number)
89
+ ], ProductImportDto.prototype, "price", void 0);
90
+ __decorate([
91
+ (0, column_decorator_1.CSVColumn)('库存数量'),
92
+ (0, column_decorator_1.ExcelColumn)(2),
93
+ (0, class_validator_1.IsNumber)(),
94
+ (0, class_validator_1.Min)(0),
95
+ __metadata("design:type", Number)
96
+ ], ProductImportDto.prototype, "stock", void 0);
97
+ __decorate([
98
+ (0, column_decorator_1.CSVColumn)(3),
99
+ (0, column_decorator_1.ExcelColumn)('D'),
100
+ (0, class_validator_1.IsOptional)(),
101
+ (0, class_validator_1.IsString)(),
102
+ __metadata("design:type", String)
103
+ ], ProductImportDto.prototype, "description", void 0);
104
+ /**
105
+ * 使用说明:
106
+ *
107
+ * 1. CSV文件:
108
+ * - 如果CSV有表头,建议使用列名(如 @CSVColumn('姓名'))
109
+ * - 如果CSV没有表头,使用数字索引(如 @CSVColumn(0) 表示第1列)
110
+ *
111
+ * 2. Excel文件:
112
+ * - 可以使用列名(如 @ExcelColumn('姓名'))
113
+ * - 可以使用数字索引(如 @ExcelColumn(0) 表示第1列)
114
+ * - 可以使用Excel列名(如 @ExcelColumn('A') 表示A列)
115
+ * - 数字索引会自动转换为对应的Excel列名(0 -> A, 1 -> B, 26 -> AA)
116
+ *
117
+ * 3. 最佳实践:
118
+ * - 优先使用列名,代码更易读
119
+ * - 对于无表头的CSV文件,使用数字索引
120
+ * - 对于Excel文件,推荐使用Excel列名(A, B, C)或数字索引
121
+ * - 可以混合使用不同的映射方式
122
+ */
@@ -1,44 +1,30 @@
1
- import { ExcelDataOptions } from '../interfaces/file-upload-options.interface';
1
+ import 'reflect-metadata';
2
2
  /**
3
- * Excel 列映射元数据键
4
- */
5
- export declare const EXCEL_COLUMN_METADATA = "excel:column";
6
- /**
7
- * Excel 列名映射装饰器
3
+ * Excel 列映射装饰器
4
+ * 用于标记 DTO 类的属性对应的 Excel 列名
5
+ *
8
6
  * @example
9
7
  * ```typescript
10
- * export class UserImportDto {
8
+ * class UserDto {
11
9
  * @ExcelColumn('姓名')
12
- * @IsString()
13
10
  * name: string;
11
+ *
12
+ * @ExcelColumn('邮箱')
13
+ * email: string;
14
14
  * }
15
15
  * ```
16
16
  */
17
17
  export declare function ExcelColumn(columnName: string): PropertyDecorator;
18
18
  /**
19
- * Excel 数据参数装饰器
20
- * @example
21
- * ```typescript
22
- * @Post('import/excel')
23
- * @FileUpload({ types: [FileType.Excel] })
24
- * async importExcel(@ExcelData(UserImportDto) users: UserImportDto[]) {
25
- * await this.userService.batchCreate(users);
26
- * return { count: users.length };
27
- * }
28
- * ```
29
- */
30
- export declare const ExcelData: (...dataOrPipes: (import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>> | {
31
- dto: any;
32
- options?: ExcelDataOptions;
33
- })[]) => ParameterDecorator;
34
- /**
35
- * 辅助函数:获取 DTO 的 Excel 列映射
19
+ * 获取 Excel 列映射
36
20
  */
37
- export declare function getExcelColumnMapping(dto: any): Map<string, string>;
21
+ export declare function getExcelColumnMapping(dto: any): Record<string, string>;
38
22
  /**
39
- * 辅助函数:解析和验证 Excel 数据
23
+ * 解析并验证 Excel 数据
40
24
  */
41
- export declare function parseAndValidateExcelData<T extends object>(rawData: any[], dtoClass: new () => T, options?: ExcelDataOptions): Promise<{
42
- data: T[];
25
+ export declare function parseAndValidateExcelData(data: any[], dto: any, options?: {
26
+ skipValidation?: boolean;
27
+ }): Promise<{
28
+ data: any[];
43
29
  errors: any[];
44
30
  }>;