swallowkit 0.1.0-alpha.1

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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +563 -0
  3. package/dist/api/rpc-handler.d.ts +71 -0
  4. package/dist/api/rpc-handler.d.ts.map +1 -0
  5. package/dist/api/rpc-handler.js +205 -0
  6. package/dist/api/rpc-handler.js.map +1 -0
  7. package/dist/cli/commands/build.d.ts +6 -0
  8. package/dist/cli/commands/build.d.ts.map +1 -0
  9. package/dist/cli/commands/build.js +193 -0
  10. package/dist/cli/commands/build.js.map +1 -0
  11. package/dist/cli/commands/dev.d.ts +3 -0
  12. package/dist/cli/commands/dev.d.ts.map +1 -0
  13. package/dist/cli/commands/dev.js +305 -0
  14. package/dist/cli/commands/dev.js.map +1 -0
  15. package/dist/cli/commands/generate.d.ts +4 -0
  16. package/dist/cli/commands/generate.d.ts.map +1 -0
  17. package/dist/cli/commands/generate.js +238 -0
  18. package/dist/cli/commands/generate.js.map +1 -0
  19. package/dist/cli/commands/index.d.ts +9 -0
  20. package/dist/cli/commands/index.d.ts.map +1 -0
  21. package/dist/cli/commands/index.js +18 -0
  22. package/dist/cli/commands/index.js.map +1 -0
  23. package/dist/cli/commands/init.d.ts +7 -0
  24. package/dist/cli/commands/init.d.ts.map +1 -0
  25. package/dist/cli/commands/init.js +383 -0
  26. package/dist/cli/commands/init.js.map +1 -0
  27. package/dist/cli/commands/setup.d.ts +6 -0
  28. package/dist/cli/commands/setup.d.ts.map +1 -0
  29. package/dist/cli/commands/setup.js +254 -0
  30. package/dist/cli/commands/setup.js.map +1 -0
  31. package/dist/cli/index.d.ts +3 -0
  32. package/dist/cli/index.d.ts.map +1 -0
  33. package/dist/cli/index.js +32 -0
  34. package/dist/cli/index.js.map +1 -0
  35. package/dist/core/config.d.ts +25 -0
  36. package/dist/core/config.d.ts.map +1 -0
  37. package/dist/core/config.js +204 -0
  38. package/dist/core/config.js.map +1 -0
  39. package/dist/database/client.d.ts +46 -0
  40. package/dist/database/client.d.ts.map +1 -0
  41. package/dist/database/client.js +156 -0
  42. package/dist/database/client.js.map +1 -0
  43. package/dist/database/repository.d.ts +71 -0
  44. package/dist/database/repository.d.ts.map +1 -0
  45. package/dist/database/repository.js +89 -0
  46. package/dist/database/repository.js.map +1 -0
  47. package/dist/generator/api-generator.d.ts +53 -0
  48. package/dist/generator/api-generator.d.ts.map +1 -0
  49. package/dist/generator/api-generator.js +284 -0
  50. package/dist/generator/api-generator.js.map +1 -0
  51. package/dist/generator/schema-parser.d.ts +45 -0
  52. package/dist/generator/schema-parser.d.ts.map +1 -0
  53. package/dist/generator/schema-parser.js +198 -0
  54. package/dist/generator/schema-parser.js.map +1 -0
  55. package/dist/generator/templates/azure-functions.d.ts +15 -0
  56. package/dist/generator/templates/azure-functions.d.ts.map +1 -0
  57. package/dist/generator/templates/azure-functions.js +274 -0
  58. package/dist/generator/templates/azure-functions.js.map +1 -0
  59. package/dist/generator/templates/default-server-functions.d.ts +2 -0
  60. package/dist/generator/templates/default-server-functions.d.ts.map +1 -0
  61. package/dist/generator/templates/default-server-functions.js +67 -0
  62. package/dist/generator/templates/default-server-functions.js.map +1 -0
  63. package/dist/hooks/server-function-registry.d.ts +67 -0
  64. package/dist/hooks/server-function-registry.d.ts.map +1 -0
  65. package/dist/hooks/server-function-registry.js +153 -0
  66. package/dist/hooks/server-function-registry.js.map +1 -0
  67. package/dist/hooks/useQuery.d.ts +61 -0
  68. package/dist/hooks/useQuery.d.ts.map +1 -0
  69. package/dist/hooks/useQuery.js +147 -0
  70. package/dist/hooks/useQuery.js.map +1 -0
  71. package/dist/hooks/useServerFn.d.ts +27 -0
  72. package/dist/hooks/useServerFn.d.ts.map +1 -0
  73. package/dist/hooks/useServerFn.js +119 -0
  74. package/dist/hooks/useServerFn.js.map +1 -0
  75. package/dist/index.d.ts +17 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +73 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/schemas/example.d.ts +657 -0
  80. package/dist/schemas/example.d.ts.map +1 -0
  81. package/dist/schemas/example.js +133 -0
  82. package/dist/schemas/example.js.map +1 -0
  83. package/dist/server/todo-functions.d.ts +21 -0
  84. package/dist/server/todo-functions.d.ts.map +1 -0
  85. package/dist/server/todo-functions.js +121 -0
  86. package/dist/server/todo-functions.js.map +1 -0
  87. package/dist/types/index.d.ts +53 -0
  88. package/dist/types/index.d.ts.map +1 -0
  89. package/dist/types/index.js +6 -0
  90. package/dist/types/index.js.map +1 -0
  91. package/package.json +68 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Takumasa Hirabayashi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,563 @@
1
+ # SwallowKit (暫定版)
2
+
3
+ Azure Static Web Apps + Cosmos DB 専用フレームワーク
4
+
5
+ > **注意**: これは暫定版のドキュメントです。API や機能は今後変更される可能性があります。
6
+
7
+ ## 🚀 特徴
8
+
9
+ - **Cosmos DB 標準搭載**: Cosmos DB をデフォルトデータベースとして採用
10
+ - **React Hooks ベース**: `useServerFn` / `callServerFn` でサーバー関数を簡単に呼び出し
11
+ - **型安全**: TypeScript による完全な型安全性
12
+ - **自動セットアップ**: 開発環境起動時に Cosmos DB を自動セットアップ
13
+ - **Azure 最適化**: Azure Static Web Apps + Azure Functions v4 に最適化
14
+ - **開発者体験**: シンプルなコマンドで開発開始
15
+
16
+ ## 📋 前提条件
17
+
18
+ - Node.js 22.x
19
+ - Azure Cosmos DB Emulator (ローカル開発用)
20
+ - Windows: [公式サイト](https://aka.ms/cosmosdb-emulator)からインストール
21
+ - Docker: `docker run -p 8081:8081 mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator`
22
+
23
+ ## 📦 インストール
24
+
25
+ ```bash
26
+ npm install swallowkit
27
+ ```
28
+
29
+ ## 🛠️ クイックスタート
30
+
31
+ ### 1. プロジェクトの初期化
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`)
111
+
112
+ ```typescript
113
+ import { CosmosClient } from '@azure/cosmos';
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
+ }
128
+
129
+ export async function getTodos(): Promise<Todo[]> {
130
+ const { resources } = await container.items.query('SELECT * FROM c').fetchAll();
131
+ return resources as Todo[];
132
+ }
133
+
134
+ export async function addTodo({ text }: { text: string }): Promise<Todo> {
135
+ const newTodo: Todo = {
136
+ id: Date.now().toString(),
137
+ text,
138
+ completed: false,
139
+ };
140
+ const { resource } = await container.items.create(newTodo);
141
+ return resource as Todo;
142
+ }
143
+
144
+ export async function deleteTodo({ id }: { id: string }): Promise<{ success: boolean }> {
145
+ await container.item(id, id).delete();
146
+ return { success: true };
147
+ }
148
+
149
+ export async function toggleTodo({ id }: { id: string }): Promise<Todo | null> {
150
+ const { resource: todo } = await container.item(id, id).read<Todo>();
151
+ if (todo) {
152
+ todo.completed = !todo.completed;
153
+ const { resource } = await container.item(id, id).replace(todo);
154
+ return resource as Todo;
155
+ }
156
+ return null;
157
+ }
158
+ ```
159
+
160
+ ## 🎯 React での使用
161
+
162
+ ### クエリ用: `useServerFn`
163
+
164
+ データ取得など、状態管理が必要な操作に使用:
165
+
166
+ ```tsx
167
+ import { useServerFn } from "swallowkit";
168
+ import { getTodos } from "./serverFns";
169
+
170
+ function TodoList() {
171
+ const { data: todos, loading, error, refetch } = useServerFn(getTodos, []);
172
+
173
+ if (loading) return <div>読み込み中...</div>;
174
+ if (error) return <div>エラー: {error.message}</div>;
175
+
176
+ return (
177
+ <div>
178
+ <ul>
179
+ {todos?.map((todo) => (
180
+ <li key={todo.id}>{todo.text}</li>
181
+ ))}
182
+ </ul>
183
+ <button onClick={refetch}>再読み込み</button>
184
+ </div>
185
+ );
186
+ }
187
+ ```
188
+
189
+ ### ミューテーション用: `callServerFn`
190
+
191
+ 追加・更新・削除など、状態管理が不要な操作に使用:
192
+
193
+ ```tsx
194
+ import { useServerFn, callServerFn } from "swallowkit";
195
+ import { getTodos, addTodo, deleteTodo, toggleTodo } from "./serverFns";
196
+
197
+ function TodoApp() {
198
+ const [newTodoText, setNewTodoText] = useState("");
199
+ const { data: todos, loading, error, refetch } = useServerFn(getTodos, []);
200
+
201
+ const handleAddTodo = async () => {
202
+ if (!newTodoText.trim()) return;
203
+
204
+ await callServerFn(addTodo, { text: newTodoText });
205
+ setNewTodoText("");
206
+ refetch(); // クエリを再実行して最新データを取得
207
+ };
208
+
209
+ const handleToggleTodo = async (id: string) => {
210
+ await callServerFn(toggleTodo, { id });
211
+ refetch();
212
+ };
213
+
214
+ const handleDeleteTodo = async (id: string) => {
215
+ await callServerFn(deleteTodo, { id });
216
+ refetch();
217
+ };
218
+
219
+ // ... レンダリング
220
+ }
221
+ ```
222
+
223
+ ## 📚 API リファレンス
224
+
225
+ ### `useServerFn<TResult>(serverFn, args, options?)`
226
+
227
+ **パラメータ:**
228
+ - `serverFn`: サーバー関数
229
+ - `args`: 関数の引数の配列
230
+ - `options?`: オプション設定
231
+
232
+ **戻り値:**
233
+ ```typescript
234
+ {
235
+ data: TResult | null;
236
+ loading: boolean;
237
+ error: Error | null;
238
+ refetch: () => Promise<void>;
239
+ }
240
+ ```
241
+
242
+ **使用例:**
243
+ ```typescript
244
+ const { data, loading, error, refetch } = useServerFn(getTodos, []);
245
+ ```
246
+
247
+ ### `callServerFn<TArgs, TResult>(serverFn, ...args)`
248
+
249
+ **パラメータ:**
250
+ - `serverFn`: サーバー関数
251
+ - `...args`: 関数の引数
252
+
253
+ **戻り値:**
254
+ - `Promise<TResult>`: サーバー関数の実行結果
255
+
256
+ **使用例:**
257
+ ```typescript
258
+ const result = await callServerFn(addTodo, { text: "新しいTodo" });
259
+ ```
260
+
261
+ ## 🔧 CLI コマンド
262
+
263
+ ### `swallowkit init <project-name>`
264
+
265
+ 新しい SwallowKit プロジェクトを作成します。
266
+
267
+ ```bash
268
+ npx swallowkit init my-app
269
+ ```
270
+
271
+ ### `swallowkit dev`
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` コマンド実行時:
406
+
407
+ ```typescript
408
+ // dev コマンドの処理フロー
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
+ ```
421
+
422
+ ## 📁 プロジェクト構造
423
+
424
+ ```
425
+ my-app/
426
+ ├── src/
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` の明示が必須:
471
+
472
+ ```typescript
473
+ await database.containers.createIfNotExists({
474
+ id: 'todos',
475
+ partitionKey: {
476
+ paths: ['/id'],
477
+ kind: PartitionKeyKind.Hash // 必須!
478
+ }
479
+ });
480
+ ```
481
+
482
+ ### 3. クライアント・サーバーの分離
483
+
484
+ - `src/serverFns.ts` - **クライアント側の型定義のみ** (throw Error)
485
+ - `api/src/shared/server-functions.ts` - **サーバー側の実装** (Cosmos DB アクセス)
486
+
487
+ この2つは **別ファイル** です。混同しないでください。
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
+ ```
506
+
507
+ **Docker:**
508
+ ```bash
509
+ docker run -p 8081:8081 mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
510
+ ```
511
+
512
+ ### パーティションキーエラー
513
+
514
+ `PartitionKeyKind.Hash` を指定してください:
515
+
516
+ ```typescript
517
+ import { CosmosClient, PartitionKeyKind } from '@azure/cosmos';
518
+
519
+ await database.containers.createIfNotExists({
520
+ id: 'your-container',
521
+ partitionKey: {
522
+ paths: ['/id'],
523
+ kind: PartitionKeyKind.Hash
524
+ }
525
+ });
526
+ ```
527
+
528
+ ### API が古い実装のまま
529
+
530
+ `generate --force` で強制的に再生成:
531
+
532
+ ```bash
533
+ npx swallowkit generate --force
534
+ cd api
535
+ npm run build
536
+ ```
537
+
538
+ ## 🎯 今後の予定 (TODO)
539
+
540
+ - [ ] Zod スキーマ統合
541
+ - [ ] 認証・認可機能
542
+ - [ ] ファイルアップロード機能
543
+ - [ ] リアルタイム通信 (SignalR)
544
+ - [ ] デプロイコマンド (`swallowkit deploy`)
545
+ - [ ] テストユーティリティ
546
+ - [ ] 本番環境用の設定管理
547
+
548
+ ## 🤝 コントリビューション
549
+
550
+ このプロジェクトは開発中です。フィードバックや提案を歓迎します!
551
+
552
+ ## 📄 ライセンス
553
+
554
+ MIT
555
+
556
+ ## 🔗 関連リンク
557
+
558
+ - [Azure Static Web Apps](https://azure.microsoft.com/ja-jp/services/app-service/static/)
559
+ - [Azure Functions](https://azure.microsoft.com/ja-jp/services/functions/)
560
+ - [Azure Cosmos DB](https://azure.microsoft.com/ja-jp/services/cosmos-db/)
561
+ - [React](https://reactjs.org/)
562
+ - [Vite](https://vitejs.dev/)
563
+
@@ -0,0 +1,71 @@
1
+ import { IncomingMessage, ServerResponse } from 'http';
2
+ export interface RpcRequest {
3
+ fnName: string;
4
+ args: any[];
5
+ }
6
+ export interface RpcResponse {
7
+ success: boolean;
8
+ data?: any;
9
+ error?: string;
10
+ }
11
+ /**
12
+ * SwallowKit RPC APIハンドラー
13
+ * useServerFnからの呼び出しを処理
14
+ */
15
+ export declare class RpcHandler {
16
+ private serverFunctions;
17
+ /**
18
+ * サーバー関数を登録
19
+ */
20
+ registerFunction(name: string, fn: Function): void;
21
+ /**
22
+ * 複数のサーバー関数を一括登録
23
+ */
24
+ registerFunctions(functions: Record<string, Function>): void;
25
+ /**
26
+ * Express.js スタイルのミドルウェア
27
+ */
28
+ expressMiddleware(): (req: any, res: any, next?: any) => Promise<any>;
29
+ /**
30
+ * Next.js API Routes 対応
31
+ */
32
+ nextApiHandler(): (req: any, res: any) => Promise<void>;
33
+ /**
34
+ * Azure Static Web Apps API 対応
35
+ */
36
+ azureStaticWebAppsHandler(): (context: any, req: any) => Promise<void>;
37
+ /**
38
+ * Node.js http サーバー対応
39
+ */
40
+ nodeHttpHandler(): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
41
+ /**
42
+ * リクエストを処理
43
+ */
44
+ private handleRequest;
45
+ /**
46
+ * 成功レスポンスを送信
47
+ */
48
+ private sendSuccess;
49
+ /**
50
+ * エラーレスポンスを送信
51
+ */
52
+ private sendError;
53
+ /**
54
+ * Node.js リクエストボディをパース
55
+ */
56
+ private parseRequestBody;
57
+ /**
58
+ * 登録された関数一覧を取得
59
+ */
60
+ getRegisteredFunctions(): string[];
61
+ /**
62
+ * 関数の登録を削除
63
+ */
64
+ unregisterFunction(name: string): boolean;
65
+ /**
66
+ * 全ての関数登録をクリア
67
+ */
68
+ clearFunctions(): void;
69
+ }
70
+ export declare const defaultRpcHandler: RpcHandler;
71
+ //# sourceMappingURL=rpc-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-handler.d.ts","sourceRoot":"","sources":["../../src/api/rpc-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAEvD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,eAAe,CAAoC;IAE3D;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAG,IAAI;IAIlD;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI;IAM5D;;OAEG;IACH,iBAAiB,KACD,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,OAAO,GAAG;IAqB9C;;OAEG;IACH,cAAc,KACE,KAAK,GAAG,EAAE,KAAK,GAAG;IAclC;;OAEG;IACH,yBAAyB,KACT,SAAS,GAAG,EAAE,KAAK,GAAG;IA2BtC;;OAEG;IACH,eAAe,KACC,KAAK,eAAe,EAAE,KAAK,cAAc;IAezD;;OAEG;YACW,aAAa;IAiB3B;;OAEG;IACH,OAAO,CAAC,WAAW;IAcnB;;OAEG;IACH,OAAO,CAAC,SAAS;IAcjB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;OAEG;IACH,sBAAsB,IAAI,MAAM,EAAE;IAIlC;;OAEG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIzC;;OAEG;IACH,cAAc,IAAI,IAAI;CAGvB;AAGD,eAAO,MAAM,iBAAiB,YAAmB,CAAC"}