swallowkit 0.1.0-alpha.1 → 0.1.0-alpha.2
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 +99 -438
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,177 +1,77 @@
|
|
|
1
|
-
# SwallowKit
|
|
1
|
+
# SwallowKit
|
|
2
2
|
|
|
3
|
-
Azure Static Web Apps
|
|
3
|
+
A React framework for building full-stack Azure Static Web Apps with Cosmos DB integration.
|
|
4
4
|
|
|
5
|
-
>
|
|
5
|
+
> **Note**: This project is in early development. APIs may change in future versions.
|
|
6
6
|
|
|
7
|
-
## 🚀
|
|
7
|
+
## 🚀 Features
|
|
8
8
|
|
|
9
|
-
- **Cosmos DB
|
|
10
|
-
- **React Hooks
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
- **
|
|
14
|
-
- **開発者体験**: シンプルなコマンドで開発開始
|
|
9
|
+
- **Cosmos DB Integration**: Built-in Cosmos DB support with automatic setup
|
|
10
|
+
- **React Hooks Based**: Simple server function calls with `useServerFn` / `callServerFn`
|
|
11
|
+
- **Type-Safe**: Full TypeScript support with end-to-end type safety
|
|
12
|
+
- **Azure Optimized**: Designed for Azure Static Web Apps + Azure Functions v4
|
|
13
|
+
- **Developer Experience**: Simple CLI commands to get started
|
|
15
14
|
|
|
16
|
-
## 📋
|
|
15
|
+
## 📋 Prerequisites
|
|
17
16
|
|
|
18
17
|
- Node.js 22.x
|
|
19
|
-
- Azure Cosmos DB Emulator (
|
|
20
|
-
- Windows: [
|
|
18
|
+
- Azure Cosmos DB Emulator (for local development)
|
|
19
|
+
- Windows: Install from [official site](https://aka.ms/cosmosdb-emulator)
|
|
21
20
|
- Docker: `docker run -p 8081:8081 mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator`
|
|
22
21
|
|
|
23
|
-
## 📦
|
|
22
|
+
## 📦 Installation
|
|
24
23
|
|
|
25
24
|
```bash
|
|
26
25
|
npm install swallowkit
|
|
27
26
|
```
|
|
28
27
|
|
|
29
|
-
## 🛠️
|
|
28
|
+
## 🛠️ Quick Start
|
|
30
29
|
|
|
31
|
-
###
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
npx swallowkit init my-todo-app
|
|
35
|
-
cd my-todo-app
|
|
36
|
-
npm install
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
これにより以下が生成されます:
|
|
40
|
-
- `src/` - React アプリケーション (Vite + React + TypeScript)
|
|
41
|
-
- `src/serverFns.ts` - サーバー関数の型定義 (クライアント側スタブ)
|
|
42
|
-
- `swallowkit.config.json` - SwallowKit 設定ファイル
|
|
43
|
-
|
|
44
|
-
### 2. Cosmos DB Emulator の起動
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# Windowsの場合: スタートメニューから起動
|
|
48
|
-
# Dockerの場合:
|
|
49
|
-
docker run -p 8081:8081 mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### 3. 開発環境の起動
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
npx swallowkit dev
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
このコマンドは:
|
|
59
|
-
1. Cosmos DB Emulator の起動確認
|
|
60
|
-
2. Cosmos DB のデータベース・コンテナの自動作成 (冪等性あり)
|
|
61
|
-
3. Azure Functions API の自動ビルド
|
|
62
|
-
4. Vite 開発サーバーの起動
|
|
63
|
-
5. SWA CLI による統合環境の起動
|
|
64
|
-
|
|
65
|
-
開発サーバーが起動したら、`http://localhost:4280` でアプリにアクセスできます。
|
|
66
|
-
|
|
67
|
-
## 📝 サーバー関数の実装
|
|
68
|
-
|
|
69
|
-
### クライアント側の型定義 (`src/serverFns.ts`)
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// クライアント側のスタブ - ブラウザでは実行されない
|
|
73
|
-
interface Todo {
|
|
74
|
-
id: string;
|
|
75
|
-
text: string;
|
|
76
|
-
completed: boolean;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export async function getTodos(): Promise<Todo[]> {
|
|
80
|
-
throw new Error("This is a server function and should be called via useServerFn");
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export async function addTodo({ text }: { text: string }): Promise<Todo> {
|
|
84
|
-
throw new Error("This is a server function and should be called via useServerFn");
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export async function deleteTodo({ id }: { id: string }): Promise<{ success: boolean }> {
|
|
88
|
-
throw new Error("This is a server function and should be called via useServerFn");
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export async function toggleTodo({ id }: { id: string }): Promise<Todo | null> {
|
|
92
|
-
throw new Error("This is a server function and should be called via useServerFn");
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### API の生成
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
npx swallowkit generate
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
これにより `api/` ディレクトリに以下が生成されます:
|
|
103
|
-
- `api/src/shared/server-functions.ts` - Cosmos DB を使った実装
|
|
104
|
-
- `api/src/functions/rpc.ts` - RPC エンドポイント (`/api/_swallowkit`)
|
|
105
|
-
- Azure Functions v4 の設定ファイル
|
|
106
|
-
|
|
107
|
-
**重要**: `server-functions.ts` は自動生成されますが、**ビジネスロジックを実装するファイル**です。
|
|
108
|
-
初回生成後はテンプレートをカスタマイズして使用してください。
|
|
109
|
-
|
|
110
|
-
### サーバー側の実装例 (`api/src/shared/server-functions.ts`)
|
|
30
|
+
### Basic Usage
|
|
111
31
|
|
|
112
32
|
```typescript
|
|
113
|
-
import {
|
|
114
|
-
|
|
115
|
-
// Cosmos DB クライアントの初期化
|
|
116
|
-
const endpoint = process.env.COSMOS_ENDPOINT || 'http://localhost:8081';
|
|
117
|
-
const key = process.env.COSMOS_KEY || 'C2y6yDjf5/R+...'; // Emulator key
|
|
118
|
-
const client = new CosmosClient({ endpoint, key });
|
|
119
|
-
|
|
120
|
-
const database = client.database('swallowkit-db');
|
|
121
|
-
const container = database.container('todos');
|
|
122
|
-
|
|
123
|
-
interface Todo {
|
|
124
|
-
id: string;
|
|
125
|
-
text: string;
|
|
126
|
-
completed: boolean;
|
|
127
|
-
}
|
|
33
|
+
import { useServerFn, callServerFn } from 'swallowkit';
|
|
128
34
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
35
|
+
// Define your server function type
|
|
36
|
+
async function getTodos(): Promise<Todo[]> {
|
|
37
|
+
// Implementation will be on the server side
|
|
38
|
+
throw new Error("Server function");
|
|
132
39
|
}
|
|
133
40
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
text,
|
|
138
|
-
completed: false,
|
|
139
|
-
};
|
|
140
|
-
const { resource } = await container.items.create(newTodo);
|
|
141
|
-
return resource as Todo;
|
|
142
|
-
}
|
|
41
|
+
// Use in React component
|
|
42
|
+
function TodoList() {
|
|
43
|
+
const { data, loading, error, refetch } = useServerFn(getTodos, []);
|
|
143
44
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return { success: true };
|
|
147
|
-
}
|
|
45
|
+
if (loading) return <div>Loading...</div>;
|
|
46
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
148
47
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
48
|
+
return (
|
|
49
|
+
<div>
|
|
50
|
+
<ul>
|
|
51
|
+
{data?.map((todo) => (
|
|
52
|
+
<li key={todo.id}>{todo.text}</li>
|
|
53
|
+
))}
|
|
54
|
+
</ul>
|
|
55
|
+
<button onClick={refetch}>Refresh</button>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
157
58
|
}
|
|
158
59
|
```
|
|
159
60
|
|
|
160
|
-
## 🎯 React
|
|
61
|
+
## 🎯 Usage with React
|
|
161
62
|
|
|
162
|
-
###
|
|
63
|
+
### Query with `useServerFn`
|
|
163
64
|
|
|
164
|
-
|
|
65
|
+
For data fetching operations that need state management:
|
|
165
66
|
|
|
166
67
|
```tsx
|
|
167
68
|
import { useServerFn } from "swallowkit";
|
|
168
|
-
import { getTodos } from "./serverFns";
|
|
169
69
|
|
|
170
70
|
function TodoList() {
|
|
171
71
|
const { data: todos, loading, error, refetch } = useServerFn(getTodos, []);
|
|
172
72
|
|
|
173
|
-
if (loading) return <div
|
|
174
|
-
if (error) return <div
|
|
73
|
+
if (loading) return <div>Loading...</div>;
|
|
74
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
175
75
|
|
|
176
76
|
return (
|
|
177
77
|
<div>
|
|
@@ -180,19 +80,18 @@ function TodoList() {
|
|
|
180
80
|
<li key={todo.id}>{todo.text}</li>
|
|
181
81
|
))}
|
|
182
82
|
</ul>
|
|
183
|
-
<button onClick={refetch}
|
|
83
|
+
<button onClick={refetch}>Refresh</button>
|
|
184
84
|
</div>
|
|
185
85
|
);
|
|
186
86
|
}
|
|
187
87
|
```
|
|
188
88
|
|
|
189
|
-
###
|
|
89
|
+
### Mutations with `callServerFn`
|
|
190
90
|
|
|
191
|
-
|
|
91
|
+
For operations like create, update, delete that don't need state management:
|
|
192
92
|
|
|
193
93
|
```tsx
|
|
194
94
|
import { useServerFn, callServerFn } from "swallowkit";
|
|
195
|
-
import { getTodos, addTodo, deleteTodo, toggleTodo } from "./serverFns";
|
|
196
95
|
|
|
197
96
|
function TodoApp() {
|
|
198
97
|
const [newTodoText, setNewTodoText] = useState("");
|
|
@@ -203,12 +102,7 @@ function TodoApp() {
|
|
|
203
102
|
|
|
204
103
|
await callServerFn(addTodo, { text: newTodoText });
|
|
205
104
|
setNewTodoText("");
|
|
206
|
-
refetch(); //
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const handleToggleTodo = async (id: string) => {
|
|
210
|
-
await callServerFn(toggleTodo, { id });
|
|
211
|
-
refetch();
|
|
105
|
+
refetch(); // Refetch to get the latest data
|
|
212
106
|
};
|
|
213
107
|
|
|
214
108
|
const handleDeleteTodo = async (id: string) => {
|
|
@@ -216,20 +110,20 @@ function TodoApp() {
|
|
|
216
110
|
refetch();
|
|
217
111
|
};
|
|
218
112
|
|
|
219
|
-
// ...
|
|
113
|
+
// ... rendering
|
|
220
114
|
}
|
|
221
115
|
```
|
|
222
116
|
|
|
223
|
-
## 📚 API
|
|
117
|
+
## 📚 API Reference
|
|
224
118
|
|
|
225
119
|
### `useServerFn<TResult>(serverFn, args, options?)`
|
|
226
120
|
|
|
227
|
-
|
|
228
|
-
- `serverFn`:
|
|
229
|
-
- `args`:
|
|
230
|
-
- `options?`:
|
|
121
|
+
**Parameters:**
|
|
122
|
+
- `serverFn`: Server function to call
|
|
123
|
+
- `args`: Array of function arguments
|
|
124
|
+
- `options?`: Optional configuration
|
|
231
125
|
|
|
232
|
-
|
|
126
|
+
**Returns:**
|
|
233
127
|
```typescript
|
|
234
128
|
{
|
|
235
129
|
data: TResult | null;
|
|
@@ -239,325 +133,92 @@ function TodoApp() {
|
|
|
239
133
|
}
|
|
240
134
|
```
|
|
241
135
|
|
|
242
|
-
|
|
136
|
+
**Example:**
|
|
243
137
|
```typescript
|
|
244
138
|
const { data, loading, error, refetch } = useServerFn(getTodos, []);
|
|
245
139
|
```
|
|
246
140
|
|
|
247
141
|
### `callServerFn<TArgs, TResult>(serverFn, ...args)`
|
|
248
142
|
|
|
249
|
-
|
|
250
|
-
- `serverFn`:
|
|
251
|
-
- `...args`:
|
|
143
|
+
**Parameters:**
|
|
144
|
+
- `serverFn`: Server function to call
|
|
145
|
+
- `...args`: Function arguments
|
|
252
146
|
|
|
253
|
-
|
|
254
|
-
- `Promise<TResult>`:
|
|
147
|
+
**Returns:**
|
|
148
|
+
- `Promise<TResult>`: Server function execution result
|
|
255
149
|
|
|
256
|
-
|
|
150
|
+
**Example:**
|
|
257
151
|
```typescript
|
|
258
|
-
const result = await callServerFn(addTodo, { text: "
|
|
152
|
+
const result = await callServerFn(addTodo, { text: "New todo" });
|
|
259
153
|
```
|
|
260
154
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
### `swallowkit init <project-name>`
|
|
264
|
-
|
|
265
|
-
新しい SwallowKit プロジェクトを作成します。
|
|
266
|
-
|
|
267
|
-
```bash
|
|
268
|
-
npx swallowkit init my-app
|
|
269
|
-
```
|
|
155
|
+
### `useQuery` / `useMutation`
|
|
270
156
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
統合開発環境を起動します:
|
|
274
|
-
- Cosmos DB の自動セットアップ
|
|
275
|
-
- Azure Functions の自動ビルド
|
|
276
|
-
- Vite + SWA CLI の統合サーバー起動
|
|
277
|
-
|
|
278
|
-
```bash
|
|
279
|
-
npx swallowkit dev
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
**オプション:**
|
|
283
|
-
- `--port <port>`: SWA CLI のポート (デフォルト: 4280)
|
|
284
|
-
- `--api-port <port>`: Azure Functions のポート (デフォルト: 7071)
|
|
285
|
-
- `--host <host>`: ホスト名 (デフォルト: localhost)
|
|
286
|
-
- `--open`: ブラウザを自動で開く
|
|
287
|
-
|
|
288
|
-
### `swallowkit generate`
|
|
289
|
-
|
|
290
|
-
`src/serverFns.ts` から Azure Functions API を生成します。
|
|
291
|
-
|
|
292
|
-
```bash
|
|
293
|
-
npx swallowkit generate
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
**オプション:**
|
|
297
|
-
- `--output <dir>`: 出力ディレクトリ (デフォルト: ./api)
|
|
298
|
-
- `--force`: 既存ファイルを上書き
|
|
299
|
-
|
|
300
|
-
### `swallowkit setup`
|
|
301
|
-
|
|
302
|
-
開発環境の依存関係をチェックします:
|
|
303
|
-
- Azure CLI
|
|
304
|
-
- Azure Static Web Apps CLI
|
|
305
|
-
- Cosmos DB Emulator
|
|
306
|
-
|
|
307
|
-
```bash
|
|
308
|
-
npx swallowkit setup
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
## 🔧 設定ファイル
|
|
312
|
-
|
|
313
|
-
## 🔧 設定ファイル
|
|
314
|
-
|
|
315
|
-
### `swallowkit.config.json`
|
|
316
|
-
|
|
317
|
-
```json
|
|
318
|
-
{
|
|
319
|
-
"database": {
|
|
320
|
-
"type": "cosmos",
|
|
321
|
-
"endpoint": "http://localhost:8081",
|
|
322
|
-
"key": "C2y6yDjf5/R+...",
|
|
323
|
-
"databaseName": "swallowkit-db"
|
|
324
|
-
},
|
|
325
|
-
"api": {
|
|
326
|
-
"endpoint": "/api/_swallowkit"
|
|
327
|
-
},
|
|
328
|
-
"functions": {
|
|
329
|
-
"outputDir": "api"
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
**プロパティ:**
|
|
335
|
-
- `database.type`: データベースタイプ (現在は `"cosmos"` のみ)
|
|
336
|
-
- `database.endpoint`: Cosmos DB エンドポイント
|
|
337
|
-
- `database.key`: Cosmos DB アクセスキー
|
|
338
|
-
- `database.databaseName`: データベース名
|
|
339
|
-
- `api.endpoint`: RPC エンドポイントのパス
|
|
340
|
-
- `functions.outputDir`: Azure Functions の出力ディレクトリ
|
|
341
|
-
|
|
342
|
-
### 環境変数 (`api/local.settings.json`)
|
|
343
|
-
|
|
344
|
-
```json
|
|
345
|
-
{
|
|
346
|
-
"IsEncrypted": false,
|
|
347
|
-
"Values": {
|
|
348
|
-
"FUNCTIONS_WORKER_RUNTIME": "node",
|
|
349
|
-
"FUNCTIONS_WORKER_RUNTIME_VERSION": "~22",
|
|
350
|
-
"AzureWebJobsStorage": "",
|
|
351
|
-
"COSMOS_ENDPOINT": "http://localhost:8081",
|
|
352
|
-
"COSMOS_KEY": "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
|
|
353
|
-
},
|
|
354
|
-
"Host": {
|
|
355
|
-
"CORS": "*",
|
|
356
|
-
"LocalHttpPort": 7071
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
## 🏗️ アーキテクチャ
|
|
362
|
-
|
|
363
|
-
### クライアント・サーバー分離
|
|
364
|
-
|
|
365
|
-
```
|
|
366
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
367
|
-
│ クライアント (Browser) │
|
|
368
|
-
│ │
|
|
369
|
-
│ src/App.tsx │
|
|
370
|
-
│ ↓ import │
|
|
371
|
-
│ src/serverFns.ts (型定義スタブ) │
|
|
372
|
-
│ ↓ useServerFn / callServerFn │
|
|
373
|
-
│ swallowkit (hooks/useServerFn.ts) │
|
|
374
|
-
│ ↓ POST /api/_swallowkit │
|
|
375
|
-
└──────────────────────────────────────────────────────────────┘
|
|
376
|
-
│
|
|
377
|
-
│ HTTP Request
|
|
378
|
-
↓
|
|
379
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
380
|
-
│ サーバー (Azure Functions v4) │
|
|
381
|
-
│ │
|
|
382
|
-
│ api/src/functions/rpc.ts │
|
|
383
|
-
│ ↓ import │
|
|
384
|
-
│ api/src/shared/server-functions.ts (Cosmos DB実装) │
|
|
385
|
-
│ ↓ @azure/cosmos │
|
|
386
|
-
│ Cosmos DB │
|
|
387
|
-
└─────────────────────────────────────────────────────────────┘
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### データフロー
|
|
391
|
-
|
|
392
|
-
1. **クエリ (useServerFn)**
|
|
393
|
-
- コンポーネントマウント時に自動実行
|
|
394
|
-
- ローディング状態を管理
|
|
395
|
-
- データをキャッシュ
|
|
396
|
-
- `refetch()` で再実行可能
|
|
397
|
-
|
|
398
|
-
2. **ミューテーション (callServerFn)**
|
|
399
|
-
- イベントハンドラから明示的に呼び出し
|
|
400
|
-
- 状態管理なし
|
|
401
|
-
- 完了後に `refetch()` を呼び出してクエリを更新
|
|
402
|
-
|
|
403
|
-
### Cosmos DB 自動セットアップ
|
|
404
|
-
|
|
405
|
-
`swallowkit dev` コマンド実行時:
|
|
157
|
+
Advanced hooks for more granular control over queries and mutations.
|
|
406
158
|
|
|
407
159
|
```typescript
|
|
408
|
-
|
|
409
|
-
1. Cosmos DB Emulator の起動確認
|
|
410
|
-
2. CosmosClient で接続
|
|
411
|
-
3. database.createIfNotExists('swallowkit-db')
|
|
412
|
-
4. container.createIfNotExists('todos', {
|
|
413
|
-
partitionKey: {
|
|
414
|
-
paths: ['/id'],
|
|
415
|
-
kind: PartitionKeyKind.Hash
|
|
416
|
-
}
|
|
417
|
-
})
|
|
418
|
-
5. Azure Functions API のビルド
|
|
419
|
-
6. Vite + SWA CLI の起動
|
|
420
|
-
```
|
|
160
|
+
import { useQuery, useMutation } from 'swallowkit';
|
|
421
161
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
│ ├── App.tsx # React アプリケーション
|
|
428
|
-
│ ├── serverFns.ts # サーバー関数の型定義 (クライアント側)
|
|
429
|
-
│ ├── index.tsx # エントリーポイント
|
|
430
|
-
│ └── index.css # スタイル
|
|
431
|
-
├── api/ # Azure Functions (自動生成)
|
|
432
|
-
│ ├── src/
|
|
433
|
-
│ │ ├── functions/
|
|
434
|
-
│ │ │ ├── rpc.ts # RPC エンドポイント
|
|
435
|
-
│ │ │ └── crud.ts # CRUD エンドポイント (未使用)
|
|
436
|
-
│ │ └── shared/
|
|
437
|
-
│ │ └── server-functions.ts # サーバー側実装 (Cosmos DB)
|
|
438
|
-
│ ├── host.json
|
|
439
|
-
│ ├── local.settings.json
|
|
440
|
-
│ ├── tsconfig.json
|
|
441
|
-
│ └── package.json
|
|
442
|
-
├── swallowkit.config.json # SwallowKit 設定
|
|
443
|
-
├── staticwebapp.config.json # Azure SWA 設定
|
|
444
|
-
├── package.json
|
|
445
|
-
└── vite.config.ts
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
## 🚨 重要な注意事項
|
|
449
|
-
|
|
450
|
-
### 1. サーバー関数の戻り値
|
|
451
|
-
|
|
452
|
-
**❌ NG: `Promise<void>`**
|
|
453
|
-
```typescript
|
|
454
|
-
export async function deleteTodo({ id }: { id: string }): Promise<void> {
|
|
455
|
-
await container.item(id, id).delete();
|
|
456
|
-
// JSON レスポンスがないため RPC 呼び出しが失敗
|
|
457
|
-
}
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
**✅ OK: 必ず値を返す**
|
|
461
|
-
```typescript
|
|
462
|
-
export async function deleteTodo({ id }: { id: string }): Promise<{ success: boolean }> {
|
|
463
|
-
await container.item(id, id).delete();
|
|
464
|
-
return { success: true }; // JSON レスポンスを返す
|
|
465
|
-
}
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
### 2. パーティションキーの指定
|
|
469
|
-
|
|
470
|
-
Cosmos DB Emulator では `kind: PartitionKeyKind.Hash` の明示が必須:
|
|
162
|
+
// Query
|
|
163
|
+
const { data, isLoading, error } = useQuery({
|
|
164
|
+
queryFn: getTodos,
|
|
165
|
+
queryKey: ['todos']
|
|
166
|
+
});
|
|
471
167
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
kind: PartitionKeyKind.Hash // 必須!
|
|
168
|
+
// Mutation
|
|
169
|
+
const { mutate } = useMutation({
|
|
170
|
+
mutationFn: addTodo,
|
|
171
|
+
onSuccess: () => {
|
|
172
|
+
// Handle success
|
|
478
173
|
}
|
|
479
174
|
});
|
|
480
175
|
```
|
|
481
176
|
|
|
482
|
-
|
|
177
|
+
## 🔧 Database Integration
|
|
483
178
|
|
|
484
|
-
|
|
485
|
-
- `api/src/shared/server-functions.ts` - **サーバー側の実装** (Cosmos DB アクセス)
|
|
179
|
+
### Cosmos DB Client
|
|
486
180
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
### 4. generateコマンドの動作
|
|
490
|
-
|
|
491
|
-
`swallowkit generate` は:
|
|
492
|
-
- `src/serverFns.ts` がクライアントスタブ (throw Error を含む) の場合
|
|
493
|
-
→ デフォルトの Cosmos DB テンプレートを使用
|
|
494
|
-
- `src/serverFns.ts` が既に実装を含む場合
|
|
495
|
-
→ その実装を `api/src/shared/server-functions.ts` にコピー
|
|
496
|
-
|
|
497
|
-
## 🐛 トラブルシューティング
|
|
498
|
-
|
|
499
|
-
### Cosmos DB Emulator が起動しない
|
|
500
|
-
|
|
501
|
-
**Windows:**
|
|
502
|
-
```bash
|
|
503
|
-
# スタートメニューから "Azure Cosmos DB Emulator" を起動
|
|
504
|
-
# または、サービスから起動
|
|
505
|
-
```
|
|
181
|
+
```typescript
|
|
182
|
+
import { getDatabaseClient } from 'swallowkit';
|
|
506
183
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
docker run -p 8081:8081 mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
|
|
184
|
+
const client = getDatabaseClient();
|
|
185
|
+
// Use Cosmos DB client
|
|
510
186
|
```
|
|
511
187
|
|
|
512
|
-
###
|
|
513
|
-
|
|
514
|
-
`PartitionKeyKind.Hash` を指定してください:
|
|
188
|
+
### Schema-based Repository
|
|
515
189
|
|
|
516
190
|
```typescript
|
|
517
|
-
import {
|
|
191
|
+
import { createRepository } from 'swallowkit';
|
|
192
|
+
import { z } from 'zod';
|
|
518
193
|
|
|
519
|
-
|
|
520
|
-
id:
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
kind: PartitionKeyKind.Hash
|
|
524
|
-
}
|
|
194
|
+
const TodoSchema = z.object({
|
|
195
|
+
id: z.string(),
|
|
196
|
+
text: z.string(),
|
|
197
|
+
completed: z.boolean()
|
|
525
198
|
});
|
|
526
|
-
```
|
|
527
199
|
|
|
528
|
-
|
|
200
|
+
const todoRepo = createRepository(TodoSchema, 'todos');
|
|
529
201
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
npm run build
|
|
202
|
+
// CRUD operations
|
|
203
|
+
await todoRepo.create({ id: '1', text: 'Task', completed: false });
|
|
204
|
+
await todoRepo.findById('1');
|
|
205
|
+
await todoRepo.update('1', { completed: true });
|
|
206
|
+
await todoRepo.delete('1');
|
|
536
207
|
```
|
|
537
208
|
|
|
538
|
-
##
|
|
539
|
-
|
|
540
|
-
- [ ] Zod スキーマ統合
|
|
541
|
-
- [ ] 認証・認可機能
|
|
542
|
-
- [ ] ファイルアップロード機能
|
|
543
|
-
- [ ] リアルタイム通信 (SignalR)
|
|
544
|
-
- [ ] デプロイコマンド (`swallowkit deploy`)
|
|
545
|
-
- [ ] テストユーティリティ
|
|
546
|
-
- [ ] 本番環境用の設定管理
|
|
547
|
-
|
|
548
|
-
## 🤝 コントリビューション
|
|
209
|
+
## 🤝 Contributing
|
|
549
210
|
|
|
550
|
-
|
|
211
|
+
This project is in early development. Feedback and suggestions are welcome!
|
|
551
212
|
|
|
552
|
-
## 📄
|
|
213
|
+
## 📄 License
|
|
553
214
|
|
|
554
215
|
MIT
|
|
555
216
|
|
|
556
|
-
## 🔗
|
|
217
|
+
## 🔗 Related Links
|
|
557
218
|
|
|
558
|
-
- [Azure Static Web Apps](https://azure.microsoft.com/
|
|
559
|
-
- [Azure Functions](https://azure.microsoft.com/
|
|
560
|
-
- [Azure Cosmos DB](https://azure.microsoft.com/
|
|
219
|
+
- [Azure Static Web Apps](https://azure.microsoft.com/services/app-service/static/)
|
|
220
|
+
- [Azure Functions](https://azure.microsoft.com/services/functions/)
|
|
221
|
+
- [Azure Cosmos DB](https://azure.microsoft.com/services/cosmos-db/)
|
|
561
222
|
- [React](https://reactjs.org/)
|
|
562
|
-
- [
|
|
223
|
+
- [TypeScript](https://www.typescriptlang.org/)
|
|
563
224
|
|