@simplysm/sd-claude 14.0.40 → 14.0.42
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/angular/docs/providers.md +2 -1
- package/claude/references/sd-simplysm14/angular/usage.md +13 -0
- package/claude/rules/sd-claude-rules.md +1 -0
- package/claude/rules/sd-simplysm14.md +35 -0
- package/claude/sd-check-forbidden-files.py +14 -0
- package/claude/settings.json +58 -0
- package/claude/skills/sd-claude-docs/SKILL.md +2 -2
- package/claude/skills/sd-wbs/SKILL.md +22 -2
- package/package.json +1 -1
- package/scripts/postinstall.mjs +5 -108
- package/scripts/sync.mjs +4 -1
- package/claude/references/sd-simplysm14.md +0 -35
|
@@ -287,7 +287,8 @@ class SdToastProvider {
|
|
|
287
287
|
danger(message: string, useProgress?: false): void;
|
|
288
288
|
|
|
289
289
|
notify<T extends SdToastContentDef<any>>(input: SdToastInput<T>): Promise<...>;
|
|
290
|
-
async try<R>(fn: () => Promise<R>, messageFn?: (err:
|
|
290
|
+
async try<R>(fn: () => Promise<R>, messageFn?: (err: Error) => string): Promise<R | undefined>;
|
|
291
|
+
try<R>(fn: () => R, messageFn?: (err: Error) => string): R | undefined;
|
|
291
292
|
}
|
|
292
293
|
```
|
|
293
294
|
|
|
@@ -338,6 +338,19 @@ export class SomePage implements OnInit {
|
|
|
338
338
|
- constructor 내 `void this._init()` 같은 수동 호출 패턴 **금지** — ngOnInit이 이미 같은 역할
|
|
339
339
|
- `resource()` / `httpResource()`는 데이터 로딩 → signal 매핑 용도. 사이드이펙트(라우팅, toast 등) 포함 초기화에는 사용하지 않는다
|
|
340
340
|
|
|
341
|
+
## inject 네이밍 컨벤션
|
|
342
|
+
|
|
343
|
+
`Sd*Provider`를 `inject()`할 때 변수명은 다음 규칙을 따른다:
|
|
344
|
+
|
|
345
|
+
- **Sd 접두어 유지**: 클래스명에서 `Sd`를 camelCase로 변환하여 유지한다
|
|
346
|
+
- **Provider 접미어 제거**: 변수명에서 `Provider`를 제거한다
|
|
347
|
+
|
|
348
|
+
| inject 대상 | 클래스 필드 | 로컬 변수 |
|
|
349
|
+
|-------------|-----------|----------|
|
|
350
|
+
| `SdToastProvider` | `private _sdToast = inject(SdToastProvider)` | `const sdToast = inject(SdToastProvider)` |
|
|
351
|
+
| `SdModalProvider` | `private _sdModal = inject(SdModalProvider)` | `const sdModal = inject(SdModalProvider)` |
|
|
352
|
+
| `SdServiceClientFactoryProvider` | `private _sdServiceClientFactory = inject(SdServiceClientFactoryProvider)` | `const sdServiceClientFactory = inject(...)` |
|
|
353
|
+
|
|
341
354
|
## Usage Examples
|
|
342
355
|
|
|
343
356
|
### 앱 부트스트랩
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
- `@angular/*` 패키지를 사용할 때 `angular-cli` mcp를 활용하여, 표준 사용법을 확인하여 따른다.
|
|
47
47
|
- 테스트 작성 시 `.claude/references/sd-testing.md`를 읽고 따른다.
|
|
48
48
|
- 프론트엔드 UI 코드 작성·수정 시 `.claude/references/sd-frontend-design.md`를 읽고 따른다.
|
|
49
|
+
- 디버깅 시 `.claude/references/sd-debug.md`를 읽고 따른다.
|
|
49
50
|
- 코딩을 하거나 코드예제를 출력할때는, 반드시 코드베이스의 기존 패턴을 확인하여 통일성있게 안내한다.
|
|
50
51
|
- 코드를 수정할 경우 수정에 의한 사이드이펙트를 항상 고려한다. (예, html구조가 바뀌면 css의 selector도 바뀌어야함)
|
|
51
52
|
- 함수 작성 혹은 함수내 기능 추가시 단일 책임 원칙을 따른다. (함수가 이름에서 드러나지 않는 일을 몰래 해선 안됨)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# sd-simplysm14: @simplysm v14 소비앱 가이드
|
|
2
|
+
|
|
3
|
+
소비앱이 `@simplysm/*` v14를 사용할 때 적용되는 규칙.
|
|
4
|
+
|
|
5
|
+
## 중간 패키지(common) 불필요
|
|
6
|
+
|
|
7
|
+
v14에서는 `import type`으로 타입을 직접 가져올 수 있으므로, 이전 버전에서 클라이언트-서버 간 타입 공유를 위해 필요하던 중간 패키지(예: `service-common`, `orm-common`)가 소비앱의 의존성으로 불필요하다.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// v14: 서버 패키지에서 타입을 직접 import — common 패키지 의존성 불필요
|
|
11
|
+
import type { ServiceMethods } from "@simplysm/service-server";
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 패키지별 상세 문서
|
|
15
|
+
|
|
16
|
+
| 패키지 | 문서 |
|
|
17
|
+
| -------------------------------------- | ----------------------------------------------------------------------------- |
|
|
18
|
+
| @simplysm/angular | [usage.md](../references/sd-simplysm14/angular/usage.md) |
|
|
19
|
+
| @simplysm/capacitor-plugin-auto-update | [usage.md](../references/sd-simplysm14/capacitor-plugin-auto-update/usage.md) |
|
|
20
|
+
| @simplysm/capacitor-plugin-file-system | [usage.md](../references/sd-simplysm14/capacitor-plugin-file-system/usage.md) |
|
|
21
|
+
| @simplysm/capacitor-plugin-intent | [usage.md](../references/sd-simplysm14/capacitor-plugin-intent/usage.md) |
|
|
22
|
+
| @simplysm/capacitor-plugin-usb-storage | [usage.md](../references/sd-simplysm14/capacitor-plugin-usb-storage/usage.md) |
|
|
23
|
+
| @simplysm/core-browser | [usage.md](../references/sd-simplysm14/core-browser/usage.md) |
|
|
24
|
+
| @simplysm/core-common | [usage.md](../references/sd-simplysm14/core-common/usage.md) |
|
|
25
|
+
| @simplysm/core-node | [usage.md](../references/sd-simplysm14/core-node/usage.md) |
|
|
26
|
+
| @simplysm/excel | [usage.md](../references/sd-simplysm14/excel/usage.md) |
|
|
27
|
+
| @simplysm/lint | [usage.md](../references/sd-simplysm14/lint/usage.md) |
|
|
28
|
+
| @simplysm/orm-common | [usage.md](../references/sd-simplysm14/orm-common/usage.md) |
|
|
29
|
+
| @simplysm/orm-node | [usage.md](../references/sd-simplysm14/orm-node/usage.md) |
|
|
30
|
+
| @simplysm/sd-claude | [usage.md](../references/sd-simplysm14/sd-claude/usage.md) |
|
|
31
|
+
| @simplysm/sd-cli | [usage.md](../references/sd-simplysm14/sd-cli/usage.md) |
|
|
32
|
+
| @simplysm/service-client | [usage.md](../references/sd-simplysm14/service-client/usage.md) |
|
|
33
|
+
| @simplysm/service-common | [usage.md](../references/sd-simplysm14/service-common/usage.md) |
|
|
34
|
+
| @simplysm/service-server | [usage.md](../references/sd-simplysm14/service-server/usage.md) |
|
|
35
|
+
| @simplysm/storage | [usage.md](../references/sd-simplysm14/storage/usage.md) |
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import json, sys, os
|
|
2
|
+
|
|
3
|
+
data = json.load(sys.stdin)
|
|
4
|
+
file_path = data["tool_input"]["file_path"].replace("\\", "/")
|
|
5
|
+
root = os.getcwd().replace("\\", "/")
|
|
6
|
+
|
|
7
|
+
BLOCKED_FILES = [
|
|
8
|
+
f"{root}/tsconfig.json",
|
|
9
|
+
f"{root}/eslint.config.ts",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
if file_path in BLOCKED_FILES:
|
|
13
|
+
print(f"Blocked: forbidden file - {file_path}", file=sys.stderr)
|
|
14
|
+
sys.exit(2)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "startup|resume|clear|compact",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "bash .claude/sd-session-start.sh"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"PreToolUse": [
|
|
15
|
+
{
|
|
16
|
+
"matcher": "Edit|Write",
|
|
17
|
+
"hooks": [
|
|
18
|
+
{
|
|
19
|
+
"type": "command",
|
|
20
|
+
"command": "python .claude/sd-check-forbidden-files.py"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"matcher": "Write",
|
|
26
|
+
"hooks": [
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "python .claude/sd-check-write.py"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"matcher": "Bash",
|
|
35
|
+
"hooks": [
|
|
36
|
+
{
|
|
37
|
+
"type": "command",
|
|
38
|
+
"command": "python .claude/sd-check-bash.py"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"SubagentStart": [
|
|
44
|
+
{
|
|
45
|
+
"hooks": [
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "bash .claude/sd-session-start.sh"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"statusLine": {
|
|
55
|
+
"type": "command",
|
|
56
|
+
"command": "python .claude/sd-statusline.py"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -67,7 +67,7 @@ description: 프로젝트 분석을 통해 CLAUDE.md와 LLM용 usage 문서를
|
|
|
67
67
|
1. 루트 `package.json`의 `name`에서 라이브러리명을 추출한다
|
|
68
68
|
2. 루트 `package.json`의 `version`에서 메이저 버전을 추출한다
|
|
69
69
|
3. usage 문서 경로: `.claude/references/sd-{name}{majorVersion}/` (예: `sd-simplysm14/`)
|
|
70
|
-
4. 인덱스 파일 경로: `.claude/
|
|
70
|
+
4. 인덱스 파일 경로: `.claude/rules/sd-{name}{majorVersion}.md` (예: `sd-simplysm14.md`)
|
|
71
71
|
|
|
72
72
|
## Step 2: 분기
|
|
73
73
|
|
|
@@ -194,7 +194,7 @@ UI: angular (Angular)
|
|
|
194
194
|
|
|
195
195
|
### sd-{name}{ver}.md (라이브러리 프로젝트만)
|
|
196
196
|
|
|
197
|
-
라이브러리 프로젝트인 경우 `.claude/
|
|
197
|
+
라이브러리 프로젝트인 경우 `.claude/rules/sd-{name}{ver}.md` 인덱스 파일을 생성/갱신한다.
|
|
198
198
|
소비앱인 경우 이 단계를 건너뛴다.
|
|
199
199
|
|
|
200
200
|
#### 포함할 내용
|
|
@@ -77,7 +77,7 @@ Feature는 독립적으로 설계·개발·검증할 수 있는 최소 기능
|
|
|
77
77
|
|
|
78
78
|
### Feature 작성 규칙
|
|
79
79
|
|
|
80
|
-
- **의존성**:
|
|
80
|
+
- **의존성**: 이 Feature의 범위(세부 기능)를 하나씩 검토하여, 해당 기능을 구현하려면 다른 어떤 Feature가 먼저 완료돼야 하는지 판단한다. 선행 Feature가 있으면 명시하고, 없으면 "없음". (의존성에 따라 병렬 진행할 수 있으므로 중요)
|
|
81
81
|
- **범위**: 해당 Feature의 세부 기능을 사용자 기능(user-facing function) 수준으로 **MUST 빠짐없이** 나열한다. (절대 누락되어선 안된다. 누락된것은 다음단계에서 제외사항으로 판단될 수 있다.)
|
|
82
82
|
- **경계**: 이 Feature가 **하지 않는 것** 중 다른 Feature에서 다루거나 다룰 수 있는 것을 명시한다. 인접 Feature와의 경계가 모호한 경우 특히 중요하다. (프로젝트 전체에서 제외되는 항목은 문서 하단의 "제외 사항"에 기재한다.)
|
|
83
83
|
- **근거**: 범위가 도출된 근거 혹은 출처를 명시한다. (요구사항, 사용자 답변, 첨부문서 등) 개발에 필요한 참조 파일/자료 경로가 있으면 확인 목적과 함께 기록한다.
|
|
@@ -158,7 +158,27 @@ Feature는 독립적으로 설계·개발·검증할 수 있는 최소 기능
|
|
|
158
158
|
|
|
159
159
|
**CRITIAL: 각 Feature는 새 세션에서 진행되므로, 절대(NEVER) wbs문서에 누락이 있어서는 안됨**
|
|
160
160
|
|
|
161
|
-
## Step 6:
|
|
161
|
+
## Step 6: 의존성 요약 테이블 출력
|
|
162
|
+
|
|
163
|
+
문서 작성이 완료되면, 전체 Feature의 의존성 관계를 한눈에 볼 수 있도록 테이블을 출력한다.
|
|
164
|
+
|
|
165
|
+
예시:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
┌─────┬─────────────────────────────┬────────┐
|
|
169
|
+
│ # │ Feature │ 의존성 │
|
|
170
|
+
├─────┼─────────────────────────────┼────────┤
|
|
171
|
+
│ 1.1 │ 공통 프로바이더 & 플러그인 │ 없음 │
|
|
172
|
+
├─────┼─────────────────────────────┼────────┤
|
|
173
|
+
│ 1.2 │ 홈 레이아웃 & 사이드바 메뉴 │ 1.1 │
|
|
174
|
+
├─────┼─────────────────────────────┼────────┤
|
|
175
|
+
│ 2.1 │ 입고 처리 │ 1.1 │
|
|
176
|
+
├─────┼─────────────────────────────┼────────┤
|
|
177
|
+
│ 2.2 │ 출고 처리 │ 1.1 │
|
|
178
|
+
└─────┴─────────────────────────────┴────────┘
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Step 7: 다음 단계 안내
|
|
162
182
|
|
|
163
183
|
WBS 완료 후, 개발을 위한 다음 단계를 안내한다.
|
|
164
184
|
|
package/package.json
CHANGED
package/scripts/postinstall.mjs
CHANGED
|
@@ -31,6 +31,10 @@ try {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
const sourceEntries = collectSdEntries(sourceDir);
|
|
34
|
+
// settings.json도 함께 복사
|
|
35
|
+
if (fs.existsSync(path.join(sourceDir, "settings.json"))) {
|
|
36
|
+
sourceEntries.push("settings.json");
|
|
37
|
+
}
|
|
34
38
|
if (sourceEntries.length === 0) {
|
|
35
39
|
process.exit(0);
|
|
36
40
|
}
|
|
@@ -39,9 +43,8 @@ try {
|
|
|
39
43
|
|
|
40
44
|
cleanSdEntries(targetDir);
|
|
41
45
|
copySdEntries(sourceDir, targetDir, sourceEntries);
|
|
42
|
-
setupSettings(targetDir);
|
|
43
46
|
|
|
44
|
-
console.log(`[@simplysm/sd-claude] Installed ${sourceEntries.length}
|
|
47
|
+
console.log(`[@simplysm/sd-claude] Installed ${sourceEntries.length} entries.`);
|
|
45
48
|
} catch (err) {
|
|
46
49
|
// Ignore errors to prevent postinstall failure from blocking the entire pnpm install
|
|
47
50
|
console.warn("[@simplysm/sd-claude] postinstall warning:", err.message);
|
|
@@ -101,109 +104,3 @@ function copySdEntries(sourceDir, targetDir, entries) {
|
|
|
101
104
|
}
|
|
102
105
|
}
|
|
103
106
|
|
|
104
|
-
/** Ensures statusLine and SessionStart hooks are configured in settings.json. */
|
|
105
|
-
function setupSettings(targetDir) {
|
|
106
|
-
const settingsPath = path.join(targetDir, "settings.json");
|
|
107
|
-
|
|
108
|
-
let settings = {};
|
|
109
|
-
if (fs.existsSync(settingsPath)) {
|
|
110
|
-
settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Migrate: move root-level SessionStart to hooks.SessionStart
|
|
114
|
-
if (settings["SessionStart"] != null) {
|
|
115
|
-
settings["hooks"] = settings["hooks"] ?? {};
|
|
116
|
-
settings["hooks"]["SessionStart"] = [
|
|
117
|
-
...(settings["hooks"]["SessionStart"] ?? []),
|
|
118
|
-
...settings["SessionStart"],
|
|
119
|
-
];
|
|
120
|
-
delete settings["SessionStart"];
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// SessionStart: ensure sd-session-start hook exists with correct config
|
|
124
|
-
settings["hooks"] = settings["hooks"] ?? {};
|
|
125
|
-
const sdSessionEntry = {
|
|
126
|
-
matcher: "startup|resume|clear|compact",
|
|
127
|
-
hooks: [{ type: "command", command: "bash .claude/sd-session-start.sh" }],
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
const sessionStart = settings["hooks"]["SessionStart"];
|
|
131
|
-
|
|
132
|
-
if (sessionStart == null) {
|
|
133
|
-
settings["hooks"]["SessionStart"] = [sdSessionEntry];
|
|
134
|
-
} else {
|
|
135
|
-
const idx = sessionStart.findIndex((entry) =>
|
|
136
|
-
entry.hooks?.some((hook) => hook.command.includes("sd-session-start")),
|
|
137
|
-
);
|
|
138
|
-
if (idx >= 0) {
|
|
139
|
-
sessionStart[idx] = sdSessionEntry;
|
|
140
|
-
} else {
|
|
141
|
-
sessionStart.push(sdSessionEntry);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// PreToolUse: ensure sd-check-write hook exists for Write tool
|
|
146
|
-
const sdWriteEntry = {
|
|
147
|
-
matcher: "Write",
|
|
148
|
-
hooks: [{ type: "command", command: "python .claude/sd-check-write.py" }],
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const preToolUse = settings["hooks"]["PreToolUse"];
|
|
152
|
-
|
|
153
|
-
if (preToolUse == null) {
|
|
154
|
-
settings["hooks"]["PreToolUse"] = [sdWriteEntry];
|
|
155
|
-
} else {
|
|
156
|
-
const idx = preToolUse.findIndex((entry) =>
|
|
157
|
-
entry.hooks?.some((hook) => hook.command.includes("sd-check-write")),
|
|
158
|
-
);
|
|
159
|
-
if (idx >= 0) {
|
|
160
|
-
preToolUse[idx] = sdWriteEntry;
|
|
161
|
-
} else {
|
|
162
|
-
preToolUse.push(sdWriteEntry);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// PreToolUse: ensure sd-check-bash hook exists for Bash tool
|
|
167
|
-
const sdBashEntry = {
|
|
168
|
-
matcher: "Bash",
|
|
169
|
-
hooks: [{ type: "command", command: "python .claude/sd-check-bash.py" }],
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
if (settings["hooks"]["PreToolUse"] == null) {
|
|
173
|
-
settings["hooks"]["PreToolUse"] = [sdBashEntry];
|
|
174
|
-
} else {
|
|
175
|
-
const bashIdx = settings["hooks"]["PreToolUse"].findIndex((entry) =>
|
|
176
|
-
entry.hooks?.some((hook) => hook.command.includes("sd-check-bash")),
|
|
177
|
-
);
|
|
178
|
-
if (bashIdx >= 0) {
|
|
179
|
-
settings["hooks"]["PreToolUse"][bashIdx] = sdBashEntry;
|
|
180
|
-
} else {
|
|
181
|
-
settings["hooks"]["PreToolUse"].push(sdBashEntry);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// SubagentStart: ensure sd-session-start hook exists
|
|
186
|
-
const sdSubagentEntry = {
|
|
187
|
-
hooks: [{ type: "command", command: "bash .claude/sd-session-start.sh" }],
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
const subagentStart = settings["hooks"]["SubagentStart"];
|
|
191
|
-
|
|
192
|
-
if (subagentStart == null) {
|
|
193
|
-
settings["hooks"]["SubagentStart"] = [sdSubagentEntry];
|
|
194
|
-
} else {
|
|
195
|
-
const idx = subagentStart.findIndex((entry) =>
|
|
196
|
-
entry.hooks?.some((hook) => hook.command.includes("sd-session-start")),
|
|
197
|
-
);
|
|
198
|
-
if (idx >= 0) {
|
|
199
|
-
subagentStart[idx] = sdSubagentEntry;
|
|
200
|
-
} else {
|
|
201
|
-
subagentStart.push(sdSubagentEntry);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// statusLine: always overwrite
|
|
206
|
-
settings["statusLine"] = { type: "command", command: "python .claude/sd-statusline.py" };
|
|
207
|
-
|
|
208
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
209
|
-
}
|
package/scripts/sync.mjs
CHANGED
|
@@ -16,8 +16,11 @@ if (fs.existsSync(targetDir)) {
|
|
|
16
16
|
fs.rmSync(targetDir, { recursive: true });
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// sd-* 항목 탐색 및
|
|
19
|
+
// sd-* 항목 탐색 및 settings.json 포함
|
|
20
20
|
const allEntries = collectSdEntries(claudeDir);
|
|
21
|
+
if (fs.existsSync(path.join(claudeDir, "settings.json"))) {
|
|
22
|
+
allEntries.push("settings.json");
|
|
23
|
+
}
|
|
21
24
|
|
|
22
25
|
for (const entry of allEntries) {
|
|
23
26
|
const src = path.join(claudeDir, entry);
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# sd-simplysm14: @simplysm v14 소비앱 가이드
|
|
2
|
-
|
|
3
|
-
소비앱이 `@simplysm/*` v14를 사용할 때 적용되는 규칙.
|
|
4
|
-
|
|
5
|
-
## 중간 패키지(common) 불필요
|
|
6
|
-
|
|
7
|
-
v14에서는 `import type`으로 타입을 직접 가져올 수 있으므로, 이전 버전에서 클라이언트-서버 간 타입 공유를 위해 필요하던 중간 패키지(예: `service-common`, `orm-common`)가 소비앱의 의존성으로 불필요하다.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
// v14: 서버 패키지에서 타입을 직접 import — common 패키지 의존성 불필요
|
|
11
|
-
import type { ServiceMethods } from "@simplysm/service-server";
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## 패키지별 상세 문서
|
|
15
|
-
|
|
16
|
-
| 패키지 | 문서 |
|
|
17
|
-
|--------|------|
|
|
18
|
-
| @simplysm/angular | [usage.md](./sd-simplysm14/angular/usage.md) |
|
|
19
|
-
| @simplysm/capacitor-plugin-auto-update | [usage.md](./sd-simplysm14/capacitor-plugin-auto-update/usage.md) |
|
|
20
|
-
| @simplysm/capacitor-plugin-file-system | [usage.md](./sd-simplysm14/capacitor-plugin-file-system/usage.md) |
|
|
21
|
-
| @simplysm/capacitor-plugin-intent | [usage.md](./sd-simplysm14/capacitor-plugin-intent/usage.md) |
|
|
22
|
-
| @simplysm/capacitor-plugin-usb-storage | [usage.md](./sd-simplysm14/capacitor-plugin-usb-storage/usage.md) |
|
|
23
|
-
| @simplysm/core-browser | [usage.md](./sd-simplysm14/core-browser/usage.md) |
|
|
24
|
-
| @simplysm/core-common | [usage.md](./sd-simplysm14/core-common/usage.md) |
|
|
25
|
-
| @simplysm/core-node | [usage.md](./sd-simplysm14/core-node/usage.md) |
|
|
26
|
-
| @simplysm/excel | [usage.md](./sd-simplysm14/excel/usage.md) |
|
|
27
|
-
| @simplysm/lint | [usage.md](./sd-simplysm14/lint/usage.md) |
|
|
28
|
-
| @simplysm/orm-common | [usage.md](./sd-simplysm14/orm-common/usage.md) |
|
|
29
|
-
| @simplysm/orm-node | [usage.md](./sd-simplysm14/orm-node/usage.md) |
|
|
30
|
-
| @simplysm/sd-claude | [usage.md](./sd-simplysm14/sd-claude/usage.md) |
|
|
31
|
-
| @simplysm/sd-cli | [usage.md](./sd-simplysm14/sd-cli/usage.md) |
|
|
32
|
-
| @simplysm/service-client | [usage.md](./sd-simplysm14/service-client/usage.md) |
|
|
33
|
-
| @simplysm/service-common | [usage.md](./sd-simplysm14/service-common/usage.md) |
|
|
34
|
-
| @simplysm/service-server | [usage.md](./sd-simplysm14/service-server/usage.md) |
|
|
35
|
-
| @simplysm/storage | [usage.md](./sd-simplysm14/storage/usage.md) |
|