@simplysm/sd-claude 14.0.82 → 14.0.84

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 (90) hide show
  1. package/claude/references/sd-requirement-source-handling.md +20 -20
  2. package/claude/references/sd-simplysm14/README.md +13 -13
  3. package/claude/references/sd-simplysm14/manuals/client-component.md +92 -92
  4. package/claude/references/sd-simplysm14/manuals/client-crud.md +11 -11
  5. package/claude/references/sd-simplysm14/manuals/client-demo.md +28 -28
  6. package/claude/references/sd-simplysm14/manuals/client-rules.md +1 -1
  7. package/claude/references/sd-simplysm14/manuals/client-setup.md +21 -21
  8. package/claude/references/sd-simplysm14/manuals/client-tab.md +3 -3
  9. package/claude/references/sd-simplysm14/manuals/logging.md +15 -15
  10. package/claude/references/sd-simplysm14/manuals/orm-union.md +6 -6
  11. package/claude/references/sd-simplysm14/manuals/orm.md +19 -19
  12. package/claude/references/sd-simplysm14/manuals/test.md +33 -33
  13. package/claude/rules/sd-design-rules.md +18 -18
  14. package/claude/sd-system-prompt.md +369 -0
  15. package/claude/skills/sd-commit/SKILL.md +10 -10
  16. package/claude/skills/sd-config/SKILL.md +2 -2
  17. package/claude/skills/sd-demo/SKILL.md +45 -45
  18. package/claude/skills/sd-dev/SKILL.md +15 -15
  19. package/claude/skills/sd-docs/SKILL.md +7 -7
  20. package/claude/skills/sd-docs/references/subagent-prompt.md +33 -33
  21. package/claude/skills/sd-impl/SKILL.md +60 -60
  22. package/claude/skills/sd-review/SKILL.md +9 -9
  23. package/claude/skills/sd-skill/SKILL.md +74 -74
  24. package/claude/skills/sd-skill/evals/fixtures/existing-skill/.claude/skills/todo-format/SKILL.md +1 -1
  25. package/claude/skills/sd-spec/SKILL.md +354 -319
  26. package/claude/skills/sd-spec/references/example-spec.md +104 -104
  27. package/claude/skills/sd-unpack/SKILL.md +34 -34
  28. package/claude/skills/sd-unpack/scripts/handlers/__pycache__/office_com.cpython-314.pyc +0 -0
  29. package/claude/skills/sd-unpack/scripts/handlers/office_com.py +234 -159
  30. package/claude/skills/sd-use/SKILL.md +4 -4
  31. package/package.json +1 -1
  32. package/claude/references/sd-simplysm14/apis/angular/README.md +0 -37
  33. package/claude/references/sd-simplysm14/apis/angular/app-structure.md +0 -92
  34. package/claude/references/sd-simplysm14/apis/angular/buttons.md +0 -88
  35. package/claude/references/sd-simplysm14/apis/angular/crud.md +0 -100
  36. package/claude/references/sd-simplysm14/apis/angular/forms.md +0 -200
  37. package/claude/references/sd-simplysm14/apis/angular/infrastructure.md +0 -231
  38. package/claude/references/sd-simplysm14/apis/angular/kanban.md +0 -80
  39. package/claude/references/sd-simplysm14/apis/angular/layout.md +0 -92
  40. package/claude/references/sd-simplysm14/apis/angular/modal.md +0 -115
  41. package/claude/references/sd-simplysm14/apis/angular/routing.md +0 -107
  42. package/claude/references/sd-simplysm14/apis/angular/select-dropdown.md +0 -35
  43. package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +0 -82
  44. package/claude/references/sd-simplysm14/apis/angular/shared-data.md +0 -134
  45. package/claude/references/sd-simplysm14/apis/angular/sheet.md +0 -127
  46. package/claude/references/sd-simplysm14/apis/angular/toast.md +0 -97
  47. package/claude/references/sd-simplysm14/apis/angular/visual.md +0 -167
  48. package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +0 -79
  49. package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +0 -83
  50. package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +0 -91
  51. package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +0 -49
  52. package/claude/references/sd-simplysm14/apis/core-browser/README.md +0 -143
  53. package/claude/references/sd-simplysm14/apis/core-common/README.md +0 -58
  54. package/claude/references/sd-simplysm14/apis/core-common/extensions.md +0 -88
  55. package/claude/references/sd-simplysm14/apis/core-common/features.md +0 -51
  56. package/claude/references/sd-simplysm14/apis/core-common/types.md +0 -88
  57. package/claude/references/sd-simplysm14/apis/core-common/utils.md +0 -189
  58. package/claude/references/sd-simplysm14/apis/core-node/README.md +0 -12
  59. package/claude/references/sd-simplysm14/apis/core-node/consola.md +0 -59
  60. package/claude/references/sd-simplysm14/apis/core-node/cpx.md +0 -44
  61. package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +0 -42
  62. package/claude/references/sd-simplysm14/apis/core-node/fsx.md +0 -53
  63. package/claude/references/sd-simplysm14/apis/core-node/pathx.md +0 -24
  64. package/claude/references/sd-simplysm14/apis/core-node/worker.md +0 -65
  65. package/claude/references/sd-simplysm14/apis/excel/README.md +0 -193
  66. package/claude/references/sd-simplysm14/apis/lint/README.md +0 -94
  67. package/claude/references/sd-simplysm14/apis/orm-common/README.md +0 -58
  68. package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +0 -77
  69. package/claude/references/sd-simplysm14/apis/orm-common/executable.md +0 -20
  70. package/claude/references/sd-simplysm14/apis/orm-common/expr.md +0 -92
  71. package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +0 -98
  72. package/claude/references/sd-simplysm14/apis/orm-common/schema-builders.md +0 -128
  73. package/claude/references/sd-simplysm14/apis/orm-node/README.md +0 -69
  74. package/claude/references/sd-simplysm14/apis/sd-claude/README.md +0 -32
  75. package/claude/references/sd-simplysm14/apis/sd-cli/README.md +0 -80
  76. package/claude/references/sd-simplysm14/apis/sd-cli/sd-config.md +0 -155
  77. package/claude/references/sd-simplysm14/apis/service-client/README.md +0 -131
  78. package/claude/references/sd-simplysm14/apis/service-common/README.md +0 -29
  79. package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +0 -63
  80. package/claude/references/sd-simplysm14/apis/service-common/messages.md +0 -56
  81. package/claude/references/sd-simplysm14/apis/service-common/protocol.md +0 -64
  82. package/claude/references/sd-simplysm14/apis/service-common/service-types.md +0 -43
  83. package/claude/references/sd-simplysm14/apis/service-server/README.md +0 -13
  84. package/claude/references/sd-simplysm14/apis/service-server/auth.md +0 -39
  85. package/claude/references/sd-simplysm14/apis/service-server/builtin-services.md +0 -71
  86. package/claude/references/sd-simplysm14/apis/service-server/define-service.md +0 -55
  87. package/claude/references/sd-simplysm14/apis/service-server/internals.md +0 -82
  88. package/claude/references/sd-simplysm14/apis/service-server/server.md +0 -57
  89. package/claude/references/sd-simplysm14/apis/storage/README.md +0 -71
  90. package/claude/rules/sd-base-rules.md +0 -306
@@ -1,193 +0,0 @@
1
- # @simplysm/excel
2
-
3
- OOXML(xlsx) ZIP 을 lazy 로 읽고 쓰는 neutral 패키지. 셀 단위 접근 시점에만 해당 XML(SharedStrings/Styles 등)을 로드하므로 대용량 파일 메모리 효율적.
4
-
5
- ## 사용 트리거 인덱스
6
-
7
- - 워크북 열기/생성/저장/해제 → [Workbook](#workbook)
8
- - 워크시트 추가·조회·이름·뷰(탭색/zoom/freeze) → [Worksheet 기본](#worksheet-기본)
9
- - 행/열/셀 접근, 데이터 범위, 2D 셀 조회 → [Row · Col · Cell 접근](#row--col--cell-접근)
10
- - 셀 값/수식/병합 읽고 쓰기 → [Cell 값·수식·병합](#cell-값수식병합)
11
- - 셀 스타일, 워크북 default 스타일 → [Style](#style)
12
- - 조건부 서식 → [Conditional Format](#conditional-format)
13
- - 이미지 삽입 → [Image](#image)
14
- - 데이터 테이블(레코드 배열) ↔ 시트 → [Data Matrix · Records](#data-matrix--records)
15
- - Zod 스키마 기반 타입 안전 입출력 → [ExcelWrapper](#excelwrapper)
16
- - 셀 주소 ↔ 좌표, Excel 날짜 ↔ JS tick → [ExcelUtils](#excelutils)
17
- - 타입(주소·값·스타일·조건부 규칙 등) → [타입](#타입)
18
-
19
- ---
20
-
21
- ## Workbook
22
-
23
- `new ExcelWorkbook(arg?: Blob | Bytes)` — 인자 없으면 빈 워크북 생성(기본 OOXML 골격: `[Content_Types].xml`, `_rels/.rels`, `xl/workbook.xml`, `xl/_rels/workbook.xml.rels`). 인자가 있으면 ZIP 을 lazy reader 로 열기.
24
-
25
- 핵심 메서드:
26
- - `getWorksheetNames(): Promise<string[]>` — 시트명 배열.
27
- - `addWorksheet(name): Promise<ExcelWorksheet>` — 새 시트 추가 + ContentTypes/Rels 갱신.
28
- - `getWorksheet(nameOrIndex: string | number): Promise<ExcelWorksheet>` — 이름 또는 0 기반 인덱스. 없으면 throw.
29
- - `setDefaultStyle(opts: ExcelStyleOptions): Promise<void>` — `styles.xml` 의 `fonts[0]/fills[0]/borders[0]` (default 자원 슬롯) 및 `cellXfs[0]` 를 옵션으로 덮어쓰기. 셀 xf 가 자원 id 미지정이면 0번 슬롯이 fallback 되어 전역 적용. 옵션 없는 자원은 0번을 빈 슬롯으로 reset. 미호출 시 원본 보존.
30
- - `toBytes(): Promise<Bytes>` / `toBlob(): Promise<Blob>` — ZIP 직렬화. Blob 의 mime = `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`.
31
- - `close(): Promise<void>` — ZIP 리더와 캐시 해제. 호출 후 다른 메서드 호출 시 throw. 재호출 safe(no-op). **반드시 try/finally 로 호출**.
32
-
33
- ```typescript
34
- const wb = new ExcelWorkbook(bytes);
35
- try {
36
- const ws = await wb.getWorksheet(0);
37
- // ...
38
- } finally { await wb.close(); }
39
- ```
40
-
41
- ## Worksheet 기본
42
-
43
- `ExcelWorksheet` 는 `addWorksheet` / `getWorksheet` 로만 획득(직접 생성자 호출 X).
44
-
45
- - `getName(): Promise<string>` / `setName(newName: string): Promise<void>`
46
- - `getRange(): Promise<ExcelAddressRangePoint>` — 데이터가 존재하는 범위(시트의 `<dimension>` 기반).
47
- - `getCells(): Promise<ExcelCell[][]>` — `range` 전체를 2차원 배열로.
48
- - `setTabColor(color: string): Promise<void>` — 시트 탭 색. ARGB 8자리 16진수(예: `"00FF0000"`).
49
- - `setZoom(percent: number): Promise<void>` — 보기 확대 비율(%).
50
- - `freezeAt(point: { r?: number; c?: number }): Promise<void>` — 행/열 틀 고정.
51
- - `copyRow(srcR, targetR)` — 행 덮어쓰기 복사.
52
- - `copyCell(srcAddr, targetAddr)` — 셀 복사.
53
- - `copyRowStyle(srcR, targetR)` / `copyCellStyle(srcAddr, targetAddr)` — 스타일만 복사.
54
- - `insertCopyRow(srcR, targetR)` — `targetR` 위치에 행 삽입 복사. 이하 기존 행은 한 칸 아래로 밀린다. 삽입 지점을 관통하는 다중행 병합은 1행 확장. 원본의 단일행 병합은 복제.
55
-
56
- ## Row · Col · Cell 접근
57
-
58
- `ExcelWorksheet` 인스턴스 메서드 (모두 0 기반 인덱스, 인스턴스는 캐싱됨):
59
- - `row(r): ExcelRow` / `col(c): ExcelCol` / `cell(r, c): ExcelCell`
60
-
61
- `ExcelRow`:
62
- - `cell(c): ExcelCell` — 같은 행의 셀.
63
- - `getCells(): Promise<ExcelCell[]>` — 시트 `range` 의 열 범위만큼.
64
-
65
- `ExcelCol`:
66
- - `cell(r): ExcelCell` — 같은 열의 셀.
67
- - `getCells(): Promise<ExcelCell[]>` — 시트 `range` 의 행 범위만큼.
68
- - `setWidth(size: number): Promise<void>` — 열 너비(OOXML 단위).
69
-
70
- ## Cell 값·수식·병합
71
-
72
- `ExcelCell.addr: ExcelAddressPoint` — 0 기반 `{r, c}`.
73
-
74
- - `getValue(): Promise<ExcelValueType>` — 셀 타입과 styles.xml 의 numFmt 를 보고 자동 변환:
75
- - `s`(SharedString) → `string`
76
- - `str`/`inlineStr` → `string`
77
- - `b` → `boolean`
78
- - `n` 또는 타입 미지정 → `numFmt` 가 날짜 계열이면 `DateOnly`/`DateTime`/`Time`, 아니면 `number`. 텍스트 형식(numFmtId 49)이면 `string`.
79
- - `e`(error) → throw.
80
- - `setValue(val: ExcelValueType): Promise<void>` — 값 타입으로 자동 분기:
81
- - `undefined` → 셀 삭제
82
- - `string` → SharedString 으로 등록(`t="s"`)
83
- - `boolean` → `t="b"`, `"1"`/`"0"`
84
- - `number` → numeric
85
- - `DateOnly`/`DateTime`/`Time` → Excel 날짜 숫자로 변환 + 해당 numFmt(14/22/18) 자동 적용
86
- - 그 외 타입 → throw.
87
- - `setFormula(val: string | undefined): Promise<void>` / `getFormula(): Promise<string | undefined>` — 수식 설정/조회. `undefined` 전달 시 셀 삭제.
88
- - `merge(r, c): Promise<void>` — 현재 셀에서 `(r, c)` 까지 병합(양 끝 inclusive). 예: `cell(0,0).merge(2,2)` → A1:C3.
89
-
90
- ## Style
91
-
92
- - `cell.setStyle(opts: ExcelStyleOptions): Promise<void>` — 셀 스타일 적용. 기존 styleId 가 있으면 clone + override.
93
- - `cell.getStyleId(): Promise<string | undefined>` / `setStyleId(id)` — 원시 cellXfs id 조작.
94
- - `wb.setDefaultStyle(opts)` — 워크북 default. [Workbook](#workbook) 참고.
95
-
96
- `ExcelStyleOptions`:
97
- - `background?: string` — 셀 배경. ARGB 8자리(예: `"00FF0000"`).
98
- - `border?: ("left" | "right" | "top" | "bottom")[]` — 활성화할 변. style 은 thin.
99
- - `horizontalAlign?: "left" | "center" | "right"` / `verticalAlign?: "top" | "center" | "bottom"`.
100
- - `numberFormat?: "number" | "string" | "DateOnly" | "DateTime" | "Time"` — 프리셋 numFmtId 매핑(0/49/14/22/18).
101
- - `numberFormatCode?: string` — 임의 Excel formatCode(예: `"0.000000"`). `numberFormat` 보다 우선.
102
- - `font?: ExcelFont` — `{ size?, family?, bold?, italic?, underline?: "single"|"double"|"singleAccounting"|"doubleAccounting", color?: ARGB8, strike? }`. 미지정 속성은 emit 안 함(Excel 기본값 표시).
103
-
104
- ## Conditional Format
105
-
106
- `ws.addConditionalFormat({ ref, rules }): Promise<void>` — 셀/범위에 조건부 서식 규칙 추가. `ref` = `"A1"` 또는 `"A1:B10"`. `rules` 배열 순서가 priority(앞 우선). 같은 시트에 여러 번 호출하면 블록이 누적되고 priority 가 시트 전역으로 이어붙음. 빈 배열이면 no-op.
107
-
108
- `ExcelConditionalRule` 종류:
109
- - `{ type: "cellIs", op: "<"|">"|"<="|">="|"="|"<>", value: number|string, style }` — 단일 비교. `value` 가 string 이면 따옴표 리터럴 formula 로 emit, number 면 raw formula.
110
- - `{ type: "cellIs", op: "between"|"notBetween", value: [a,b], style }` — 양 끝 inclusive 구간.
111
- - `{ type: "text", op: "contains"|"notContains"|"beginsWith"|"endsWith", value: string, style }` — SEARCH 기반(대소문자 무시) 고정.
112
- - `{ type: "expression", formula: string, style }` — 임의 수식 식.
113
-
114
- `ExcelConditionalRuleStyle`:
115
- - `background?: ARGB8` — 강조 배경.
116
- - `fontColor?: ARGB8` — 글자색.
117
- - `fontWeight?: "bold" | "normal"` — `"normal"` 은 base 가 bold 라도 강제 normal.
118
-
119
- 미지정 필드는 base 셀 스타일을 유지하며, 지정 필드만 OOXML dxf 로 emit 되어 Excel native CF 오버레이로 합성.
120
-
121
- ```typescript
122
- await ws.addConditionalFormat({
123
- ref: "B2:B100",
124
- rules: [{ type: "cellIs", op: "<", value: 1000, style: { background: "00FF0000" } }],
125
- });
126
- ```
127
-
128
- ## Image
129
-
130
- `ws.addImage(opts): Promise<void>`
131
- - `bytes: Bytes` — 이미지 바이너리.
132
- - `ext: string` — 확장자(`png`/`jpg` 등). `mime` 라이브러리로 MIME 결정, 미인식 시 throw.
133
- - `from: { r, c, rOff?: number|string, cOff?: number|string }` — 시작 위치(0 기반 행/열, `rOff/cOff` 는 EMU 오프셋).
134
- - `to?: { r, c, rOff?, cOff? }` — 끝 위치. 생략 시 `from.r+1`, `from.c+1` 의 1×1 셀 크기.
135
-
136
- 기존 drawing 이 있으면 거기에 picture 를 추가하고, 없으면 `xl/drawings/drawing{N}.xml` 신규 생성 + ContentTypes/sheet rels 연결.
137
-
138
- ## Data Matrix · Records
139
-
140
- `ws.setDataMatrix(matrix: ExcelValueType[][]): Promise<void>` — 2D 배열(행 우선)을 (0,0) 부터 기록. 셀 값은 `setValue` 와 동일 규칙으로 자동 분기.
141
-
142
- `ws.setRecords(records: Record<string, ExcelValueType>[]): Promise<void>` — 0행에 헤더(레코드들의 key union, 빈 문자열 제외), 1행부터 데이터.
143
-
144
- `ws.getDataTable(opt?): Promise<Record<string, ExcelValueType>[]>`:
145
- - `opt.headerRowIndex?: number` — 헤더 행 인덱스(기본 = `range.s.r`).
146
- - `opt.checkEndColIndex?: number` — 이 열이 비어 있으면 데이터 종료로 판정.
147
- - `opt.usableHeaderNameFn?: (headerName) => boolean` — 사용할 헤더 필터. 헤더가 string 타입인 컬럼만 후보. 헤더 중복 발견 시 throw.
148
-
149
- ## ExcelWrapper
150
-
151
- `new ExcelWrapper<TSchema>(schema)` — Zod 스키마로 Excel ↔ 레코드 변환. 필드의 `.describe("...")` 가 Excel 헤더 이름. describe 없으면 필드 key.
152
-
153
- - `read(file, wsNameOrIndex = 0, options?: { excludes? }): Promise<z.infer<TSchema>[]>`
154
- - 시트의 헤더 행에서 스키마와 매칭되는 컬럼만 추출.
155
- - 각 행을 변환(`ZodString`→string, `ZodNumber`→`num.parseFloat`, `ZodBoolean`→`"1"/"true"`/`"0"/"false"`/Boolean 강제), `safeParse` 로 검증, 실패 시 throw.
156
- - 전 컬럼이 null/empty 인 행은 skip.
157
- - 데이터 0행이면 throw.
158
- - `options.excludes` 로 특정 필드 제외.
159
- - 내부적으로 ExcelWorkbook 을 열고 finally 에서 close.
160
- - `write(wsName, records, options?: { excludes? }): Promise<ExcelWorkbook>`
161
- - 헤더 = describe 이름 또는 key.
162
- - 데이터 본문 기록 후 전체 셀에 4변 테두리.
163
- - 필수 필드(Optional/Nullable/Default 가 아님) + boolean 아닌 필드의 헤더 셀에 노란색(`"00FFFF00"`) 배경.
164
- - `setZoom(85)`, `freezeAt({ r: 0 })`.
165
- - 반환된 워크북의 `close()` 는 호출자 책임. 내부 throw 시에는 자동 close 후 rethrow.
166
-
167
- ## ExcelUtils
168
-
169
- 정적 메서드 모음.
170
-
171
- - `stringifyAddr({r,c})` → `"B3"`. `stringifyRowAddr(r)` → `"3"`. `stringifyColAddr(c)` → `"AA"` 등. `c` 범위 0~16383, 초과 시 throw.
172
- - `parseCellAddr("B3")` → `{r:2, c:1}`. `parseRowAddr`/`parseColAddr` 동일 패턴.
173
- - `parseRangeAddr("A1:C3")` → `{s, e}`. 단일 셀 입력 시 `s === e`.
174
- - `stringifyRangeAddr({s,e})` → `"A1:C3"`. `s === e` 면 단일 주소만.
175
- - `convertTimeTickToNumber(tick)` / `convertNumberToTimeTick(value)` — JS ms tick ↔ Excel serial date. Excel 기준일 = 1899-12-30.
176
- - `convertNumFmtCodeToName(code)` → `ExcelNumberFormat`. `"General"` = number. `yy`/`dd`/`mm` 패턴 검출(`hh:mm`/`mm:ss` 의 mm 은 분으로 제외)로 Date/Time 분류. 매칭 실패 시 throw.
177
- - `convertNumFmtIdToName(id)` → `ExcelNumberFormat`. Excel 내장 ID 범위 기반(숫자: 0–13,37–40,48 / Date: 14–17,27–31,34–36,50–58 / DateTime: 22 / Time: 18–21,32–33,45–47 / string: 49). 매칭 실패 시 throw.
178
- - `convertNumFmtNameToId(name)` — number→0, DateOnly→14, DateTime→22, Time→18, string→49.
179
-
180
- ## 타입
181
-
182
- - `ExcelValueType = number | string | DateOnly | DateTime | Time | boolean | undefined` — 셀 값 도메인. `undefined` = 빈 셀.
183
- - `ExcelNumberFormat = "number" | "string" | "DateOnly" | "DateTime" | "Time"` — 숫자 형식 프리셋 이름.
184
- - `ExcelCellType = "s" | "b" | "str" | "n" | "inlineStr" | "e"` — OOXML 의 셀 `t` 속성: SharedString / boolean / 수식결과문자열 / 숫자 / 인라인문자열 / 에러.
185
- - `ExcelAddressPoint = { r: number; c: number }` — 0 기반 좌표.
186
- - `ExcelAddressRangePoint = { s: ExcelAddressPoint; e: ExcelAddressPoint }` — start/end inclusive.
187
- - `ExcelBorderPosition = "left" | "right" | "top" | "bottom"`.
188
- - `ExcelHorizontalAlign = "center" | "left" | "right"` / `ExcelVerticalAlign = "center" | "top" | "bottom"`.
189
- - `ExcelFontUnderline = "single" | "double" | "singleAccounting" | "doubleAccounting"` — OOXML `<u val>` 그대로.
190
- - `ExcelFont`, `ExcelStyleOptions` — [Style](#style) 참고.
191
- - `ExcelConditionalRule`, `ExcelConditionalRuleStyle` — [Conditional Format](#conditional-format) 참고.
192
- - `ExcelXml` — `{ data: unknown; cleanup(): void }`. ZipCache 가 보관하는 XML 객체의 공통 인터페이스(내부용).
193
- - `Excel*Data` 인터페이스들 — OOXML XML 의 JS 객체 표현(xml2js 스타일, 내부 처리용). 외부 코드에서 직접 다룰 일 없음.
@@ -1,94 +0,0 @@
1
- # @simplysm/lint
2
-
3
- Simplysm 컨벤션용 ESLint 플러그인 패키지. 커스텀 규칙 묶음(`./eslint-plugin`)과 typescript-eslint·angular-eslint 통합 flat config 프리셋(`./eslint-recommended`)을 제공한다.
4
-
5
- ## 사용 트리거 인덱스
6
-
7
- - **`./eslint-recommended` (default export)** — 프로젝트 `eslint.config.{js,mjs,cjs}` 에서 그대로 spread 해 simplysm 표준 lint 규칙을 적용할 때.
8
- - **`./eslint-plugin` (default export)** — recommended 를 사용하지 않고 개별 규칙만 골라 쓰거나, 다른 flat config 에서 `@simplysm/<rule>` 로 참조할 때.
9
- - **`ng-no-async-effect`** — Angular `effect()` 콜백을 async 로 작성하지 않게 막을 때.
10
- - **`ng-template-no-strict-null-check`** — Angular 템플릿에서 `=== null|undefined` 대신 `== null` 로 통일시킬 때.
11
- - **`ng-template-no-todo-comments`** — Angular 템플릿 내 `<!-- TODO: ... -->` 를 빌드 경고로 남길 때.
12
- - **`ng-template-sd-require-binding-attrs`** — `sd-*` 컴포넌트에 plain attribute 못 쓰게 하고 property binding 으로 강제할 때.
13
- - **`no-hard-private`** — `#field` 대신 TypeScript `private _field` 스타일을 강제할 때.
14
- - **`no-subpath-imports-from-simplysm`** — `@simplysm/<pkg>/src/...` 직접 import 를 차단할 때.
15
- - **`ts-no-throw-not-implemented-error`** — `NotImplementedError` 잔존을 빌드 경고로 표면화할 때.
16
- - **`ts-no-unused-injects`** — Angular `inject()` 로 받은 미사용 필드를 정리할 때.
17
- - **`ts-no-unused-protected-readonly`** — Angular 컴포넌트 인라인 템플릿/클래스 어느 쪽에서도 안 쓰는 `protected readonly` 필드를 정리할 때.
18
-
19
- ## `./eslint-recommended`
20
-
21
- ```ts
22
- // eslint.config.mjs
23
- import recommended from "@simplysm/lint/eslint-recommended";
24
- export default recommended;
25
- // 또는 추가 config 와 함께
26
- export default [...recommended, { /* overrides */ }];
27
- ```
28
-
29
- `typescript-eslint.config(...)` 결과(flat config 배열). 다음을 합쳐 export 한다:
30
-
31
- - `ignores`: `**/node_modules/**`, `**/dist/**`, `**/.*/**` (디렉터리 단위 스킵).
32
- - `**/*.{js,mjs,cjs}` 블록: globals=node, 플러그인 `import`/`@simplysm`/`unused-imports`, `import/no-extraneous-dependencies` 예외 경로 = `**/lib/**`, `**/eslint.config.{js,cjs,mjs}`, `**/simplysm.{js,cjs,mjs}`, `**/vitest.config.{js,cjs,mjs}`.
33
- - `angular.configs.tsRecommended` + `**/*.ts` 블록: `tseslint.parser` + `parserOptions.project: true`, `angular.processInlineTemplates` processor, `eslint-import-resolver-typescript` resolver(`alwaysTryTypes: true`).
34
- - `**/*.html` 블록: `angular.configs.templateRecommended` + `templateAccessibility` extends, `@angular-eslint/template/eqeqeq` 는 `allowNullOrUndefined: true`, `label-has-associated-control` off, `template/no-any` error.
35
- - `**/tests/**/*.ts` override: `no-console`, `import/no-extraneous-dependencies`, `@simplysm/ts-no-throw-not-implemented-error` off.
36
- - `**/vitest.config.ts` override: `no-restricted-properties` off (vitest 가 `process` 접근 필요).
37
-
38
- 공통으로 강제되는 simplysm 컨벤션:
39
-
40
- - `Buffer`/`buffer`/`events`/`eventemitter3` 금지 → `Uint8Array`/`@simplysm/core-common` 사용 유도.
41
- - `process.env`/`import.meta.env` 직접 접근 금지 → `env("...")` 호출 강제. `env("NODE_ENV")` 자체 금지.
42
- - `=== undefined` / `!== undefined` 금지 → `== null` / `!= null` 통일.
43
- - TS 블록 전용: `naming-convention` 으로 `private` 멤버에 leading underscore(`_foo`) 강제, `strict-boolean-expressions` (nullable boolean/object 허용), `ban-ts-comment` (`ts-expect-error` 는 3자 이상 설명 필수), `only-throw-error`, `no-floating-promises` 등.
44
- - `unused-imports/no-unused-imports` error, `unused-imports/no-unused-vars` error (vars=all, args=after-used, 둘 다 `^_` 시작 식별자는 제외).
45
- - `@typescript-eslint/no-misused-promises`: `checksVoidReturn.arguments=false`, `inheritedMethods=false` (Angular 이벤트 핸들러 패턴 허용).
46
- - TS 블록에 등록되는 `@simplysm/*` 룰: `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.
47
- - HTML 블록에 등록되는 `@simplysm/*` 룰: `ng-template-no-strict-null-check` error, `ng-template-sd-require-binding-attrs` error, `ng-template-no-todo-comments` warn.
48
- - JS 블록에 등록되는 `@simplysm/*` 룰: `no-subpath-imports-from-simplysm`, `no-hard-private` (둘 다 error).
49
-
50
- ## `./eslint-plugin`
51
-
52
- ```ts
53
- // eslint.config.mjs
54
- import simplysm from "@simplysm/lint/eslint-plugin";
55
- export default [{
56
- plugins: { "@simplysm": simplysm },
57
- rules: { "@simplysm/no-hard-private": "error" },
58
- }];
59
- ```
60
-
61
- `{ rules: { ... } }` 형태의 ESLint 플러그인 객체. 노출 규칙(전부 `@simplysm/<name>` 으로 참조):
62
-
63
- ### `ng-no-async-effect` (problem)
64
- `@angular/core`에서 import 한 `effect()` 1번째 인자가 async 함수면 보고. named/aliased/namespace import 모두 추적. `await` 이후 signal read 가 의존성 추적 밖으로 빠지는 문제 방지. 안내: 비동기 작업은 `void untracked(async () => { ... })` 로 감쌀 것.
65
-
66
- ### `ng-template-no-strict-null-check` (problem)
67
- HTML 템플릿 바인딩에서 `=== null|undefined`, `!== null|undefined` 사용 시 보고. `== null`/`!= null` 로 통일 유도. autofix 없음(인라인 템플릿 offset 매핑 문제).
68
-
69
- ### `ng-template-no-todo-comments` (problem, recommended=warn)
70
- HTML 주석 `<!-- TODO: ... -->` 를 정규식으로 탐지해 본문을 메시지로 보고. AST 방문자 없이 raw text 스캔.
71
-
72
- ### `ng-template-sd-require-binding-attrs` (problem, fixable)
73
- `sd-*` 접두사 컴포넌트의 plain attribute 사용을 제한하고 property binding 으로 변환.
74
- - 옵션: `selectorPrefixes`(기본 `["sd-"]`), `allowAttributes`(기본 `["id","class","style","title","tabindex","role"]`), `allowAttributePrefixes`(기본 `["aria-","data-","sd-"]`).
75
- - Autofix: `foo="bar"` → `[foo]="'bar'"`, 값 없으면 `[foo]="true"`.
76
-
77
- ### `no-hard-private` (problem, fixable)
78
- ES private 필드(`#field`, `#method()`, `accessor #field`, `this.#field`) 금지. TypeScript `private _field` 스타일 강제. Autofix 로 `#x` → `_x` 치환 + 선언부에 `private` 키워드 삽입(데코레이터/`static`/`async`/`readonly` 순서 보존). 동일 클래스에 `_x` 멤버가 이미 있으면 `nameConflict` 로 보고만(자동 수정 안 함).
79
-
80
- ### `no-subpath-imports-from-simplysm` (problem, fixable)
81
- `@simplysm/<pkg>/src/...` 형태 import 금지. 정적 `import`, 동적 `import()`, `export ... from`, `export * from` 모두 검사. Autofix: `@simplysm/<pkg>` 로 단축.
82
-
83
- ### `ts-no-throw-not-implemented-error` (suggestion, recommended=warn)
84
- `@simplysm/core-common` 에서 import 한 `NotImplementedError` 의 `new` 호출 보고. named/aliased/namespace import 추적. 인자가 비어있지 않은 문자열 리터럴이면 메시지에 그대로 노출(없으면 `"미구현"`). 동적 import 는 미지원. `**/tests/**/*.ts` 에서는 off.
85
-
86
- ### `ts-no-unused-injects` (problem, fixable)
87
- 클래스 내 `inject()` 로 초기화된 PropertyDefinition 중 같은 클래스 본문에서 식별자로 단 한 번도 참조되지 않는 필드 보고. Autofix 로 해당 필드 라인 제거.
88
-
89
- ### `ts-no-unused-protected-readonly` (problem, fixable)
90
- `@Component({ template: "..." })` 클래스의 `protected readonly` 인스턴스 필드(=static 제외) 중 인라인 템플릿과 클래스 본문 모두에서 미참조면 보고·자동 제거. `templateUrl` 만 있는 경우(=`template` 프로퍼티 없음) 검사 스킵. 템플릿은 `@angular/compiler` 의 `parseTemplate` 로 파싱하며 `*ngFor` 로컬 변수, `@let`, `@if as alias`, `@for item/context`, `@switch`/`@defer` 트리거까지 스코프 처리.
91
-
92
- ## 규칙 작성용 유틸 (내부)
93
-
94
- `createRule` 은 패키지 내부 규칙 정의 전용 헬퍼(`ESLintUtils.RuleCreator` 래퍼)로, 외부 export 표면(`exports` 필드) 에 노출되지 않는다. 소비자 코드에서 직접 사용하지 않음.
@@ -1,58 +0,0 @@
1
- # @simplysm/orm-common
2
-
3
- Dialect 독립 ORM 코어. `DbContext` 상속으로 테이블/뷰/프로시저를 등록하고, fluent builder + Expr AST 로 쿼리를 구성하면, 각 DBMS(MySQL/MSSQL/PostgreSQL) QueryBuilder 가 SQL 로 렌더한다. 실제 connect/execute 는 외부 executor 가 구현 (서버=`@simplysm/orm-node`, 클라이언트=`@simplysm/service-client` 의 OrmServiceClient).
4
-
5
- ## 사용 트리거 인덱스
6
-
7
- - **`DbContext` (abstract class)** — DB 1개에 매핑되는 서브클래스를 만들 때. `protected queryable(Builder)` / `executable(Builder)` 로 테이블·뷰·프로시저를 인스턴스 프로퍼티로 등록, `connect()`/`transaction()` 로 실행 경계 잡고, DDL/`initialize()` 로 스키마 만들 때. 자세히: [db-context.md](./db-context.md)
8
- - **Schema Builders** — `Table(name)`, `View(name)`, `Procedure(name)` 로 스키마 객체 정의할 때. Column / Index / Relation factory 포함. 자세히: [schema-builders.md](./schema-builders.md)
9
- - **`Queryable` / `queryable()`** — `DbContext` 에 등록된 테이블/뷰에서 SELECT/INSERT/UPDATE/DELETE/UPSERT 빌더 체이닝, JOIN/include/recursive CTE/UNION/search 할 때. 자세히: [queryable.md](./queryable.md)
10
- - **`Executable` / `executable()`** — 등록된 프로시저 호출 결과 받을 때. 자세히: [executable.md](./executable.md)
11
- - **`expr` namespace + `ExprUnit`/`WhereExprUnit`** — `where`/`select`/`groupBy`/`having`/`update` 콜백 안에서 비교·논리·문자열·날짜·집계·윈도우·CASE·subquery 등 SQL 표현식 만들 때. dialect 독립 AST. 자세히: [expr.md](./expr.md)
12
- - **`parseSearchQuery(text)`** — `Queryable.search()` 내부에서 쓰는 OR/`+`AND/`-`NOT/`"…"`/`*` 구문 파서. 직접 LIKE 패턴이 필요할 때만 외부 사용. (`ParsedSearchQuery` = `{ or, must, not }`)
13
- - **`createQueryBuilder(dialect)`** — `Dialect` 문자열로 dialect 별 QueryBuilder 인스턴스 받을 때 (executor 진입점).
14
- - **`QueryBuilderBase` / `ExprRendererBase`** — 커스텀 dialect 구현을 위해 상속 베이스 필요할 때.
15
- - **`MysqlQueryBuilder` / `MssqlQueryBuilder` / `PostgresqlQueryBuilder`** (와 대응 `*ExprRenderer`) — 특정 dialect 인스턴스를 직접 new 하거나 `instanceof` 분기할 때. 일반은 `createQueryBuilder` 사용.
16
- - **`QueryDef` (union) + `QueryDefObjectName` (`./types/query-def`)** — executor 가 받는 query AST 의 union 타입 / 모든 DDL/DML 이 공통으로 쓰는 `{database?, schema?, name}` 형태의 DB 객체 식별자.
17
- - **`SelectQueryDef`, `InsertQueryDef`, `InsertIfNotExistsQueryDef`, `InsertIntoQueryDef`, `UpdateQueryDef`, `DeleteQueryDef`, `UpsertQueryDef`, `SelectQueryDefJoin`, `CudOutputDef`** — DML AST 노드를 직접 만들거나 검사할 때 (executor·테스트).
18
- - **DDL QueryDef (`Create*` / `Drop*` / `Rename*` / `Add*` / `Modify*` / `Truncate*` / `Clear*` / `Schema*` / `ExecProc*` 등)** — 스키마 변경/프로시저 호출 AST 를 직접 다룰 때 (`getXxxQueryDef()` 반환 타입과 일치).
19
- - **`DDL_TYPES` (배열) / `DdlType` (union)** — query 가 DDL 인지 런타임/타입 레벨에서 검사할 때. 트랜잭션 내 DDL 차단 가드에서 사용.
20
- - **`Expr` (union) / `WhereExpr` (union)** — SELECT·ORDER BY·SET 콜백이 모두 받는 일반 표현식 AST 와, WHERE·HAVING 전용 boolean 표현식 AST. ExprRenderer 가 dispatch 하는 대상.
21
- - **개별 Expr 노드 (`ExprColumn`, `ExprValue`, `ExprRaw`, `ExprEq`, `ExprLike`, `ExprConcat`, `ExprDateDiff`, `ExprSwitch`, `ExprCount`, `ExprWindow`, `ExprSubquery` …)** — Expr renderer 구현, AST 검사, 디버깅 시 개별 노드 타입 필요할 때. 응용 코드는 `expr.*` 헬퍼만 사용.
22
- - **`WinFn` (union) / `WinSpec` / `WinFn*` 개별 노드** — Window 함수 AST 분기 (`rowNumber`, `rank`, `lag`, `sumOver` 등) 를 직접 처리할 때.
23
- - **`DateUnit`** — `dateDiff`/`dateAdd` 의 단위 union (`"year" | "month" | "day" | "hour" | "minute" | "second"`). 동적으로 단위 선택할 때.
24
- - **`DataType` (`./types/column`)** — SQL 타입 union (`{type:"int"}` / `{type:"varchar",length}` / `{type:"decimal",precision,scale?}` ...). DDL/cast 의 타입 인자.
25
- - **`ColumnPrimitive` / `ColumnPrimitiveStr` / `ColumnPrimitiveMap`** — Column 값으로 허용되는 TS 타입 union (`string|number|boolean|DateTime|DateOnly|Time|Uuid|Bytes|undefined`), 그 키 이름 union, 키→타입 매핑. ExprUnit/ResultMeta 가 사용.
26
- - **`ColumnMeta`** — `ColumnBuilder.meta` 의 형태 (`{type, dataType, autoIncrement?, nullable?, default?, description?}`). 외부에서 column 정의를 읽어 DDL 만들 때.
27
- - **`dataTypeStrToColumnPrimitiveStr`** — `DataType.type` → `ColumnPrimitiveStr` 상수 매핑. cast 결과 dataType 추론에 사용.
28
- - **`InferColumnPrimitiveFromDataType<T>`** — `DataType` 타입에서 TS 값 타입 추론 (제네릭 타입 유틸).
29
- - **`inferColumnPrimitiveStr(value)`** — 런타임 값에서 `ColumnPrimitiveStr` 추론. NULL/unknown 이면 throw.
30
- - **`Dialect`** — `"mysql" | "mssql" | "postgresql"` union. dialect 분기/`createQueryBuilder` 인자.
31
- - **`dialects`** — `Dialect[]` 상수 배열. 테스트의 `it.each(dialects)` 또는 모든 dialect 순회용.
32
- - **`DataRecord`** — query 결과 row 의 재귀 타입 (`{ [key]: ColumnPrimitive | DataRecord | DataRecord[] }`). Queryable/Executable 의 결과 제약.
33
- - **`DbContextExecutor`** — 외부에서 DbContext 에 주입할 executor 인터페이스 (`connect`/`close`/`beginTransaction`/`commitTransaction`/`rollbackTransaction`/`executeDefs`). 신규 dialect/원격 executor 구현 시.
34
- - **`ResultMeta`** — `executeDefs` 가 받는 `{columns: Record<string,ColumnPrimitiveStr>, joins: Record<string,{isSingle}>}`. raw row → 타입 변환·JOIN 그룹핑에 필요.
35
- - **`IsolationLevel`** — `"READ_UNCOMMITTED" | "READ_COMMITTED" | "REPEATABLE_READ" | "SERIALIZABLE"`. `connect`/`transaction` 인자.
36
- - **`Migration`** — `{name, up(db)}`. DbContext 서브클래스의 `migrations` 프로퍼티 타입. `initialize()` 가 적용.
37
- - **`QueryBuildResult`** — `QueryBuilder.build()` 반환 (`{sql, resultSetIndex?, resultSetStride?}`). executor 가 `pickResultSets` 로 좁힐 때 필요.
38
- - **`DbContextBase` (`./types/db-context-def`)** — DbContext 의 코어 인터페이스 (`status`/`database`/`schema`/`executeDefs`/`getNextAlias` 등). Queryable·Executable·ViewBuilder 가 의존하므로 mock/대체 구현 시 사용.
39
- - **`DbContextStatus`** — `"ready" | "connect" | "transact"`. status 분기 시.
40
- - **`DbContextDdlMethods`** — `createTable`/`addColumn`/`addForeignKey` 등 DDL 메서드 집합 인터페이스. `Migration.up` 의 db 인자 타입.
41
- - **`DbTransactionError`** — executor 가 트랜잭션 에러를 표준화해 throw 하는 클래스. 호출측은 `instanceof DbTransactionError` 로 분기.
42
- - **`DbErrorCode`** — `NO_ACTIVE_TRANSACTION` / `TRANSACTION_ALREADY_STARTED` / `DEADLOCK` / `LOCK_TIMEOUT` enum. `err.code === DbErrorCode.DEADLOCK` 같은 분기에 사용.
43
- - **`parseQueryResult(rows, meta)` (`./utils/result-parser`)** — flat row 배열 + `ResultMeta` → 타입 변환 + JOIN 그룹핑된 중첩 객체 배열. async. 빈 결과면 undefined. executor 가 SELECT/OUTPUT 결과를 사용자 객체로 가공할 때.
44
- - **`pickResultSets(rawResults, buildResult)` (`./utils/pick-result-sets`)** — `QueryBuildResult` 의 `resultSetIndex`/`resultSetStride` 따라 여러 결과 셋 중 필요한 셋만 추출/concat. MySQL 배치 INSERT 의 OUTPUT SELECT 만 모을 때.
45
- - **`_Migration`** — `_migration(code PK varchar(255))` 시스템 테이블의 TableBuilder. DbContext 가 자동 등록, 사용자 직접 import 불필요.
46
- - **`SD_BUILDER`** — `queryable()`/`executable()` 팩토리 함수에 builder 를 부착하는 심볼. `initialize()` 가 DbContext 의 프로퍼티에서 builder 를 회수할 때 사용. 사용자 코드 직접 사용 X.
47
-
48
- ## QueryBuilder (인라인)
49
-
50
- ```ts
51
- import { createQueryBuilder } from "@simplysm/orm-common";
52
- const qb = createQueryBuilder("mysql"); // | "mssql" | "postgresql"
53
- const { sql, resultSetIndex, resultSetStride } = qb.build(queryDef);
54
- ```
55
-
56
- `QueryBuilderBase.build(def)` 가 `def.type` 으로 동적 dispatch 하여 dialect 별 메서드 호출. 결과는 `QueryBuildResult { sql; resultSetIndex?; resultSetStride? }` — 여러 result set 이 돌아오는 dialect 별 패턴(MySQL OUTPUT INSERT 등)을 위해 추출 인덱스/스트라이드 동봉. executor 는 받은 raw set 배열을 `pickResultSets(raw, buildResult)` 로 좁힌다.
57
-
58
- `createQueryBuilder(dialect)` 외에 dialect 클래스(`MysqlQueryBuilder`/`MssqlQueryBuilder`/`PostgresqlQueryBuilder` 와 대응 `*ExprRenderer`)도 export. 일반적으로 `createQueryBuilder` 만 쓰면 충분, 커스텀 확장 시 `QueryBuilderBase`/`ExprRendererBase` 상속.
@@ -1,77 +0,0 @@
1
- # @simplysm/orm-common — DbContext
2
-
3
- DB 1개에 대응하는 추상 클래스. 서브클래싱하여 테이블/뷰/프로시저를 인스턴스 프로퍼티로 등록하고, connect/transaction/DDL/initialize 진입점을 제공한다. 실제 SQL 실행은 생성자에 주입된 `DbContextExecutor` 가 담당.
4
-
5
- ## 생성·등록
6
-
7
- ```ts
8
- class MainDb extends DbContext {
9
- user = this.queryable(User); // → () => Queryable<User.$inferSelect, typeof User>
10
- vUser = this.queryable(UserSummary); // View 도 동일
11
- getUserById = this.executable(GetUserById); // → () => Executable<TParams, TReturns>
12
-
13
- migrations = [
14
- { name: "001-init", up: async (db) => { await db.createTable(User); } },
15
- ];
16
- }
17
-
18
- const db = new MainDb(executor, { database: "mydb", schema: "dbo" });
19
- ```
20
-
21
- - `protected queryable(builder)`: `TableBuilder | ViewBuilder` 를 받아 호출시마다 새 alias 가 할당된 `Queryable` 을 만드는 팩토리 함수를 반환. 반환 함수에는 `SD_BUILDER` 심볼로 원본 builder 가 부착됨 (initialize 가 회수).
22
- - `protected executable(builder)`: `ProcedureBuilder` → `Executable` 팩토리. 동일하게 `SD_BUILDER` 부착.
23
- - `_migration` 프로퍼티: 시스템 마이그레이션 테이블(`_migration(code PK varchar(255))`) 이 자동 등록됨.
24
-
25
- ## 연결 / 트랜잭션
26
-
27
- ```ts
28
- await db.connect(async () => { ... }); // connect + tx (auto commit/rollback)
29
- await db.connect(async () => { ... }, "REPEATABLE_READ"); // isolation level
30
- await db.connectWithoutTransaction(async () => { ... }); // connect only
31
- await db.transaction(async () => { ... }); // 이미 connect 인 상태에서 tx 만
32
- ```
33
-
34
- - `status: "ready" | "connect" | "transact"`. 잘못된 진입(중복 connect, 중복 tx)은 throw.
35
- - `connect()` 진입시 1회 `validateRelationsImpl` 호출 (relation 무결성 검사 — 잘못된 FK 정의는 여기서 throw).
36
- - 본문 throw 시 자동 rollback → `_executor.close()` 후 status `ready` 복귀. rollback 중 `DbTransactionError(NO_ACTIVE_TRANSACTION)` 는 무시.
37
- - `transaction()` 단독은 `status==="connect"` 일 때만. 이미 transact 면 throw.
38
- - `executeDefs(defs, resultMetas?)`: `_executor.executeDefs` 위임. `status==="transact"` 중 DDL 포함 시 throw.
39
-
40
- ## DDL 실행
41
-
42
- `createTable`, `dropTable`, `renameTable`, `createView`, `dropView`, `createProc`, `dropProc`, `addColumn`, `dropColumn`, `modifyColumn`, `renameColumn`, `addPrimaryKey`, `dropPrimaryKey`, `addForeignKey`, `addIndex`, `dropForeignKey`, `dropIndex`, `clearSchema({database, schema?})`, `schemaExists(database, schema?): Promise<boolean>`, `truncate(table)`, `switchFk(table, enabled)`.
43
-
44
- 각각 `executeDefs([...QueryDef])` 로 1건씩 실행. 트랜잭션 내에서는 `switchFk` 외 모두 차단(`executeDefs` 에서 검사).
45
-
46
- 대응 `getXxxQueryDef(...)` 형태의 *생성기* 메서드도 동일 시그니처로 제공 (실행 없이 `QueryDef` 만 반환). `initialize()` 가 배치 DDL 을 모을 때 사용.
47
-
48
- `getCreateObjectQueryDef(builder)` — Table/View/Procedure 중 무엇이든 받아 알맞은 create DDL 반환.
49
-
50
- ## initialize
51
-
52
- ```ts
53
- await db.initialize(); // 미적용 migration 만 실행
54
- await db.initialize({ dbs: ["a", "b"] }); // 다중 DB
55
- await db.initialize({ force: true }); // 스키마 clear + 전체 재생성 + 모든 migration 을 "적용됨" 등록
56
- ```
57
-
58
- 반환값: 실행된 migration 이 있으면 `true`, 아니면 `false`.
59
-
60
- 동작:
61
- - `force=true`: `clearSchema` → DbContext 의 모든 등록 객체(`queryable`/`executable` 프로퍼티에서 `SD_BUILDER` 로 회수) create → `_Migration` 에 모든 migration name 등록 → `false`.
62
- - `force=false`:
63
- - `_Migration` 테이블 없음 = 신규 DB → 전체 create + 모든 migration 등록 → `false`.
64
- - 있음 → 미적용 migration 만 순차 실행 → 실행분 있으면 `true`.
65
-
66
- 서브클래스가 `migrations: Migration[]` 를 오버라이드해 `{ name, up(db) }` 목록 제공.
67
-
68
- ## 헬퍼
69
-
70
- - `database`/`schema` getter — 생성자 옵션 노출.
71
- - `getNextAlias(): string` — `T1`, `T2`, ... alias 카운터. `connect`/`connectWithoutTransaction` 진입시 reset.
72
- - `resetAliasCounter()`.
73
- - `getQueryDefObjectName(tableOrView)` — Table/View 메타에서 `{database, schema, name}` 산출 (없으면 DbContext 옵션 fallback).
74
-
75
- ## 인터페이스
76
-
77
- 외부에서 DbContext 를 의존성으로 다룰 때는 `DbContextBase`(코어) + `DbContextDdlMethods`(DDL) 인터페이스 사용 (`./types/db-context-def`). `DbContext` 가 둘 다 구현.
@@ -1,20 +0,0 @@
1
- # @simplysm/orm-common — Executable
2
-
3
- 저장 프로시저 호출 래퍼. `DbContext.executable(builder)` 가 만든 팩토리 호출(`db.getUserById()`)마다 새 인스턴스 반환.
4
-
5
- ```ts
6
- class Executable<TParams extends ColumnBuilderRecord, TReturns extends ColumnBuilderRecord> {
7
- getExecProcQueryDef(params?: InferColumnExprs<TParams>): ExecProcQueryDef
8
- async execute(params: InferColumnExprs<TParams>): Promise<InferColumnExprs<TReturns>[][]>
9
- }
10
- ```
11
-
12
- - `params` 의 각 값은 `ExprInput<T>` (= `ExprUnit<T> | T`). 리터럴이면 `expr.val(meta.type, value)` 로 자동 래핑.
13
- - 프로시저에 `params` 가 정의되지 않은 builder 에 인자를 넘기면 throw.
14
- - 반환은 결과 셋의 배열 (프로시저가 여러 SELECT 를 반환할 수 있음).
15
-
16
- ```ts
17
- const [users] = await db.getUserById().execute({ userId: 1 });
18
- ```
19
-
20
- `executable(db, builder)` — 팩토리. `DbContext.executable` 의 내부 구현이며, `SD_BUILDER` 심볼로 builder 를 부착해야 `initialize()` 가 회수할 수 있다 (직접 쓰지 말고 `DbContext.executable` 사용 권장).
@@ -1,92 +0,0 @@
1
- # @simplysm/orm-common — expr
2
-
3
- Dialect 독립 SQL 표현식 빌더. SQL 문자열 대신 JSON AST(`Expr`/`WhereExpr`) 를 만들어 `Queryable` 메타에 누적되고, QueryBuilder 가 DBMS 별로 렌더.
4
-
5
- ## 래퍼
6
-
7
- - `ExprUnit<T extends ColumnPrimitive>` — `{ dataType: ColumnPrimitiveStr, expr: Expr }`. `.n` 게터로 `NonNullable<T>` 로 cast.
8
- - `WhereExprUnit` — boolean 컨텍스트 (`where`/`having`/논리 연산자) 전용.
9
- - `ExprInput<T> = ExprUnit<T> | T` — 리터럴도 받는 입력 타입.
10
- - `expr.toExpr(value)` / `toExpr(value)` 헬퍼 — `ExprUnit` 이면 풀고, 아니면 `{type:"value", value}` 로 감쌈.
11
-
12
- ## 카테고리별 API
13
-
14
- ### 값 / 컬럼 / Raw
15
- - `expr.val(dataType, value)` — 리터럴 → `ExprUnit`. `dataType ∈ "string"|"number"|"boolean"|"DateTime"|"DateOnly"|"Time"|"Uuid"|"Bytes"`.
16
- - `expr.col(dataType, ...path)` — 컬럼 참조(주로 내부).
17
- - `expr.raw(dataType)\`SQL ${interp}\`` — 태그드 템플릿. 보간값은 파라미터화. dialect 의존 함수 사용 시 escape hatch.
18
-
19
- ### 비교 / NULL (→ `WhereExprUnit`)
20
- - `eq`, `gt`, `lt`, `gte`, `lte`(source, target)
21
- - `between(source, from?, to?)`
22
- - `null(source)` — IS NULL
23
- - `like(source, pattern)`, `regexp(source, pattern)`
24
- - `in(source, values[])`, `inQuery(source, queryable)` — `queryable` 은 1-컬럼 select 여야 함. `exists(queryable)`.
25
-
26
- ### 논리
27
- - `not(WhereExprUnit)`, `and(WhereExprUnit[])`, `or(WhereExprUnit[])` — 빈 배열은 throw.
28
-
29
- ### 문자열 (→ `ExprUnit<string ...>`)
30
- - `concat(...args)`, `left(s, n)`, `right(s, n)`, `trim(s)`
31
- - `padStart(s, length, fillString)`, `replace(s, from, to)`
32
- - `upper(s)`, `lower(s)`
33
- - `length(s)` → number, `byteLength(s)` → number
34
- - `substring(s, start, length?)`, `indexOf(s, search)` → number
35
-
36
- ### 숫자
37
- - `abs`, `round(s, digits)`, `ceil`, `floor`.
38
-
39
- ### 날짜 (`DateUnit = "year"|"month"|"day"|"hour"|"minute"|"second"`)
40
- - `year/month/day/hour/minute/second(source)`
41
- - `isoWeek(d)`, `isoWeekStartDate(d)`, `isoYearMonth(d)`
42
- - `dateDiff(unit, from, to)` → number
43
- - `dateAdd(unit, source, value)`
44
- - `formatDate(source, format: string)` — format 문자열은 dialect 변환.
45
-
46
- ### NULL 처리 / 조건
47
- - `coalesce(...args)` — 첫 non-null. 마지막 인자가 NonNullable 이면 반환 타입도 NonNullable.
48
- - `nullIf(source, value)`
49
- - `is(WhereExprUnit)` → `ExprUnit<boolean>` (boolean 변환)
50
- - `if(condition, then, else_)` → `ExprUnit<T>` — 결과 dataType 은 ExprUnit/non-null 리터럴에서 추론.
51
- - `switch<T>()` → `SwitchExprBuilder<T>` — `.case(cond, then).case(...).default(value)` 체이닝.
52
-
53
- ### 집계 (GROUP BY 컨텍스트)
54
- - `count(arg?, distinct?)` → number
55
- - `sum(arg)`, `avg(arg)` → `number | undefined`
56
- - `max(arg)`, `min(arg)` → `T | undefined`
57
- - `greatest(...args)`, `least(...args)` — 행 내 최대/최소.
58
-
59
- ### 기타 스칼라
60
- - `rowNum()` → number — MSSQL `ROW_NUMBER() OVER(...)` 가 아니라 dialect 별 row 식별 함수 (간단 시퀀스).
61
- - `random()` → number, 0~1.
62
- - `cast(source, targetType: DataType)` — 결과 dataType 은 `dataTypeStrToColumnPrimitiveStr` 매핑.
63
- - `subquery(dataType, queryable)` — 1-컬럼 select 의 스칼라 서브쿼리.
64
-
65
- ### 윈도우 함수 (`WinSpecInput = { partitionBy?: ExprInput[], orderBy?: [ExprInput, "ASC"|"DESC"?][] }`)
66
- - 순위: `rowNumber(spec)`, `rank(spec)`, `denseRank(spec)`, `ntile(n, spec)`
67
- - 시퀀스 비교: `lag(column, spec, { offset?, default? })`, `lead(column, spec, { offset?, default? })`
68
- - 첫/끝: `firstValue(column, spec)`, `lastValue(column, spec)`
69
- - 집계 윈도우: `sumOver(column, spec)`, `avgOver(column, spec)`, `countOver(spec, column?)`, `minOver(column, spec)`, `maxOver(column, spec)`
70
-
71
- ## 예시
72
-
73
- ```ts
74
- db.user()
75
- .where(u => [
76
- expr.eq(u.status, "active"),
77
- expr.between(u.age, 18, 65),
78
- expr.or([expr.like(u.name, "%kim%"), expr.like(u.email, "%kim%")]),
79
- ])
80
- .select(u => ({
81
- name: expr.concat(u.firstName, " ", u.lastName),
82
- rank: expr.rowNumber({ partitionBy: [u.deptId], orderBy: [[u.score, "DESC"]] }),
83
- label: expr.switch<string>()
84
- .case(expr.gte(u.score, 90), "A")
85
- .case(expr.gte(u.score, 80), "B")
86
- .default("C"),
87
- }))
88
- ```
89
-
90
- ## Expr AST 타입
91
-
92
- 세부 노드 타입은 `./types/expr` 의 union (`ExprColumn`/`ExprValue`/`ExprRaw`/...`ExprWindow`/`ExprSubquery`). 일반 사용자는 직접 다룰 필요 없음 — ExprRenderer 구현이나 디버깅·검증 시만.