@simplysm/sd-cli 13.0.84 → 13.0.86
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/README.md +302 -23
- package/docs/architecture.md +311 -0
- package/docs/config-types.md +253 -0
- package/package.json +6 -6
- package/templates/init/mise.toml +2 -2
- package/templates/init/package.json.hbs +8 -4
- package/templates/init/packages/client-admin/package.json.hbs +6 -5
- package/templates/init/packages/client-admin/src/events/AuthChangeEvent.ts +3 -0
- package/templates/init/packages/client-admin/src/main.tsx.hbs +2 -2
- package/templates/init/packages/client-admin/src/providers/AppServiceProvider.tsx.hbs +4 -4
- package/templates/init/packages/client-admin/src/providers/AuthProvider.tsx.hbs +27 -2
- package/templates/init/packages/client-admin/src/providers/configureSharedData.ts.hbs +8 -8
- package/templates/init/packages/client-admin/src/views/auth/LoginView.tsx +4 -4
- package/templates/init/packages/client-admin/src/views/home/HomeView.tsx +2 -2
- package/templates/init/packages/db-main/package.json.hbs +2 -2
- package/templates/init/packages/db-main/src/MainDbContext.ts +8 -6
- package/templates/init/packages/db-main/src/dataLogExt.ts +1 -1
- package/templates/init/packages/db-main/src/index.ts +10 -6
- package/templates/init/packages/server/package.json.hbs +4 -4
- package/templates/init/pnpm-workspace.yaml +1 -0
- package/templates/init/sd.config.ts.hbs +21 -9
- package/templates/init/{tests/e2e → tests-e2e}/package.json.hbs +1 -1
- package/templates/init/{tests/e2e → tests-e2e}/vitest.setup.ts.hbs +1 -1
- package/templates/init/tsconfig.json.hbs +2 -1
- package/templates/init/vitest-e2e.config.ts +23 -0
- package/templates/init/vitest.config.ts +0 -13
- package/docs/commands.md +0 -177
- package/docs/configuration.md +0 -211
- package/docs/vite-config.md +0 -67
- /package/templates/init/packages/db-main/src/tables/{Employee.ts → base/Employee.ts} +0 -0
- /package/templates/init/packages/db-main/src/tables/{EmployeeConfig.ts → base/EmployeeConfig.ts} +0 -0
- /package/templates/init/packages/db-main/src/tables/{Role.ts → base/Role.ts} +0 -0
- /package/templates/init/packages/db-main/src/tables/{RolePermission.ts → base/RolePermission.ts} +0 -0
- /package/templates/init/packages/db-main/src/tables/{_DataLog.ts → system/_DataLog.ts} +0 -0
- /package/templates/init/packages/db-main/src/tables/{_Log.ts → system/_Log.ts} +0 -0
- /package/templates/init/{tests/e2e → tests-e2e}/src/e2e.spec.ts +0 -0
- /package/templates/init/{tests/e2e → tests-e2e}/src/employee-crud.ts +0 -0
- /package/templates/init/{tests/e2e → tests-e2e}/src/login.ts +0 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# 설정 타입 레퍼런스
|
|
2
|
+
|
|
3
|
+
`sd.config.ts`에서 사용하는 모든 타입의 상세 레퍼런스.
|
|
4
|
+
|
|
5
|
+
## SdConfig
|
|
6
|
+
|
|
7
|
+
`sd.config.ts`의 최상위 설정 타입.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
interface SdConfig {
|
|
11
|
+
packages: Record<string, SdPackageConfig | undefined>;
|
|
12
|
+
replaceDeps?: Record<string, string>;
|
|
13
|
+
postPublish?: SdPostPublishScriptConfig[];
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| 필드 | 타입 | 설명 |
|
|
18
|
+
|------|------|------|
|
|
19
|
+
| `packages` | `Record<string, SdPackageConfig>` | 패키지별 설정. 키는 `packages/` 하위 디렉토리명 |
|
|
20
|
+
| `replaceDeps` | `Record<string, string>` | 의존성 교체 설정. 키: glob 패턴, 값: 로컬 경로 (`*` 치환 지원) |
|
|
21
|
+
| `postPublish` | `SdPostPublishScriptConfig[]` | 배포 완료 후 실행할 스크립트 |
|
|
22
|
+
|
|
23
|
+
### replaceDeps 예시
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
replaceDeps: {
|
|
27
|
+
"@simplysm/*": "../simplysm/packages/*"
|
|
28
|
+
}
|
|
29
|
+
// @simplysm/core-common → ../simplysm/packages/core-common 으로 심링크
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## SdConfigFn / SdConfigParams
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
type SdConfigFn = (params: SdConfigParams) => SdConfig | Promise<SdConfig>;
|
|
36
|
+
|
|
37
|
+
interface SdConfigParams {
|
|
38
|
+
cwd: string; // 현재 작업 디렉토리
|
|
39
|
+
dev: boolean; // 개발 모드 여부 (dev/watch: true, build/publish: false)
|
|
40
|
+
options: string[]; // CLI -o 플래그 값 (예: ["key=value"])
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 패키지 설정 타입
|
|
45
|
+
|
|
46
|
+
### SdBuildPackageConfig
|
|
47
|
+
|
|
48
|
+
라이브러리 패키지 (node/browser/neutral) 설정.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
interface SdBuildPackageConfig {
|
|
52
|
+
target: "node" | "browser" | "neutral";
|
|
53
|
+
publish?: SdPublishConfig;
|
|
54
|
+
copySrc?: string[];
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| 필드 | 타입 | 설명 |
|
|
59
|
+
|------|------|------|
|
|
60
|
+
| `target` | `BuildTarget` | 빌드 대상 플랫폼 |
|
|
61
|
+
| `publish` | `SdPublishConfig` | 배포 설정 |
|
|
62
|
+
| `copySrc` | `string[]` | `src/`에서 `dist/`로 복사할 파일 glob 패턴 (src 기준 상대 경로) |
|
|
63
|
+
|
|
64
|
+
### SdClientPackageConfig
|
|
65
|
+
|
|
66
|
+
클라이언트 앱 패키지 설정 (Vite + SolidJS).
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
interface SdClientPackageConfig {
|
|
70
|
+
target: "client";
|
|
71
|
+
server: string | number;
|
|
72
|
+
env?: Record<string, string>;
|
|
73
|
+
publish?: SdPublishConfig;
|
|
74
|
+
capacitor?: SdCapacitorConfig;
|
|
75
|
+
electron?: SdElectronConfig;
|
|
76
|
+
configs?: Record<string, unknown>;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| 필드 | 타입 | 설명 |
|
|
81
|
+
|------|------|------|
|
|
82
|
+
| `target` | `"client"` | 고정값 |
|
|
83
|
+
| `server` | `string \| number` | 서버 패키지명(프록시 연결) 또는 Vite 포트 번호 |
|
|
84
|
+
| `env` | `Record<string, string>` | 빌드 시 `process.env` 치환 값 |
|
|
85
|
+
| `publish` | `SdPublishConfig` | 배포 설정 |
|
|
86
|
+
| `capacitor` | `SdCapacitorConfig` | Capacitor 설정 (모바일 앱) |
|
|
87
|
+
| `electron` | `SdElectronConfig` | Electron 설정 (데스크톱 앱) |
|
|
88
|
+
| `configs` | `Record<string, unknown>` | 런타임 설정 (`dist/.config.json`에 기록) |
|
|
89
|
+
|
|
90
|
+
### SdServerPackageConfig
|
|
91
|
+
|
|
92
|
+
서버 앱 패키지 설정 (Fastify).
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
interface SdServerPackageConfig {
|
|
96
|
+
target: "server";
|
|
97
|
+
env?: Record<string, string>;
|
|
98
|
+
publish?: SdPublishConfig;
|
|
99
|
+
configs?: Record<string, unknown>;
|
|
100
|
+
externals?: string[];
|
|
101
|
+
pm2?: {
|
|
102
|
+
name?: string;
|
|
103
|
+
ignoreWatchPaths?: string[];
|
|
104
|
+
};
|
|
105
|
+
packageManager?: "volta" | "mise";
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
| 필드 | 타입 | 설명 |
|
|
110
|
+
|------|------|------|
|
|
111
|
+
| `target` | `"server"` | 고정값 |
|
|
112
|
+
| `env` | `Record<string, string>` | `process.env.KEY` 치환 값 |
|
|
113
|
+
| `publish` | `SdPublishConfig` | 배포 설정 |
|
|
114
|
+
| `configs` | `Record<string, unknown>` | 런타임 설정 (`dist/.config.json`에 기록) |
|
|
115
|
+
| `externals` | `string[]` | esbuild 번들에서 제외할 외부 모듈 |
|
|
116
|
+
| `pm2` | `object` | PM2 설정 (`dist/pm2.config.cjs` 생성) |
|
|
117
|
+
| `packageManager` | `"volta" \| "mise"` | 패키지 매니저 설정 파일 생성 |
|
|
118
|
+
|
|
119
|
+
### SdScriptsPackageConfig
|
|
120
|
+
|
|
121
|
+
스크립트 전용 패키지 (빌드/watch/typecheck 제외).
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
interface SdScriptsPackageConfig {
|
|
125
|
+
target: "scripts";
|
|
126
|
+
publish?: SdPublishConfig;
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 배포 설정 타입
|
|
131
|
+
|
|
132
|
+
### SdPublishConfig (유니온)
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
type SdPublishConfig = SdNpmPublishConfig | SdLocalDirectoryPublishConfig | SdStoragePublishConfig;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### SdNpmPublishConfig
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
interface SdNpmPublishConfig {
|
|
142
|
+
type: "npm";
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### SdLocalDirectoryPublishConfig
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
interface SdLocalDirectoryPublishConfig {
|
|
150
|
+
type: "local-directory";
|
|
151
|
+
path: string; // %VER%, %PROJECT% 치환 지원
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### SdStoragePublishConfig
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
interface SdStoragePublishConfig {
|
|
159
|
+
type: "ftp" | "ftps" | "sftp";
|
|
160
|
+
host: string;
|
|
161
|
+
port?: number;
|
|
162
|
+
path?: string;
|
|
163
|
+
user?: string;
|
|
164
|
+
password?: string; // 미지정 시 SSH 키 인증 사용 (SFTP)
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### SdPostPublishScriptConfig
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
interface SdPostPublishScriptConfig {
|
|
172
|
+
type: "script";
|
|
173
|
+
cmd: string;
|
|
174
|
+
args: string[]; // %VER%, %PROJECT% 치환 지원
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Capacitor 설정
|
|
179
|
+
|
|
180
|
+
### SdCapacitorConfig
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
interface SdCapacitorConfig {
|
|
184
|
+
appId: string; // 예: "com.example.app"
|
|
185
|
+
appName: string;
|
|
186
|
+
plugins?: Record<string, Record<string, unknown> | true>;
|
|
187
|
+
icon?: string; // 패키지 디렉토리 기준 상대 경로
|
|
188
|
+
debug?: boolean;
|
|
189
|
+
platform?: {
|
|
190
|
+
android?: SdCapacitorAndroidConfig;
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### SdCapacitorAndroidConfig
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
interface SdCapacitorAndroidConfig {
|
|
199
|
+
config?: Record<string, string>; // AndroidManifest application 속성
|
|
200
|
+
bundle?: boolean; // true: AAB, false: APK
|
|
201
|
+
intentFilters?: SdCapacitorIntentFilter[];
|
|
202
|
+
sign?: SdCapacitorSignConfig;
|
|
203
|
+
sdkVersion?: number; // minSdk, targetSdk
|
|
204
|
+
permissions?: SdCapacitorPermission[];
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### SdCapacitorSignConfig
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
interface SdCapacitorSignConfig {
|
|
212
|
+
keystore: string; // 패키지 디렉토리 기준 상대 경로
|
|
213
|
+
storePassword: string;
|
|
214
|
+
alias: string;
|
|
215
|
+
password: string;
|
|
216
|
+
keystoreType?: string; // 기본값: "jks"
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### SdCapacitorPermission
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
interface SdCapacitorPermission {
|
|
224
|
+
name: string; // 예: "CAMERA"
|
|
225
|
+
maxSdkVersion?: number;
|
|
226
|
+
ignore?: string; // tools:ignore 속성
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### SdCapacitorIntentFilter
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
interface SdCapacitorIntentFilter {
|
|
234
|
+
action?: string; // 예: "android.intent.action.VIEW"
|
|
235
|
+
category?: string; // 예: "android.intent.category.DEFAULT"
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Electron 설정
|
|
240
|
+
|
|
241
|
+
### SdElectronConfig
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
interface SdElectronConfig {
|
|
245
|
+
appId: string; // 예: "com.example.myapp"
|
|
246
|
+
portable?: boolean; // true: portable .exe, false: NSIS 설치
|
|
247
|
+
installerIcon?: string; // .ico 파일 경로
|
|
248
|
+
reinstallDependencies?: string[]; // Electron에 포함할 npm 패키지
|
|
249
|
+
postInstallScript?: string; // npm postinstall 스크립트
|
|
250
|
+
nsisOptions?: Record<string, unknown>;
|
|
251
|
+
env?: Record<string, string>; // electron-main.ts에서 사용할 환경 변수
|
|
252
|
+
}
|
|
253
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/sd-cli",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.86",
|
|
4
4
|
"description": "Simplysm package - CLI tool",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@fastify/http-proxy": "^11.4.1",
|
|
25
25
|
"@inquirer/prompts": "^8.3.0",
|
|
26
26
|
"consola": "^3.4.2",
|
|
27
|
-
"esbuild": "^0.27.
|
|
27
|
+
"esbuild": "^0.27.4",
|
|
28
28
|
"esbuild-plugin-solid": "^0.6.0",
|
|
29
29
|
"eslint": "^9.39.4",
|
|
30
30
|
"execa": "^9.6.1",
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
"typescript": "^5.9.3",
|
|
41
41
|
"vite": "^7.3.1",
|
|
42
42
|
"vite-plugin-pwa": "^1.2.0",
|
|
43
|
-
"vite-plugin-solid": "^2.11.
|
|
43
|
+
"vite-plugin-solid": "^2.11.11",
|
|
44
44
|
"vite-tsconfig-paths": "^6.1.1",
|
|
45
45
|
"yargs": "^18.0.0",
|
|
46
|
-
"@simplysm/core-common": "13.0.
|
|
47
|
-
"@simplysm/
|
|
48
|
-
"@simplysm/
|
|
46
|
+
"@simplysm/core-common": "13.0.86",
|
|
47
|
+
"@simplysm/storage": "13.0.86",
|
|
48
|
+
"@simplysm/core-node": "13.0.86"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/semver": "^7.7.1",
|
package/templates/init/mise.toml
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
[tools]
|
|
2
|
-
node = "20
|
|
3
|
-
pnpm = "
|
|
2
|
+
node = "20"
|
|
3
|
+
pnpm = "latest"
|
|
@@ -14,16 +14,20 @@
|
|
|
14
14
|
"lint": "sd-cli lint",
|
|
15
15
|
"lint:fix": "sd-cli lint --fix",
|
|
16
16
|
"check": "sd-cli check",
|
|
17
|
-
"
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:e2e": "vitest run -c vitest-e2e.config.ts",
|
|
19
|
+
"postinstall": "playwright install && playwright-cli install --skills"
|
|
18
20
|
},
|
|
19
21
|
"devDependencies": {
|
|
20
|
-
"@simplysm/lint": "~13.0.
|
|
21
|
-
"@simplysm/sd-cli": "~13.0.
|
|
22
|
+
"@simplysm/lint": "~13.0.86",
|
|
23
|
+
"@simplysm/sd-cli": "~13.0.86",
|
|
22
24
|
"@types/node": "^20.19.35",
|
|
23
25
|
"eslint": "^9.39.3",
|
|
24
26
|
"prettier": "^3.8.1",
|
|
25
27
|
"typescript": "^5.9.3",
|
|
26
28
|
"vite-tsconfig-paths": "^6.1.1",
|
|
27
|
-
"vitest": "^4.0.18"
|
|
29
|
+
"vitest": "^4.0.18",
|
|
30
|
+
"@playwright/cli": "^0.1.1",
|
|
31
|
+
"playwright": "^1.58.2"
|
|
28
32
|
}
|
|
29
33
|
}
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
"private": true,
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@{{projectName}}/db-main": "workspace:*",
|
|
9
|
-
"@simplysm/core-browser": "~13.0.
|
|
10
|
-
"@simplysm/core-common": "~13.0.
|
|
9
|
+
"@simplysm/core-browser": "~13.0.86",
|
|
10
|
+
"@simplysm/core-common": "~13.0.86",
|
|
11
11
|
"@simplysm/excel": "^13.0.71",
|
|
12
|
-
"@simplysm/orm-common": "~13.0.
|
|
13
|
-
"@simplysm/service-client": "~13.0.
|
|
14
|
-
"@simplysm/
|
|
12
|
+
"@simplysm/orm-common": "~13.0.86",
|
|
13
|
+
"@simplysm/service-client": "~13.0.86",
|
|
14
|
+
"@simplysm/service-common": "~13.0.86",
|
|
15
|
+
"@simplysm/solid": "~13.0.86",
|
|
15
16
|
"@solid-primitives/event-listener": "^2.4.5",
|
|
16
17
|
"@solidjs/router": "^0.15.4",
|
|
17
18
|
"@tabler/icons-solidjs": "^3.37.1",
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
useLogger,
|
|
9
9
|
useSyncStorage,
|
|
10
10
|
} from "@simplysm/solid";
|
|
11
|
-
import { DateTime, env,
|
|
11
|
+
import { DateTime, env, json } from "@simplysm/core-common";
|
|
12
12
|
import { expr } from "@{{projectName}}/db-main";
|
|
13
13
|
import { App } from "./App";
|
|
14
14
|
|
|
@@ -85,7 +85,7 @@ function AppRoot() {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
try {
|
|
88
|
-
const message = data.map((d) => (typeof d === "string" ? d :
|
|
88
|
+
const message = data.map((d) => (typeof d === "string" ? d : json.stringify(d))).join(" ");
|
|
89
89
|
|
|
90
90
|
await appService.orm.connect(async (db) => {
|
|
91
91
|
await db._log().insert([
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import { useServiceClient } from "@simplysm/solid";
|
|
10
10
|
import {
|
|
11
11
|
createOrmClientConnector,
|
|
12
|
-
type
|
|
12
|
+
type ServiceProxy,
|
|
13
13
|
type ServiceClient,
|
|
14
14
|
} from "@simplysm/service-client";
|
|
15
15
|
import type {
|
|
@@ -20,9 +20,9 @@ import type {
|
|
|
20
20
|
import { MainDbContext, type MainDbContext as MainDbContextType } from "@{{projectName}}/db-main";
|
|
21
21
|
|
|
22
22
|
export interface IAppServiceClient {
|
|
23
|
-
auth:
|
|
24
|
-
dev:
|
|
25
|
-
employee:
|
|
23
|
+
auth: ServiceProxy<AuthServiceMethods>;
|
|
24
|
+
dev: ServiceProxy<DevServiceMethods>;
|
|
25
|
+
employee: ServiceProxy<EmployeeServiceMethods>;
|
|
26
26
|
sc: ServiceClient;
|
|
27
27
|
orm: {
|
|
28
28
|
connect: <R>(
|
|
@@ -3,11 +3,12 @@ import { createSignal } from "solid-js";
|
|
|
3
3
|
import { useLocalStorage } from "@simplysm/solid";
|
|
4
4
|
import { useAppService } from "./AppServiceProvider";
|
|
5
5
|
import type { IAuthData } from "@{{projectName}}/server";
|
|
6
|
+
import { AuthChangeEvent } from "../events/AuthChangeEvent";
|
|
6
7
|
|
|
7
8
|
interface IAuthContextValue {
|
|
8
9
|
authInfo: Accessor<IAuthData | undefined>;
|
|
9
10
|
login: (email: string, password: string) => Promise<void>;
|
|
10
|
-
logout: () => void
|
|
11
|
+
logout: () => Promise<void>;
|
|
11
12
|
tryReloadAuth: () => Promise<boolean>;
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -18,6 +19,26 @@ export const AuthProvider: ParentComponent = (props) => {
|
|
|
18
19
|
const [authInfo, setAuthInfo] = createSignal<IAuthData>();
|
|
19
20
|
const [token, setToken] = useLocalStorage<string | undefined>("auth-token");
|
|
20
21
|
|
|
22
|
+
let listenerKey: string | undefined;
|
|
23
|
+
|
|
24
|
+
const registerAuthEvent = async (employeeId: number) => {
|
|
25
|
+
await unregisterAuthEvent();
|
|
26
|
+
listenerKey = await appService.sc.addListener(
|
|
27
|
+
AuthChangeEvent,
|
|
28
|
+
{ employeeId },
|
|
29
|
+
async () => {
|
|
30
|
+
await tryReloadAuth();
|
|
31
|
+
},
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const unregisterAuthEvent = async () => {
|
|
36
|
+
if (listenerKey != null) {
|
|
37
|
+
await appService.sc.removeListener(listenerKey);
|
|
38
|
+
listenerKey = undefined;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
21
42
|
const login = async (email: string, password: string) => {
|
|
22
43
|
const result = await appService.auth.login(email, password);
|
|
23
44
|
|
|
@@ -26,9 +47,11 @@ export const AuthProvider: ParentComponent = (props) => {
|
|
|
26
47
|
await appService.sc.auth(newToken);
|
|
27
48
|
|
|
28
49
|
setAuthInfo(authData);
|
|
50
|
+
await registerAuthEvent(authData.employeeId);
|
|
29
51
|
};
|
|
30
52
|
|
|
31
|
-
const logout = () => {
|
|
53
|
+
const logout = async () => {
|
|
54
|
+
await unregisterAuthEvent();
|
|
32
55
|
setToken(undefined);
|
|
33
56
|
setAuthInfo(undefined);
|
|
34
57
|
};
|
|
@@ -47,11 +70,13 @@ export const AuthProvider: ParentComponent = (props) => {
|
|
|
47
70
|
await appService.sc.auth(newToken);
|
|
48
71
|
|
|
49
72
|
setAuthInfo(authData);
|
|
73
|
+
await registerAuthEvent(authData.employeeId);
|
|
50
74
|
|
|
51
75
|
return true;
|
|
52
76
|
} catch (err) {
|
|
53
77
|
// eslint-disable-next-line no-console
|
|
54
78
|
console.warn("Failed to reload auth:", err);
|
|
79
|
+
await unregisterAuthEvent();
|
|
55
80
|
setToken(undefined);
|
|
56
81
|
return false;
|
|
57
82
|
}
|
|
@@ -25,7 +25,7 @@ export function configureSharedData() {
|
|
|
25
25
|
|
|
26
26
|
useSharedData<AppSharedData>().configure((_origin) => ({
|
|
27
27
|
employee: {
|
|
28
|
-
fetch:
|
|
28
|
+
fetch: (changeKeys) => {
|
|
29
29
|
return appService.orm.connect(async (db) => {
|
|
30
30
|
let qr = db.employee().select((item) => ({
|
|
31
31
|
id: item.id,
|
|
@@ -36,16 +36,16 @@ export function configureSharedData() {
|
|
|
36
36
|
if (changeKeys) {
|
|
37
37
|
qr = qr.where((item) => [expr.in(item.id, changeKeys)]);
|
|
38
38
|
}
|
|
39
|
-
return qr.
|
|
39
|
+
return qr.execute();
|
|
40
40
|
});
|
|
41
41
|
},
|
|
42
42
|
orderBy: [[(item) => item.name, "asc"]],
|
|
43
43
|
getKey: (item) => item.id,
|
|
44
|
-
getSearchText: (item) => item.name,
|
|
45
|
-
getIsHidden: (item) => item.isDeleted,
|
|
44
|
+
getSearchText: (item: EmployeeSharedItem) => item.name,
|
|
45
|
+
getIsHidden: (item: EmployeeSharedItem) => item.isDeleted,
|
|
46
46
|
},
|
|
47
47
|
role: {
|
|
48
|
-
fetch:
|
|
48
|
+
fetch: (changeKeys) => {
|
|
49
49
|
return appService.orm.connect(async (db) => {
|
|
50
50
|
let qr = db.role().select((item) => ({
|
|
51
51
|
id: item.id,
|
|
@@ -55,13 +55,13 @@ export function configureSharedData() {
|
|
|
55
55
|
if (changeKeys) {
|
|
56
56
|
qr = qr.where((item) => [expr.in(item.id, changeKeys)]);
|
|
57
57
|
}
|
|
58
|
-
return qr.
|
|
58
|
+
return qr.execute();
|
|
59
59
|
});
|
|
60
60
|
},
|
|
61
61
|
orderBy: [[(item) => item.name, "asc"]],
|
|
62
62
|
getKey: (item) => item.id,
|
|
63
|
-
getSearchText: (item) => item.name,
|
|
64
|
-
getIsHidden: (item) => item.isDeleted,
|
|
63
|
+
getSearchText: (item: RoleSharedItem) => item.name,
|
|
64
|
+
getIsHidden: (item: RoleSharedItem) => item.isDeleted,
|
|
65
65
|
},
|
|
66
66
|
}));
|
|
67
67
|
}
|
|
@@ -67,11 +67,11 @@ export function LoginView() {
|
|
|
67
67
|
>
|
|
68
68
|
<div class={"max-w-sm"}>
|
|
69
69
|
{/* Logo */}
|
|
70
|
-
<div class={clsx("flex justify-center", "mb-4", "animate-fade-
|
|
70
|
+
<div class={clsx("flex justify-center", "mb-4", "animate-[fade-in_0.6s_ease-out_both]")}>
|
|
71
71
|
<img src="assets/logo.png" alt="logo" class="scale-75" />
|
|
72
72
|
</div>
|
|
73
73
|
|
|
74
|
-
<Card class={clsx("rounded-2xl p-8", "animate-fade-
|
|
74
|
+
<Card class={clsx("rounded-2xl p-8", "animate-[fade-in_0.6s_ease-out_both] [animation-delay:0.3s]")}>
|
|
75
75
|
{/* Form */}
|
|
76
76
|
<form onSubmit={handleSubmit}>
|
|
77
77
|
<FormGroup class={"w-full"}>
|
|
@@ -83,7 +83,7 @@ export function LoginView() {
|
|
|
83
83
|
required
|
|
84
84
|
lazyValidation
|
|
85
85
|
size="lg"
|
|
86
|
-
autocomplete="
|
|
86
|
+
autocomplete="username"
|
|
87
87
|
value={data.email}
|
|
88
88
|
onValueChange={(v) => setData("email", v)}
|
|
89
89
|
>
|
|
@@ -116,7 +116,7 @@ export function LoginView() {
|
|
|
116
116
|
variant="solid"
|
|
117
117
|
class="w-full"
|
|
118
118
|
type="submit"
|
|
119
|
-
size="
|
|
119
|
+
size="lg"
|
|
120
120
|
disabled={busyCount() > 0}
|
|
121
121
|
>
|
|
122
122
|
로그인
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { defineDbContext, type DbContextInstance } from "@simplysm/orm-common";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
2
|
+
// base
|
|
3
|
+
import { Employee } from "./tables/base/Employee";
|
|
4
|
+
import { Role } from "./tables/base/Role";
|
|
5
|
+
import { RolePermission } from "./tables/base/RolePermission";
|
|
6
|
+
import { EmployeeConfig } from "./tables/base/EmployeeConfig";
|
|
7
|
+
// system
|
|
8
|
+
import { _Log } from "./tables/system/_Log";
|
|
9
|
+
import { _DataLog } from "./tables/system/_DataLog";
|
|
8
10
|
|
|
9
11
|
export const MainDbContext = defineDbContext({
|
|
10
12
|
tables: {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
|
|
1
|
+
// base
|
|
2
|
+
export * from "./tables/base/Role";
|
|
3
|
+
export * from "./tables/base/RolePermission";
|
|
4
|
+
export * from "./tables/base/Employee";
|
|
5
|
+
export * from "./tables/base/EmployeeConfig";
|
|
6
|
+
|
|
7
|
+
// system
|
|
8
|
+
export * from "./tables/system/_Log";
|
|
9
|
+
export * from "./tables/system/_DataLog";
|
|
10
|
+
|
|
7
11
|
export { MainDbContext } from "./MainDbContext";
|
|
8
12
|
export { expr } from "@simplysm/orm-common";
|
|
9
13
|
import "./dataLogExt";
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"private": true,
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@{{projectName}}/db-main": "workspace:*",
|
|
8
|
-
"@simplysm/core-common": "~13.0.
|
|
8
|
+
"@simplysm/core-common": "~13.0.86",
|
|
9
9
|
"@simplysm/excel": "^13.0.71",
|
|
10
|
-
"@simplysm/orm-common": "~13.0.
|
|
11
|
-
"@simplysm/orm-node": "~13.0.
|
|
12
|
-
"@simplysm/service-server": "~13.0.
|
|
10
|
+
"@simplysm/orm-common": "~13.0.86",
|
|
11
|
+
"@simplysm/orm-node": "~13.0.86",
|
|
12
|
+
"@simplysm/service-server": "~13.0.86",
|
|
13
13
|
"bcrypt": "^6.0.0",
|
|
14
14
|
"pg": "^8.19.0",
|
|
15
15
|
"pg-copy-streams": "^7.0.0"
|