@simplysm/sd-claude 14.0.91 → 14.0.93
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/claude/references/sd-simplysm14/README.md +7 -6
- package/claude/references/sd-simplysm14/apis/angular/README.md +59 -39
- package/claude/references/sd-simplysm14/apis/angular/controls.md +119 -186
- package/claude/references/sd-simplysm14/apis/angular/crud.md +70 -31
- package/claude/references/sd-simplysm14/apis/angular/directives.md +55 -57
- package/claude/references/sd-simplysm14/apis/angular/features.md +86 -105
- package/claude/references/sd-simplysm14/apis/angular/infra.md +48 -57
- package/claude/references/sd-simplysm14/apis/angular/layout.md +37 -47
- package/claude/references/sd-simplysm14/apis/angular/overlay.md +82 -74
- package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +61 -50
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +74 -57
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +63 -72
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +23 -18
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +21 -19
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +23 -18
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +72 -32
- package/claude/references/sd-simplysm14/apis/core-browser/README.md +18 -18
- package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +29 -29
- package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +41 -41
- package/claude/references/sd-simplysm14/apis/core-common/README.md +97 -90
- package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +75 -51
- package/claude/references/sd-simplysm14/apis/core-common/collection-ext.md +81 -0
- package/claude/references/sd-simplysm14/apis/core-common/errors.md +27 -29
- package/claude/references/sd-simplysm14/apis/core-common/obj.md +44 -45
- package/claude/references/sd-simplysm14/apis/core-common/serialization.md +34 -33
- package/claude/references/sd-simplysm14/apis/core-common/value-types.md +86 -0
- package/claude/references/sd-simplysm14/apis/core-node/README.md +6 -6
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +3 -0
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +2 -2
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +1 -1
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +2 -2
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +6 -3
- package/claude/references/sd-simplysm14/apis/excel/README.md +10 -10
- package/claude/references/sd-simplysm14/apis/excel/conditional-format.md +4 -2
- package/claude/references/sd-simplysm14/apis/excel/utils.md +1 -1
- package/claude/references/sd-simplysm14/apis/excel/workbook-worksheet.md +6 -6
- package/claude/references/sd-simplysm14/apis/lint/README.md +6 -32
- package/claude/references/sd-simplysm14/apis/lint/recommended.md +60 -0
- package/claude/references/sd-simplysm14/apis/lint/rules.md +17 -17
- package/claude/references/sd-simplysm14/apis/orm-common/README.md +15 -6
- package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +68 -102
- package/claude/references/sd-simplysm14/apis/orm-common/expr.md +75 -89
- package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +87 -99
- package/claude/references/sd-simplysm14/apis/orm-common/schema.md +110 -147
- package/claude/references/sd-simplysm14/apis/orm-common/types.md +48 -51
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +8 -13
- package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +5 -5
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +9 -6
- package/claude/references/sd-simplysm14/apis/sd-cli/SdTsCompiler.md +9 -8
- package/claude/references/sd-simplysm14/apis/sd-cli/sd-config-types.md +23 -19
- package/claude/references/sd-simplysm14/apis/service-client/README.md +20 -12
- package/claude/references/sd-simplysm14/apis/service-client/orm.md +6 -6
- package/claude/references/sd-simplysm14/apis/service-client/transport.md +1 -1
- package/claude/references/sd-simplysm14/apis/service-common/README.md +35 -32
- package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +23 -22
- package/claude/references/sd-simplysm14/apis/service-common/protocol.md +23 -23
- package/claude/references/sd-simplysm14/apis/service-server/README.md +51 -43
- package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +6 -6
- package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +31 -21
- package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +8 -8
- package/claude/references/sd-simplysm14/apis/storage/README.md +55 -49
- package/claude/references/sd-simplysm14/manuals/client-component.md +843 -740
- package/claude/references/sd-simplysm14/manuals/client-crud.md +8 -0
- package/claude/references/sd-simplysm14/manuals/client-demo.md +6 -16
- package/claude/references/sd-simplysm14/manuals/client-shared-data.md +26 -0
- package/claude/references/sd-simplysm14/manuals/logging.md +1 -1
- package/claude/references/sd-simplysm14/manuals/orm.md +15 -1
- package/claude/rules/sd-design-rules.md +7 -0
- package/claude/sd-system-prompt.md +5 -8
- package/claude/skills/sd-debug/SKILL.md +43 -0
- package/claude/skills/sd-debug/workflow.js +390 -0
- package/claude/skills/sd-demo/SKILL.md +18 -20
- package/claude/skills/sd-dev/SKILL.md +127 -24
- package/claude/skills/sd-docs/SKILL.md +5 -3
- package/claude/skills/sd-docs/references/subagent-prompt.md +2 -3
- package/claude/skills/sd-impl/SKILL.md +18 -18
- package/claude/skills/sd-manual/SKILL.md +1 -0
- package/claude/skills/sd-review/SKILL.md +24 -18
- package/claude/skills/sd-review/workflow.js +324 -0
- package/claude/skills/sd-spec/SKILL.md +96 -679
- package/claude/skills/sd-spec/references/example-spec.md +28 -50
- package/claude/skills/sd-spec/references/format-analyze.md +232 -0
- package/claude/skills/sd-spec/references/format-design.md +248 -0
- package/claude/skills/sd-spec/workflow-analyze.js +615 -0
- package/claude/skills/sd-spec/workflow-design.js +667 -0
- package/claude/skills/sd-unpack/scripts/handlers/office_com.py +5 -1
- package/package.json +1 -1
- package/scripts/postinstall.mjs +157 -18
- package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +0 -68
- package/claude/references/sd-simplysm14/apis/core-common/array-ext.md +0 -77
- package/claude/references/sd-simplysm14/apis/core-common/datetime.md +0 -86
- package/claude/skills/sd-skill/SKILL.md +0 -245
- package/claude/skills/sd-skill/scripts/run_eval.py +0 -380
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## createWorker (워커 스레드 측)
|
|
6
6
|
|
|
7
7
|
- `createWorker<TMethods, TEvents>(methods): { send; __methods; __events }` — 워커 스레드 진입 파일에서 호출하고 그 반환을 `export default`. `parentPort` 가 없으면(워커 컨텍스트 아님) `SdError` throw. 메서드 호출 메시지를 수신해 실행 후 결과/에러를 응답하고, 워커의 `process.stdout.write` 를 가로채 메인으로 로그를 전달한다.
|
|
8
|
-
- `methods: TMethods` (`Record<string, (...args: any[]) => unknown>`) — 워커가 제공할 메서드 맵. 동기/비동기 모두 가능(내부에서 await). 알 수 없는 메서드 호출 시 `SdError("알 수 없는 메서드: ...")` 로 응답.
|
|
8
|
+
- `methods: TMethods` (`Record<string, (...args: any[]) => unknown>`) — 워커가 제공할 메서드 맵. 동기/비동기 모두 가능(내부에서 await). 알 수 없는 메서드 호출 시 `SdError("알 수 없는 메서드: ...")` 로 응답, 잘못된 요청 형식이면 `SdError("잘못된 워커 요청 형식: ...")` 응답.
|
|
9
9
|
- 제네릭 `TEvents extends Record<string, unknown>`(기본 `Record<string, never>`) — 워커가 보낼 이벤트명→데이터 타입 맵(메인의 `on` 타입 추론에 사용).
|
|
10
10
|
- 반환 `send<K extends keyof TEvents & string>(event, data?): void` — 워커→메인 이벤트 전송. 진행률 등 메서드 반환과 별개의 통지에 사용.
|
|
11
11
|
- 반환 `__methods` / `__events` — 타입 추론용 마커. 런타임 값이 아니라 `Worker.create<typeof import(...)>` 의 타입에서만 참조됨.
|
|
@@ -49,6 +49,9 @@ await worker.terminate();
|
|
|
49
49
|
|
|
50
50
|
- `interface WorkerModule { default: { __methods: Record<string, (...args: any[]) => unknown>; __events: Record<string, unknown> } }` — `Worker.create` 의 제네릭 제약. `typeof import("./worker")` 가 이 구조를 만족(=`createWorker` 반환을 default export).
|
|
51
51
|
- `type PromisifyMethods<TMethods>` — 각 메서드 반환을 `Promise<Awaited<R>>` 로 바꾸는 매핑 타입. 함수가 아닌 멤버는 `never`.
|
|
52
|
-
- `type WorkerProxy<TModule>` — 위 프록시
|
|
52
|
+
- `type WorkerProxy<TModule>` — 위 프록시 타입(Promise화 메서드 + on/off/terminate).
|
|
53
53
|
- `interface WorkerRequest { id: string; method: string; params: unknown[] }` — 내부 요청 메시지.
|
|
54
|
-
- `
|
|
54
|
+
- `id: string` — 요청 식별자(Uuid). 응답을 대기 중 호출과 매칭하는 키.
|
|
55
|
+
- `method: string` — 호출할 워커 메서드명.
|
|
56
|
+
- `params: unknown[]` — 메서드 인자 배열.
|
|
57
|
+
- `type WorkerResponse` — 내부 응답 메시지 union: `return`(결과 body) / `error`(Error body) / `event`(워커 send: event+body) / `log`(stdout 전달 body). 직접 다룰 일은 거의 없음.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# @simplysm/excel
|
|
2
2
|
|
|
3
|
-
OOXML(.xlsx) 워크북을 ZIP 단위 lazy-load 로 읽고 쓰는
|
|
3
|
+
OOXML(.xlsx) 워크북을 ZIP 단위 lazy-load 로 읽고 쓰는 라이브러리. 접근한 셀에 필요한 XML 파트(SharedStrings/Styles 등)만 그때그때 로드하므로 모든 셀/시트 I/O 메서드가 `async` 다. `ExcelWorkbook` 진입점에서 시트 추가·셀 값/수식·스타일·조건부 서식·이미지·행 복사·뷰를, `ExcelWrapper` 로 Zod 스키마 기반 레코드 배열 ↔ 엑셀 변환을, `ExcelUtils` 로 주소·날짜 시리얼·숫자형식 변환을 다룬다. 외부 의존은 `@simplysm/core-common`(DateOnly/DateTime/Time/Bytes), `zod`, `mime`.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **ExcelWorkbook / ExcelWorksheet** — .xlsx 를 열거나 새로
|
|
8
|
-
- **ExcelCell / ExcelRow / ExcelCol** — 개별 셀의 값·수식·병합·스타일을 읽고
|
|
9
|
-
- **셀 스타일 (ExcelStyleOptions / ExcelFont)** — 셀(`cell.setStyle`)
|
|
7
|
+
- **ExcelWorkbook / ExcelWorksheet** — .xlsx 를 열거나 새로 만들고, 시트 추가/조회/이름, 데이터 테이블·매트릭스·레코드 읽기·쓰기, 행 복사/삽입, 뷰(zoom/freeze/탭색), 이미지 삽입, 바이트/Blob 내보내기를 할 때. 자세히: [workbook-worksheet.md](./workbook-worksheet.md)
|
|
8
|
+
- **ExcelCell / ExcelRow / ExcelCol** — 개별 셀의 값·수식·병합·스타일을 읽고 쓰거나, 행/열 단위로 셀을 순회하고 열 너비를 줄 때. 자세히: [cell.md](./cell.md)
|
|
9
|
+
- **셀 스타일 (ExcelStyleOptions / ExcelFont)** — 셀(`cell.setStyle`)이나 워크북 default(`wb.setDefaultStyle`)의 배경·테두리·정렬·숫자형식·폰트를 지정할 때. 자세히: [style.md](./style.md)
|
|
10
10
|
- **조건부 서식 (ExcelConditionalRule / ExcelConditionalRuleStyle)** — 셀/범위에 값 비교·텍스트 매칭·수식 기반 native CF 규칙을 추가할 때. 자세히: [conditional-format.md](./conditional-format.md)
|
|
11
11
|
- **ExcelWrapper** — Zod 스키마로 헤더 매핑·타입 변환·유효성 검사를 자동화해 레코드 배열 ↔ 엑셀을 변환할 때. 자세히: [wrapper.md](./wrapper.md)
|
|
12
12
|
- **ExcelUtils** — 셀 주소(A1 ↔ 좌표) 변환, 엑셀 날짜 시리얼 ↔ 타임스탬프 변환, 숫자형식 코드/ID/이름 상호 변환이 필요할 때. 자세히: [utils.md](./utils.md)
|
|
13
|
-
- **값/주소/형식 타입** — 셀 값 유니온·숫자형식 프리셋·셀 타입·주소 좌표·정렬/테두리/밑줄 enum 을 시그니처에서 참조할 때. 아래 인라인
|
|
14
|
-
- **OOXML XML-shape 타입** — `ExcelXml*` / `Excel*Data`
|
|
13
|
+
- **값/주소/형식 타입** — 셀 값 유니온·숫자형식 프리셋·셀 타입·주소 좌표·정렬/테두리/밑줄 enum 을 시그니처에서 참조할 때. 아래 인라인 섹션.
|
|
14
|
+
- **OOXML XML-shape 타입** — `ExcelXml*` / `Excel*Data` 류 내부 직렬화 타입. 아래 인라인 섹션.
|
|
15
15
|
|
|
16
16
|
## 값/주소/형식 타입
|
|
17
17
|
|
|
18
18
|
`./types` 가 노출하는 사용자 대면 값/형식 타입. 셀 값을 다루거나 메서드 시그니처를 해석할 때 참조.
|
|
19
19
|
|
|
20
|
-
- `ExcelValueType` = `number | string | DateOnly | DateTime | Time | boolean | undefined` — 셀이 가질 수 있는 값 유니온. `getValue()` 반환·`setValue()` 인자 타입. `undefined` = "값 없음"(읽기 시 빈 셀, 쓰기 시 셀 삭제)이므로 결측을 끝까지
|
|
21
|
-
- `ExcelNumberFormat` = `"number" | "string" | "DateOnly" | "DateTime" | "Time"` — 숫자형식 프리셋 이름. `"number"` = 일반 수치, `"string"` = 텍스트
|
|
22
|
-
- `ExcelCellType` = `"s" | "b" | "str" | "n" | "inlineStr" | "e"` — OOXML 셀 `t` 속성. `"s"` = SharedString 인덱스 참조, `"b"` = boolean(`"1"`/`"0"`), `"str"` = 수식 결과 문자열, `"n"` = 숫자, `"inlineStr"` = 인라인 서식 텍스트, `"e"` = 에러(읽기 시 throw). 보통
|
|
20
|
+
- `ExcelValueType` = `number | string | DateOnly | DateTime | Time | boolean | undefined` — 셀이 가질 수 있는 값 유니온. `getValue()` 반환·`setValue()` 인자 타입. `undefined` = "값 없음"(읽기 시 빈 셀, 쓰기 시 셀 삭제)이므로 결측을 끝까지 보존한다. `DateOnly`/`DateTime`/`Time` 은 `@simplysm/core-common` 타입이며 셀에 시리얼 숫자 + 날짜 numFmt 로 저장된다.
|
|
21
|
+
- `ExcelNumberFormat` = `"number" | "string" | "DateOnly" | "DateTime" | "Time"` — 숫자형식 프리셋 이름. `"number"` = 일반 수치, `"string"` = 텍스트 형식(numFmtId 49), `"DateOnly"`/`"DateTime"`/`"Time"` = 날짜/시간 시리얼 해석·표시. `ExcelStyleOptions.numberFormat` 와 `ExcelUtils` 변환의 공용 단위. 날짜 셀은 값으로 직접 `DateOnly`/`Time` 을 넣으면 numFmt 가 자동 부여되므로 따로 지정할 필요가 적다.
|
|
22
|
+
- `ExcelCellType` = `"s" | "b" | "str" | "n" | "inlineStr" | "e"` — OOXML 셀 `t` 속성. `"s"` = SharedString 인덱스 참조, `"b"` = boolean(`"1"`/`"0"`), `"str"` = 수식 결과 문자열, `"n"` = 숫자, `"inlineStr"` = 인라인 서식 텍스트, `"e"` = 에러(읽기 시 throw). 보통 `getValue`/`setValue` 가 자동 매핑하므로, 외부 생성 파일의 셀 타입을 직접 분기 검사할 때만 참조. 숫자/날짜 셀은 타입 코드가 `null` 이고 스타일 numFmt 로 구분된다.
|
|
23
23
|
- `ExcelAddressPoint` = `{ r: number; c: number }` — 0 기반 행(`r`)·열(`c`) 좌표. 셀 단일 위치 단위. `cell(r, c)` 인덱스와 동일 0 기반.
|
|
24
24
|
- `ExcelAddressRangePoint` = `{ s: ExcelAddressPoint; e: ExcelAddressPoint }` — 범위 좌표. `s` = 시작(좌상단), `e` = 끝(우하단, inclusive). `getRange()` 반환 타입이며 시트 순회 루프 경계로 쓴다.
|
|
25
25
|
- `ExcelBorderPosition` = `"left" | "right" | "top" | "bottom"` — 테두리 적용 변. `ExcelStyleOptions.border` 배열 원소. 4변 전부면 4개를 배열에 모두 넣음.
|
|
@@ -40,4 +40,4 @@ OOXML(.xlsx) 워크북을 ZIP 단위 lazy-load 로 읽고 쓰는 순수 TypeScri
|
|
|
40
40
|
- `ExcelXmlDrawingData` — `xl/drawings/drawingN.xml` 의 `wsDr`(twoCellAnchor from/to 앵커, pic/blipFill/spPr 이미지 노드) 구조.
|
|
41
41
|
- `ExcelXmlSharedStringData` / `ExcelXmlSharedStringDataSi` / `ExcelXmlSharedStringDataText` — `xl/sharedStrings.xml` 의 `sst` 와 `si` 항목(단순 `t` 또는 서식 run `r[]` 유니온), 텍스트 노드(`space="preserve"` 공백 보존) 구조.
|
|
42
42
|
- `ExcelXmlStyleData` 및 하위(`...Font` / `...Fill` / `...Border` / `...Xf` / `...Dxf`) — `xl/styles.xml` 의 `styleSheet`(numFmts/fonts/fills/borders/cellXfs/dxfs) 와 각 자원 노드 구조.
|
|
43
|
-
- `ExcelXml` = `{ readonly data: unknown; cleanup(): void }` — 모든 XML 파트 래퍼 클래스가 따르는 공통 인터페이스. `data` = 파싱된 노드 트리, `cleanup()` = 직렬화 직전
|
|
43
|
+
- `ExcelXml` = `{ readonly data: unknown; cleanup(): void }` — 모든 XML 파트 래퍼 클래스가 따르는 공통 인터페이스. `data` = 파싱된 노드 트리, `cleanup()` = 직렬화 직전 마무리 정리. 외부에서 구현할 일은 거의 없다.
|
|
@@ -19,16 +19,18 @@ ws.addConditionalFormat(opts: { ref: string; rules: ExcelConditionalRule[] }): P
|
|
|
19
19
|
|
|
20
20
|
값 비교(구간):
|
|
21
21
|
|
|
22
|
-
- `{ type: "cellIs"; op: "between" | "notBetween"; value: [number, number] | [string, string]; style }` — 두 값 사이 구간 비교(양 끝 inclusive). `op` = 구간
|
|
22
|
+
- `{ type: "cellIs"; op: "between" | "notBetween"; value: [number, number] | [string, string]; style }` — 두 값 사이 구간 비교(양 끝 inclusive). `op` = `"between"`(구간 안)/`"notBetween"`(구간 밖). `value` = `[a, b]` 튜플.
|
|
23
23
|
|
|
24
24
|
텍스트 매칭:
|
|
25
25
|
|
|
26
|
-
- `{ type: "text"; op: "contains" | "notContains" | "beginsWith" | "endsWith"; value: string; style }` — 문자열 매칭. `op` =
|
|
26
|
+
- `{ type: "text"; op: "contains" | "notContains" | "beginsWith" | "endsWith"; value: string; style }` — 문자열 매칭. `op` = `"contains"`(포함)/`"notContains"`(미포함)/`"beginsWith"`(시작)/`"endsWith"`(끝). 내부적으로 SEARCH 기반(대소문자 무시) formula 로 변환되며 비교 기준은 ref 좌상단 셀. 부분 문자열·접두/접미 강조에.
|
|
27
27
|
|
|
28
28
|
수식:
|
|
29
29
|
|
|
30
30
|
- `{ type: "expression"; formula: string; style }` — 임의 엑셀 수식 기반. `formula` 가 TRUE 인 셀에 style 적용. `=` 없이 본문만(예 `"$B2>$C2"`). 다른 셀 참조·복합 조건 등 위 프리셋으로 안 되는 규칙에.
|
|
31
31
|
|
|
32
|
+
각 규칙의 `style` 은 아래 `ExcelConditionalRuleStyle`.
|
|
33
|
+
|
|
32
34
|
## ExcelConditionalRuleStyle
|
|
33
35
|
|
|
34
36
|
```typescript
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
`ExcelNumberFormat` = `"number" | "string" | "DateOnly" | "DateTime" | "Time"` 와 엑셀 formatCode/numFmtId 사이 변환.
|
|
28
28
|
|
|
29
|
-
- `convertNumFmtCodeToName(numFmtCode: string): ExcelNumberFormat` — formatCode 문자열을 형식 이름으로. `"General"`→`"number"`, yy/dd/mm·h/ss 패턴 조합으로 `"DateOnly"`/`"DateTime"`/`"Time"` 판별(시간 문맥의 `mm` 은 분으로 제외), 숫자 패턴이면 `"number"`. 미해석 코드면 throw.
|
|
29
|
+
- `convertNumFmtCodeToName(numFmtCode: string): ExcelNumberFormat` — formatCode 문자열을 형식 이름으로. `"General"`→`"number"`, yy/dd/mm·h/ss 패턴 조합으로 `"DateOnly"`/`"DateTime"`/`"Time"` 판별(시간 문맥의 `mm` 은 분으로 보아 날짜 판정에서 제외), 숫자 패턴이면 `"number"`. 미해석 코드면 throw.
|
|
30
30
|
- `convertNumFmtIdToName(numFmtId: number): ExcelNumberFormat` — 엑셀 내장 형식 ID 를 이름으로. 0~13·37~40·48→`"number"`, 14~17·27~31·34~36·50~58→`"DateOnly"`, 22→`"DateTime"`, 18~21·32~33·45~47→`"Time"`, 49→`"string"`. 그 외 ID 면 throw.
|
|
31
31
|
- `convertNumFmtNameToId(numFmtName: ExcelNumberFormat): number` — 이름을 내장 형식 ID 로. `"number"`→0, `"DateOnly"`→14, `"DateTime"`→22, `"Time"`→18, `"string"`→49.
|
|
32
32
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @simplysm/excel — ExcelWorkbook / ExcelWorksheet
|
|
2
2
|
|
|
3
|
-
.xlsx 파일을 열거나 새로 만들고, 시트를 추가/조회하고, 시트 단위로 데이터 테이블·매트릭스·레코드
|
|
3
|
+
.xlsx 파일을 열거나 새로 만들고, 시트를 추가/조회하고, 시트 단위로 데이터 테이블·매트릭스·레코드 읽기·쓰기·행 복사/삽입·이미지·뷰를 다룬 뒤 바이트/Blob 로 내보내는 진입 흐름. 워크북은 내부적으로 ZIP 리소스를 잡으므로 사용 후 반드시 `close()` 해야 한다(미해제 시 리소스 누수).
|
|
4
4
|
|
|
5
5
|
## ExcelWorkbook
|
|
6
6
|
|
|
@@ -53,7 +53,7 @@ try {
|
|
|
53
53
|
|
|
54
54
|
이름:
|
|
55
55
|
|
|
56
|
-
- `getName(): Promise<string>` — 시트 이름 반환.
|
|
56
|
+
- `getName(): Promise<string>` — 시트 이름 반환. ID 에 대응하는 이름이 없으면 throw.
|
|
57
57
|
- `setName(newName: string): Promise<void>` — 시트 이름 변경.
|
|
58
58
|
|
|
59
59
|
셀 접근:
|
|
@@ -72,7 +72,7 @@ try {
|
|
|
72
72
|
- `getDataTable(opt?): Promise<Record<string, ExcelValueType>[]>` — 헤더 행을 키로 한 레코드 배열로 읽기.
|
|
73
73
|
- `opt.headerRowIndex?: number` — 헤더로 쓸 행 인덱스. 미지정 시 range 시작 행. 상단에 제목 행이 있으면 실제 헤더 행 인덱스를 지정.
|
|
74
74
|
- `opt.checkEndColIndex?: number` — 데이터 끝 판정 열. 그 열 셀이 비면 이후 행을 더 읽지 않고 종료. 빈 행으로 데이터가 끊기는 양식에서 사용.
|
|
75
|
-
- `opt.usableHeaderNameFn?: (headerName: string) => boolean` — 헤더 채택 필터. `true` 인 헤더만 키로 사용. 일부 열만 읽을 때. 채택된 헤더가 중복이면 throw.
|
|
75
|
+
- `opt.usableHeaderNameFn?: (headerName: string) => boolean` — 헤더 채택 필터. `true` 인 헤더만 키로 사용. 일부 열만 읽을 때. 채택된 헤더가 한 행 내 중복이면 throw.
|
|
76
76
|
- `setDataMatrix(matrix: ExcelValueType[][]): Promise<void>` — 2차원 배열을 0,0 부터 행 우선으로 쓰기. 헤더 없이 좌표 그대로 채울 때. `undefined` 원소는 해당 셀 삭제.
|
|
77
77
|
- `setRecords(records: Record<string, ExcelValueType>[]): Promise<void>` — 0행에 헤더(전 레코드 키 합집합, 빈 키 제외)를 자동 생성하고 1행부터 값 기록. 키 순서는 첫 등장 순. 표 형태 출력의 기본 수단.
|
|
78
78
|
|
|
@@ -90,17 +90,17 @@ try {
|
|
|
90
90
|
|
|
91
91
|
- `copyCellStyle(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint): Promise<void>` — 셀 스타일 ID 만 복사(값 제외). 원본에 스타일이 없으면 무변경.
|
|
92
92
|
- `copyRowStyle(srcR: number, targetR: number): Promise<void>` — range 내 모든 열에 대해 행 스타일 복사.
|
|
93
|
-
- `copyCell(srcAddr, targetAddr): Promise<void>` — 셀(값+스타일)을 대상에 복사.
|
|
93
|
+
- `copyCell(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint): Promise<void>` — 셀(값+스타일)을 대상에 복사.
|
|
94
94
|
- `copyRow(srcR: number, targetR: number): Promise<void>` — 행 전체를 대상 행에 복사(대상 기존 내용 덮어쓰기).
|
|
95
95
|
- `insertCopyRow(srcR: number, targetR: number): Promise<void>` — 원본 행을 대상 위치에 "삽입" 복사. 대상 이하 기존 행은 1칸 아래로 밀리고, 삽입 지점을 관통하는 다중행 병합은 1행 확장, 원본의 단일행 병합은 대상 행에 복제된다. 템플릿 행을 반복 펼칠 때 사용(덮어쓰기 방지).
|
|
96
96
|
|
|
97
97
|
이미지:
|
|
98
98
|
|
|
99
|
-
- `addImage(opts): Promise<void>` — 시트에 이미지 삽입.
|
|
99
|
+
- `addImage(opts): Promise<void>` — 시트에 이미지 삽입. 같은 시트에 여러 번 호출하면 기존 drawing 파트에 이어 붙인다.
|
|
100
100
|
- `opts.bytes: Bytes` — 이미지 바이너리.
|
|
101
101
|
- `opts.ext: string` — 확장자(`"png"`, `"jpg"` 등). MIME 미해석 시 throw.
|
|
102
102
|
- `opts.from: { r: number; c: number; rOff?: number | string; cOff?: number | string }` — 시작 위치(0 기반 행/열, `rOff`/`cOff` 는 셀 내부 EMU 오프셋).
|
|
103
|
-
- `opts.to?: { r; c; rOff
|
|
103
|
+
- `opts.to?: { r: number; c: number; rOff?: number | string; cOff?: number | string }` — 끝 위치. 생략 시 `from` 의 한 칸 우하단(`from.r+1, from.c+1`)에 배치되어 약 1셀 크기로 들어간다. 명시하면 두 셀 앵커 사이로 늘려 배치.
|
|
104
104
|
|
|
105
105
|
데이터 읽기 예:
|
|
106
106
|
|
|
@@ -1,43 +1,17 @@
|
|
|
1
1
|
# @simplysm/lint
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
심플리즘 전용 ESLint 자산 패키지. 커스텀 규칙 9종을 담은 플러그인과, 그 규칙들에 typescript-eslint·angular-eslint·import·unused-imports 를 결합한 flat config 프리셋을 제공. `src/index.ts` 는 없음 — `package.json` 의 `exports` 두 subpath(`./eslint-plugin`, `./eslint-recommended`)만 진입점이며 패키지 루트 import 는 없음.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **eslint-recommended** (`@simplysm/lint/eslint-recommended`) — 프로젝트 `eslint.config.ts` 에서
|
|
8
|
-
- **eslint-plugin** (`@simplysm/lint/eslint-plugin`) — 커스텀 규칙만 담은 ESLint Plugin 객체(`{ rules }`). recommended 를 쓰지 않고 규칙을 직접 골라 등록할 때, 또는
|
|
7
|
+
- **eslint-recommended** (`@simplysm/lint/eslint-recommended`) — 프로젝트 `eslint.config.ts` 에서 그대로 spread 해 쓰는 완성형 flat config 배열. JS/TS/HTML/tests 파일 패턴별 활성 규칙·심각도·ignore·플러그인·Angular 통합과 금지 globals/imports/syntax 를 확인할 때. 자세히: [recommended.md](./recommended.md)
|
|
8
|
+
- **eslint-plugin** (`@simplysm/lint/eslint-plugin`) — 커스텀 규칙만 담은 ESLint Plugin 객체(`{ rules }`). recommended 를 쓰지 않고 규칙을 직접 골라 등록할 때, 또는 개별 규칙의 위반 메시지·autofix·옵션 의미를 검토할 때. 자세히: [rules.md](./rules.md)
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
`@simplysm/lint/eslint-recommended` 의 default export. `typescript-eslint` 의 `tseslint.config(...)` 결과 = flat-config 객체 배열. 그대로 spread 해서 사용함.
|
|
13
|
-
|
|
14
|
-
```typescript
|
|
15
|
-
// eslint.config.ts
|
|
16
|
-
import recommended from "@simplysm/lint/eslint-recommended";
|
|
17
|
-
|
|
18
|
-
export default [...recommended];
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
배열을 구성하는 config 블록(순서대로):
|
|
22
|
-
|
|
23
|
-
- **globalIgnores** — `**/node_modules/**`, `**/dist/**`, `**/.*/**` 순회 자체를 건너뜀. 점(.)으로 시작하는 디렉토리 전체가 제외 대상.
|
|
24
|
-
- **공통 languageOptions** — `ecmaVersion: "latest"`, `sourceType: "module"`.
|
|
25
|
-
- **JS 블록** (`**/*.js`, `**/*.mjs`, `**/*.cjs`) — node 글로벌, `import`/`@simplysm`/`unused-imports` 플러그인 등록. 활성 규칙: `require-await`, `no-shadow`, `no-duplicate-imports`, `no-unused-expressions`, `no-undef`, unused-imports 2종, `import/no-extraneous-dependencies`(lib·`eslint.config`·`simplysm`·`vitest.config` 파일은 devDeps 허용), `@simplysm/no-subpath-imports-from-simplysm`, `@simplysm/no-hard-private`, node 빌트인 차단 규칙군, env 직접접근 차단 규칙군.
|
|
26
|
-
- **angular tsRecommended** — `angular.configs.tsRecommended` spread.
|
|
27
|
-
- **TS 블록** (`**/*.ts`) — `processor: angular.processInlineTemplates`(인라인 템플릿 추출 후 별도 lint), `parserOptions.project: true`(타입 정보 사용), `import/resolver` 로 typescript resolver(`alwaysTryTypes: true`) 지정. typescript-eslint 타입체크 규칙 다수 + `@simplysm` 커스텀 규칙 6종 활성. 커스텀 규칙 심각도: `ng-no-async-effect`/`no-hard-private`/`no-subpath-imports-from-simplysm`/`ts-no-unused-injects`/`ts-no-unused-protected-readonly` = `error`, `ts-no-throw-not-implemented-error` = `warn`. `@angular-eslint/no-output-native` 은 `off`.
|
|
28
|
-
- **HTML 블록** (`**/*.html`) — `angular.configs.templateRecommended` + `templateAccessibility` extends. `@simplysm` 템플릿 규칙 3종 활성: `ng-template-no-strict-null-check`=`error`, `ng-template-no-todo-comments`=`warn`, `ng-template-sd-require-binding-attrs`=`error`. `@angular-eslint/template/eqeqeq` 는 `allowNullOrUndefined: true`, `label-has-associated-control`=`off`, `no-any`=`error`.
|
|
29
|
-
- **테스트 오버라이드** (`**/tests/**/*.ts`) — 테스트 코드 완화: `no-console`=`off`, `import/no-extraneous-dependencies`=`off`, `@simplysm/ts-no-throw-not-implemented-error`=`off`.
|
|
30
|
-
- **vitest.config 오버라이드** (`**/vitest.config.ts`) — `no-restricted-properties`=`off` (설정 파일에서 `process.env` 접근 허용).
|
|
31
|
-
|
|
32
|
-
주의:
|
|
33
|
-
|
|
34
|
-
- TS 블록은 타입 정보(`parserOptions.project: true`)를 요구하므로, 대상 프로젝트에 유효한 `tsconfig` 가 있어야 함.
|
|
35
|
-
- node 빌트인 차단(`noNodeBuiltinsRules`): `Buffer` 글로벌 및 `buffer`/`events`/`eventemitter3` import 금지 — 각각 `Uint8Array`/`@simplysm/core-common`의 `BytesUtils`·`EventEmitter` 로 대체 유도. JS·TS 블록 모두에 적용.
|
|
36
|
-
- env 직접접근 차단(`noDirectEnvAccessRules`): `process.env`·`import.meta.env` 직접 접근, `env("NODE_ENV")` 호출, `=== undefined`/`!== undefined`(엄격 비교) 를 `no-restricted-properties`/`no-restricted-syntax` 로 막음(엄격 비교는 `== null`/`!= null` 로 유도). JS·TS 블록 모두에 적용.
|
|
10
|
+
> 두 진입점 모두 default export 만 가짐. `import recommended from "@simplysm/lint/eslint-recommended"`, `import plugin from "@simplysm/lint/eslint-plugin"` 형태로 사용. 규칙 생성 팩토리 `createRule`(`src/utils/create-rule.ts`, `ESLintUtils.RuleCreator` 래퍼로 문서 URL 자동 부여)는 내부 전용이며 두 진입점 어디로도 재노출되지 않음.
|
|
37
11
|
|
|
38
12
|
## eslint-plugin
|
|
39
13
|
|
|
40
|
-
`@simplysm/lint/eslint-plugin` 의 default export. ESLint Plugin 형태
|
|
14
|
+
`@simplysm/lint/eslint-plugin` 의 default export. ESLint Plugin 형태 객체 `{ rules }`.
|
|
41
15
|
|
|
42
16
|
```typescript
|
|
43
17
|
import plugin from "@simplysm/lint/eslint-plugin";
|
|
@@ -46,4 +20,4 @@ import plugin from "@simplysm/lint/eslint-plugin";
|
|
|
46
20
|
|
|
47
21
|
- `rules` — 규칙 id → 규칙 객체 맵. 등록된 9개 id: `ng-no-async-effect`, `ng-template-no-strict-null-check`, `ng-template-no-todo-comments`, `ng-template-sd-require-binding-attrs`, `no-hard-private`, `no-subpath-imports-from-simplysm`, `ts-no-throw-not-implemented-error`, `ts-no-unused-injects`, `ts-no-unused-protected-readonly`.
|
|
48
22
|
|
|
49
|
-
flat
|
|
23
|
+
flat config 에서 직접 등록할 때는 `plugins: { "@simplysm": plugin }` 로 매핑 후 `"@simplysm/<id>"` 로 켬. 각 규칙의 검사 대상·옵션·autofix·메시지는 [rules.md](./rules.md) 참조.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# @simplysm/lint — recommended
|
|
2
|
+
|
|
3
|
+
`@simplysm/lint/eslint-recommended` 의 default export. `typescript-eslint` 의 `tseslint.config(...)` 결과 = flat config 객체 배열. 프로젝트 `eslint.config.ts` 에서 그대로 spread 해 표준 lint 세트를 적용할 때 같이 읽는 묶음.
|
|
4
|
+
|
|
5
|
+
## 사용
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// eslint.config.ts
|
|
9
|
+
import recommended from "@simplysm/lint/eslint-recommended";
|
|
10
|
+
|
|
11
|
+
export default [...recommended];
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## config 블록 (배열 순서대로)
|
|
15
|
+
|
|
16
|
+
각 블록은 `files` 패턴으로 적용 범위를 한정. 같은 파일이 여러 블록 패턴에 걸리면 규칙이 병합됨.
|
|
17
|
+
|
|
18
|
+
- **globalIgnores** — 순회 자체를 건너뛸 경로. `**/node_modules/**`, `**/dist/**`, `**/.*/**`(점으로 시작하는 디렉토리 전체). lint 대상에서 완전히 제외할 때.
|
|
19
|
+
- **공통 languageOptions** — `ecmaVersion: "latest"`(최신 ECMAScript 구문 허용), `sourceType: "module"`(ESM 으로 파싱). 전 파일 공통 파서 기준.
|
|
20
|
+
- **JS 블록** (`files: **/*.js, **/*.mjs, **/*.cjs`) — `languageOptions.globals: globals.node`(node 전역 인식), `plugins: import/@simplysm/unused-imports` 등록. 활성 규칙:
|
|
21
|
+
- `require-await: error` — async 함수 안에 `await` 가 없으면 위반. 불필요한 async 표시 방지.
|
|
22
|
+
- `no-shadow: error` — 바깥 스코프 변수명을 안쪽에서 가림(shadowing) 금지.
|
|
23
|
+
- `no-duplicate-imports: error` — 같은 모듈을 여러 import 문으로 중복 import 금지.
|
|
24
|
+
- `no-unused-expressions: error` — 값을 쓰지 않는 식문(부작용 없는 표현식) 금지.
|
|
25
|
+
- `no-undef: error` — 선언되지 않은 식별자 참조 금지.
|
|
26
|
+
- `unused-imports/no-unused-imports: error` — 미사용 import 제거(autofix).
|
|
27
|
+
- `unused-imports/no-unused-vars: error` — 미사용 변수/인자 금지. `varsIgnorePattern`·`argsIgnorePattern` = `^_`(언더스코어 접두는 의도적 미사용으로 허용), `args: "after-used"`(마지막 사용 인자 뒤만 검사).
|
|
28
|
+
- `import/no-extraneous-dependencies: error` — `package.json` 의존성에 없는 패키지 import 금지. `devDependencies` 허용 경로: `**/lib/**`, `**/eslint.config.{js,cjs,mjs}`, `**/simplysm.{js,cjs,mjs}`, `**/vitest.config.{js,cjs,mjs}`(빌드·설정 파일은 devDeps 사용 허용).
|
|
29
|
+
- `@simplysm/no-subpath-imports-from-simplysm: error`, `@simplysm/no-hard-private: error` — 커스텀 규칙(자세히는 [rules.md](./rules.md)).
|
|
30
|
+
- node 빌트인 차단 규칙군·env 직접접근 차단 규칙군(아래 "공유 규칙 묶음").
|
|
31
|
+
- **angular tsRecommended** — `angular.configs.tsRecommended` spread. angular-eslint 의 TS 권장 세트.
|
|
32
|
+
- **TS 블록** (`files: **/*.ts`) — `processor: angular.processInlineTemplates`(컴포넌트 인라인 템플릿을 추출해 별도 lint), `parser: tseslint.parser` + `parserOptions.project: true`(타입 정보 기반 규칙 활성화 요구), `settings.import/resolver` = typescript resolver(`alwaysTryTypes: true`). 활성 규칙:
|
|
33
|
+
- typescript-eslint 타입체크 규칙군: `@typescript-eslint/require-await`, `await-thenable`, `return-await(["error","in-try-catch"])`, `no-floating-promises`, `no-shadow`, `no-unnecessary-condition({allowConstantLoopConditions:true})`, `no-unnecessary-type-assertion`, `prefer-reduce-type-parameter`, `prefer-return-this-type`, `no-unused-expressions`, `strict-boolean-expressions({allowNullableBoolean:true, allowNullableObject:true})`, `ban-ts-comment({"ts-expect-error":"allow-with-description", minimumDescriptionLength:3})`, `prefer-readonly`, `naming-convention`(private memberLike 는 `_` 접두 강제), `no-misused-promises({checksVoidReturn:{arguments:false, inheritedMethods:false}})`, `only-throw-error`, `no-array-delete` — 모두 `error`.
|
|
34
|
+
- `no-console: error` — 콘솔 출력 금지(TS 블록 한정).
|
|
35
|
+
- `@simplysm` 커스텀 규칙 6종 심각도: `ng-no-async-effect`/`no-hard-private`/`no-subpath-imports-from-simplysm`/`ts-no-unused-injects`/`ts-no-unused-protected-readonly` = `error`, `ts-no-throw-not-implemented-error` = `warn`.
|
|
36
|
+
- `@angular-eslint/no-output-native: off` — output 명이 네이티브 DOM 이벤트와 겹쳐도 허용.
|
|
37
|
+
- unused-imports 2종·node 빌트인 차단·env 직접접근 차단 규칙군 + `import/no-extraneous-dependencies: error`(TS 는 예외 경로 없이 전면 적용).
|
|
38
|
+
- **HTML 블록** (`files: **/*.html`) — `extends: angular.configs.templateRecommended + templateAccessibility`. 활성 규칙:
|
|
39
|
+
- `@simplysm/ng-template-no-strict-null-check: error`, `ng-template-no-todo-comments: warn`, `ng-template-sd-require-binding-attrs: error` — 커스텀 템플릿 규칙(자세히는 [rules.md](./rules.md)).
|
|
40
|
+
- `@angular-eslint/template/eqeqeq: ["error",{allowNullOrUndefined:true}]` — 템플릿 엄격 비교 강제하되 null/undefined 비교는 예외.
|
|
41
|
+
- `@angular-eslint/template/label-has-associated-control: off` — label-control 연결 검사 비활성.
|
|
42
|
+
- `@angular-eslint/template/no-any: error` — 템플릿에서 `$any` 사용 금지.
|
|
43
|
+
- **테스트 오버라이드** (`files: **/tests/**/*.ts`) — 테스트 코드 완화: `no-console: off`, `import/no-extraneous-dependencies: off`, `@simplysm/ts-no-throw-not-implemented-error: off`.
|
|
44
|
+
- **vitest.config 오버라이드** (`files: **/vitest.config.ts`) — `no-restricted-properties: off`(설정 파일에서 `process.env` 접근 허용).
|
|
45
|
+
|
|
46
|
+
## 공유 규칙 묶음
|
|
47
|
+
|
|
48
|
+
JS·TS 블록에 함께 적용되는 내부 상수 묶음(외부로 export 되진 않으나 동작 이해용):
|
|
49
|
+
|
|
50
|
+
- **noNodeBuiltinsRules** — node 빌트인 차단.
|
|
51
|
+
- `no-restricted-globals` 로 `Buffer` 전역 금지 → `Uint8Array`/`@simplysm/core-common` 의 `BytesUtils` 유도.
|
|
52
|
+
- `no-restricted-imports` 로 `buffer`(→ `Uint8Array`/`BytesUtils`), `events`·`eventemitter3`(→ `@simplysm/core-common` 의 `EventEmitter`) import 금지.
|
|
53
|
+
- **noDirectEnvAccessRules** — 환경변수 직접접근·엄격 비교 차단.
|
|
54
|
+
- `no-restricted-properties` 로 `process.env` 직접 접근 금지 → `env("...")` 유도.
|
|
55
|
+
- `no-restricted-syntax` 로 `import.meta.env` 직접 접근 금지(→ `env("...")`), `env("NODE_ENV")` 호출 금지, `=== undefined`/`!== undefined`(엄격 비교 양방향) 금지 → `== null`/`!= null` 유도.
|
|
56
|
+
|
|
57
|
+
## 주의
|
|
58
|
+
|
|
59
|
+
- TS 블록은 타입 정보(`parserOptions.project: true`)를 요구하므로 대상 프로젝트에 유효한 `tsconfig` 가 있어야 함.
|
|
60
|
+
- recommended 는 그 자체로 ESLint 9 flat config 배열이므로 추가 spread/병합 없이도 동작. 프로젝트별 규칙을 덧붙일 땐 배열 뒤에 config 객체를 이어 붙임.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# @simplysm/lint — rules
|
|
2
2
|
|
|
3
|
-
`eslint-plugin` 이 노출하는 커스텀 ESLint 규칙 9종. 규칙 id 는
|
|
3
|
+
`eslint-plugin` 이 노출하는 커스텀 ESLint 규칙 9종. 등록 시 규칙 id 는 `@simplysm/<name>`. 개별 규칙을 켜거나 lint 위반 메시지·autofix·옵션 의미를 파악할 때 같이 읽는 묶음. 모든 규칙은 `createRule`(= `ESLintUtils.RuleCreator`, `src/utils/create-rule.ts`)로 생성되어 문서 URL 이 자동 부여됨. 옵션 없는 규칙은 `schema: []`. autofix 는 각 항목의 표기대로만 제공.
|
|
4
4
|
|
|
5
5
|
## no-hard-private
|
|
6
6
|
|
|
7
|
-
ECMAScript hard private(`#field`) 사용을 금지하고 TypeScript `private _` 스타일을 강제. `type: "problem"`, autofix 있음, 옵션 없음. JS·TS
|
|
7
|
+
ECMAScript hard private(`#field`) 사용을 금지하고 TypeScript `private _` 스타일을 강제. `type: "problem"`, autofix 있음, 옵션 없음. JS·TS 양쪽 동작.
|
|
8
8
|
|
|
9
9
|
검사 대상: 클래스 필드 선언(`#field`), 메서드 선언(`#method()`), 접근자 선언(`accessor #field`), 멤버 접근 표현식(`this.#field`).
|
|
10
10
|
|
|
11
11
|
메시지:
|
|
12
|
-
- `preferSoftPrivate` — hard private(
|
|
12
|
+
- `preferSoftPrivate` — hard private(`#`) 금지, `private _` 스타일 사용 안내. autofix 는 `#name` → `_name` 치환 후, 선언부에 접근제어자가 없으면 `private ` 를 앞에 삽입(데코레이터·`static`·`async`·`readonly` 순서를 보존해 그 뒤 위치에 삽입). 토큰 계산 실패 시 이름만 바뀌는 불완전 수정을 막기 위해 수정 전체를 건너뜀.
|
|
13
13
|
- `nameConflict` — `#{{name}}` 을 `_{{name}}` 으로 바꿀 수 없음(동일 이름 멤버가 클래스에 이미 존재). 이 경우 보고만 하고 autofix 안 함. 중첩 클래스는 스택으로 각 클래스 멤버 집합을 관리.
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
@@ -19,12 +19,12 @@ class A { #count = 0; inc() { this.#count++; } }
|
|
|
19
19
|
|
|
20
20
|
## no-subpath-imports-from-simplysm
|
|
21
21
|
|
|
22
|
-
`@simplysm/*` 패키지의 `src` 하위 경로 import 를 금지(빌드
|
|
22
|
+
`@simplysm/*` 패키지의 `src` 하위 경로 import 를 금지(빌드 export 경유 강제). `type: "problem"`, autofix 있음, 옵션 없음. JS·TS 양쪽 동작.
|
|
23
23
|
|
|
24
|
-
검사 대상: 정적 import(`import ... from`), 동적 import(`import("...")`), 재내보내기(`export { x } from`), 전체 재내보내기(`export * from`). import 경로를 `/` 로 분리해 3번째 세그먼트가 `src` 인 경우(`@simplysm/pkg/src`, `@simplysm/pkg/src/xxx`)만 위반. `@simplysm/pkg`·`@simplysm/pkg/xxx`(src
|
|
24
|
+
검사 대상: 정적 import(`import ... from`), 동적 import(`import("...")`), 재내보내기(`export { x } from`), 전체 재내보내기(`export * from`). import 경로를 `/` 로 분리해 3번째 세그먼트가 `src` 인 경우(`@simplysm/pkg/src`, `@simplysm/pkg/src/xxx`)만 위반. `@simplysm/pkg`·`@simplysm/pkg/xxx`(src 아닌 subpath)는 허용.
|
|
25
25
|
|
|
26
26
|
메시지:
|
|
27
|
-
- `noSubpathImport` — `'@simplysm/{{pkg}}'` 에서 `src` 하위 경로 import
|
|
27
|
+
- `noSubpathImport` — `'@simplysm/{{pkg}}'` 에서 `src` 하위 경로 import 불가(`{{importPath}}` 출력). autofix 는 경로를 `@simplysm/<pkg>`(원래 따옴표 보존)로 치환.
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
30
|
import { x } from "@simplysm/core-common/src/x"; // → "@simplysm/core-common"
|
|
@@ -32,12 +32,12 @@ import { x } from "@simplysm/core-common/src/x"; // → "@simplysm/core-common"
|
|
|
32
32
|
|
|
33
33
|
## ng-no-async-effect
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
`@angular/core` 의 `effect()` 에 async 함수를 직접 전달하는 것을 금지. `type: "problem"`, autofix 없음, 옵션 없음. `await` 이후 signal read 가 reactive 의존성으로 추적되지 않고 반환값이 `Promise<void>` 가 되어 cleanup 등록이 막히는 문제 방지.
|
|
36
36
|
|
|
37
37
|
검사 대상: `effect(...)` 호출의 첫 인자가 async ArrowFunction/FunctionExpression 인 경우. `effect` 식별자가 `@angular/core` 에서 import 되었는지 스코프로 검증 — named(`import { effect }`)·aliased(`effect as ngEffect`)·namespace(`import * as ng` → `ng.effect(...)`) import 만 인정. 다른 모듈 또는 로컬 선언 `effect` 는 무시.
|
|
38
38
|
|
|
39
39
|
메시지:
|
|
40
|
-
- `noAsyncEffect` — async 함수 직접 전달
|
|
40
|
+
- `noAsyncEffect` — async 함수 직접 전달 금지, 비동기는 `void untracked(async () => { ... })` 내부에서 수행하라고 안내. 보고 위치는 첫 인자(콜백) 노드.
|
|
41
41
|
|
|
42
42
|
```typescript
|
|
43
43
|
effect(() => { this.sig(); void untracked(async () => { await this.load(); }); });
|
|
@@ -50,7 +50,7 @@ effect(() => { this.sig(); void untracked(async () => { await this.load(); }); }
|
|
|
50
50
|
검사 대상: `new NotImplementedError(...)`(named/aliased import), `new CC.NotImplementedError(...)`(namespace import). 식별자가 `@simplysm/core-common` 에서 import 되었는지 스코프로 검증. 동적 import(`await import(...)`)는 감지 안 함.
|
|
51
51
|
|
|
52
52
|
메시지:
|
|
53
|
-
- `noThrowNotImplementedError` —
|
|
53
|
+
- `noThrowNotImplementedError` — 본문은 `{{text}}` 치환. `new` 의 첫 인자가 비어있지 않은 문자열 리터럴이면 그 값을, 아니면 `"미구현"` 을 출력.
|
|
54
54
|
|
|
55
55
|
```typescript
|
|
56
56
|
import { NotImplementedError } from "@simplysm/core-common";
|
|
@@ -74,7 +74,7 @@ class C { private _svc = inject(MyService); } // _svc 미참조 시 제거
|
|
|
74
74
|
|
|
75
75
|
Angular `@Component` 의 인라인 템플릿·클래스 본문 어디에서도 안 쓰이는 `protected readonly` 필드를 감지. `type: "problem"`, autofix 있음, 옵션 없음.
|
|
76
76
|
|
|
77
|
-
검사 대상: `@Component` 데코레이터가 있고 그 첫 인자 객체에 `template` 속성(문자열 리터럴 또는 템플릿 리터럴)이 있는 클래스. 그 클래스의 `protected readonly` 비-static 필드(키가 Identifier)가 ① 인라인 템플릿에서 미참조 ② 클래스 본문 다른 멤버에서 미참조 둘 다일 때 보고. 템플릿 식별자는 `@angular/compiler` 의 `parseTemplate` 으로 AST 파싱 후 `ImplicitReceiver`/`ThisReceiver` 위 `PropertyRead`(클래스 필드 참조)만 수집하며, `*ngFor` 로컬·`@let`·`@if ... as`·`@for` item/별칭 등 스코프 로컬 변수는 제외. `@if`/`@switch`/`@for`/`@defer`
|
|
77
|
+
검사 대상: `@Component` 데코레이터가 있고 그 첫 인자 객체에 `template` 속성(문자열 리터럴 또는 템플릿 리터럴)이 있는 클래스. 그 클래스의 `protected readonly` 비-static 필드(키가 Identifier)가 ① 인라인 템플릿에서 미참조 ② 클래스 본문 다른 멤버에서 미참조 둘 다일 때 보고. 템플릿 식별자는 `@angular/compiler` 의 `parseTemplate` 으로 AST 파싱 후 `ImplicitReceiver`/`ThisReceiver` 위 `PropertyRead`(클래스 필드 참조)만 수집하며, `*ngFor` 로컬·`@let`·`@if ... as`·`@for` item/별칭 등 스코프 로컬 변수는 제외. `@if`/`@switch`/`@for`/`@defer` 블록과 입력/이벤트/구조 디렉티브 바인딩까지 순회. `templateUrl`(외부 템플릿)은 대상 아님(`template` 문자열만).
|
|
78
78
|
|
|
79
79
|
메시지:
|
|
80
80
|
- `unusedField` — `Protected readonly field "{{name}}" is not used in class or template.` autofix 는 필드 선언과 앞 들여쓰기·뒤 `;`·개행을 함께 제거.
|
|
@@ -86,7 +86,7 @@ class C { protected readonly title = "x"; protected readonly unused = 1; } // un
|
|
|
86
86
|
|
|
87
87
|
## ng-template-no-strict-null-check
|
|
88
88
|
|
|
89
|
-
Angular HTML 템플릿에서 엄격 비교(`=== null`, `!== null`, `=== undefined`, `!== undefined`)를 금지하고 `== null`/`!= null` 로 통일하도록 강제. `type: "problem"`, autofix 없음(인라인 템플릿 offset 매핑 문제로 미제공), 옵션 없음. HTML
|
|
89
|
+
Angular HTML 템플릿에서 엄격 비교(`=== null`, `!== null`, `=== undefined`, `!== undefined`)를 금지하고 `== null`/`!= null` 로 통일하도록 강제. `type: "problem"`, autofix 없음(인라인 템플릿 offset 매핑 문제로 미제공), 옵션 없음. HTML 대상.
|
|
90
90
|
|
|
91
91
|
검사 대상: 템플릿 표현식의 `Binary` 노드 중 연산자가 `===`/`!==` 이고 양변 중 하나가 nil 리터럴(value 가 null/undefined)인 경우.
|
|
92
92
|
|
|
@@ -94,14 +94,14 @@ Angular HTML 템플릿에서 엄격 비교(`=== null`, `!== null`, `=== undefine
|
|
|
94
94
|
- `noStrictNullCheck` — `{{actual}}`(예: `x === null`) 사용 금지, `{{replacement}}`(예: `x == null`) 사용 안내. `===`→`==`, `!==`→`!=` 로 변환한 권장 표현을 제시.
|
|
95
95
|
|
|
96
96
|
```html
|
|
97
|
-
@if (user !== null) {} <!-- user != null
|
|
97
|
+
@if (user !== null) {} <!-- "user != null 사용" 으로 보고 -->
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
## ng-template-no-todo-comments
|
|
101
101
|
|
|
102
|
-
Angular HTML 템플릿 내 `<!-- TODO: ... -->` 주석을 경고. `type: "problem"`, autofix 없음, 옵션 없음. recommended 에서 `warn`. HTML
|
|
102
|
+
Angular HTML 템플릿 내 `<!-- TODO: ... -->` 주석을 경고. `type: "problem"`, autofix 없음, 옵션 없음. recommended 에서 `warn`. HTML 대상.
|
|
103
103
|
|
|
104
|
-
동작: raw 텍스트를 `<!--...-->` 정규식으로 훑어 주석 내용에 `TODO:` 가 있으면 보고(AST 방문자 없이 빈 객체 반환). 메시지 본문은 `TODO:`
|
|
104
|
+
동작: raw 텍스트를 `<!--...-->` 정규식으로 훑어 주석 내용에 `TODO:` 가 있으면 보고(AST 방문자 없이 빈 객체 반환). 메시지 본문은 `TODO:` 뒤를 trim 한 내용.
|
|
105
105
|
|
|
106
106
|
메시지:
|
|
107
107
|
- `noTodo` — 본문은 `{{content}}`(TODO 뒤 텍스트) 그대로 출력.
|
|
@@ -112,17 +112,17 @@ Angular HTML 템플릿 내 `<!-- TODO: ... -->` 주석을 경고. `type: "proble
|
|
|
112
112
|
|
|
113
113
|
## ng-template-sd-require-binding-attrs
|
|
114
114
|
|
|
115
|
-
`sd-*` 접두사 커스텀 컴포넌트에서 허용목록 밖 plain attribute 사용을 금지하고 Angular property binding(`[attr]="..."`)을 강제. `type: "problem"`, autofix 있음. HTML
|
|
115
|
+
`sd-*` 접두사 커스텀 컴포넌트에서 허용목록 밖 plain attribute 사용을 금지하고 Angular property binding(`[attr]="..."`)을 강제. `type: "problem"`, autofix 있음. HTML 대상. **9종 중 유일하게 옵션 있는 규칙**.
|
|
116
116
|
|
|
117
117
|
옵션(`RuleOptions`, 모두 선택):
|
|
118
|
-
- `selectorPrefixes: string[]` — 검사 대상 요소 태그 접두사. 미지정 시 `["sd-"]`. 태그명을 소문자로 비교. 다른 디자인 시스템 접두사를 검사하려면 지정.
|
|
118
|
+
- `selectorPrefixes: string[]` — 검사 대상 요소 태그 접두사. 미지정 시 `["sd-"]`. 태그명을 소문자로 비교. 다른 디자인 시스템 접두사를 함께 검사하려면 지정.
|
|
119
119
|
- `allowAttributes: string[]` — plain attribute 로 허용할 정확한 이름 목록. 미지정 시 `["id","class","style","title","tabindex","role"]`. 소문자 비교. 추가로 허용할 표준 속성을 늘릴 때.
|
|
120
120
|
- `allowAttributePrefixes: string[]` — plain attribute 로 허용할 접두사 목록. 미지정 시 `["aria-","data-","sd-"]`. 소문자 비교. 접두사 기반(aria/data 등) 속성군을 통째 허용할 때.
|
|
121
121
|
|
|
122
122
|
동작: 대상 태그(접두사 매칭) 요소의 attribute 중 `allowAttributes`(정확 일치)·`allowAttributePrefixes`(접두사 일치) 어디에도 안 드는 것을 보고.
|
|
123
123
|
|
|
124
124
|
메시지:
|
|
125
|
-
- `requireBindingForAttribute` — `"{{attrName}}"` 은 `"{{elementName}}"` 의 plain attribute 로 불가, property binding 사용 안내. autofix 는 값이 빈 문자열이면 `[attr]="true"`, 값이 있으면 `\` 와 `'` 를 이스케이프해 `[attr]="'값'"` 로 치환(span 의 start≥end 면 수정 안 함).
|
|
125
|
+
- `requireBindingForAttribute` — `"{{attrName}}"` 은 `"{{elementName}}"` 의 plain attribute 로 불가, property binding 사용 안내. autofix 는 값이 빈 문자열이면 `[attr]="true"`, 값이 있으면 `\` 와 `'` 를 이스케이프해 `[attr]="'값'"` 로 치환(attribute span 의 start≥end 면 수정 안 함).
|
|
126
126
|
|
|
127
127
|
```html
|
|
128
128
|
<sd-button myattr="hello"></sd-button> <!-- → <sd-button [myattr]="'hello'"></sd-button> -->
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
# @simplysm/orm-common
|
|
2
2
|
|
|
3
|
-
Dialect
|
|
3
|
+
Dialect(MySQL/MSSQL/PostgreSQL) 독립 ORM 코어. 스키마를 빌더로 정의하고, `DbContext` 를 상속해 연결/트랜잭션/DDL 을 다루며, `Queryable` 체이닝과 `expr` 표현식 빌더로 타입 안전한 쿼리 AST(QueryDef/Expr)를 만든 뒤 dialect 별 QueryBuilder 로 SQL 을 렌더링한다. 실제 DB 연결·실행은 `@simplysm/orm-node` 등 `DbContextExecutor` 구현체가 담당하고, 이 패키지 자체는 dialect 독립 로직(빌더·AST·SQL 문자열 생성)까지만 가진다.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **DbContext /
|
|
8
|
-
- **스키마
|
|
9
|
-
- **Queryable
|
|
10
|
-
- **expr 표현식 빌더** — `where`/`select`/`orderBy
|
|
11
|
-
-
|
|
7
|
+
- **DbContext / 연결·트랜잭션·DDL·마이그레이션** — `DbContext` 를 상속해 테이블·뷰·프로시저를 프로퍼티로 등록하고 `connect`/`transaction`/`createTable`/`initialize` 등으로 연결·트랜잭션 경계와 스키마 변경을 다룰 때. 자세히: [db-context.md](./db-context.md)
|
|
8
|
+
- **스키마 빌더 (Table/View/Procedure/Column/Index/Relation)** — `Table()`/`View()`/`Procedure()` 와 column·index·relation 팩토리로 테이블·뷰·프로시저 정의를 fluent 하게 작성할 때. 자세히: [schema.md](./schema.md)
|
|
9
|
+
- **Queryable / Executable / 검색** — `db.X()` 로 시작하는 SELECT/INSERT/UPDATE/DELETE/UPSERT 체이닝, join/include/union/recursive, 텍스트 검색(`search`/`parseSearchQuery`), 프로시저 실행을 작성할 때. 자세히: [queryable.md](./queryable.md)
|
|
10
|
+
- **expr 표현식 빌더** — `where`/`select`/`groupBy`/`orderBy` 콜백 안에서 비교·논리·문자열·숫자·날짜·집계·조건·윈도우·서브쿼리 표현식을 만들 때. `ExprUnit`/`WhereExprUnit`/`ExprInput`/`expr.val`/`expr.raw` 포함. 자세히: [expr.md](./expr.md)
|
|
11
|
+
- **타입 / QueryDef·Expr AST / QueryBuilder / 결과 파싱** — executor 구현, dialect 별 SQL 렌더링(`createQueryBuilder`), QueryDef/Expr AST 타입, 컬럼 원시 타입(`ColumnPrimitive*`/`DataType`), 결과 변환(`parseQueryResult`/`pickResultSets`)을 다룰 때. 자세히: [types.md](./types.md)
|
|
12
|
+
|
|
13
|
+
## 전형적 사용 흐름
|
|
14
|
+
|
|
15
|
+
이 패키지의 export 는 위 5개 군으로 나뉘며 모두 별도 `.md` 로 분할되어 있다.
|
|
16
|
+
|
|
17
|
+
1. `schema.md` — `Table("User").columns(...).primaryKey(...).relations(...)` 로 스키마 정의.
|
|
18
|
+
2. `db-context.md` — `class AppDb extends DbContext { user = this.queryable(User); }` 로 컨텍스트 구성, `db.connect(async () => { ... })` 로 트랜잭션 경계 잡기.
|
|
19
|
+
3. `queryable.md` + `expr.md` — `db.user().where((u) => [expr.eq(u.id, 1)]).execute()` 형태로 조회·CUD.
|
|
20
|
+
4. `types.md` — executor·dialect 어댑터를 직접 구현하거나 AST/결과 파싱을 다룰 때.
|