@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.
- package/claude/references/sd-requirement-source-handling.md +20 -20
- package/claude/references/sd-simplysm14/README.md +13 -13
- package/claude/references/sd-simplysm14/manuals/client-component.md +92 -92
- package/claude/references/sd-simplysm14/manuals/client-crud.md +11 -11
- package/claude/references/sd-simplysm14/manuals/client-demo.md +28 -28
- package/claude/references/sd-simplysm14/manuals/client-rules.md +1 -1
- package/claude/references/sd-simplysm14/manuals/client-setup.md +21 -21
- package/claude/references/sd-simplysm14/manuals/client-tab.md +3 -3
- package/claude/references/sd-simplysm14/manuals/logging.md +15 -15
- package/claude/references/sd-simplysm14/manuals/orm-union.md +6 -6
- package/claude/references/sd-simplysm14/manuals/orm.md +19 -19
- package/claude/references/sd-simplysm14/manuals/test.md +33 -33
- package/claude/rules/sd-design-rules.md +18 -18
- package/claude/sd-system-prompt.md +369 -0
- package/claude/skills/sd-commit/SKILL.md +10 -10
- package/claude/skills/sd-config/SKILL.md +2 -2
- package/claude/skills/sd-demo/SKILL.md +45 -45
- package/claude/skills/sd-dev/SKILL.md +15 -15
- package/claude/skills/sd-docs/SKILL.md +7 -7
- package/claude/skills/sd-docs/references/subagent-prompt.md +33 -33
- package/claude/skills/sd-impl/SKILL.md +60 -60
- package/claude/skills/sd-review/SKILL.md +9 -9
- package/claude/skills/sd-skill/SKILL.md +74 -74
- package/claude/skills/sd-skill/evals/fixtures/existing-skill/.claude/skills/todo-format/SKILL.md +1 -1
- package/claude/skills/sd-spec/SKILL.md +354 -319
- package/claude/skills/sd-spec/references/example-spec.md +104 -104
- package/claude/skills/sd-unpack/SKILL.md +34 -34
- package/claude/skills/sd-unpack/scripts/handlers/__pycache__/office_com.cpython-314.pyc +0 -0
- package/claude/skills/sd-unpack/scripts/handlers/office_com.py +234 -159
- package/claude/skills/sd-use/SKILL.md +4 -4
- package/package.json +1 -1
- package/claude/references/sd-simplysm14/apis/angular/README.md +0 -37
- package/claude/references/sd-simplysm14/apis/angular/app-structure.md +0 -92
- package/claude/references/sd-simplysm14/apis/angular/buttons.md +0 -88
- package/claude/references/sd-simplysm14/apis/angular/crud.md +0 -100
- package/claude/references/sd-simplysm14/apis/angular/forms.md +0 -200
- package/claude/references/sd-simplysm14/apis/angular/infrastructure.md +0 -231
- package/claude/references/sd-simplysm14/apis/angular/kanban.md +0 -80
- package/claude/references/sd-simplysm14/apis/angular/layout.md +0 -92
- package/claude/references/sd-simplysm14/apis/angular/modal.md +0 -115
- package/claude/references/sd-simplysm14/apis/angular/routing.md +0 -107
- package/claude/references/sd-simplysm14/apis/angular/select-dropdown.md +0 -35
- package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +0 -82
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +0 -134
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +0 -127
- package/claude/references/sd-simplysm14/apis/angular/toast.md +0 -97
- package/claude/references/sd-simplysm14/apis/angular/visual.md +0 -167
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +0 -79
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +0 -83
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +0 -91
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +0 -49
- package/claude/references/sd-simplysm14/apis/core-browser/README.md +0 -143
- package/claude/references/sd-simplysm14/apis/core-common/README.md +0 -58
- package/claude/references/sd-simplysm14/apis/core-common/extensions.md +0 -88
- package/claude/references/sd-simplysm14/apis/core-common/features.md +0 -51
- package/claude/references/sd-simplysm14/apis/core-common/types.md +0 -88
- package/claude/references/sd-simplysm14/apis/core-common/utils.md +0 -189
- package/claude/references/sd-simplysm14/apis/core-node/README.md +0 -12
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +0 -59
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +0 -44
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +0 -42
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +0 -53
- package/claude/references/sd-simplysm14/apis/core-node/pathx.md +0 -24
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +0 -65
- package/claude/references/sd-simplysm14/apis/excel/README.md +0 -193
- package/claude/references/sd-simplysm14/apis/lint/README.md +0 -94
- package/claude/references/sd-simplysm14/apis/orm-common/README.md +0 -58
- package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +0 -77
- package/claude/references/sd-simplysm14/apis/orm-common/executable.md +0 -20
- package/claude/references/sd-simplysm14/apis/orm-common/expr.md +0 -92
- package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +0 -98
- package/claude/references/sd-simplysm14/apis/orm-common/schema-builders.md +0 -128
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +0 -69
- package/claude/references/sd-simplysm14/apis/sd-claude/README.md +0 -32
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +0 -80
- package/claude/references/sd-simplysm14/apis/sd-cli/sd-config.md +0 -155
- package/claude/references/sd-simplysm14/apis/service-client/README.md +0 -131
- package/claude/references/sd-simplysm14/apis/service-common/README.md +0 -29
- package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +0 -63
- package/claude/references/sd-simplysm14/apis/service-common/messages.md +0 -56
- package/claude/references/sd-simplysm14/apis/service-common/protocol.md +0 -64
- package/claude/references/sd-simplysm14/apis/service-common/service-types.md +0 -43
- package/claude/references/sd-simplysm14/apis/service-server/README.md +0 -13
- package/claude/references/sd-simplysm14/apis/service-server/auth.md +0 -39
- package/claude/references/sd-simplysm14/apis/service-server/builtin-services.md +0 -71
- package/claude/references/sd-simplysm14/apis/service-server/define-service.md +0 -55
- package/claude/references/sd-simplysm14/apis/service-server/internals.md +0 -82
- package/claude/references/sd-simplysm14/apis/service-server/server.md +0 -57
- package/claude/references/sd-simplysm14/apis/storage/README.md +0 -71
- package/claude/rules/sd-base-rules.md +0 -306
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# @simplysm/orm-common — Queryable
|
|
2
|
-
|
|
3
|
-
체이닝 SELECT/INSERT/UPDATE/DELETE/UPSERT 빌더. `DbContext.queryable(builder)` 가 만든 팩토리 호출(`db.user()`)마다 새 alias 가 할당된 새 `Queryable` 이 반환된다. 모든 체이닝 메서드는 새 인스턴스를 반환(immutable).
|
|
4
|
-
|
|
5
|
-
```ts
|
|
6
|
-
class Queryable<TData extends DataRecord, TFrom extends TableBuilder | never>
|
|
7
|
-
```
|
|
8
|
-
- `TData` — 결과 row 타입 (관계 include 포함).
|
|
9
|
-
- `TFrom` — CUD(INSERT/UPDATE/DELETE/UPSERT) 시 필요한 원본 TableBuilder. `select`/`join`/`union`/`wrap`/`groupBy`/`recursive`/`distinct` 한 후엔 `never` 가 되어 CUD 불가.
|
|
10
|
-
|
|
11
|
-
## 옵션 체이닝
|
|
12
|
-
|
|
13
|
-
- `.select(fn: cols => mapped)` — SELECT 컬럼/표현식 재구성. 원시 리터럴은 자동 `ExprUnit` 으로 래핑. → `Queryable<UnwrapQueryableRecord<R>, never>`.
|
|
14
|
-
- `.distinct()` — DISTINCT.
|
|
15
|
-
- `.lock()` — FOR UPDATE.
|
|
16
|
-
- `.top(n)` — TOP N (ORDER BY 무관).
|
|
17
|
-
- `.limit(skip, take)` — `orderBy` 필수, 없으면 throw.
|
|
18
|
-
- `.orderBy(fn | "key.path", "ASC" | "DESC"?)` — 누적. 문자열 overload 는 `obj.getChainValue` 로 컬럼 검색 (동적 정렬용).
|
|
19
|
-
- `.where(predicate: cols => WhereExprUnit[])` — 누적, AND 결합.
|
|
20
|
-
- `.search(cols => ExprUnit<string|undefined>[], text)` — `parseSearchQuery` 의 OR/AND(`+`)/NOT(`-`)/`"…"`/`*` 구문을 컬럼들에 LIKE 로 적용 (소문자 비교).
|
|
21
|
-
- `.groupBy(cols => ExprUnit[])` — `TFrom` → never.
|
|
22
|
-
- `.having(predicate)` — GROUP BY 후 필터, 누적 AND.
|
|
23
|
-
|
|
24
|
-
## JOIN / INCLUDE
|
|
25
|
-
|
|
26
|
-
```ts
|
|
27
|
-
.join(as, (qr, cols) => Queryable) // 1:N — { ..., [as]?: R[] }
|
|
28
|
-
.joinSingle(as, (qr, cols) => Queryable) // N:1 또는 1:1 — { ..., [as]?: R }
|
|
29
|
-
.include(item => item.user.company) // PathProxy 기반 자동 JOIN (TableBuilder 기반만)
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
- 콜백의 `qr: JoinQueryable` 은 `.from(table)` / `.select(customCols)` / `.union(...queries)` 제공.
|
|
33
|
-
- `.include` 는 `TableBuilder.relations` 정의를 따라 FK/RelationKey(=joinSingle) 또는 FKT/RelationKeyTarget(=join, `single:true` 면 joinSingle) 으로 풀림. 동일 경로 중복 호출은 무시. 다단계(`a.b.c`)는 부모 객체 안으로 nested 됨.
|
|
34
|
-
- PathProxy 는 ColumnPrimitive 필드 접근을 컴파일 에러로 막아 관계 키만 허용.
|
|
35
|
-
|
|
36
|
-
## Subquery / UNION / Recursive CTE
|
|
37
|
-
|
|
38
|
-
- `.wrap()` — 현재 Queryable 을 서브쿼리로 감싼 새 Queryable. `distinct()`/`groupBy()` 후 `count()` 직전에 필요.
|
|
39
|
-
- `Queryable.union(q1, q2, ...)` (static) — UNION (중복 제거). 2개 미만 throw. 첫 query 의 컬럼 구조 사용.
|
|
40
|
-
- `.recursive(fn: (cte: RecursiveQueryable<TData>) => Queryable<TData>)` — WITH RECURSIVE 생성. 콜백 안에서 `cte.from(table)` 한 결과에 `self` 프로퍼티(현재 CTE 자기 참조)가 부여됨. `.union(...)` 도 가능.
|
|
41
|
-
|
|
42
|
-
## 실행 (SELECT)
|
|
43
|
-
|
|
44
|
-
- `await qr.execute(): Promise<TData[]>`
|
|
45
|
-
- `await qr.single(): Promise<TData | undefined>` — 2개 이상이면 throw.
|
|
46
|
-
- `await qr.first(): Promise<TData | undefined>` — 내부 `top(1)`.
|
|
47
|
-
- `await qr.count(fn?): Promise<number>` — `distinct`/`groupBy` 후 직접 호출시 throw → `wrap()` 필요.
|
|
48
|
-
- `await qr.exists(): Promise<boolean>` — `top(1)` 으로 행 존재 확인.
|
|
49
|
-
|
|
50
|
-
## CUD (TFrom = TableBuilder 필요)
|
|
51
|
-
|
|
52
|
-
```ts
|
|
53
|
-
await q.insert(records);
|
|
54
|
-
const [{ id }] = await q.insert([{...}], ["id"]); // OUTPUT
|
|
55
|
-
|
|
56
|
-
await q.insertIfNotExists(record); // WHERE 조건과 결합
|
|
57
|
-
await q.insertIfNotExists(record, ["id"]); // 단건 반환
|
|
58
|
-
|
|
59
|
-
await q2.insertInto(TargetTable); // INSERT INTO ... SELECT
|
|
60
|
-
await q2.insertInto(TargetTable, ["id"]);
|
|
61
|
-
|
|
62
|
-
await q.update(cols => ({ name: expr.val("string", "x") }));
|
|
63
|
-
await q.update(cols => ({...}), ["id"]);
|
|
64
|
-
|
|
65
|
-
await q.delete();
|
|
66
|
-
await q.delete(["id", "name"]);
|
|
67
|
-
|
|
68
|
-
await q.upsert(updateFn); // UPDATE 또는 INSERT (existsSelectQuery=현재 where)
|
|
69
|
-
await q.upsert(updateFn, ["id"]);
|
|
70
|
-
await q.upsert(updateFn, insertFn);
|
|
71
|
-
await q.upsert(updateFn, insertFn, ["id"]);
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
- `insert(records)` 는 records 0건이면 noop. MSSQL 1000행 제한을 위해 청크 분할(`CHUNK_SIZE=1000`) — 각 청크는 별도 `executeDefs` 호출, OUTPUT 도 누적.
|
|
75
|
-
- `insert` 의 records 에 autoIncrement 컬럼 값이 명시되면 자동으로 `overrideIdentity` 켜짐.
|
|
76
|
-
- CUD 는 `TFrom` 이 `TableBuilder` 일 때만 — 아니면 `_getCudOutputDef` 에서 throw. ViewBuilder/Queryable 합성/Union 후엔 사용 불가.
|
|
77
|
-
- `await q.switchFk(enabled)` — TableBuilder/ViewBuilder 기반에서 FK on/off (트랜잭션 내 사용 가능).
|
|
78
|
-
|
|
79
|
-
## QueryDef 생성기 (실행 없이 def 만)
|
|
80
|
-
|
|
81
|
-
`getSelectQueryDef()`, `getInsertQueryDef(records, output?)`, `getInsertIfNotExistsQueryDef(record, output?)`, `getInsertIntoQueryDef(target, output?)`, `getUpdateQueryDef(recordFwd, output?)`, `getDeleteQueryDef(output?)`, `getUpsertQueryDef(updateFn, insertFn, output?)`, `getResultMeta(outputColumns?)`.
|
|
82
|
-
|
|
83
|
-
## 타입
|
|
84
|
-
|
|
85
|
-
`QueryableRecord<TData>` — `TData` 의 원시 필드를 `ExprUnit<T>`, 중첩 객체/배열은 재귀로 감싼 형태. `where`/`select` 콜백 인자 타입.
|
|
86
|
-
|
|
87
|
-
`QueryableWriteRecord<TData>` — `ExprInput<T>` (= `ExprUnit<T> | T`) 으로, `update`/`upsert` 의 record 값 입력 타입.
|
|
88
|
-
|
|
89
|
-
`UnwrapQueryableRecord<R>` — `.select` 결과를 다시 DataRecord 로 역추론.
|
|
90
|
-
|
|
91
|
-
`PathProxy<T>` — `.include` 인자 타입. 비-ColumnPrimitive 필드만 노출.
|
|
92
|
-
|
|
93
|
-
## 보조 함수
|
|
94
|
-
|
|
95
|
-
```ts
|
|
96
|
-
queryable(db, tableOrView, as?) // Queryable factory 생성. DbContext.queryable 의 내부 구현
|
|
97
|
-
getMatchedPrimaryKeys(fkCols, targetTable) // include 가 FK 컬럼과 대상 PK 매칭
|
|
98
|
-
```
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# @simplysm/orm-common — Schema Builders
|
|
2
|
-
|
|
3
|
-
테이블/뷰/프로시저를 fluent 로 정의하는 immutable 빌더. `DbContext` 의 `queryable()`/`executable()` 에 전달하여 등록한다. 모든 메서드는 `new Xxx({...this.meta, ...})` 형태로 새 인스턴스 반환.
|
|
4
|
-
|
|
5
|
-
## Table / TableBuilder
|
|
6
|
-
|
|
7
|
-
```ts
|
|
8
|
-
import { Table } from "@simplysm/orm-common";
|
|
9
|
-
|
|
10
|
-
const User = Table("User") // Table<TName>(name)
|
|
11
|
-
.database("mydb")
|
|
12
|
-
.schema("dbo") // MSSQL/PostgreSQL only
|
|
13
|
-
.description("사용자")
|
|
14
|
-
.columns((c) => ({
|
|
15
|
-
id: c.bigint().autoIncrement(),
|
|
16
|
-
name: c.varchar(100),
|
|
17
|
-
email: c.varchar(200).nullable(),
|
|
18
|
-
status: c.varchar(20).default("active"),
|
|
19
|
-
}))
|
|
20
|
-
.primaryKey("id") // 복합: .primaryKey("a","b")
|
|
21
|
-
.indexes((i) => [i.index("email").unique()])
|
|
22
|
-
.relations((r) => ({
|
|
23
|
-
posts: r.foreignKeyTarget(() => Post, "author"),
|
|
24
|
-
}));
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
타입 추론 프로퍼티 (`readonly $xxx!` — 런타임 값 X, 타입 추출용):
|
|
28
|
-
- `$inferSelect` — 컬럼 + (deep) 관계 (관계는 optional)
|
|
29
|
-
- `$inferColumns` — 컬럼만
|
|
30
|
-
- `$inferInsert` — `autoIncrement`/`nullable`/`default` 컬럼은 optional
|
|
31
|
-
- `$inferUpdate` — 모든 필드 optional
|
|
32
|
-
- `$columns`, `$relations` — 정의 자체
|
|
33
|
-
|
|
34
|
-
`meta`: `{ name; description?; database?; schema?; columns?; primaryKey?; relations?; indexes? }`.
|
|
35
|
-
|
|
36
|
-
## View / ViewBuilder
|
|
37
|
-
|
|
38
|
-
```ts
|
|
39
|
-
import { View } from "@simplysm/orm-common";
|
|
40
|
-
|
|
41
|
-
const ActiveUsers = View("ActiveUsers")
|
|
42
|
-
.database("mydb")
|
|
43
|
-
.query((db: MainDb) =>
|
|
44
|
-
db.user().where(u => [expr.eq(u.status, "active")])
|
|
45
|
-
.select(u => ({ id: u.id, name: u.name })))
|
|
46
|
-
.relations(r => ({ posts: r.relationKeyTarget(() => Post, "author") }));
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
- `.query<TData>(viewFn: (db) => Queryable<TData>)` 의 viewFn 은 `queryable()` 호출시(=`createView` DDL 만들 때, `db.queryable(ViewBuilder)` 팩토리에서) 실행된다.
|
|
50
|
-
- View 의 관계는 `relationKey`/`relationKeyTarget` 만 사용 (DB FK 미생성).
|
|
51
|
-
- `$inferSelect: TData`.
|
|
52
|
-
|
|
53
|
-
## Procedure / ProcedureBuilder
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
import { Procedure } from "@simplysm/orm-common";
|
|
57
|
-
|
|
58
|
-
const GetUserById = Procedure("GetUserById")
|
|
59
|
-
.database("mydb")
|
|
60
|
-
.params(c => ({ userId: c.bigint() }))
|
|
61
|
-
.returns(c => ({ id: c.bigint(), name: c.varchar(100) }))
|
|
62
|
-
.body("SELECT id, name FROM User WHERE id = userId");
|
|
63
|
-
// MSSQL 본문은 @userId 사용. PostgreSQL 은 RETURN QUERY 필요.
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
`$params`, `$returns` 타입 추론. `meta`: `{ name; description?; database?; schema?; params?; returns?; query? }`.
|
|
67
|
-
|
|
68
|
-
## Column Factory (`columns((c) => ...)` 안에서 사용)
|
|
69
|
-
|
|
70
|
-
`createColumnFactory()` 반환 객체의 메서드 — 모두 `ColumnBuilder<TValue, TMeta>` 반환:
|
|
71
|
-
|
|
72
|
-
| 메서드 | TS 타입 | SQL 매핑 |
|
|
73
|
-
|---|---|---|
|
|
74
|
-
| `int()` | number | INT |
|
|
75
|
-
| `bigint()` | number | BIGINT |
|
|
76
|
-
| `float()` | number | FLOAT/REAL |
|
|
77
|
-
| `double()` | number | DOUBLE |
|
|
78
|
-
| `decimal(precision, scale?)` | number | DECIMAL(p,s) |
|
|
79
|
-
| `varchar(length)` | string | VARCHAR(n) |
|
|
80
|
-
| `char(length)` | string | CHAR(n) |
|
|
81
|
-
| `text()` | string | TEXT/LONGTEXT |
|
|
82
|
-
| `binary()` | Bytes | LONGBLOB/VARBINARY(MAX)/BYTEA |
|
|
83
|
-
| `boolean()` | boolean | TINYINT(1)/BIT/BOOLEAN |
|
|
84
|
-
| `datetime()` | DateTime | DATETIME |
|
|
85
|
-
| `date()` | DateOnly | DATE |
|
|
86
|
-
| `time()` | Time | TIME |
|
|
87
|
-
| `uuid()` | Uuid | BINARY(16)/UNIQUEIDENTIFIER/UUID |
|
|
88
|
-
|
|
89
|
-
`ColumnBuilder` 체이닝:
|
|
90
|
-
- `.autoIncrement()` — INSERT 시 자동 증가, `$inferInsert` 에서 optional.
|
|
91
|
-
- `.nullable()` — TS 타입에 `| undefined` 추가.
|
|
92
|
-
- `.default(value)` — 기본값. `$inferInsert` 에서 optional.
|
|
93
|
-
- `.description(text)` — DDL Comment.
|
|
94
|
-
|
|
95
|
-
타입 유틸: `ColumnBuilderRecord`, `InferColumns<T>`, `InferColumnExprs<T>` (Executable params), `RequiredInsertKeys<T>`, `OptionalInsertKeys<T>`, `InferInsertColumns<T>`, `InferUpdateColumns<T>`, `DataToColumnBuilderRecord<TData>`.
|
|
96
|
-
|
|
97
|
-
## Index Factory (`indexes((i) => ...)` 안에서)
|
|
98
|
-
|
|
99
|
-
```ts
|
|
100
|
-
i.index("email").unique()
|
|
101
|
-
i.index("name", "createdAt").orderBy("ASC", "DESC")
|
|
102
|
-
i.index("createdAt").name("IX_Foo")
|
|
103
|
-
i.index("a").description("...")
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
`IndexBuilder<TKeys>` 의 `meta`: `{ columns; name?; unique?; orderBy?; description? }`.
|
|
107
|
-
|
|
108
|
-
## Relation Factory (`relations((r) => ...)` 안에서)
|
|
109
|
-
|
|
110
|
-
Table 은 4개 모두, View 는 `relationKey`/`relationKeyTarget` 만 노출.
|
|
111
|
-
|
|
112
|
-
```ts
|
|
113
|
-
// N:1
|
|
114
|
-
r.foreignKey(["authorId"], () => User, { description?: string }) // DB FK 생성
|
|
115
|
-
r.relationKey(["companyId"], () => Company, { description?: string }) // 논리 관계 (FK X) — View 가능
|
|
116
|
-
|
|
117
|
-
// 1:N (기본) 또는 1:1 (single: true)
|
|
118
|
-
r.foreignKeyTarget(() => Post, "author")
|
|
119
|
-
r.foreignKeyTarget(() => Profile, "user", { single: true })
|
|
120
|
-
r.relationKeyTarget(() => UserSummary, "company", { single?, description? })
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
- `foreignKey` 의 두 번째 인자는 *대상 테이블 factory* `() => TableBuilder` (순환 참조 회피).
|
|
124
|
-
- `foreignKeyTarget` 의 두 번째 인자 `relationName` 은 대상 테이블에 정의된 자기방향 FK 의 키 이름.
|
|
125
|
-
- 메서드 체이닝(`.description()`/`.single()`)은 TS 순환 참조 (TS7022) 회피용으로 *제거됨* — 옵션은 마지막 `opts` 객체로만 전달.
|
|
126
|
-
- 빌더 클래스: `ForeignKeyBuilder`, `ForeignKeyTargetBuilder`, `RelationKeyBuilder`, `RelationKeyTargetBuilder`.
|
|
127
|
-
|
|
128
|
-
타입 유틸: `RelationBuilderRecord`, `ExtractRelationTarget<T>`, `ExtractRelationTargetResult<T>`, `InferDeepRelations<TRelations>` — 모두 관계를 optional 로 추론, 같은 테이블 재방문 시 더 깊이 들어가지 않음 (순환 끊김).
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# @simplysm/orm-node
|
|
2
|
-
|
|
3
|
-
Node.js 환경에서 `@simplysm/orm-common` 의 `DbContext` 를 실제 DB(MSSQL/MySQL/PostgreSQL)에 붙여 실행하기 위한 어댑터. 드라이버 모듈(`tedious`/`mysql2`/`pg`/`pg-copy-streams`)은 dialect 선택 시점에 지연 import.
|
|
4
|
-
|
|
5
|
-
## 사용 트리거 인덱스
|
|
6
|
-
|
|
7
|
-
- **`createOrm`** — `DbContext` 서브클래스 + `DbConnConfig` 로 ORM 인스턴스 생성. 일반 ORM 사용의 진입점.
|
|
8
|
-
- **`Orm<T>`** — `createOrm` 반환 타입. 함수 시그니처·DI 토큰에서 참조하거나 `connect` / `connectWithoutTransaction` 호출 시.
|
|
9
|
-
- **`OrmOptions`** — `createOrm` 3번째 인자. `DbConnConfig` 의 `database` / `schema` 를 런타임에 덮어쓸 때.
|
|
10
|
-
- **`createDbConn`** — `DbConnConfig` 만으로 저수준 `DbConn` 인스턴스 직접 생성. `DbContext` 없이 raw SQL/bulk insert 가 필요할 때.
|
|
11
|
-
- **`NodeDbContextExecutor`** — `DbContext` 의 executor 직접 주입이 필요할 때. 일반적으로는 `createOrm` 이 내부적으로 사용.
|
|
12
|
-
- **`MysqlDbConn`** — MySQL 용 `DbConn` 구현 클래스. 직접 `new` 하지 말고 `createDbConn` 사용. 타입 참조용 import.
|
|
13
|
-
- **`MssqlDbConn`** — MSSQL/Azure SQL 용 `DbConn` 구현 클래스. 직접 `new` 하지 말고 `createDbConn` 사용. 타입 참조용 import.
|
|
14
|
-
- **`PostgresqlDbConn`** — PostgreSQL 용 `DbConn` 구현 클래스. 직접 `new` 하지 말고 `createDbConn` 사용. 타입 참조용 import.
|
|
15
|
-
- **`DbConn`** — 저수준 연결 인터페이스. 모든 dialect 공통 메서드(`connect`/`close`/트랜잭션/`execute`/`executeParametrized`/`bulkInsert`) 와 `close` 이벤트.
|
|
16
|
-
- **`DbConnConfig`** — dialect 분기 union 타입. `createOrm`/`createDbConn` 입력.
|
|
17
|
-
- **`MysqlDbConnConfig`** — `dialect: "mysql"` 한정 설정 타입.
|
|
18
|
-
- **`MssqlDbConnConfig`** — `dialect: "mssql" | "mssql-azure"` 설정 타입. `schema?` 포함.
|
|
19
|
-
- **`PostgresqlDbConnConfig`** — `dialect: "postgresql"` 설정 타입. `schema?` 포함.
|
|
20
|
-
- **`getDialectFromConfig`** — `DbConnConfig` → `Dialect` 변환(`mssql-azure` → `mssql`). 쿼리 빌더 선택 시.
|
|
21
|
-
- **`DB_CONN_CONNECT_TIMEOUT`** — DB 연결 수립 타임아웃 상수 (10초).
|
|
22
|
-
- **`DB_CONN_DEFAULT_TIMEOUT`** — 쿼리/유휴 기본 타임아웃 상수 (10분).
|
|
23
|
-
- **`DB_CONN_ERRORS`** — `NOT_CONNECTED` / `ALREADY_CONNECTED` 에러 메시지 리터럴.
|
|
24
|
-
|
|
25
|
-
## createOrm
|
|
26
|
-
|
|
27
|
-
```ts
|
|
28
|
-
function createOrm<T extends DbContext>(
|
|
29
|
-
DbClass: new (executor: DbContextExecutor, opt: { database: string; schema?: string }) => T,
|
|
30
|
-
config: DbConnConfig,
|
|
31
|
-
options?: OrmOptions, // { database?: string; schema?: string } — config 보다 우선
|
|
32
|
-
): Orm<T>;
|
|
33
|
-
|
|
34
|
-
interface Orm<T> {
|
|
35
|
-
connect<R>(cb: (db: T) => Promise<R>, isolationLevel?: IsolationLevel): Promise<R>; // 트랜잭션
|
|
36
|
-
connectWithoutTransaction<R>(cb: (db: T) => Promise<R>): Promise<R>; // 트랜잭션 없음
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
`database` 가 `options` 와 `config` 양쪽 모두 없으면 throw. 매 `connect*` 호출마다 새 `DbContext` 인스턴스를 만들어 콜백 종료 시 연결을 닫는다.
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
const orm = createOrm(MyDb, { dialect: "mysql", host, port, username, password, database });
|
|
44
|
-
await orm.connect(async (db) => db.user().execute());
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## createDbConn
|
|
48
|
-
|
|
49
|
-
```ts
|
|
50
|
-
function createDbConn(config: DbConnConfig): Promise<DbConn>;
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
dialect 에 따라 드라이버 모듈을 lazy import 한 뒤 해당 `DbConn` 구현 반환. **반환된 객체는 미연결 상태** — 호출자가 `conn.connect()` → 사용 → `conn.close()` 까지 책임. `DbConn` 은 `EventEmitter<{ close: void }>` 이며 다음 메서드 제공: `connect`, `close`, `beginTransaction(isolationLevel?)`, `commitTransaction`, `rollbackTransaction`, `execute(queries: string[])`, `executeParametrized(query, params?)`, `bulkInsert(tableName, columnMetas, records)`. `bulkInsert` 는 dialect별 네이티브 경로 사용(MSSQL: tedious BulkLoad / MySQL: `LOAD DATA LOCAL INFILE` 임시파일 / PostgreSQL: `COPY FROM STDIN`).
|
|
54
|
-
|
|
55
|
-
## DbConnConfig
|
|
56
|
-
|
|
57
|
-
dialect 분기 union. 공통 필드: `host`, `port?`, `username`, `password`, `database?`, `defaultIsolationLevel?`.
|
|
58
|
-
|
|
59
|
-
- `MysqlDbConnConfig` — `dialect: "mysql"`.
|
|
60
|
-
- `MssqlDbConnConfig` — `dialect: "mssql" | "mssql-azure"`, `schema?`. `mssql-azure` 는 `encrypt: true` 로 연결.
|
|
61
|
-
- `PostgresqlDbConnConfig` — `dialect: "postgresql"`, `schema?`.
|
|
62
|
-
|
|
63
|
-
## NodeDbContextExecutor
|
|
64
|
-
|
|
65
|
-
```ts
|
|
66
|
-
new NodeDbContextExecutor(config: DbConnConfig)
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
`DbContextExecutor` 구현. `connect` 시 내부에서 `createDbConn` + `conn.connect()` 수행. `executeDefs(defs, resultMetas?)` 는 `@simplysm/orm-common` 의 `createQueryBuilder` + `parseQueryResult` 를 사용해 `QueryDef[]` → SQL → 파싱 결과. `resultMetas` 가 전부 `null` 인 경우 단일 결합 SQL 1회로 묶어 실행하고 `defs.length` 개의 빈 배열 반환(결과 불필요 케이스 최적화). 미연결 상태에서 메서드 호출 시 `DB_CONN_ERRORS.NOT_CONNECTED` SdError throw.
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# @simplysm/sd-claude
|
|
2
|
-
|
|
3
|
-
Claude Code 셋업 자산(`.claude/` 의 sd-* 스킬·룰·훅) 배포 및 `sd-claude` CLI 제공 패키지. 코드 API 없음 — 외부 import 가능한 라이브러리 심볼 미노출.
|
|
4
|
-
|
|
5
|
-
## 사용 트리거 인덱스
|
|
6
|
-
|
|
7
|
-
- 현재 로그인된 Claude 계정을 프로필로 저장 → [auth save](#cli-sd-claude)
|
|
8
|
-
- 저장된 다른 Claude 계정으로 전환 → [auth switch](#cli-sd-claude)
|
|
9
|
-
- 소비 프로젝트 설치 시 `.claude/` 자산 자동 배치 → [postinstall](#패키지-훅)
|
|
10
|
-
- 워크스페이스 `.claude/` 변경분을 패키지 `claude/` 로 동기화(배포 직전) → [prepack / sync](#패키지-훅)
|
|
11
|
-
|
|
12
|
-
## CLI `sd-claude`
|
|
13
|
-
|
|
14
|
-
`bin: sd-claude` → `scripts/cli.mjs`. 사용법: `sd-claude <subcommand> <action>`.
|
|
15
|
-
|
|
16
|
-
- `auth save`: 현재 `claude auth status` 의 `orgName` 을 프로필 키로, `~/.claude/.credentials.json` 의 `claudeAiOauth.refreshToken` 과 `~/.claude/statusline-cache.json` 의 사용량 스냅샷을 `~/.claude/profiles.json` 에 저장하고 `current` 를 해당 프로필로 설정. orgName 또는 refreshToken 미획득 시 stderr 출력 후 exit 1.
|
|
17
|
-
- `auth switch`: `profiles.json` 의 계정 목록을 번호 + 현재 마커(`*`) + 사용량(현재 계정은 live, 그 외는 저장 시점) 으로 출력. 번호 입력으로 대상 선택 → 현재 계정의 최신 refreshToken·사용량을 백업 저장 → `CLAUDE_CODE_OAUTH_REFRESH_TOKEN`/`CLAUDE_CODE_OAUTH_SCOPES` 환경변수로 `claude auth login` 을 spawn → 갱신된 refreshToken 저장 + `current` 업데이트. TTY 아니면 exit 1.
|
|
18
|
-
- 그 외 인자: 사용법 출력 후 exit 1.
|
|
19
|
-
|
|
20
|
-
저장 위치 식별자 풀이:
|
|
21
|
-
- `~/.claude/profiles.json`: `{ current: string, accounts: { [orgName]: { refreshToken, usage } } }` 구조. 패키지가 관리.
|
|
22
|
-
- `~/.claude/.credentials.json`: Claude Code 본체가 관리. `claudeAiOauth.refreshToken` 만 읽음.
|
|
23
|
-
- `~/.claude/statusline-cache.json`: Claude Code 본체가 관리. `rate_limits.five_hour` / `seven_day` 의 `used_percentage` + `resets_at` 만 읽음.
|
|
24
|
-
|
|
25
|
-
## 패키지 훅
|
|
26
|
-
|
|
27
|
-
- `postinstall` (`scripts/postinstall.mjs`): 소비 프로젝트의 `node_modules` 설치 시 자동 실행. `INIT_CWD` 또는 `node_modules` 경로 역추적으로 프로젝트 루트 결정 → `<projectRoot>/.claude/` 의 기존 sd-* 항목(root 1단계 + 하위 디렉토리 1단계의 `^sd[-_]` 매칭) 정리 후 패키지 `claude/` 의 동일 항목 + `settings.json` + `simplysm.json` 을 복사. 소비 프로젝트가 `name: "simplysm"` 이고 메이저 버전이 같으면 skip(모노레포 자기 자신 보호). 실패해도 throw 하지 않음(install 차단 방지).
|
|
28
|
-
- `prepack` (`scripts/sync.mjs`): `pnpm pub`/`npm pack` 직전 실행. 워크스페이스 루트(`../../`)의 `.claude/` 에서 sd-* 항목(+ `settings.json`/`simplysm.json`) 을 패키지 `claude/` 로 증분 복사. 동일 파일은 mtime+size 비교로 skip, 변경분은 unlink 후 copy + src mtime 보존, src 에 없는 dest 항목은 prune. 제외: `evals/` 하위, 파일명 `SKILL.eval.md`, `eval_*` 접두 파일. (Windows EPERM 회피 위해 일괄 rmSync 미사용.)
|
|
29
|
-
|
|
30
|
-
식별자 풀이:
|
|
31
|
-
- sd-* 항목 스캔 범위: 디렉토리 root + 1단계 하위. 정규식 `^sd[-_]`. 즉 `.claude/skills/sd-foo/`, `.claude/rules/sd-bar.md`, `.claude/sd-baz/` 등 매칭.
|
|
32
|
-
- watch 훅 연동: 모노레포에서는 `sd.config.ts` 의 `scripts` 타겟이 `.claude/sd-*` 변경 감지 시 본 `sync.mjs` 를 호출(패키지 외부 설정).
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# @simplysm/sd-cli
|
|
2
|
-
|
|
3
|
-
워크스페이스 빌드/배포 오케스트레이터. 소비 표면은 두 갈래다 — `pnpm sd-cli <cmd>` 서브커맨드와 `sd.config.ts` 작성용 타입. 라이브러리 export 로는 Vitest Angular 플러그인과 외부 도구가 재사용할 `SdTsCompiler` 도 노출한다.
|
|
4
|
-
|
|
5
|
-
## 사용 트리거 인덱스
|
|
6
|
-
|
|
7
|
-
### 서브커맨드 (`pnpm sd-cli <cmd>`)
|
|
8
|
-
|
|
9
|
-
- **`check`** — 타입체크와 lint 를 병렬 실행. 일반 검증 명령으로 가장 자주 호출됨.
|
|
10
|
-
- **`watch`** — 워크스페이스 전체 또는 일부 패키지를 watch 모드로 증분 빌드.
|
|
11
|
-
- **`dev`** — server 패키지를 dev 모드로 실행 (`tsx` 핫리로드 + client 패키지의 dev http 서버 동반 기동).
|
|
12
|
-
- **`device`** — client 패키지를 안드로이드 디바이스 또는 Electron 데스크톱에서 실행. dev 서버가 떠 있어야 함.
|
|
13
|
-
- **`build`** — 프로덕션 빌드. `sd.config.ts` 의 `packages` 전 항목 또는 `-t` 지정 항목.
|
|
14
|
-
- **`publish`** — 빌드 후 `publish` 설정을 따라 배포 (npm / 로컬 디렉토리 / FTP·SFTP). `--no-build` 로 기존 산출물만 배포.
|
|
15
|
-
- **`replace-deps`** — `sd.config.ts.replaceDeps` 에 따라 `node_modules` 패키지를 로컬 소스로 심링크 교체.
|
|
16
|
-
- **`init`** — 인터랙티브 프롬프트로 SI 워크스페이스 골격 생성.
|
|
17
|
-
|
|
18
|
-
공통 옵션:
|
|
19
|
-
- `-t / --target <pkg>` (반복 가능) — 대상 패키지. `sd.config.ts.packages` 키 (= `@simplysm/` 접두사 **제외**한 짧은 이름). 미지정 시 전체. `check`/`watch`/`dev`/`build`/`publish` 에서 지원. `device` 는 단수(`-t <pkg>` 1회). `replace-deps`/`init` 미지원.
|
|
20
|
-
- `-o / --opt <val>` (반복 가능) — `sd.config.ts` 함수의 `params.opt[]` 로 전달. `check` 와 `init` 제외 전 커맨드에서 지원.
|
|
21
|
-
- `--debug` — 디버그 로그 출력 (모든 커맨드).
|
|
22
|
-
- `--help / -h` — 단독 호출 시 모든 서브커맨드 종합 도움말.
|
|
23
|
-
|
|
24
|
-
커맨드별 고유 옵션:
|
|
25
|
-
- `check`: `--type typecheck|lint` (반복 가능, 기본 둘 다), `--fix` (lint 자동 수정).
|
|
26
|
-
- `device`: `--target <pkg>` (단수, 미지정 시 유일 client 자동 선택), `--url <devServerUrl>` (미지정 시 `sd.config.ts` 의 server 설정에서 자동 도출).
|
|
27
|
-
- `publish`: `--no-build` (빌드 생략), `--dry-run` (실제 배포 없이 시뮬레이션).
|
|
28
|
-
|
|
29
|
-
진실 근거: `packages/sd-cli/src/sd-cli-entry.ts` (yargs 등록부), `packages/sd-cli/src/commands/<cmd>.ts`.
|
|
30
|
-
|
|
31
|
-
### 설정 타입 (`sd.config.ts`)
|
|
32
|
-
|
|
33
|
-
- **`SdConfigFn` / `SdConfig` / `SdConfigParams`** — `sd.config.ts` 의 default export 함수와 그 반환 타입. 자세히: [sd-config.md](./sd-config.md)
|
|
34
|
-
- **`SdBuildPackageConfig` / `SdClientPackageConfig` / `SdServerPackageConfig` / `SdScriptsPackageConfig`** — `SdConfig.packages` 의 값 타입. 각각 라이브러리 / Frontend 앱 / Fastify 서버 / 유틸 패키지에 대응. 자세히: [sd-config.md](./sd-config.md)
|
|
35
|
-
- **`SdPublishConfig` / `SdPostPublishScriptConfig`** — 패키지의 `publish` 와 전역 `postPublish` 항목 타입. 자세히: [sd-config.md](./sd-config.md)
|
|
36
|
-
- **`SdCapacitorConfig` / `SdElectronConfig` / `SdPwaConfig` / `SdBrowserSupportConfig`** — client 패키지의 모바일·데스크톱·PWA·브라우저 지원 옵션. 자세히: [sd-config.md](./sd-config.md)
|
|
37
|
-
|
|
38
|
-
### 라이브러리 export
|
|
39
|
-
|
|
40
|
-
- **`sdAngularPlugin(options)`** — Vitest 의 `vite.config` / `vitest.config` 에서 Angular 패키지 AOT 컴파일이 필요할 때 plugin 으로 추가.
|
|
41
|
-
- **`SdTsCompiler` (+ `ISdTsCompilerOptions`, `ISdTsCompilerResult`)** — Angular/Non-Angular TS 패키지를 증분 컴파일·진단·lint·SCSS 통합 처리하는 엔진. `sd-cli` 내부와 `sdAngularPlugin` 이 사용. 외부에서 동일한 엔진을 재사용할 때만 직접 import.
|
|
42
|
-
|
|
43
|
-
## sdAngularPlugin
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
import { sdAngularPlugin, type SdAngularPluginOptions } from "@simplysm/sd-cli";
|
|
47
|
-
|
|
48
|
-
// vitest.config.ts
|
|
49
|
-
plugins: [sdAngularPlugin({ pkg: "angular" })]
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
`pkg` 는 `sd.config.ts.packages` 키 (= `packages/<pkg>/` 디렉토리명). 패키지의 `.ts` 를 AOT 컴파일해 `transform` 훅에서 JS 로 치환한다. `tsconfig.json` 의 `angularCompilerOptions` 유무로 Angular 모드를 자동 감지. Vitest watch 의 `watchChange` 를 받아 증분 재컴파일. 첫 `buildStart` 전에 `config()` 호출 필수 (Vitest 가 자동 호출).
|
|
53
|
-
|
|
54
|
-
## SdTsCompiler
|
|
55
|
-
|
|
56
|
-
```typescript
|
|
57
|
-
import { SdTsCompiler } from "@simplysm/sd-cli";
|
|
58
|
-
|
|
59
|
-
const compiler = new SdTsCompiler({
|
|
60
|
-
pkgDir: "/abs/path/to/packages/foo",
|
|
61
|
-
cwd: "/abs/path/to/workspace",
|
|
62
|
-
output: { js: true, dts: false }, // 출력 제어 — 둘 다 false 면 typecheck only
|
|
63
|
-
includeTests: false, // true 면 tests/ 도 rootNames 에 포함
|
|
64
|
-
lint: false,
|
|
65
|
-
globalScss: false,
|
|
66
|
-
});
|
|
67
|
-
const result = await compiler.compileAsync(/* modifiedFiles? */);
|
|
68
|
-
// result.diagnostics, result.errorCount, result.emitResults (Angular), ...
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
특징:
|
|
72
|
-
- 인스턴스를 재사용해 호출 간 incremental 빌드 (`tsBuildInfoFile` 은 `<pkgDir>/.cache/` 하위).
|
|
73
|
-
- `compileAsync(modifiedFiles)` 의 modifiedFiles 는 watch 모드의 변경 파일. 미전달 시 전체 affected 탐색.
|
|
74
|
-
- Angular 패키지(`tsconfig.angularCompilerOptions`)는 자동으로 NgtscProgram 사용. 결과의 `emitResults: { filename, contents, sourceFileName }[]` 를 호출자가 디스크/번들러에 전달. Non-Angular 은 `host.writeFile` 로 디스크에 직접 emit (결과의 `emitResults` undefined).
|
|
75
|
-
- `compilerOptionsTransformer` 로 target/module/outDir 등을 후처리 override 가능.
|
|
76
|
-
- `transformStylesheet`, `externalStylesheets`, `sourceFileCache` 는 Angular 클라이언트 빌드 통합용 (esbuild 플러그인이 사용).
|
|
77
|
-
- 단계별 try/catch 로 부분 복구 — 한 단계 실패해도 다른 진단/emit 결과는 유지.
|
|
78
|
-
- 결과의 `affectedFiles` 가 `undefined` 면 전역 변경 (전체 리빌드 신호).
|
|
79
|
-
|
|
80
|
-
전체 옵션·결과 필드 정의는 `packages/sd-cli/src/ts-compiler/sd-ts-compiler-options.ts`, `sd-ts-compiler-result.ts` 참조.
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
# @simplysm/sd-cli — sd-config
|
|
2
|
-
|
|
3
|
-
`sd.config.ts` 작성용 타입 모음. 진실 근거: `packages/sd-cli/src/sd-config.types.ts`.
|
|
4
|
-
|
|
5
|
-
## 진입 타입
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
import type { SdConfig, SdConfigFn, SdConfigParams } from "@simplysm/sd-cli";
|
|
9
|
-
|
|
10
|
-
const config: SdConfigFn = (params) => ({
|
|
11
|
-
packages: {
|
|
12
|
-
"core-common": { target: "neutral" },
|
|
13
|
-
"core-node": { target: "node" },
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
export default config;
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
- `SdConfigFn = (params: SdConfigParams) => SdConfig | Promise<SdConfig>`
|
|
20
|
-
- `SdConfigParams = { cwd: string; dev: boolean; opt: string[] }` — `opt` 는 CLI `-o` 플래그.
|
|
21
|
-
- `SdConfig = { packages: Record<string, SdPackageConfig | undefined>; replaceDeps?: Record<string, string>; postPublish?: SdPostPublishScriptConfig[] }`
|
|
22
|
-
- `packages` 키 = `packages/` 하위 디렉토리명.
|
|
23
|
-
- `replaceDeps`: node_modules 의 패키지를 로컬 소스로 심링크 교체. 예: `{ "@simplysm/*": "../simplysm/packages/*" }` (key 의 `*` 가 value 의 `*` 로 치환).
|
|
24
|
-
|
|
25
|
-
## 패키지 설정
|
|
26
|
-
|
|
27
|
-
`SdPackageConfig = SdBuildPackageConfig | SdClientPackageConfig | SdServerPackageConfig | SdScriptsPackageConfig`.
|
|
28
|
-
|
|
29
|
-
### SdBuildPackageConfig (라이브러리: node/browser/neutral)
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
{
|
|
33
|
-
target: "node" | "browser" | "neutral"; // BuildTarget
|
|
34
|
-
publish?: SdPublishConfig;
|
|
35
|
-
copySrc?: string[]; // src/ 기준 glob → dist/ 로 복사
|
|
36
|
-
watch?: SdWatchHookConfig; // watch 모드 훅
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### SdClientPackageConfig (Frontend 앱)
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
{
|
|
44
|
-
target: "client";
|
|
45
|
-
server: string | number; // 연결 서버 패키지명, 또는 포트
|
|
46
|
-
env?: Record<string, string>; // esbuild define 으로 process.env 치환
|
|
47
|
-
publish?: SdPublishConfig;
|
|
48
|
-
capacitor?: SdCapacitorConfig;
|
|
49
|
-
electron?: SdElectronConfig;
|
|
50
|
-
configs?: Record<string, unknown>; // 런타임 설정 → dist/.config.json
|
|
51
|
-
exclude?: string[]; // Capacitor/Electron package.json 에 추가
|
|
52
|
-
browserSupport?: SdBrowserSupportConfig;
|
|
53
|
-
pwa?: false | SdPwaConfig; // 미지정 시 기본값으로 활성
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### SdServerPackageConfig (Fastify 서버)
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
{
|
|
61
|
-
target: "server";
|
|
62
|
-
env?: Record<string, string>; // esbuild banner 로 process.env.KEY 상수 치환
|
|
63
|
-
publish?: SdPublishConfig;
|
|
64
|
-
configs?: Record<string, unknown>; // 런타임 설정 → dist/.config.json
|
|
65
|
-
externals?: string[]; // esbuild external (binding.gyp 자동 감지에 추가)
|
|
66
|
-
pm2?: { name?: string; ignoreWatchPaths?: string[] }; // 지정 시 dist/pm2.config.cjs 생성
|
|
67
|
-
packageManager?: "volta" | "mise"; // mise.toml / volta 설정 생성에 영향
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### SdScriptsPackageConfig (유틸·임의 명령 실행)
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
{
|
|
75
|
-
target: "scripts";
|
|
76
|
-
publish?: SdPublishConfig;
|
|
77
|
-
watch?: SdWatchHookConfig; // 미지정이면 watch/typecheck 에서 제외
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
`SdWatchHookConfig`: `{ target: string[]; cmd: string; args?: string[] }`. `target` 은 패키지 디렉토리 기준 glob. 매칭 변경 시 `cmd args` 실행.
|
|
82
|
-
|
|
83
|
-
## 배포 설정
|
|
84
|
-
|
|
85
|
-
`SdPublishConfig`:
|
|
86
|
-
- `{ type: "npm" }` — npm 레지스트리.
|
|
87
|
-
- `{ type: "local-directory"; path: string }` — 로컬 복사. `path` 에 `%VER%`, `%PROJECT%` 치환.
|
|
88
|
-
- `{ type: "ftp" | "ftps" | "sftp"; host; port?; path?; user?; password? }`.
|
|
89
|
-
|
|
90
|
-
`postPublish` 항목 `SdPostPublishScriptConfig`: `{ type: "script"; cmd: string; args: string[] }`. `args` 의 `%VER%`, `%PROJECT%` 치환.
|
|
91
|
-
|
|
92
|
-
## 클라이언트 부속 옵션
|
|
93
|
-
|
|
94
|
-
### SdCapacitorConfig
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
{
|
|
98
|
-
appId: string; // 예 "com.example.app"
|
|
99
|
-
appName: string;
|
|
100
|
-
plugins?: Record<string, Record<string, unknown> | true>;
|
|
101
|
-
icon?: string; // 패키지 기준 상대 경로
|
|
102
|
-
debug?: boolean;
|
|
103
|
-
platform?: { android?: SdCapacitorAndroidConfig };
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
`SdCapacitorAndroidConfig`: `config`(AndroidManifest application 속성), `bundle`(true=AAB, false=APK), `intentFilters`, `sign: SdCapacitorSignConfig`, `sdkVersion`, `permissions: SdCapacitorPermission[]`.
|
|
108
|
-
|
|
109
|
-
- `SdCapacitorSignConfig`: `keystore, storePassword, alias, password, keystoreType?` (기본 `"jks"`).
|
|
110
|
-
- `SdCapacitorPermission`: `{ name; maxSdkVersion?; ignore? }`.
|
|
111
|
-
- `SdCapacitorIntentFilter`: `{ action?; category? }`.
|
|
112
|
-
|
|
113
|
-
### SdElectronConfig
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
{
|
|
117
|
-
appId: string;
|
|
118
|
-
portable?: boolean; // true=포터블 exe, 미지정/false=NSIS 설치본
|
|
119
|
-
installerIcon?: string; // .ico, 패키지 기준 상대 경로
|
|
120
|
-
reinstallDependencies?: string[]; // 네이티브 모듈 등
|
|
121
|
-
postInstallScript?: string;
|
|
122
|
-
nsisOptions?: Record<string, unknown>;
|
|
123
|
-
env?: Record<string, string>; // electron-main.ts 의 process.env
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### SdPwaConfig
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
{
|
|
131
|
-
manifest?: {
|
|
132
|
-
name?; short_name?;
|
|
133
|
-
display?: "standalone" | "fullscreen" | "minimal-ui" | "browser";
|
|
134
|
-
theme_color?; background_color?;
|
|
135
|
-
icons?: Array<{ src: string; sizes: string; type?: string }>;
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
`pwa: false` 로 비활성. 미지정 시 기본값으로 활성.
|
|
141
|
-
|
|
142
|
-
### SdBrowserSupportConfig
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
{
|
|
146
|
-
browserslist?: string | string[]; // 예 "last 2 Chrome versions"
|
|
147
|
-
postCss?: { plugins: [string, (object | string)?][] };
|
|
148
|
-
legacyModule?: boolean; // 코드 분할 비활성 + import.meta 치환
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## 부수 타입
|
|
153
|
-
|
|
154
|
-
- `BuildTarget = "node" | "browser" | "neutral"` — `SdBuildPackageConfig.target`.
|
|
155
|
-
- `NpmConfig` — `package.json` 구조 헬퍼 (`name`, `version`, `dependencies`, `devDependencies`, `peerDependencies`, `volta?`).
|