@simplysm/excel 13.0.36 → 13.0.38

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/README.md CHANGED
@@ -299,23 +299,15 @@ await ws.setName("New Sheet Name");
299
299
  import { z } from "zod";
300
300
  import { ExcelWrapper } from "@simplysm/excel";
301
301
 
302
- // 1. Define schema
302
+ // Define schema (use .describe() for Excel header names; defaults to field key if omitted)
303
303
  const schema = z.object({
304
- name: z.string(),
305
- age: z.number(),
306
- email: z.string().optional(),
307
- active: z.boolean(),
304
+ name: z.string().describe("Name"),
305
+ age: z.number().describe("Age"),
306
+ email: z.string().optional().describe("Email"),
307
+ active: z.boolean().describe("Active Status"),
308
308
  });
309
309
 
310
- // 2. Field name to display name mapping (names displayed in Excel headers)
311
- const displayNameMap = {
312
- name: "Name",
313
- age: "Age",
314
- email: "Email",
315
- active: "Active Status",
316
- };
317
-
318
- const wrapper = new ExcelWrapper(schema, displayNameMap);
310
+ const wrapper = new ExcelWrapper(schema);
319
311
  ```
320
312
 
321
313
  #### Writing to Excel
@@ -349,7 +341,7 @@ const records3 = await wrapper.read(bytes, 0);
349
341
  ```
350
342
 
351
343
  Behavior of the `read()` method:
352
- - Only reads headers defined in the schema's `_displayNameMap`
344
+ - Only reads headers defined in the schema (via `.describe()` or field key names)
353
345
  - Skips rows where all values are empty
354
346
  - Validates each row with the Zod schema, throws error on validation failure
355
347
  - Throws error if there is no data
@@ -440,7 +432,7 @@ Behavior of the `read()` method:
440
432
 
441
433
  | Member | Type / Return Type | Description |
442
434
  |--------|-----------|------|
443
- | `constructor(schema, displayNameMap)` | — | Create wrapper with a Zod schema and field-to-display-name map |
435
+ | `constructor(schema)` | — | Create wrapper with a Zod schema (use `.describe()` on fields for Excel header names; defaults to field key) |
444
436
  | `read(file, wsNameOrIndex?)` | `Promise<z.infer<TSchema>[]>` | Read records from Excel file (Uint8Array or Blob); defaults to first worksheet |
445
437
  | `write(wsName, records)` | `Promise<ExcelWorkbook>` | Write partial records to a new workbook; caller must manage the returned workbook's lifecycle |
446
438
 
@@ -8,12 +8,10 @@ import { ExcelWorkbook } from "./excel-workbook";
8
8
  */
9
9
  export declare class ExcelWrapper<TSchema extends z.ZodObject<z.ZodRawShape>> {
10
10
  private readonly _schema;
11
- private readonly _displayNameMap;
12
11
  /**
13
- * @param _schema Zod 스키마 (레코드 구조 정의)
14
- * @param _displayNameMap 필드명-표시명 매핑 (Excel 헤더로 사용)
12
+ * @param _schema Zod 스키마 (레코드 구조 정의, `.describe()`로 Excel 헤더명 지정)
15
13
  */
16
- constructor(_schema: TSchema, _displayNameMap: Record<keyof z.infer<TSchema>, string>);
14
+ constructor(_schema: TSchema);
17
15
  /**
18
16
  * Excel 파일 읽기 → 레코드 배열
19
17
  */
@@ -32,6 +30,7 @@ export declare class ExcelWrapper<TSchema extends z.ZodObject<z.ZodRawShape>> {
32
30
  * ```
33
31
  */
34
32
  write(wsName: string, records: Partial<z.infer<TSchema>>[]): Promise<ExcelWorkbook>;
33
+ private _getDisplayNameMap;
35
34
  private _getReverseDisplayNameMap;
36
35
  private _convertValue;
37
36
  private _unwrapSchema;
@@ -1 +1 @@
1
- {"version":3,"file":"excel-wrapper.d.ts","sourceRoot":"","sources":["../src/excel-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EACL,KAAK,CAAC,EAOP,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;GAIG;AACH,qBAAa,YAAY,CAAC,OAAO,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;IAMhE,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe;IANlC;;;OAGG;gBAEgB,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAG1E;;OAEG;IACG,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,aAAa,GAAE,MAAM,GAAG,MAAU,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;IAuD/F;;;;;;;;;;;;OAYG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAoDzF,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,UAAU;CAMnB"}
1
+ {"version":3,"file":"excel-wrapper.d.ts","sourceRoot":"","sources":["../src/excel-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EACL,KAAK,CAAC,EAOP,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;GAIG;AACH,qBAAa,YAAY,CAAC,OAAO,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;IAItD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC;;OAEG;gBAC0B,OAAO,EAAE,OAAO;IAE7C;;OAEG;IACG,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,aAAa,GAAE,MAAM,GAAG,MAAU,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;IAwD/F;;;;;;;;;;;;OAYG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAqDzF,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,UAAU;CAMnB"}
@@ -55,12 +55,10 @@ import {
55
55
  import { ExcelWorkbook } from "./excel-workbook.js";
56
56
  class ExcelWrapper {
57
57
  /**
58
- * @param _schema Zod 스키마 (레코드 구조 정의)
59
- * @param _displayNameMap 필드명-표시명 매핑 (Excel 헤더로 사용)
58
+ * @param _schema Zod 스키마 (레코드 구조 정의, `.describe()`로 Excel 헤더명 지정)
60
59
  */
61
- constructor(_schema, _displayNameMap) {
60
+ constructor(_schema) {
62
61
  this._schema = _schema;
63
- this._displayNameMap = _displayNameMap;
64
62
  }
65
63
  /**
66
64
  * Excel 파일 읽기 → 레코드 배열
@@ -71,7 +69,8 @@ class ExcelWrapper {
71
69
  const wb = __using(_stack, new ExcelWorkbook(file), true);
72
70
  const ws = await wb.getWorksheet(wsNameOrIndex);
73
71
  const wsName = await ws.getName();
74
- const displayNames = Object.values(this._displayNameMap);
72
+ const displayNameMap = this._getDisplayNameMap();
73
+ const displayNames = Object.values(displayNameMap);
75
74
  const rawData = await ws.getDataTable({
76
75
  usableHeaderNameFn: (headerName) => displayNames.includes(headerName)
77
76
  });
@@ -128,8 +127,9 @@ class ExcelWrapper {
128
127
  async write(wsName, records) {
129
128
  const wb = new ExcelWorkbook();
130
129
  const ws = await wb.createWorksheet(wsName);
131
- const keys = Object.keys(this._displayNameMap);
132
- const headers = keys.map((key) => this._displayNameMap[key]);
130
+ const displayNameMap = this._getDisplayNameMap();
131
+ const keys = Object.keys(displayNameMap);
132
+ const headers = keys.map((key) => displayNameMap[key]);
133
133
  for (let c = 0; c < headers.length; c++) {
134
134
  await ws.cell(0, c).setVal(headers[c]);
135
135
  }
@@ -162,9 +162,16 @@ class ExcelWrapper {
162
162
  return wb;
163
163
  }
164
164
  //#region Private Methods
165
+ _getDisplayNameMap() {
166
+ const map = {};
167
+ for (const [key, fieldSchema] of Object.entries(this._schema.shape)) {
168
+ map[key] = fieldSchema.description ?? key;
169
+ }
170
+ return map;
171
+ }
165
172
  _getReverseDisplayNameMap() {
166
173
  const map = /* @__PURE__ */ new Map();
167
- for (const [fieldKey, displayName] of Object.entries(this._displayNameMap)) {
174
+ for (const [fieldKey, displayName] of Object.entries(this._getDisplayNameMap())) {
168
175
  map.set(displayName, fieldKey);
169
176
  }
170
177
  return map;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/excel-wrapper.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": []
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/excel",
3
- "version": "13.0.36",
3
+ "version": "13.0.38",
4
4
  "description": "Excel 파일 처리 라이브러리",
5
5
  "author": "김석래",
6
6
  "license": "Apache-2.0",
@@ -20,6 +20,6 @@
20
20
  "dependencies": {
21
21
  "mime": "^4.1.0",
22
22
  "zod": "^4.3.6",
23
- "@simplysm/core-common": "13.0.36"
23
+ "@simplysm/core-common": "13.0.38"
24
24
  }
25
25
  }
@@ -19,13 +19,9 @@ import type { ExcelValueType } from "./types";
19
19
  */
20
20
  export class ExcelWrapper<TSchema extends z.ZodObject<z.ZodRawShape>> {
21
21
  /**
22
- * @param _schema Zod 스키마 (레코드 구조 정의)
23
- * @param _displayNameMap 필드명-표시명 매핑 (Excel 헤더로 사용)
22
+ * @param _schema Zod 스키마 (레코드 구조 정의, `.describe()`로 Excel 헤더명 지정)
24
23
  */
25
- constructor(
26
- private readonly _schema: TSchema,
27
- private readonly _displayNameMap: Record<keyof z.infer<TSchema>, string>,
28
- ) {}
24
+ constructor(private readonly _schema: TSchema) {}
29
25
 
30
26
  /**
31
27
  * Excel 파일 읽기 → 레코드 배열
@@ -36,7 +32,8 @@ export class ExcelWrapper<TSchema extends z.ZodObject<z.ZodRawShape>> {
36
32
  const ws = await wb.getWorksheet(wsNameOrIndex);
37
33
  const wsName = await ws.getName();
38
34
 
39
- const displayNames = Object.values(this._displayNameMap);
35
+ const displayNameMap = this._getDisplayNameMap();
36
+ const displayNames = Object.values(displayNameMap);
40
37
  const rawData = await ws.getDataTable({
41
38
  usableHeaderNameFn: (headerName) => displayNames.includes(headerName),
42
39
  });
@@ -102,8 +99,9 @@ export class ExcelWrapper<TSchema extends z.ZodObject<z.ZodRawShape>> {
102
99
  const wb = new ExcelWorkbook();
103
100
  const ws = await wb.createWorksheet(wsName);
104
101
 
105
- const keys = Object.keys(this._displayNameMap) as (keyof z.infer<TSchema>)[];
106
- const headers = keys.map((key) => this._displayNameMap[key]);
102
+ const displayNameMap = this._getDisplayNameMap();
103
+ const keys = Object.keys(displayNameMap) as (keyof z.infer<TSchema>)[];
104
+ const headers = keys.map((key) => displayNameMap[key as string]);
107
105
 
108
106
  // 헤더 행 작성
109
107
  for (let c = 0; c < headers.length; c++) {
@@ -150,9 +148,17 @@ export class ExcelWrapper<TSchema extends z.ZodObject<z.ZodRawShape>> {
150
148
 
151
149
  //#region Private Methods
152
150
 
151
+ private _getDisplayNameMap(): Record<string, string> {
152
+ const map: Record<string, string> = {};
153
+ for (const [key, fieldSchema] of Object.entries(this._schema.shape)) {
154
+ map[key] = (fieldSchema as z.ZodType).description ?? key;
155
+ }
156
+ return map;
157
+ }
158
+
153
159
  private _getReverseDisplayNameMap(): Map<string, string> {
154
160
  const map = new Map<string, string>();
155
- for (const [fieldKey, displayName] of Object.entries(this._displayNameMap)) {
161
+ for (const [fieldKey, displayName] of Object.entries(this._getDisplayNameMap())) {
156
162
  map.set(displayName, fieldKey);
157
163
  }
158
164
  return map;