@simplysm/sd-claude 14.0.97 → 14.0.99
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 +16 -16
- package/claude/references/sd-simplysm14/apis/angular/README.md +81 -153
- package/claude/references/sd-simplysm14/apis/angular/controls.md +179 -205
- package/claude/references/sd-simplysm14/apis/angular/crud.md +71 -57
- package/claude/references/sd-simplysm14/apis/angular/directives.md +49 -109
- package/claude/references/sd-simplysm14/apis/angular/features.md +58 -86
- package/claude/references/sd-simplysm14/apis/angular/kanban.md +32 -40
- package/claude/references/sd-simplysm14/apis/angular/layout.md +38 -52
- package/claude/references/sd-simplysm14/apis/angular/overlay.md +86 -110
- package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +54 -86
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +82 -74
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +56 -80
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +15 -15
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +21 -21
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +79 -53
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +9 -11
- package/claude/references/sd-simplysm14/apis/core-browser/README.md +15 -15
- package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +20 -20
- package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +18 -18
- package/claude/references/sd-simplysm14/apis/core-common/README.md +20 -49
- package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +66 -55
- package/claude/references/sd-simplysm14/apis/core-common/collection-ext.md +83 -56
- package/claude/references/sd-simplysm14/apis/core-common/errors.md +32 -21
- package/claude/references/sd-simplysm14/apis/core-common/obj.md +57 -39
- package/claude/references/sd-simplysm14/apis/core-common/serialization.md +36 -30
- package/claude/references/sd-simplysm14/apis/core-common/value-types.md +69 -41
- package/claude/references/sd-simplysm14/apis/core-node/README.md +4 -4
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +15 -13
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +11 -7
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +8 -8
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +29 -20
- package/claude/references/sd-simplysm14/apis/core-node/pathx.md +14 -6
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +3 -3
- package/claude/references/sd-simplysm14/apis/excel/README.md +3 -3
- package/claude/references/sd-simplysm14/apis/excel/cell.md +32 -32
- package/claude/references/sd-simplysm14/apis/excel/conditional-format.md +23 -24
- package/claude/references/sd-simplysm14/apis/excel/style.md +24 -30
- package/claude/references/sd-simplysm14/apis/excel/utils.md +20 -23
- package/claude/references/sd-simplysm14/apis/excel/workbook-worksheet.md +60 -71
- package/claude/references/sd-simplysm14/apis/excel/wrapper.md +36 -36
- package/claude/references/sd-simplysm14/apis/lint/README.md +7 -9
- package/claude/references/sd-simplysm14/apis/lint/recommended.md +59 -37
- package/claude/references/sd-simplysm14/apis/lint/rules.md +81 -74
- package/claude/references/sd-simplysm14/apis/orm-common/README.md +6 -6
- package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +112 -78
- package/claude/references/sd-simplysm14/apis/orm-common/expr.md +131 -75
- package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +126 -82
- package/claude/references/sd-simplysm14/apis/orm-common/schema.md +170 -113
- package/claude/references/sd-simplysm14/apis/orm-common/types.md +102 -48
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +12 -13
- package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +3 -3
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +5 -5
- package/claude/references/sd-simplysm14/apis/sd-cli/SdTsCompiler.md +67 -65
- package/claude/references/sd-simplysm14/apis/sd-cli/sd-config-types.md +130 -123
- package/claude/references/sd-simplysm14/apis/service-client/README.md +63 -63
- package/claude/references/sd-simplysm14/apis/service-client/orm.md +22 -22
- package/claude/references/sd-simplysm14/apis/service-client/transport.md +30 -26
- package/claude/references/sd-simplysm14/apis/service-common/README.md +8 -8
- package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +13 -6
- package/claude/references/sd-simplysm14/apis/service-common/protocol.md +1 -1
- package/claude/references/sd-simplysm14/apis/service-server/README.md +43 -47
- package/claude/references/sd-simplysm14/apis/service-server/built-in-services.md +35 -0
- package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +20 -19
- package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +23 -25
- package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +9 -9
- package/claude/references/sd-simplysm14/apis/storage/README.md +26 -26
- package/claude/references/sd-simplysm14/manuals/client-component.md +9 -1
- package/claude/references/sd-simplysm14/manuals/client-crud.md +1 -1
- package/claude/references/sd-simplysm14/manuals/client-orm.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-service.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-shared-data.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-ssg.md +1 -0
- package/claude/sd-system-prompt.md +11 -26
- package/claude/skills/sd-docs/references/subagent-prompt.md +4 -3
- package/claude/skills/sd-spec/SKILL.md +87 -18
- package/claude/skills/sd-spec/references/format.md +2 -2
- package/package.json +1 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# @simplysm/excel — ExcelWrapper
|
|
2
2
|
|
|
3
|
-
Zod 스키마로 엑셀 헤더 ↔ 필드 매핑, 셀 값 타입 변환, 행 단위 유효성 검사를 자동화해 "레코드 배열 ↔ 엑셀" 변환을 한 번에
|
|
3
|
+
Zod 스키마로 엑셀 헤더 ↔ 필드 매핑, 셀 값 타입 변환, 행 단위 유효성 검사를 자동화해 "레코드 배열 ↔ 엑셀" 변환을 한 번에 처리하는 고수준 래퍼. 헤더 텍스트는 각 필드의 `.describe()` 로 지정하며, 미지정 필드는 키 이름을 헤더로 쓴다. 클라이언트 화면의 엑셀 다운로드(`write`)·업로드(`read`)에서 같은 wrapper 인스턴스를 공유하는 패턴에 쓰인다.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 생성
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
|
-
new ExcelWrapper<TSchema extends z.ZodObject
|
|
8
|
+
new ExcelWrapper<TSchema extends z.ZodObject>(_schema: TSchema)
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
- `
|
|
11
|
+
- `_schema` — Zod 객체 스키마. 각 필드가 한 컬럼이 되고, `.describe("헤더명")` 으로 엑셀 헤더를 지정한다.
|
|
12
12
|
|
|
13
13
|
## read
|
|
14
14
|
|
|
@@ -20,19 +20,13 @@ read(
|
|
|
20
20
|
): Promise<z.infer<TSchema>[]>
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
- `wsNameOrIndex: string | number` — 읽을 시트 이름 또는 0 기반 인덱스. 기본 `0`(첫 시트).
|
|
25
|
-
- `options.excludes?: (keyof Schema)[]` — 매핑에서 제외할 필드 키 배열. 해당 헤더는 읽지 않음.
|
|
23
|
+
엑셀 파일을 레코드 배열로 읽는다. 헤더는 스키마 displayName(`.describe()`)으로 매칭한 컬럼만 채택. 전부 빈 값인 행은 건너뛴다. 각 행을 스키마로 `safeParse` 하며 실패 시 시트명 + 상세 메시지로 throw. 데이터가 0건이면 throw. 내부에서 워크북을 열고 finally 로 `close` 까지 책임진다.
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
- `file` — 엑셀 바이트 또는 Blob.
|
|
26
|
+
- `wsNameOrIndex` — 읽을 시트 이름 또는 0 기반 인덱스(기본 0).
|
|
27
|
+
- `options.excludes` — 읽기에서 제외할 필드 키 배열(파생 컬럼 등). 매핑·파싱에서 빠진다.
|
|
28
28
|
|
|
29
|
-
값
|
|
30
|
-
|
|
31
|
-
- `ZodString` → 문자열(비문자열은 `String()`).
|
|
32
|
-
- `ZodNumber` → `num.parseFloat`.
|
|
33
|
-
- `ZodBoolean` → `"1"`/`"true"`→`true`, `"0"`/`"false"`→`false`, 그 외 `Boolean()`.
|
|
34
|
-
- `DateOnly`/`DateTime`/`Time` 인스턴스 → 그대로 보존.
|
|
35
|
-
- 빈/누락 값(`null`/`""`) → 스키마 기본값: `ZodDefault` 면 그 기본값, optional/nullable 면 `undefined`, 필수 boolean 이면 `false`, 그 외 `undefined`.
|
|
29
|
+
값 변환: 빈 셀/빈 문자열은 `ZodDefault` 면 기본값, `optional`/`nullable` 이면 `undefined`, 필수 boolean 이면 `false` 로 채운다. 그 외에는 스키마 inner 타입(String/Number/Boolean)에 맞춰 변환(`"1"`/`"true"` → `true` 등), `DateOnly`/`DateTime`/`Time` 인스턴스는 그대로 보존.
|
|
36
30
|
|
|
37
31
|
## write
|
|
38
32
|
|
|
@@ -44,37 +38,43 @@ write(
|
|
|
44
38
|
): Promise<ExcelWorkbook>
|
|
45
39
|
```
|
|
46
40
|
|
|
47
|
-
- `
|
|
48
|
-
- `records: Partial<Schema>[]` — 출력할 레코드 배열(부분 객체 허용 — 누락 키는 빈 셀).
|
|
49
|
-
- `options.excludes?: (keyof Schema)[]` — 출력에서 제외할 필드 키 배열.
|
|
41
|
+
레코드 배열을 엑셀 워크북으로 변환해 반환. 0 행에 헤더, 이후 행에 데이터를 쓰고, 표 전체에 테두리, 필수(non-optional/nullable/default)이면서 boolean 이 아닌 필드 헤더에 노란 배경(`00FFFF00`)을 칠한다. zoom 85%, 0 행 틀고정, 헤더~데이터 전체 범위 자동 필터를 설정한다. 변환 중 예외 발생 시 워크북을 `close` 하고 re-throw 한다(부분 산출물 방지).
|
|
50
42
|
|
|
51
|
-
|
|
43
|
+
- `wsName` — 생성할 시트 이름.
|
|
44
|
+
- `records` — 쓸 레코드 배열(`Partial` — 일부 필드 누락 허용).
|
|
45
|
+
- `options.excludes` — 컬럼에서 제외할 필드 키 배열.
|
|
52
46
|
|
|
53
|
-
|
|
47
|
+
반환된 워크북의 리소스 관리는 호출자 책임 — 사용 후 `close()` 해야 한다.
|
|
54
48
|
|
|
55
|
-
|
|
56
|
-
const schema = z.object({
|
|
57
|
-
code: z.string().describe("코드"),
|
|
58
|
-
qty: z.number().describe("수량"),
|
|
59
|
-
note: z.string().optional().describe("비고"),
|
|
60
|
-
});
|
|
61
|
-
const wrapper = new ExcelWrapper(schema);
|
|
49
|
+
## 사용 예
|
|
62
50
|
|
|
63
|
-
|
|
64
|
-
const records = await wrapper.read(bytes, "입력", { excludes: ["note"] });
|
|
51
|
+
다운로드/업로드에서 같은 wrapper 를 공유한다.
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
53
|
+
```typescript
|
|
54
|
+
private readonly _excelWrapper = new ExcelWrapper(
|
|
55
|
+
z.object({
|
|
56
|
+
id: z.number().optional().describe("ID"),
|
|
57
|
+
name: z.string().describe("이름"),
|
|
58
|
+
lastModifiedAt: z.instanceof(DateTime).optional().describe("수정일시"),
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// 다운로드
|
|
63
|
+
const wb = await this._excelWrapper.write(this.viewTitle(), items);
|
|
68
64
|
try {
|
|
69
|
-
|
|
65
|
+
downloadBlob(await wb.toBlob(), `${this.viewTitle()}_${new DateTime().toFormatString("yyMMdd")}.xlsx`);
|
|
70
66
|
} finally {
|
|
71
67
|
await wb.close();
|
|
72
68
|
}
|
|
69
|
+
|
|
70
|
+
// 업로드 (파생 컬럼은 제외)
|
|
71
|
+
const records = await this._excelWrapper.read(files[0], 0, {
|
|
72
|
+
excludes: ["lastModifiedAt"],
|
|
73
|
+
});
|
|
73
74
|
```
|
|
74
75
|
|
|
75
76
|
## 주의사항
|
|
76
77
|
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
- `
|
|
80
|
-
- 결측 보존: optional/nullable 필드의 빈 값은 `undefined` 로 유지된다(임의 치환 없음). 필수 boolean 만 `false` 로 채워진다.
|
|
78
|
+
- `write` 반환 워크북은 호출자가 `close()` 해야 한다(`read` 는 내부에서 자동 close).
|
|
79
|
+
- 빈 데이터(0건) 읽기·스키마 검증 실패는 silent skip 없이 throw — 부분 처리하지 않는다.
|
|
80
|
+
- 다운로드 파일명·`downloadBlob` 사용법은 client-crud 매뉴얼 및 [core-browser README](../core-browser/README.md) 참조.
|
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
# @simplysm/lint
|
|
2
2
|
|
|
3
|
-
심플리즘 전용 ESLint
|
|
3
|
+
심플리즘 전용 ESLint 자산. 커스텀 규칙 9종을 담은 플러그인과, 그 규칙들에 typescript-eslint·angular-eslint·import·unused-imports 를 결합한 flat config 프리셋을 제공. `src/index.ts` 는 없고, `package.json` 의 `exports` 두 subpath(`./eslint-plugin`, `./eslint-recommended`)만 진입점이다. 두 진입점 모두 `default` export 만 가진다.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **eslint-recommended** (`@simplysm/lint/eslint-recommended`) — 프로젝트 `eslint.config.ts` 에서 그대로 spread
|
|
8
|
-
- **eslint-plugin** (`@simplysm/lint/eslint-plugin`) — 커스텀 규칙만 담은 ESLint Plugin
|
|
9
|
-
|
|
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 자동 부여)는 내부 전용이며 두 진입점 어디로도 재노출되지 않음.
|
|
7
|
+
- **eslint-recommended** (`@simplysm/lint/eslint-recommended`) — 프로젝트 `eslint.config.ts` 에서 그대로 spread 하는 완성형 flat config 배열. 파일 패턴(JS / TS / HTML / tests)별 활성 규칙·심각도·플러그인·ignore·금지 global/import/syntax 를 확인할 때. 자세히: [recommended.md](./recommended.md)
|
|
8
|
+
- **eslint-plugin** (`@simplysm/lint/eslint-plugin`) — 커스텀 규칙만 담은 ESLint Plugin 객체. recommended 를 안 쓰고 규칙을 직접 골라 등록하거나, 개별 규칙의 검사 대상·위반 메시지·autofix·옵션을 검토할 때. 자세히: [rules.md](./rules.md)
|
|
11
9
|
|
|
12
10
|
## eslint-plugin
|
|
13
11
|
|
|
14
|
-
`@simplysm/lint/eslint-plugin` 의 default export
|
|
12
|
+
`@simplysm/lint/eslint-plugin` 의 default export 는 ESLint Plugin 형태 객체 `{ rules: Record<id, Rule> }`. `src/eslint-plugin.ts` 가 9개 규칙을 id 로 묶어 노출한다.
|
|
15
13
|
|
|
16
14
|
```typescript
|
|
17
15
|
import plugin from "@simplysm/lint/eslint-plugin";
|
|
18
|
-
//
|
|
16
|
+
// flat config 에서: plugins: { "@simplysm": plugin } 매핑 후 "@simplysm/<id>" 로 켬
|
|
19
17
|
```
|
|
20
18
|
|
|
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`.
|
|
19
|
+
- `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`. 각 규칙의 검사 대상·옵션·autofix·메시지는 [rules.md](./rules.md) 참조.
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
> 규칙 생성 팩토리 `createRule`(`src/utils/create-rule.ts`, `ESLintUtils.RuleCreator` 래퍼로 규칙 문서 URL 자동 부여)는 내부 전용이며 두 진입점 어디로도 재노출되지 않는다.
|
|
@@ -1,60 +1,82 @@
|
|
|
1
1
|
# @simplysm/lint — recommended
|
|
2
2
|
|
|
3
|
-
`@simplysm/lint/eslint-recommended` 의 default export
|
|
4
|
-
|
|
5
|
-
## 사용
|
|
3
|
+
`@simplysm/lint/eslint-recommended` 의 default export 는 `tseslint.config(...)` 결과 = ESLint 9 flat config 객체 배열. 프로젝트 `eslint.config.ts` 에서 그대로 spread 하면 표준 lint 세트가 적용된다. 그 자체로 완성형 배열이라 추가 병합 없이 동작하며, 프로젝트별 규칙은 배열 뒤에 config 객체를 이어 붙인다.
|
|
6
4
|
|
|
7
5
|
```typescript
|
|
8
6
|
// eslint.config.ts
|
|
9
7
|
import recommended from "@simplysm/lint/eslint-recommended";
|
|
10
|
-
|
|
11
8
|
export default [...recommended];
|
|
12
9
|
```
|
|
13
10
|
|
|
14
11
|
## config 블록 (배열 순서대로)
|
|
15
12
|
|
|
16
|
-
각 블록은 `files` 패턴으로 적용 범위를
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
13
|
+
각 블록은 `files` 패턴으로 적용 범위를 한정하고, 한 파일이 여러 블록에 걸리면 규칙이 병합된다.
|
|
14
|
+
|
|
15
|
+
### globalIgnores
|
|
16
|
+
|
|
17
|
+
순회 자체를 건너뛸 경로: `**/node_modules/**`, `**/dist/**`, `**/.*/**`(점으로 시작하는 디렉토리 전체).
|
|
18
|
+
|
|
19
|
+
### 공통 languageOptions
|
|
20
|
+
|
|
21
|
+
전 파일 공통: `ecmaVersion: "latest"`(최신 ECMAScript 구문 허용), `sourceType: "module"`(ESM 파싱).
|
|
22
|
+
|
|
23
|
+
### JS 블록 (`**/*.js`, `**/*.mjs`, `**/*.cjs`)
|
|
24
|
+
|
|
25
|
+
`globals: globals.node`(node 전역 인식), `import`/`@simplysm`/`unused-imports` 플러그인 등록. 활성 규칙:
|
|
26
|
+
|
|
27
|
+
- `require-await: error` — async 함수 안에 `await` 없으면 위반.
|
|
28
|
+
- `no-shadow: error` — 바깥 스코프 변수명을 안쪽에서 가림 금지.
|
|
29
|
+
- `no-duplicate-imports: error` — 같은 모듈을 여러 import 문으로 중복 import 금지.
|
|
30
|
+
- `no-unused-expressions: error` — 값을 쓰지 않는 식문 금지.
|
|
31
|
+
- `no-undef: error` — 미선언 식별자 참조 금지.
|
|
32
|
+
- `unused-imports/no-unused-imports: error` — 미사용 import 제거(autofix).
|
|
33
|
+
- `unused-imports/no-unused-vars: error` — 미사용 변수/인자 금지. `varsIgnorePattern`·`argsIgnorePattern` = `^_`(언더스코어 접두는 의도적 미사용으로 허용), `args: "after-used"`(마지막 사용 인자 뒤만 검사).
|
|
34
|
+
- `import/no-extraneous-dependencies: error` — `package.json` 의존성에 없는 패키지 import 금지. `devDependencies` 허용 경로: `**/lib/**`, `**/eslint.config.{js,cjs,mjs}`, `**/simplysm.{js,cjs,mjs}`, `**/vitest.config.{js,cjs,mjs}`.
|
|
35
|
+
- 커스텀: `@simplysm/no-subpath-imports-from-simplysm: error`, `@simplysm/no-hard-private: error`([rules.md](./rules.md)).
|
|
36
|
+
- 공유 묶음: node 빌트인 차단 + env 직접접근 차단(아래 "공유 규칙 묶음").
|
|
37
|
+
|
|
38
|
+
### angular tsRecommended
|
|
39
|
+
|
|
40
|
+
`angular.configs.tsRecommended` spread — angular-eslint TS 권장 세트.
|
|
41
|
+
|
|
42
|
+
### TS 블록 (`**/*.ts`)
|
|
43
|
+
|
|
44
|
+
`processor: angular.processInlineTemplates`(컴포넌트 인라인 템플릿 추출해 별도 lint), `parser: tseslint.parser` + `parserOptions.project: true`(타입 정보 기반 규칙 활성화), `settings.import/resolver` = typescript resolver(`alwaysTryTypes: true`). 활성 규칙:
|
|
45
|
+
|
|
46
|
+
- 타입체크 규칙군(모두 `error`): `@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`.
|
|
47
|
+
- `no-console: error` — TS 블록 한정 콘솔 출력 금지.
|
|
48
|
+
- `@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`.
|
|
49
|
+
- `@angular-eslint/no-output-native: off` — output 명이 네이티브 DOM 이벤트와 겹쳐도 허용.
|
|
50
|
+
- 공유 묶음(unused-imports 2종·node 빌트인 차단·env 직접접근 차단) + `import/no-extraneous-dependencies: error`(TS 는 예외 경로 없이 전면 적용).
|
|
51
|
+
|
|
52
|
+
### HTML 블록 (`**/*.html`)
|
|
53
|
+
|
|
54
|
+
`extends: angular.configs.templateRecommended + templateAccessibility`. 활성 규칙:
|
|
55
|
+
|
|
56
|
+
- 커스텀: `@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)).
|
|
57
|
+
- `@angular-eslint/template/eqeqeq: ["error",{allowNullOrUndefined:true}]` — 템플릿 엄격 비교 강제하되 null/undefined 비교는 예외.
|
|
58
|
+
- `@angular-eslint/template/label-has-associated-control: off` — label-control 연결 검사 비활성.
|
|
59
|
+
- `@angular-eslint/template/no-any: error` — 템플릿에서 `$any` 사용 금지.
|
|
60
|
+
|
|
61
|
+
### 테스트 오버라이드 (`**/tests/**/*.ts`)
|
|
62
|
+
|
|
63
|
+
테스트 완화: `no-console: off`, `import/no-extraneous-dependencies: off`, `@simplysm/ts-no-throw-not-implemented-error: off`.
|
|
64
|
+
|
|
65
|
+
### vitest.config 오버라이드 (`**/vitest.config.ts`)
|
|
66
|
+
|
|
67
|
+
`no-restricted-properties: off` — 설정 파일에서 `process.env` 접근 허용.
|
|
45
68
|
|
|
46
69
|
## 공유 규칙 묶음
|
|
47
70
|
|
|
48
|
-
JS·TS 블록에 함께 적용되는 내부 상수 묶음(
|
|
71
|
+
JS·TS 블록에 함께 적용되는 내부 상수 묶음(export 되진 않으나 동작 이해용):
|
|
49
72
|
|
|
50
73
|
- **noNodeBuiltinsRules** — node 빌트인 차단.
|
|
51
|
-
- `no-restricted-globals` 로 `Buffer` 전역 금지 → `Uint8Array
|
|
74
|
+
- `no-restricted-globals` 로 `Buffer` 전역 금지 → `Uint8Array` / `@simplysm/core-common` 의 `BytesUtils` 유도.
|
|
52
75
|
- `no-restricted-imports` 로 `buffer`(→ `Uint8Array`/`BytesUtils`), `events`·`eventemitter3`(→ `@simplysm/core-common` 의 `EventEmitter`) import 금지.
|
|
53
76
|
- **noDirectEnvAccessRules** — 환경변수 직접접근·엄격 비교 차단.
|
|
54
77
|
- `no-restricted-properties` 로 `process.env` 직접 접근 금지 → `env("...")` 유도.
|
|
55
|
-
- `no-restricted-syntax`
|
|
78
|
+
- `no-restricted-syntax` 로: `import.meta.env` 직접 접근 금지(→ `env("...")`), `env("NODE_ENV")` 호출 금지, `=== undefined` / `!== undefined`(좌·우변 양방향) 금지 → `== null` / `!= null` 유도.
|
|
56
79
|
|
|
57
80
|
## 주의
|
|
58
81
|
|
|
59
82
|
- TS 블록은 타입 정보(`parserOptions.project: true`)를 요구하므로 대상 프로젝트에 유효한 `tsconfig` 가 있어야 함.
|
|
60
|
-
- recommended 는 그 자체로 ESLint 9 flat config 배열이므로 추가 spread/병합 없이도 동작. 프로젝트별 규칙을 덧붙일 땐 배열 뒤에 config 객체를 이어 붙임.
|
|
@@ -1,130 +1,137 @@
|
|
|
1
1
|
# @simplysm/lint — rules
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@simplysm/lint/eslint-plugin` 이 노출하는 커스텀 규칙 9종. `plugins: { "@simplysm": plugin }` 매핑 후 `"@simplysm/<id>"` 로 켠다. id 접두어로 검사 대상 파일군이 갈림: `ts-*` 는 TS 소스, `ng-*` 는 Angular(TS effect 또는 HTML 템플릿), `no-*` 는 JS/TS 공통. 모든 규칙은 `createRule`(`ESLintUtils.RuleCreator` 래퍼)로 생성되어 문서 URL 이 자동 부여된다. 옵션 없는 규칙은 `schema: []`.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
ECMAScript hard private(`#field`) 사용을 금지하고 TypeScript `private _` 스타일을 강제. `type: "problem"`, autofix 있음, 옵션 없음. JS·TS 양쪽 동작.
|
|
5
|
+
---
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
## ng-no-async-effect
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
- `
|
|
13
|
-
-
|
|
9
|
+
- **검사 대상**: `@angular/core` 에서 import 한 `effect()` 호출의 첫 인자가 async 함수(`async () => {}` 또는 `async function`)인 경우. `effect` 식별자가 `@angular/core` 출처인지 스코프로 검증 — named(`import { effect }`) / aliased(`effect as ngEffect`) / namespace(`import * as ng` → `ng.effect(...)`) import 만 인정. 다른 모듈 또는 로컬 선언 `effect` 는 무시.
|
|
10
|
+
- **메시지** `noAsyncEffect`: effect 콜백을 async 로 하면 `await` 이후 signal read 가 reactive 의존성으로 추적되지 않으니, 비동기 작업은 `void untracked(async () => { ... })` 안에서 하라고 안내. 보고 위치는 첫 인자(콜백) 노드.
|
|
11
|
+
- **autofix**: 없음. **옵션**: 없음.
|
|
14
12
|
|
|
15
13
|
```typescript
|
|
16
|
-
|
|
17
|
-
// → private _count = 0; inc() { this._count++; }
|
|
14
|
+
effect(() => { this.sig(); void untracked(async () => { await this.load(); }); });
|
|
18
15
|
```
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
`@simplysm/*` 패키지의 `src` 하위 경로 import 를 금지(빌드 export 경유 강제). `type: "problem"`, autofix 있음, 옵션 없음. JS·TS 양쪽 동작.
|
|
17
|
+
---
|
|
23
18
|
|
|
24
|
-
|
|
19
|
+
## ng-template-no-strict-null-check
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
- `
|
|
21
|
+
- **검사 대상**: Angular 템플릿(`*.html` 및 인라인)의 `Binary` 표현식 중 연산자가 `===` / `!==` 이고 한쪽 피연산자가 nil 리터럴(value 가 null/undefined)인 경우. 즉 `x === null`, `x !== null`, `x === undefined`, `x !== undefined`. `== null` / `!= null` 은 통과.
|
|
22
|
+
- **메시지** `noStrictNullCheck`: `{{actual}}`(예: `x === null`) 대신 `{{replacement}}`(`===`→`==`, `!==`→`!=` 로 바꾸고 우변을 `null` 로 통일한 형태) 를 쓰라고 안내.
|
|
23
|
+
- **autofix**: 없음 — 인라인 템플릿 offset 매핑 문제로 미제공(JSDoc 근거). **옵션**: 없음.
|
|
28
24
|
|
|
29
|
-
```
|
|
30
|
-
|
|
25
|
+
```html
|
|
26
|
+
@if (user !== null) {} <!-- "user != null 사용" 으로 보고 -->
|
|
31
27
|
```
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
`@angular/core` 의 `effect()` 에 async 함수를 직접 전달하는 것을 금지. `type: "problem"`, autofix 없음, 옵션 없음. `await` 이후 signal read 가 reactive 의존성으로 추적되지 않고 반환값이 `Promise<void>` 가 되어 cleanup 등록이 막히는 문제 방지.
|
|
29
|
+
---
|
|
36
30
|
|
|
37
|
-
|
|
31
|
+
## ng-template-no-todo-comments
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
- `
|
|
33
|
+
- **검사 대상**: 템플릿 raw 텍스트의 HTML 주석 `<!-- ... -->` 중 본문에 `TODO:` 를 포함하는 것. AST 방문자가 아니라 정규식(`/<!--([\s\S]*?)-->/g`)으로 원문을 스캔(빈 visitor `{}` 반환). 한 파일의 여러 TODO 주석을 각각 개별 보고.
|
|
34
|
+
- **메시지** `noTodo`: 본문은 `{{content}}` — `TODO:` 이후 텍스트를 trim 한 내용을 그대로 출력.
|
|
35
|
+
- **autofix**: 없음. **옵션**: 없음.
|
|
41
36
|
|
|
42
|
-
```
|
|
43
|
-
|
|
37
|
+
```html
|
|
38
|
+
<!-- TODO: 페이징 추가 --> <!-- "페이징 추가" 경고 -->
|
|
44
39
|
```
|
|
45
40
|
|
|
46
|
-
|
|
41
|
+
---
|
|
47
42
|
|
|
48
|
-
|
|
43
|
+
## ng-template-sd-require-binding-attrs
|
|
49
44
|
|
|
50
|
-
|
|
45
|
+
`sd-*` 접두사 컴포넌트의 허용목록 밖 plain attribute 를 금지하고 property binding(`[attr]="..."`)을 강제. **9종 중 유일하게 옵션이 있는 규칙**.
|
|
51
46
|
|
|
52
|
-
|
|
53
|
-
- `
|
|
47
|
+
- **검사 대상**: 태그명이 지정 접두사(기본 `sd-`)로 시작하는 Element 의 attribute 중 `allowAttributes`(정확 일치)·`allowAttributePrefixes`(접두사 일치) 어디에도 안 드는 것(태그명·attribute 명 소문자 비교).
|
|
48
|
+
- **메시지** `requireBindingForAttribute`: `"{{attrName}}"` 는 `"{{elementName}}"` 의 plain attribute 로 불가, `[{{attrName}}]="…"` property binding 을 쓰라고 안내.
|
|
49
|
+
- **autofix**: 있음. 값이 빈 문자열이면 `[attr]="true"`, 값이 있으면 `\`·`'` 를 escape 해 `[attr]="'값'"` 로 치환. attribute span 이 비정상(`start >= end`)이면 fix 생략(`null` 반환).
|
|
50
|
+
- **옵션**(객체 1개, 모두 string 배열, `additionalProperties: false`):
|
|
51
|
+
- `selectorPrefixes` — 검사 대상 태그 접두사. 기본 `["sd-"]`. 다른 디자인 시스템 접두사를 함께 검사할 때 지정.
|
|
52
|
+
- `allowAttributes` — plain 허용 attribute 정확 이름. 기본 `["id","class","style","title","tabindex","role"]`. 표준 속성을 추가 허용할 때.
|
|
53
|
+
- `allowAttributePrefixes` — plain 허용 attribute 접두사. 기본 `["aria-","data-","sd-"]`. aria/data 류 속성군을 통째 허용할 때.
|
|
54
54
|
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
```html
|
|
56
|
+
<sd-button myattr="hello"></sd-button> <!-- → <sd-button [myattr]="'hello'"></sd-button> -->
|
|
57
|
+
<sd-button disabled></sd-button> <!-- → <sd-button [disabled]="true"></sd-button> -->
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
---
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
## no-hard-private
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
ECMAScript hard private(`#`) 멤버 금지 → TypeScript `private _` 스타일 강제. JS·TS 양쪽 동작.
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
-
|
|
66
|
+
- **검사 대상**: 선언(`#field`, `#method()`, `accessor #field`, getter/setter, static/async/generator 변형)과 사용(`this.#field`, `other.#field`, `MyClass.#static`) 모두. 중첩 클래스·클래스 표현식은 멤버 집합을 스택으로 추적.
|
|
67
|
+
- **메시지**:
|
|
68
|
+
- `preferSoftPrivate`: hard private(`#`) 금지, `private _` 스타일 안내.
|
|
69
|
+
- `nameConflict`: `#{{name}}` 을 `_{{name}}` 로 바꾸려는데 동일 이름 멤버가 클래스에 이미 있어 변환 불가 — 보고만, autofix 안 함.
|
|
70
|
+
- **autofix**: 있음. 선언은 `#x → _x`, 접근 제어자가 없으면 데코레이터·`static`·`async`·`readonly` 순서를 보존해 그 앞에 `private ` 삽입(`static #x → private static _x`, `@Deco #x → @Deco private _x`). 기존 `private`/`public`/`protected` 가 있으면 접근자는 두고 이름만 변경. 사용처는 `this.#x → this._x`. 토큰 계산 실패 시 이름만 바뀌는 불완전 수정을 막으려 fix 전체 생략.
|
|
71
|
+
- **옵션**: 없음.
|
|
68
72
|
|
|
69
73
|
```typescript
|
|
70
|
-
class
|
|
74
|
+
class A { #count = 0; inc() { this.#count++; } }
|
|
75
|
+
// → private _count = 0; inc() { this._count++; }
|
|
71
76
|
```
|
|
72
77
|
|
|
73
|
-
|
|
78
|
+
---
|
|
74
79
|
|
|
75
|
-
|
|
80
|
+
## no-subpath-imports-from-simplysm
|
|
76
81
|
|
|
77
|
-
|
|
82
|
+
`@simplysm/*` 패키지의 `src` 하위 경로 import 금지(빌드 export 경유 강제). JS·TS 양쪽 동작.
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
- `
|
|
84
|
+
- **검사 대상**: import 경로를 `/` 로 분리해 첫 패키지 세그먼트 뒤가 `src` 인 경우(`@simplysm/<pkg>/src`, `@simplysm/<pkg>/src/...`). `@simplysm/<pkg>` 루트·`src` 외 하위 경로(`@simplysm/<pkg>/utils`)는 통과, 비-`@simplysm` 패키지(`lodash/src/...`)도 통과. 정적 import, 동적 `import(...)`, `export { } from`, `export * from` 모두 검사(side-effect·type-only import 포함).
|
|
85
|
+
- **메시지** `noSubpathImport`: `'@simplysm/{{pkg}}'` 에서 `src` 하위 경로 `'{{importPath}}'` 를 import 할 수 없다는 위반.
|
|
86
|
+
- **autofix**: 있음. 경로를 패키지 루트 `@simplysm/<pkg>` 로 치환하며 원본 따옴표(`'`/`"`) 보존.
|
|
87
|
+
- **옵션**: 없음.
|
|
81
88
|
|
|
82
89
|
```typescript
|
|
83
|
-
|
|
84
|
-
class C { protected readonly title = "x"; protected readonly unused = 1; } // unused 제거
|
|
90
|
+
import { x } from "@simplysm/core-common/src/x"; // → "@simplysm/core-common"
|
|
85
91
|
```
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
---
|
|
88
94
|
|
|
89
|
-
|
|
95
|
+
## ts-no-throw-not-implemented-error
|
|
90
96
|
|
|
91
|
-
|
|
97
|
+
`@simplysm/core-common` 의 `NotImplementedError` `new` 인스턴스화 감지(미구현 코드 프로덕션 유입 방지).
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
- `
|
|
99
|
+
- **검사 대상**: `new NotImplementedError(...)`(named/aliased import), `new CC.NotImplementedError(...)`(namespace import). 식별자가 `@simplysm/core-common` 출처인지 스코프로 검증. 다른 모듈 동명 클래스, import 없는 사용, 동적 `await import(...)`, 재내보내기 경유는 감지 안 함(JSDoc·테스트 근거).
|
|
100
|
+
- **메시지** `noThrowNotImplementedError`: 본문은 `{{text}}` — `new` 의 첫 인자가 비어있지 않은 문자열 리터럴이면 그 값을, 아니면(템플릿 리터럴·숫자·빈 문자열·인자 없음) 기본값 `"미구현"` 을 출력.
|
|
101
|
+
- **autofix**: 없음. **옵션**: 없음. recommended 에서 TS 는 `warn`, tests 는 `off`.
|
|
95
102
|
|
|
96
|
-
```
|
|
97
|
-
|
|
103
|
+
```typescript
|
|
104
|
+
import { NotImplementedError } from "@simplysm/core-common";
|
|
105
|
+
new NotImplementedError("결제 연동"); // → "결제 연동" 경고
|
|
98
106
|
```
|
|
99
107
|
|
|
100
|
-
|
|
108
|
+
---
|
|
101
109
|
|
|
102
|
-
|
|
110
|
+
## ts-no-unused-injects
|
|
103
111
|
|
|
104
|
-
|
|
112
|
+
미사용 Angular `inject()` 필드 감지.
|
|
105
113
|
|
|
106
|
-
|
|
107
|
-
- `
|
|
114
|
+
- **검사 대상**: 클래스 본문에서 `inject(...)` 호출로 초기화된 PropertyDefinition(key 가 Identifier). 같은 클래스 본문 전체를 순회해 필드명과 동일한 Identifier 참조(선언 key 자신 제외)가 0개면 미사용 판정. 클래스 내부 참조만 검사 — 템플릿 사용 여부는 안 봄.
|
|
115
|
+
- **메시지** `unusedInject`: `inject() field "{{name}}" is never used.`
|
|
116
|
+
- **autofix**: 있음. 해당 필드 선언을 앞 토큰 끝부터 제거(뒤 토큰이 있으면 필드 끝까지). 사용 중인 다른 inject 필드는 보존.
|
|
117
|
+
- **옵션**: 없음.
|
|
108
118
|
|
|
109
|
-
```
|
|
110
|
-
|
|
119
|
+
```typescript
|
|
120
|
+
class C { private _svc = inject(MyService); } // _svc 미참조 시 제거
|
|
111
121
|
```
|
|
112
122
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
`sd-*` 접두사 커스텀 컴포넌트에서 허용목록 밖 plain attribute 사용을 금지하고 Angular property binding(`[attr]="..."`)을 강제. `type: "problem"`, autofix 있음. HTML 대상. **9종 중 유일하게 옵션 있는 규칙**.
|
|
123
|
+
---
|
|
116
124
|
|
|
117
|
-
|
|
118
|
-
- `selectorPrefixes: string[]` — 검사 대상 요소 태그 접두사. 미지정 시 `["sd-"]`. 태그명을 소문자로 비교. 다른 디자인 시스템 접두사를 함께 검사하려면 지정.
|
|
119
|
-
- `allowAttributes: string[]` — plain attribute 로 허용할 정확한 이름 목록. 미지정 시 `["id","class","style","title","tabindex","role"]`. 소문자 비교. 추가로 허용할 표준 속성을 늘릴 때.
|
|
120
|
-
- `allowAttributePrefixes: string[]` — plain attribute 로 허용할 접두사 목록. 미지정 시 `["aria-","data-","sd-"]`. 소문자 비교. 접두사 기반(aria/data 등) 속성군을 통째 허용할 때.
|
|
125
|
+
## ts-no-unused-protected-readonly
|
|
121
126
|
|
|
122
|
-
|
|
127
|
+
Angular `@Component` 인라인 템플릿·클래스 본문 어디에서도 안 쓰이는 `protected readonly` 필드 감지.
|
|
123
128
|
|
|
124
|
-
|
|
125
|
-
- `
|
|
129
|
+
- **검사 대상**: `@Component({ template: ... })` 데코레이터(첫 인자 객체에 `template` 키, 비어있지 않은 문자열/템플릿 리터럴)가 달린 클래스의 `protected readonly` 비-static 필드(key 가 Identifier) 중 ① 인라인 템플릿 미참조 ② 클래스 본문 다른 멤버 미참조 둘 다인 것. 템플릿 식별자는 `@angular/compiler` 의 `parseTemplate` 로 AST 파싱 후 `ImplicitReceiver`/`ThisReceiver` 위 `PropertyRead`(클래스 필드 참조)만 수집하며, `*ngFor` 로컬·`@let`·`@if ... as`·`@for` item/별칭 등 스코프 로컬은 제외. `@if`/`@switch`/`@for`/`@defer` 블록과 입력/이벤트/구조 디렉티브 바인딩까지 순회. `templateUrl`(외부 템플릿)은 대상 아님.
|
|
130
|
+
- **메시지** `unusedField`: `Protected readonly field "{{name}}" is not used in class or template.`
|
|
131
|
+
- **autofix**: 있음. 필드 선언을 앞 들여쓰기·뒤 `;`·개행까지 줄 단위로 제거.
|
|
132
|
+
- **옵션**: 없음.
|
|
126
133
|
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
```typescript
|
|
135
|
+
@Component({ template: `<div>{{title}}</div>` })
|
|
136
|
+
class C { protected readonly title = "x"; protected readonly unused = 1; } // unused 제거
|
|
130
137
|
```
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# @simplysm/orm-common
|
|
2
2
|
|
|
3
|
-
Dialect(MySQL/MSSQL/PostgreSQL) 독립 ORM 코어. 스키마를
|
|
3
|
+
Dialect(MySQL/MSSQL/PostgreSQL) 독립 ORM 코어. 빌더로 스키마를 정의하고, `DbContext` 를 상속해 연결·트랜잭션·DDL 을 다루며, `Queryable` 체이닝 + `expr` 표현식 빌더로 타입 안전한 쿼리 AST(`QueryDef`/`Expr`)를 만든 뒤 dialect 별 QueryBuilder 로 SQL 문자열을 렌더링한다. 실제 DB 연결·실행은 `DbContextExecutor` 구현체(`@simplysm/orm-node` 등)가 담당하고, 이 패키지는 dialect 독립 로직(빌더·AST·SQL 렌더링·결과 파싱)까지만 가진다.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **DbContext / 연결·트랜잭션·DDL·마이그레이션** — `DbContext` 를 상속해 테이블·뷰·프로시저를 프로퍼티로
|
|
8
|
-
- **스키마 빌더 (Table/View/Procedure/Column/Index/Relation)** — `Table()`/`View()`/`Procedure()` 와 column·index·relation 팩토리로
|
|
9
|
-
- **Queryable / Executable / 검색** — `db.X()` 로 시작하는 SELECT/INSERT/UPDATE/DELETE/UPSERT 체이닝, join
|
|
10
|
-
- **expr 표현식 빌더** — `where`/`select`/`groupBy`/`orderBy` 콜백 안에서 비교·논리·문자열·숫자·날짜·집계·조건·윈도우·서브쿼리 표현식을 만들 때. `ExprUnit`/`WhereExprUnit`/`ExprInput
|
|
11
|
-
- **타입 / QueryDef·Expr AST / QueryBuilder / 결과 파싱** — executor 구현, dialect 별 SQL 렌더링(`createQueryBuilder`), QueryDef
|
|
7
|
+
- **DbContext / 연결·트랜잭션·DDL·마이그레이션** — `DbContext` 를 상속해 테이블·뷰·프로시저를 프로퍼티로 등록하고, `connect`/`transaction`/`createTable`/`initialize` 등으로 연결·트랜잭션 경계와 스키마 변경을 다룰 때. `DbContextExecutor`/`DbTransactionError`/`Migration` 포함. 자세히: [db-context.md](./db-context.md)
|
|
8
|
+
- **스키마 빌더 (Table/View/Procedure/Column/Index/Relation)** — `Table()`/`View()`/`Procedure()` 와 column·index·relation 팩토리로 스키마를 fluent 하게 정의하고 `$inferSelect` 등으로 타입을 추론할 때. 자세히: [schema.md](./schema.md)
|
|
9
|
+
- **Queryable / Executable / 검색** — `db.X()` 로 시작하는 SELECT/INSERT/UPDATE/DELETE/UPSERT 체이닝, `join`/`joinSingle`/`include`/`union`/`recursive`, 텍스트 검색(`search`/`parseSearchQuery`), 프로시저 실행(`Executable`)을 작성할 때. 자세히: [queryable.md](./queryable.md)
|
|
10
|
+
- **expr 표현식 빌더** — `where`/`select`/`groupBy`/`orderBy`/`update` 콜백 안에서 비교·논리·문자열·숫자·날짜·집계·조건·윈도우·서브쿼리 표현식을 만들 때. `expr` 객체와 `ExprUnit`/`WhereExprUnit`/`ExprInput` 포함. 자세히: [expr.md](./expr.md)
|
|
11
|
+
- **타입 / QueryDef·Expr AST / QueryBuilder / 결과 파싱** — executor·dialect 어댑터 구현, dialect 별 SQL 렌더링(`createQueryBuilder`), `QueryDef`/`Expr` AST 타입, 컬럼 원시 타입(`ColumnPrimitive*`/`DataType`), 결과 변환(`parseQueryResult`/`pickResultSets`)을 다룰 때. 자세히: [types.md](./types.md)
|
|
12
12
|
|
|
13
13
|
## 전형적 사용 흐름
|
|
14
14
|
|