From 3d21ab08cfd2c77b08c6fc4d9b8dc105b4f70b0b Mon Sep 17 00:00:00 2001 From: 1gk4330y-ctrl <1gk4330y@komazawa-u.ac.jp> Date: Tue, 10 Feb 2026 21:25:07 +0900 Subject: [PATCH 1/6] Update IPO card template --- docs/ipo_card_template.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/ipo_card_template.md b/docs/ipo_card_template.md index 8409646..cfb95e9 100644 --- a/docs/ipo_card_template.md +++ b/docs/ipo_card_template.md @@ -11,13 +11,13 @@ ## IPOカード -### 機能名: __________ +### 機能名: ____返答処理______ | 項目 | 内容 | |------|------| -| **Input (きっかけ)** | ユーザーが何を入力し、何をするか? | -| **Process (裏側の処理)** | サーバーは何を受け取り、DBに何を保存/削除するか? | -| **Output (結果)** | 処理後、画面はどう変化し、データはどうなっているか? | +| **Input (きっかけ)** | ユーザーは時間に応じた挨拶をインプット +| **Process (裏側の処理)** | サーバーは言葉を受け取り、現在時刻に応じた挨拶文を生成する +| **Output (結果)** | 時間帯に応じた挨拶文を返す --- From c1d85e4ced322246ef651fb3582b59e058eb6aeb Mon Sep 17 00:00:00 2001 From: yuki332 Date: Tue, 17 Feb 2026 21:28:24 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20Phase=202=20=E3=82=AB=E3=83=AA?= =?UTF-8?q?=E3=82=AD=E3=83=A5=E3=83=A9=E3=83=A0=E3=82=92=E5=AE=9F=E9=A8=93?= =?UTF-8?q?=E9=A7=86=E5=8B=95=E5=9E=8B=E3=81=AB=E6=94=B9=E8=A8=82=EF=BC=88?= =?UTF-8?q?v3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 1ファイルからDay別に6ファイルへ分割 - IPOカードをAIへのプロンプトとして統合(参考情報→能動的に使う形式へ) - レポートを実験結果ベース(予想→結果→わかったこと)に変更 - 各Dayのセクション構成を統一(IPOカード→準備・実行→ファイル確認→実験→実験レポート) - 開発環境をWSL + VS Code + nodenv向けに更新 --- docs/phase2/00_overview.md | 116 ++++++++++++++++++++ docs/phase2/day06_client_only.md | 119 ++++++++++++++++++++ docs/phase2/day07_client_server.md | 140 ++++++++++++++++++++++++ docs/phase2/day08_with_db.md | 167 +++++++++++++++++++++++++++++ docs/phase2/day09_read.md | 130 ++++++++++++++++++++++ docs/phase2/day10_summary.md | 125 +++++++++++++++++++++ 6 files changed, 797 insertions(+) create mode 100644 docs/phase2/00_overview.md create mode 100644 docs/phase2/day06_client_only.md create mode 100644 docs/phase2/day07_client_server.md create mode 100644 docs/phase2/day08_with_db.md create mode 100644 docs/phase2/day09_read.md create mode 100644 docs/phase2/day10_summary.md diff --git a/docs/phase2/00_overview.md b/docs/phase2/00_overview.md new file mode 100644 index 0000000..d405c2a --- /dev/null +++ b/docs/phase2/00_overview.md @@ -0,0 +1,116 @@ +# Phase 2: Webアプリの3層構造を体感する + +## 目的 + +**データがどこにあり、どう流れるかを体感する。** +Phase 1で体験した「消えるデータ」の問題を、Client → Server → Database と層を1つずつ追加しながら解決していく。 + +コードの実装はAIが行う。人間がやることは以下の4つ。 + +1. **IPOカードをAIに渡してコードを生成させる** — 教材のIPOカードをコピーしてAIに渡す +2. **生成されたファイルを確認する** — どのファイルがどの層に対応するかを理解する +3. **実験を実施する** — 教材の手順に従い、データの挙動を観察する +4. **実験レポートを書く** — 観察した結果を自分の言葉で記録する + +--- + +## 全体像: 3層構造とデータの流れ + +``` +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ Client │ HTTP │ Server │ ORM │ Database │ +│ (ブラウザ) │ ────► │ (Node.js) │ ────► │ (SQLite) │ +│ │ ◄──── │ │ ◄──── │ │ +├─────────────────┤ ├─────────────────┤ ├─────────────────┤ +│ 確認: F12 │ │ 確認: ターミナル │ │ 確認: Prisma │ +│ 編集: HTML/JS │ │ 編集: server.js │ │ Studio/DBファイル│ +└─────────────────┘ └─────────────────┘ └─────────────────┘ +``` + +Phase 2では、この3層を **1日1層ずつ** 追加して理解する。 + +| Day | 層の構成 | 学ぶこと | +|-----|---------|---------| +| Day 6 | **Client のみ** | データはブラウザの中にある | +| Day 7 | **Client + Server** | データをサーバーに送れる | +| Day 8 | **Client + Server + DB** | データをDBに保存できる(Create) | +| Day 9 | **全層を往復** | DBのデータを画面に表示できる(Read) | +| Day 10 | **永続化の証明** | 再起動してもデータが残る | + +--- + +## 開発環境の準備 + +Phase 2を始める前に、以下の環境を整える。Windows の WSL(Ubuntu)上で作業する。 + +### 1. WSL + VS Code の確認 + +VS Code がインストール済みであること。WSL 内のフォルダを VS Code で開いて作業する。 + +1. VS Code の拡張機能「**WSL**」(Microsoft製)がインストールされていることを確認する +2. WSL のターミナルを開き、作業フォルダで `code .` を実行すると VS Code が WSL に接続して開く +3. VS Code 内のターミナル(`Ctrl + `` `)は WSL のシェルになる — ここでコマンドを実行する + +### 2. Node.js の確認 + +WSL のターミナルで以下を実行し、バージョンが表示されることを確認する。 + +```bash +node -v +# v20.x.x のように表示されればOK +``` + +表示されない場合は、nodenv でインストールする(講師に確認すること)。 + +### 3. npm の確認 + +```bash +npm -v +# 10.x.x のように表示されればOK +``` + +> npm は Node.js と一緒にインストールされる。パッケージ(ライブラリ)を管理するツール。 + +### 4. ブラウザの開発者ツール + +Windows 側の Google Chrome を使う。以下を確認する。 + +1. Chrome を開く +2. **F12キー** を押す → 開発者ツールが開く +3. **Console タブ** をクリック → ここにブラウザ側のログが表示される + +> WSL で起動したサーバー(`http://localhost:3000`)には、Windows 側のブラウザからそのままアクセスできる。 + +### 5. 作業ディレクトリの準備 + +```bash +# 自分のPhase 2フォルダに移動(名前は自分のものに変える) +cd members/[あなたの名前]/phase2_web +``` + +--- + +## Phase 2 チェックリスト + +| Day | テーマ | 層の構成 | 実験レポート | 完了 | +|-----|-------|---------|------------|------| +| Day 6 | データはブラウザの中にある | Client | `day6_report.md` | [ ] | +| Day 7 | データをサーバーに送る | Client + Server | `day7_report.md` | [ ] | +| Day 8 | データをDBに保存する | Client + Server + DB | `day8_report.md` | [ ] | +| Day 9 | DBのデータを画面に表示する | Client + Server + DB | `day9_report.md` | [ ] | +| Day 10 | 永続化の証明 & 総まとめ | 全体まとめ | `day10_report.md` | [ ] | + +--- + +## 次のPhaseへ + +Phase 2を完了したあなたは、以下を学びました。 + +- **3層構造** — Client / Server / Database の役割と場所 +- **データの流れ** — 書き込み(Client → Server → DB)と読み取り(DB → Server → Client) +- **永続化** — データベースを使えばデータは消えない +- **ファイルとレイヤーの対応** — どのファイルを編集すると、どこが変わるか + +Phase 3では、**チーム開発** の作法を学びます。 +複数人で同じコードを編集するとき、どうやって衝突を避けるか? +Gitのブランチ、プルリクエスト、コンフリクト解決を体験します。 diff --git a/docs/phase2/day06_client_only.md b/docs/phase2/day06_client_only.md new file mode 100644 index 0000000..710957b --- /dev/null +++ b/docs/phase2/day06_client_only.md @@ -0,0 +1,119 @@ +# Day 6: Client のみ — データはブラウザの中にある + +## 学習目標 + +- データが「ブラウザの中(JavaScriptの変数)」に存在することを理解する +- F12(開発者ツール)の Console でデータを確認する方法を覚える +- ページを更新するとデータが消えることを体験する(Phase 1と同じ揮発性) + +## ファイル構成とレイヤーの対応 + +``` +day6_client_only/ +└── index.html ← これが Client(ブラウザ)で動く唯一のファイル +``` + +| ファイル | レイヤー | 確認場所 | 役割 | +|---------|---------|---------|------| +| `index.html` | Client(ブラウザ) | F12 Console | 画面表示、ユーザー操作の受付、データの一時保存 | + +> Day 6ではサーバーもDBも使わない。HTMLファイルをブラウザで直接開くだけ。 + +## AIへのプロンプト(IPOカード形式) + +以下のIPOカードをコピーしてAIに渡し、コードを生成させる。 + +> **IPOカード — Day 6: Client のみ(メッセージボード)** +> +> | 層 | Input (きっかけ) | Process (処理) | Output (結果) | +> |----|-----------------|---------------|--------------| +> | **Client** | ユーザーがメッセージを入力し「追加」ボタンをクリック | JavaScript が入力値を受け取り、配列(messages)に追加する | 画面のリストにメッセージが表示される。Console にデータが出力される | +> +> **ファイル構成:** +> - `day6_client_only/index.html`(Client層)— これ1ファイルだけ +> +> **仕様:** +> - `index.html` 1ファイルだけで動くメッセージボード +> - テキスト入力欄と「追加」ボタンがある +> - メッセージを追加すると画面のリストに表示される +> - データはJavaScript の配列(`messages`)に保存する +> - メッセージを追加するたびに `console.log` で配列の中身を出力する +> - ログには `[CLIENT]` プレフィックスをつける +> +> **データの流れ:** +> ``` +> ユーザー入力 → [Client: JavaScript の配列に追加] → 画面のリストに表示 +> ↓ +> F12 Console で確認 +> ``` + +## 準備・実行 + +### プロジェクト準備 + +```bash +mkdir -p day6_client_only +``` + +> Day 6では `npm` は使わない。HTMLファイル1つだけで動く。 + +### 実行方法 + +サーバーは不要。HTMLファイルをブラウザで直接開く。 + +**ブラウザで `index.html` を開く手順:** + +1. Windows のエクスプローラーのアドレスバーに `\\wsl$\Ubuntu` と入力して Enter +2. WSL 内の作業フォルダまで移動する(`home/[ユーザー名]/...`) +3. `day6_client_only/index.html` を見つける +4. ファイルを右クリック → **プログラムから開く** → **Google Chrome** を選択 + +> WSL のターミナルから `explorer.exe .` を実行すると、カレントディレクトリをエクスプローラーで開くこともできる。 + +## ファイルの確認 + +AIがコードを生成したら、以下を確認する。 + +- [ ] ファイルは `index.html` の1つだけか? +- [ ] データの保存先は JavaScript の配列(変数)か? +- [ ] `console.log` で `[CLIENT]` プレフィックス付きのログが出るか? +- [ ] サーバーやデータベースのコードは含まれていないか? + +## 実験 + +### 実験1: メッセージを追加する + +1. ブラウザで `index.html` を開く +2. **F12キー** → **Console タブ** を開く +3. メッセージを3つ追加する +4. **Console に `[CLIENT]` のログが表示されることを確認する** +5. ログの中の配列データを見て、3件のメッセージが入っていることを確認する + +### 実験2: ページを更新する(F5) + +1. メッセージを3つ追加した状態で、Console でデータが3件あることを確認する +2. **ブラウザのページを更新する(F5キー)** +3. 画面とConsole を確認する + +## 実験レポート + +`day6_report.md` として保存し、コミットすること。 + +``` +実験1: メッセージを追加する + F12 Console に表示されたログ:(実験後に書く) + 画面の変化:(実験後に書く) + +実験2: ページを更新する(F5) + 予想:(実験前に書く — ページを更新したらデータはどうなると思うか?) + 結果:(実験後に書く — 何が起きたか、画面とConsoleに何が表示されたか) + わかったこと:(なぜそうなったかの考察) +``` + +## 完了条件 + +- [ ] `index.html` だけでメッセージボードが動作する +- [ ] F12 Console でデータ(配列の中身)を確認できた +- [ ] ページ更新後にデータが消えることを確認した +- [ ] 実験レポート(`day6_report.md`)を提出した +- [ ] コミット&プッシュ完了 diff --git a/docs/phase2/day07_client_server.md b/docs/phase2/day07_client_server.md new file mode 100644 index 0000000..cd18867 --- /dev/null +++ b/docs/phase2/day07_client_server.md @@ -0,0 +1,140 @@ +# Day 7: Client + Server — データをサーバーに送る + +## 学習目標 + +- Client(ブラウザ)から Server(Node.js)にデータを送る方法を学ぶ +- データが **2つの場所**(F12 Console と ターミナル)に現れることを確認する +- `fetch` によるHTTP通信の基本を理解する + +## ファイル構成とレイヤーの対応 + +``` +day7_client_server/ +├── server.js ← Server(Node.js): ターミナルで動く 【Day 7 で新規追加】 +├── package.json ← npm の設定ファイル(npm init で自動生成) +└── public/ + └── index.html ← Client(ブラウザ): ブラウザで動く +``` + +| ファイル | レイヤー | 確認場所 | 役割 | +|---------|---------|---------|------| +| `public/index.html` | Client(ブラウザ) | F12 Console | ユーザー操作の受付、サーバーへのデータ送信 | +| `server.js` | Server(Node.js) | VS Code ターミナル | Client からのデータ受信、データの一時保存 | + +> Day 6 と比べて、`server.js` が追加された。データの流れが Client → Server に広がる。 + +## AIへのプロンプト(IPOカード形式) + +以下のIPOカードをコピーしてAIに渡し、コードを生成させる。 + +> **IPOカード — Day 7: Client + Server(メッセージ送信)** +> +> | 層 | Input (きっかけ) | Process (処理) | Output (結果) | +> |----|-----------------|---------------|--------------| +> | **Client** | ユーザーがメッセージを入力し「送信」ボタンをクリック | JavaScript が入力値を取得し、`fetch` で Server(`POST /api/messages`)にデータを送信する | Console に送信ログが表示される。画面に「送信しました」と表示される | +> | **Server** | Client から `POST /api/messages` でメッセージデータ(JSON)を受け取る | 受け取ったデータをターミナルに表示し、配列に保存する | Client に `{ success: true }` をJSONで返す | +> +> **ファイル構成:** +> - `day7_client_server/public/index.html`(Client層) +> - `day7_client_server/server.js`(Server層) +> +> **server.js の仕様:** +> - Express を使った Node.js サーバー(ポート3000) +> - `public/` フォルダの静的ファイルを配信する +> - `POST /api/messages` エンドポイント: Client からメッセージ(JSON)を受け取り、サーバーの配列に保存する +> - 受信時に `console.log` でデータを表示する(`[SERVER]` プレフィックス) +> - 成功時に `{ success: true }` を返す +> +> **public/index.html の仕様:** +> - テキスト入力欄と「送信」ボタンがある +> - ボタンをクリックすると `fetch` で `POST /api/messages` にデータを送信する +> - 送信前後に `console.log` でログを出す(`[CLIENT]` プレフィックス) +> - 送信完了後、画面に「送信しました」と表示する +> +> **データの流れ:** +> ``` +> ユーザー入力 → [Client: fetch POST で送信] → [Server: データを受信、配列に保存] +> ↓ ↓ +> F12 Console で確認 VS Code ターミナルで確認 +> ``` + +## 準備・実行 + +### プロジェクト準備 + +```bash +mkdir -p day7_client_server +cd day7_client_server +npm init -y +npm install express +``` + +> `npm init -y` で `package.json` が作られる。`npm install express` で Express(Webサーバーのライブラリ)がインストールされる。 + +### 実行方法 + +```bash +node server.js +``` + +ブラウザで `http://localhost:3000` を開く。 + +> Day 6 と違い、HTMLファイルを直接開くのではなく、サーバー経由でアクセスする。 + +## ファイルの確認 + +AIがコードを生成したら、以下を確認する。 + +- [ ] `server.js` と `public/index.html` の2ファイルがあるか? +- [ ] `server.js` は Server レイヤー(ターミナルで動く)のコードか? +- [ ] `public/index.html` は Client レイヤー(ブラウザで動く)のコードか? +- [ ] Client は `fetch` でサーバーにデータを送っているか? +- [ ] Server は `console.log` で受信データを表示しているか? +- [ ] データベース関連のコードは含まれていないか? + +## 実験 + +### 実験1: メッセージを送信する + +1. **ターミナル** で `node server.js` を実行 +2. **ブラウザ** で `http://localhost:3000` を開く +3. **F12キー** → **Console タブ** を開く +4. メッセージを入力して「送信」をクリック +5. **2つの場所でログを確認する:** + +| 確認場所 | 表示されるログ | 意味 | +|---------|--------------|------| +| ブラウザの F12 Console | `[CLIENT] ...` | Client(ブラウザ)側の処理 | +| VS Code のターミナル | `[SERVER] ...` | Server(Node.js)側の処理 | + +### 実験2: サーバーを再起動する + +1. メッセージを3つ送信する +2. ターミナルでデータが3件保存されていることを確認する +3. ターミナルで **Ctrl+C** を押してサーバーを停止する +4. `node server.js` でサーバーを再起動する +5. ターミナルを確認する + +## 実験レポート + +`day7_report.md` として保存し、コミットすること。 + +``` +実験1: メッセージを送信する + F12 Console に表示されたログ:(実験後に書く) + ターミナルに表示されたログ:(実験後に書く) + なぜログが2か所に表示されるか:(考察を書く) + +実験2: サーバーを再起動する + 予想:(実験前に書く — サーバーを再起動したらデータはどうなると思うか?) + 結果:(実験後に書く — ターミナルに何が表示されたか、以前のデータはあるか) + わかったこと:(なぜそうなったかの考察。Day 6 との共通点は何か) +``` + +## 完了条件 + +- [ ] Client から送信したデータが Server のターミナルに表示される +- [ ] `[CLIENT]` ログと `[SERVER]` ログが別の場所に出ることを確認した +- [ ] サーバー再起動後にデータが消えることを確認した +- [ ] 実験レポート(`day7_report.md`)を提出した +- [ ] コミット&プッシュ完了 diff --git a/docs/phase2/day08_with_db.md b/docs/phase2/day08_with_db.md new file mode 100644 index 0000000..a767bb8 --- /dev/null +++ b/docs/phase2/day08_with_db.md @@ -0,0 +1,167 @@ +# Day 8: Client + Server + DB — データをDBに保存する(Create) + +## 学習目標 + +- データベース(SQLite)にデータを永続的に保存する方法を学ぶ +- 3層すべてを通るデータの流れ(Client → Server → DB)を理解する +- ORM(Prisma)の基本的な使い方を学ぶ + +## ファイル構成とレイヤーの対応 + +``` +day8_with_db/ +├── server.js ← Server: API処理 + DB操作 +├── package.json ← npm の設定ファイル +├── public/ +│ └── index.html ← Client: 画面表示 + データ送信 +└── prisma/ + ├── schema.prisma ← DB定義: テーブルの構造を定義 【Day 8 で新規追加】 + └── dev.db ← Database: データが保存されるファイル(自動生成)【Day 8 で新規追加】 +``` + +| ファイル | レイヤー | 確認場所 | 役割 | +|---------|---------|---------|------| +| `public/index.html` | Client(ブラウザ) | F12 Console | 画面表示、データ送信 | +| `server.js` | Server(Node.js) | VS Code ターミナル | API処理、Prisma を使った DB 操作 | +| `prisma/schema.prisma` | DB定義 | — | テーブルの構造(カラム名、型)を定義 | +| `prisma/dev.db` | Database(SQLite) | Prisma Studio | データが物理的に保存されるファイル | + +> Day 7 と比べて、`prisma/` フォルダが追加された。Server がデータを受け取った後、変数ではなく **DBファイルに保存** する。 + +## AIへのプロンプト(IPOカード形式) + +以下のIPOカードをコピーしてAIに渡し、コードを生成させる。 + +> **IPOカード — Day 8: Client + Server + DB(メッセージ保存 — Create)** +> +> | 層 | Input (きっかけ) | Process (処理) | Output (結果) | +> |----|-----------------|---------------|--------------| +> | **Client** | ユーザーが名前とメッセージを入力し「送信」ボタンをクリック | JavaScript が入力値を取得し、`fetch` で Server(`POST /api/messages`)にデータを送信する | Console に送信ログが表示される。入力欄がクリアされる | +> | **Server** | Client から `POST /api/messages` で名前・メッセージのJSONデータを受け取る | Prisma を使って、受け取ったデータを Database の `Message` テーブルに INSERT する | ターミナルに保存ログが出力される。Client に `{ success: true, message: {...} }` を返す | +> | **Database** | Server(Prisma)から INSERT 命令を受け取る | `Message` テーブルに新しい行(レコード)を追加する。`id` と `createdAt` は自動生成 | 保存したレコード(id, name, content, createdAt)を Server に返す | +> +> **ファイル構成:** +> - `day8_with_db/public/index.html`(Client層) +> - `day8_with_db/server.js`(Server層) +> - `day8_with_db/prisma/schema.prisma`(DB定義) +> - `day8_with_db/prisma/dev.db`(Database — migrate 後に自動生成) +> +> **prisma/schema.prisma の仕様:** +> - Message モデル: id(自動採番)、name(文字列)、content(文字列)、createdAt(日時、自動生成) +> +> **server.js の仕様:** +> - Express サーバー(ポート3000) +> - PrismaClient を使ってDBにアクセスする +> - `POST /api/messages` エンドポイント: name と content を受け取り、DBに保存する +> - 保存時に `console.log` で `[SERVER]` プレフィックス付きのログを出す +> - 成功時に保存したデータを返す +> +> **public/index.html の仕様:** +> - 名前とメッセージの2つの入力欄と「送信」ボタン +> - `fetch` で `POST /api/messages` にデータを送信する +> - `console.log` で `[CLIENT]` プレフィックス付きのログを出す +> +> **データの流れ:** +> ``` +> ユーザー入力 → [Client: fetch POST] → [Server: Prismaで保存命令] → [DB: ファイルに書き込み] +> ↓ ↓ ↓ +> F12 Console VS Code ターミナル prisma/dev.db に保存 +> (Prisma Studio で確認) +> ``` + +## 準備・実行 + +### プロジェクト準備 + +```bash +mkdir -p day8_with_db +cd day8_with_db +npm init -y +npm install express @prisma/client +npm install -D prisma +npx prisma init --datasource-provider sqlite +``` + +> `npx prisma init` を実行すると `prisma/schema.prisma` が自動生成される。 + +### schema 定義後に実行するコマンド + +AIが `prisma/schema.prisma` を生成した後、以下を実行する。 + +```bash +npx prisma migrate dev --name init +``` + +> このコマンドで `prisma/dev.db` ファイルが作成される。これがデータベースの実体。 + +### 実行方法 + +```bash +node server.js +``` + +ブラウザで `http://localhost:3000` を開く。 + +## ファイルの確認 + +AIがコードを生成したら、以下を確認する。 + +- [ ] 以下の4つのファイル/フォルダが存在するか? + - `public/index.html`(Client) + - `server.js`(Server) + - `prisma/schema.prisma`(DB定義) + - `prisma/dev.db`(Database ファイル — migrate 後に生成) +- [ ] `server.js` の中で `PrismaClient` を使っているか? +- [ ] `server.js` の中で `prisma.message.create()` でDBに保存しているか? +- [ ] Day 7 のように配列(変数)に保存するコードは**ないか**? + +## 実験 + +### 実験1: メッセージを送信して3か所で確認する + +メッセージを送信した後、**3つの場所** でデータを確認する。 + +| 確認場所 | 確認方法 | 何が見えるか | +|---------|---------|------------| +| ブラウザ F12 Console | F12 → Console タブ | `[CLIENT] ...` 送信ログ | +| VS Code ターミナル | サーバー実行中のターミナル | `[SERVER] ...` DB保存ログ | +| Prisma Studio | 別ターミナルで `npx prisma studio` を実行 | テーブルにレコードが追加されている | + +Prisma Studio の開き方: +```bash +# サーバーとは別のターミナルを開いて実行 +npx prisma studio +``` +ブラウザで `http://localhost:5555` が開き、DBの中身を直接見ることができる。 + +### 実験2: サーバーを再起動する + +1. メッセージを3件送信する +2. Prisma Studio で3件のレコードを確認する +3. ターミナルで **Ctrl+C** を押してサーバーを停止する +4. `node server.js` でサーバーを再起動する +5. Prisma Studio でDBの中身を確認する + +## 実験レポート + +`day8_report.md` として保存し、コミットすること。 + +``` +実験1: メッセージを送信して3か所で確認する + F12 Console に表示されたログ:(実験後に書く) + ターミナルに表示されたログ:(実験後に書く) + Prisma Studio で見えたデータ:(実験後に書く) + +実験2: サーバーを再起動する + 予想:(実験前に書く — サーバーを再起動したらデータはどうなると思うか?Day 7 と同じか?) + 結果:(実験後に書く — Prisma Studio でデータは残っていたか) + わかったこと:(なぜ Day 7 と違う結果になったかの考察) +``` + +## 完了条件 + +- [ ] メッセージがDBに保存される(Prisma Studio で確認) +- [ ] F12 Console、ターミナル、Prisma Studio の3か所でデータを確認した +- [ ] サーバー再起動後もDBのデータが残ることを確認した +- [ ] 実験レポート(`day8_report.md`)を提出した +- [ ] コミット&プッシュ完了 diff --git a/docs/phase2/day09_read.md b/docs/phase2/day09_read.md new file mode 100644 index 0000000..a768748 --- /dev/null +++ b/docs/phase2/day09_read.md @@ -0,0 +1,130 @@ +# Day 9: 全層を往復 — DBのデータを画面に表示する(Read) + +## 学習目標 + +- データの**逆方向の流れ**(DB → Server → Client)を理解する +- GET API でデータを取得する方法を学ぶ +- 画面にデータベースの内容を表示する + +## ファイル構成とレイヤーの対応 + +Day 8 と同じプロジェクト(`day8_with_db/`)に機能を追加する。 + +``` +day8_with_db/ +├── server.js ← Server: POST API + GET API(★ GET を追加) +├── package.json +├── public/ +│ └── index.html ← Client: 送信機能 + 一覧表示機能(★ 表示を追加) +└── prisma/ + ├── schema.prisma ← DB定義(変更なし) + └── dev.db ← Database(変更なし) +``` + +| ファイル | Day 9 で追加する内容 | +|---------|-------------------| +| `server.js` | `GET /api/messages` エンドポイントを追加 | +| `public/index.html` | ページ読み込み時にメッセージ一覧を取得・表示する処理を追加 | +| `prisma/schema.prisma` | 変更なし | +| `prisma/dev.db` | 変更なし(Day 8 で保存したデータがそのまま入っている) | + +## AIへのプロンプト(IPOカード形式) + +Day 8 のプロジェクトに機能を追加する。以下のIPOカードをコピーしてAIに渡し、既存コードに追加させる。 + +> **IPOカード — Day 9: 全層を往復(メッセージ一覧表示 — Read)** +> +> | 層 | Input (きっかけ) | Process (処理) | Output (結果) | +> |----|-----------------|---------------|--------------| +> | **Client** | ページが読み込まれたとき(自動実行) | `fetch` で Server(`GET /api/messages`)からデータを取得する | 取得したメッセージ一覧を画面のリストに表示する | +> | **Server** | Client から `GET /api/messages` リクエストを受け取る | Prisma を使って Database の `Message` テーブルから全件取得する(新しい順) | 取得したメッセージの配列をJSONで Client に返す | +> | **Database** | Server(Prisma)から SELECT 命令を受け取る | `Message` テーブルから全レコードを `createdAt` の降順で取得する | レコードの配列を Server に返す | +> +> **編集対象ファイル(Day 8 のプロジェクトに追加):** +> - `day8_with_db/server.js` — `GET /api/messages` エンドポイントを追加 +> - `day8_with_db/public/index.html` — ページ読み込み時のデータ取得・表示処理を追加 +> - `prisma/schema.prisma` — 変更なし +> +> **server.js に追加する仕様:** +> - `GET /api/messages` エンドポイント: DB から全メッセージを新しい順で取得し、JSON で返す +> - 取得時に `console.log` で `[SERVER]` プレフィックス付きのログを出す(取得件数を表示) +> +> **public/index.html に追加する仕様:** +> - ページ読み込み時に `fetch` で `GET /api/messages` を呼び、メッセージ一覧を取得する +> - 取得したメッセージを画面のリストに表示する(名前、内容、日時) +> - 取得時に `console.log` で `[CLIENT]` プレフィックス付きのログを出す +> - メッセージ送信後にも一覧を再取得して表示を更新する +> +> **データの流れ(Read — 今日追加する流れ):** +> ``` +> ページ読込 → [Client: fetch GET] ← [Server: Prismaで取得命令] ← [DB: データを返す] +> ↓ ↓ ↓ +> 画面にリスト表示 ターミナルにログ dev.db から読み出し +> ``` + +## 準備・実行 + +Day 8 のプロジェクト(`day8_with_db/`)をそのまま使う。新しいフォルダは作らない。 + +```bash +node server.js +``` + +ブラウザで `http://localhost:3000` を開く。 + +## ファイルの確認 + +AIがコードを編集したら、以下を確認する。 + +- [ ] `server.js` に `GET /api/messages` が追加されたか? +- [ ] `server.js` で `prisma.message.findMany()` を使ってDBからデータを取得しているか? +- [ ] `public/index.html` にページ読み込み時のデータ取得処理が追加されたか? +- [ ] `public/index.html` で取得したデータを画面に表示する処理があるか? +- [ ] `prisma/schema.prisma` は変更されていないか? + +## 実験 + +### 実験1: ページを開いてデータを取得する + +1. `node server.js` でサーバーを起動する +2. ブラウザで `http://localhost:3000` を開く +3. **Day 8 で保存したメッセージが自動的に画面に表示されることを確認する** +4. F12 Console とターミナルのログを確認する: + +| 確認場所 | 表示されるログ | +|---------|--------------| +| F12 Console | `[CLIENT] 取得したメッセージ: [{...}, {...}, ...]` | +| ターミナル | `[SERVER] DBから取得: 3 件` | + +5. 新しいメッセージを送信し、一覧に追加されることを確認する + +### 実験2: サーバーを再起動してデータの往復を確認する + +1. サーバーを停止する(Ctrl+C) +2. サーバーを再起動する(`node server.js`) +3. ブラウザで `http://localhost:3000` を開く +4. 以前のメッセージが表示されるか確認する + +## 実験レポート + +`day9_report.md` として保存し、コミットすること。 + +``` +実験1: ページを開いてデータを取得する + 画面に表示されたメッセージ:(実験後に書く — Day 8 で保存したデータが出たか) + F12 Console に表示されたログ:(実験後に書く) + ターミナルに表示されたログ:(実験後に書く) + +実験2: サーバーを再起動してデータの往復を確認する + 予想:(実験前に書く — サーバーを再起動した後、ページを開いたらデータは表示されるか?) + 結果:(実験後に書く — メッセージは表示されたか) + わかったこと:(Read のデータの流れを自分の言葉で書く。Create との方向の違いは何か) +``` + +## 完了条件 + +- [ ] ページを開くとDBに保存済みのメッセージが表示される +- [ ] 新しいメッセージを追加すると一覧に即反映される +- [ ] サーバー再起動後もメッセージが表示される +- [ ] 実験レポート(`day9_report.md`)を提出した +- [ ] コミット&プッシュ完了 diff --git a/docs/phase2/day10_summary.md b/docs/phase2/day10_summary.md new file mode 100644 index 0000000..97587e6 --- /dev/null +++ b/docs/phase2/day10_summary.md @@ -0,0 +1,125 @@ +# Day 10: 永続化の証明 — 全てを再起動する + +## 学習目標 + +- データベースによる永続化を最終確認する +- Phase 1(揮発性)と Phase 2(永続性)の違いを整理する +- 3層構造の全体像を自分の言葉で説明できるようになる + +## 実験 + +### 実験1: 永続化の最終確認 + +以下の手順を実行し、**データが消えないこと** を確認する。 + +1. ゲストブックにメッセージを3件以上登録する +2. サーバーを停止する(Ctrl+C) +3. **PCを再起動する**(または数時間後に再開) +4. `node server.js` でサーバーを起動する +5. ブラウザで `http://localhost:3000` を開く +6. メッセージが残っているか確認する + +### Day 6〜9 の比較表 + +| 項目 | Day 6 (Client のみ) | Day 7 (Client + Server) | Day 8-9 (Client + Server + DB) | +|------|---------------------|------------------------|-------------------------------| +| データ保存場所 | ブラウザの変数 | サーバーの変数 | SQLite ファイル | +| ページ更新後 | **消える** | 残る(サーバーが動いていれば) | **残る** | +| サーバー再起動後 | — | **消える** | **残る** | +| PC再起動後 | **消える** | **消える** | **残る** | +| 永続性 | 揮発性 | 揮発性 | **永続性** | + +### ファイルとレイヤーの対応 総まとめ + +``` +day8_with_db/ +│ +├── public/ +│ └── index.html → Client(ブラウザ) +│ ・ユーザー操作を受け付ける +│ ・fetch でサーバーにデータを送る(Create) +│ ・fetch でサーバーからデータを取得する(Read) +│ ・取得したデータを画面に表示する +│ ・確認場所: F12 Console +│ +├── server.js → Server(Node.js) +│ ・Client からのリクエストを受け付ける +│ ・Prisma を使って DB にデータを保存する(Create) +│ ・Prisma を使って DB からデータを取得する(Read) +│ ・結果を JSON で Client に返す +│ ・確認場所: VS Code ターミナル +│ +└── prisma/ + ├── schema.prisma → DB定義 + │ ・テーブルの構造(カラム名、型)を定義する + │ ・人間が読んで「どんなデータが保存されるか」を理解する + │ + └── dev.db → Database(SQLite) + ・データが物理的に保存されるファイル + ・サーバーを止めてもPCを再起動しても消えない + ・確認場所: Prisma Studio +``` + +### データフロー 総まとめ + +``` +【Create(書き込み)の流れ → → →】 + + ユーザーが入力 + ↓ + [Client: index.html] + fetch POST /api/messages でサーバーに送信 + ↓ F12 Console で確認 + [Server: server.js] + prisma.message.create() で DB に保存命令 + ↓ ターミナルで確認 + [DB: dev.db] + Message テーブルにレコードを追加 + Prisma Studio で確認 + + +【Read(読み取り)の流れ ← ← ←】 + + ページを開く + ↓ + [Client: index.html] + fetch GET /api/messages でサーバーにリクエスト + ↓ + [Server: server.js] + prisma.message.findMany() で DB から取得命令 + ↓ + [DB: dev.db] + Message テーブルから全レコードを取得 + ↓ + [Server: server.js] + 取得したデータを JSON で Client に返す + ↓ ターミナルで確認 + [Client: index.html] + 受け取ったデータを画面のリストに表示 + F12 Console + 画面で確認 +``` + +## 実験レポート + +`day10_report.md` として保存し、コミットすること。 + +``` +実験1: 永続化の最終確認(PC再起動後) + 予想:(実験前に書く — PC再起動後、データは残っていると思うか?) + 結果:(実験後に書く — メッセージは表示されたか) + わかったこと:(なぜデータが残ったか / 消えたかの考察) + +Phase 2 全体のまとめ: + Phase 1 のToDoリストはなぜデータが消えたか: + Phase 2 のゲストブックはなぜデータが残るか: + Client、Server、DB それぞれの役割(1文ずつ): + Create(書き込み)のデータの流れ: + Read(読み取り)のデータの流れ: +``` + +## 完了条件 + +- [ ] PC再起動後もデータが残ることを確認した +- [ ] Day 6〜9 の比較表の違いを説明できる +- [ ] 各ファイルがどのレイヤーに対応するか説明できる +- [ ] 実験レポート(`day10_report.md`)を提出した From c96550d591aa42050aad1f5de87a0c7fdc4f25be Mon Sep 17 00:00:00 2001 From: tmakkrhr-ctrl Date: Sat, 21 Feb 2026 11:30:03 +0900 Subject: [PATCH 3/6] =?UTF-8?q?day6=E3=82=92=E5=AE=9F=E6=96=BD=E3=81=97?= =?UTF-8?q?=EF=BC=8C=E3=83=AC=E3=83=9D=E3=83=BC=E3=83=88=E3=81=A8index.htm?= =?UTF-8?q?l=E3=82=92=E4=BD=9C=E6=88=90=E3=81=97=E3=81=BE=E3=81=97?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- members/kurihara/phase2_web/day6_report.md | 38 ++++++++++++ members/kurihara/phase2_web/index.html | 69 ++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 members/kurihara/phase2_web/day6_report.md create mode 100644 members/kurihara/phase2_web/index.html diff --git a/members/kurihara/phase2_web/day6_report.md b/members/kurihara/phase2_web/day6_report.md new file mode 100644 index 0000000..0e0307c --- /dev/null +++ b/members/kurihara/phase2_web/day6_report.md @@ -0,0 +1,38 @@ +## 実験レポート + +### 実験1: メッセージを追加する +**方法** +"Hello, world!", "This is a test.", "Day6"の3つのメッセージを順に追加した. + +**結果** + F12 Console に表示されたログ: +index.html:60 [CLIENT] messages: ['Hello, world!'] +index.html:60 [CLIENT] messages: (2) ['Hello, world!', 'This is a test.'] +index.html:60 [CLIENT] messages: (3) ['Hello, world!', 'This is a test.', 'Day6'] + + 画面の変化: +メッセージボックスの下に,箇条書きで +Hello, world! +This is a test. +Day6 +という文字が追加されていった. + +### 実験2: F5キーを押してページを更新する + 予想: +ページを更新するとコンソールが一度破棄されて,データは消える. + + 結果: +画面,コンソールともに,何も書かれていないものに切り替わった. + + 分かったこと: +画面を更新したことでindex.htmlが読み直されて,JavaScriptの配列の中に追加したデータが,追加される前の状態,つまり空の状態になったと考えられる.実際,index.htmlの +
+ + +
+の部分を書き換え, +
+ + +
+としてページを更新すると,メッセージ入力欄の文字も変化したからである. \ No newline at end of file diff --git a/members/kurihara/phase2_web/index.html b/members/kurihara/phase2_web/index.html new file mode 100644 index 0000000..e255b44 --- /dev/null +++ b/members/kurihara/phase2_web/index.html @@ -0,0 +1,69 @@ + + + + + + Day 6 Client Only Message Board + + + +

メッセージボード

+ +
+ + +
+ + + + + + From b6bfa559751b5f1397ee4b0ae05dd361af112818 Mon Sep 17 00:00:00 2001 From: tmakkrhr-ctrl Date: Sun, 22 Feb 2026 11:43:21 +0900 Subject: [PATCH 4/6] =?UTF-8?q?Day7=E3=82=92=E5=AE=9F=E6=96=BD=E3=81=97?= =?UTF-8?q?=EF=BC=8C=E3=83=AC=E3=83=9D=E3=83=BC=E3=83=88=E3=81=A8=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=97=E3=81=BE?= =?UTF-8?q?=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => day6_client_only}/day6_report.md | 0 .../{ => day6_client_only}/index.html | 0 .../day7_client_server/day7_report.md | 56 ++ .../day7_client_server/package-lock.json | 827 ++++++++++++++++++ .../day7_client_server/package.json | 17 + .../day7_client_server/public/index.html | 82 ++ .../phase2_web/day7_client_server/server.js | 29 + 7 files changed, 1011 insertions(+) rename members/kurihara/phase2_web/{ => day6_client_only}/day6_report.md (100%) rename members/kurihara/phase2_web/{ => day6_client_only}/index.html (100%) create mode 100644 members/kurihara/phase2_web/day7_client_server/day7_report.md create mode 100644 members/kurihara/phase2_web/day7_client_server/package-lock.json create mode 100644 members/kurihara/phase2_web/day7_client_server/package.json create mode 100644 members/kurihara/phase2_web/day7_client_server/public/index.html create mode 100644 members/kurihara/phase2_web/day7_client_server/server.js diff --git a/members/kurihara/phase2_web/day6_report.md b/members/kurihara/phase2_web/day6_client_only/day6_report.md similarity index 100% rename from members/kurihara/phase2_web/day6_report.md rename to members/kurihara/phase2_web/day6_client_only/day6_report.md diff --git a/members/kurihara/phase2_web/index.html b/members/kurihara/phase2_web/day6_client_only/index.html similarity index 100% rename from members/kurihara/phase2_web/index.html rename to members/kurihara/phase2_web/day6_client_only/index.html diff --git a/members/kurihara/phase2_web/day7_client_server/day7_report.md b/members/kurihara/phase2_web/day7_client_server/day7_report.md new file mode 100644 index 0000000..dbb7012 --- /dev/null +++ b/members/kurihara/phase2_web/day7_client_server/day7_report.md @@ -0,0 +1,56 @@ +*** 実験1 *** + +## 方法 +メッセージ"This is a test."を送信した. + +## 結果 + F12 Console に表示されたログ: +[CLIENT] 送信前データ: {message: 'This is a test.'} +(index):67 [CLIENT] 送信後レスポンス: {success: true} + + ターミナルに表示されたログ: +[SERVER] 受信データ: { message: 'This is a test.', receivedAt: '2026-02-21T11:42:27.902Z' } + + 考察(なぜログが2か所に表示されるか): +cliant 側のindex.htmlについて, +const payload = { message }; +console.log('[CLIENT] 送信前データ:', payload); + +server 側のserver.jsについて, +app.use(express.json()); +app.use(express.static(path.join(__dirname, 'public'))); +... +app.post('/api/messages', (req, res) => { + const { message } = req.body; + const item = { + message, + receivedAt: new Date().toISOString(), + }; + ... +} +) + + messages.push(item); + console.log('[SERVER] 受信データ:', item); + +の部分から,cliantがブラウザからメッセージを送ると,ブラウザのコンソールにNode.jsのExpressに送信前データが,serverのExpressがメッセージを受け取ると,サーバー側のコンソールに受信データがconsole.logによって表示されるためだと考えられる. + + +*** 実験2 *** + +## 方法 +1. メッセージ"hop", "step", "jumping"を送信した. +2. ターミナルでデータが3件保存されていることを確認した. +3. ターミナルで **Ctrl+C** を押してサーバーを停止させた. +4. `node server.js` によってサーバーを再起動させた. +5. ターミナルを確認した. + +## 結果 + 予想: +サーバーを再起動すると,server.jsを読み込み直すため,javaScriptのリストに保存してあったデータは消える. + + 結果: +サーバーに以前のデータはなく,データを保存するためのリストは空のリストになっていた. + + 分かったこと: +サーバーを再起動させると,server.jsを読み込み直すため,以前リストに保存してあったデータは消える.これは,Day6で,ファイルを読み込み直してデータが消えたという点で共通している. \ No newline at end of file diff --git a/members/kurihara/phase2_web/day7_client_server/package-lock.json b/members/kurihara/phase2_web/day7_client_server/package-lock.json new file mode 100644 index 0000000..befc79b --- /dev/null +++ b/members/kurihara/phase2_web/day7_client_server/package-lock.json @@ -0,0 +1,827 @@ +{ + "name": "day7_client_server", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "day7_client_server", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "express": "^5.2.1" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/members/kurihara/phase2_web/day7_client_server/package.json b/members/kurihara/phase2_web/day7_client_server/package.json new file mode 100644 index 0000000..4403297 --- /dev/null +++ b/members/kurihara/phase2_web/day7_client_server/package.json @@ -0,0 +1,17 @@ +{ + "name": "day7_client_server", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "dependencies": { + "express": "^5.2.1" + } +} diff --git a/members/kurihara/phase2_web/day7_client_server/public/index.html b/members/kurihara/phase2_web/day7_client_server/public/index.html new file mode 100644 index 0000000..3041c65 --- /dev/null +++ b/members/kurihara/phase2_web/day7_client_server/public/index.html @@ -0,0 +1,82 @@ + + + + + + Day7 Client-Server + + + +

Client / Server メッセージ送信

+ +
+ + +
+ +

+ + + + diff --git a/members/kurihara/phase2_web/day7_client_server/server.js b/members/kurihara/phase2_web/day7_client_server/server.js new file mode 100644 index 0000000..ef94eca --- /dev/null +++ b/members/kurihara/phase2_web/day7_client_server/server.js @@ -0,0 +1,29 @@ +const express = require('express'); +const path = require('path'); + +const app = express(); +const PORT = 3000; +const messages = []; + +console.log('messages:', messages); + +app.use(express.json()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.post('/api/messages', (req, res) => { + const { message } = req.body; + const item = { + message, + receivedAt: new Date().toISOString(), + }; + + messages.push(item); + console.log('[SERVER] 受信データ:', item); + + res.json({ success: true }); + console.log('messages:', messages); +}); + +app.listen(PORT, () => { + console.log(`[SERVER] http://localhost:${PORT} で起動しました`); +}); From b66f2ff678352b9c7bf45017282b989a6a1f4849 Mon Sep 17 00:00:00 2001 From: tmakkrhr-ctrl Date: Mon, 23 Feb 2026 12:21:16 +0900 Subject: [PATCH 5/6] =?UTF-8?q?day8=E3=82=92=E5=AE=9F=E6=96=BD=E3=81=97?= =?UTF-8?q?=EF=BC=8C=E3=83=AC=E3=83=9D=E3=83=BC=E3=83=88=E3=81=A8DB?= =?UTF-8?q?=E3=81=AE=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=81=97=E3=81=BE=E3=81=97=E3=81=9F=EF=BC=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../phase2_web/day8_with_db/day8_report.md | 39 + .../phase2_web/day8_with_db/package-lock.json | 1254 +++++++++++++++++ .../phase2_web/day8_with_db/package.json | 20 + .../phase2_web/day8_with_db/prisma/dev.db | Bin 0 -> 20480 bytes .../20260222122442_init/migration.sql | 7 + .../prisma/migrations/migration_lock.toml | 3 + .../day8_with_db/prisma/schema.prisma | 15 + .../phase2_web/day8_with_db/public/index.html | 90 ++ .../phase2_web/day8_with_db/server.js | 46 + 9 files changed, 1474 insertions(+) create mode 100644 members/kurihara/phase2_web/day8_with_db/day8_report.md create mode 100644 members/kurihara/phase2_web/day8_with_db/package-lock.json create mode 100644 members/kurihara/phase2_web/day8_with_db/package.json create mode 100644 members/kurihara/phase2_web/day8_with_db/prisma/dev.db create mode 100644 members/kurihara/phase2_web/day8_with_db/prisma/migrations/20260222122442_init/migration.sql create mode 100644 members/kurihara/phase2_web/day8_with_db/prisma/migrations/migration_lock.toml create mode 100644 members/kurihara/phase2_web/day8_with_db/prisma/schema.prisma create mode 100644 members/kurihara/phase2_web/day8_with_db/public/index.html create mode 100644 members/kurihara/phase2_web/day8_with_db/server.js diff --git a/members/kurihara/phase2_web/day8_with_db/day8_report.md b/members/kurihara/phase2_web/day8_with_db/day8_report.md new file mode 100644 index 0000000..a59f0ca --- /dev/null +++ b/members/kurihara/phase2_web/day8_with_db/day8_report.md @@ -0,0 +1,39 @@ +# Day8_report + +## 実験1 + +### 方法 +Cliant側でメッセージを送信して,ブラウザF12 console, VS Code ターミナル,Prisma Studioでデータを確認した.なお,一度Prisma Studioを開くのを忘れてメッセージを送ったため,やり直した. + +### 結果 +- ブラウザF12 console: +(index):61 [CLIENT] 送信前データ: {name: 'Lisp Alien', content: 'Hello, world!'} +(index):73 [CLIENT] 送信後レスポンス: {success: true, message: {…}} + +- VS Code ターミナル: +[SERVER] 保存しました: { + id: 2, + name: 'Lisp Alien', + content: 'Hello, world!', + createdAt: 2026-02-23T01:41:37.088Z +} + +- Prisma Studio: +| id # | name A | content A | +| ------ | ------ | ------ | +| 2 | Lisp Alien | Hello, world!| + + +## 実験2 + +### 方法 +メッセージを追加で3件送信し,Prisma Studio で3件のレコードを確認した.その後,ターミナルで Ctrl + C でサーバーを停止し,node server.js によってサーバーを再起動した.そして,Prisma StudioでDBの中身を確認した. + +### 予想 +サーバーを再起動すると,Day6, Day7同様,ブラウザF12 consoleとサーバーからは送信したデータは消えるが,DBであるPrisma Studioにはデータが残る + +### 結果 +Prisma Studioのみに送信したデータが残っていた. + +### 考察 +送ったメッセージのデータはdev.dbに書き込まれ,それをPrisma Studioで表示していると考えられる.実際,メッセージを送信し,データが記録されているのを確認後,dev.dbを消去し, npx prisma migrate dev --name init によって新しくdev.dbを作り,Prisma Studioでデータを見ると,データがすべて消えたからである. \ No newline at end of file diff --git a/members/kurihara/phase2_web/day8_with_db/package-lock.json b/members/kurihara/phase2_web/day8_with_db/package-lock.json new file mode 100644 index 0000000..893499a --- /dev/null +++ b/members/kurihara/phase2_web/day8_with_db/package-lock.json @@ -0,0 +1,1254 @@ +{ + "name": "day8_with_db", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "day8_with_db", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@prisma/client": "^6.19.2", + "express": "^5.2.1" + }, + "devDependencies": { + "prisma": "^6.19.2" + } + }, + "node_modules/@prisma/client": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.19.2.tgz", + "integrity": "sha512-gR2EMvfK/aTxsuooaDA32D8v+us/8AAet+C3J1cc04SW35FPdZYgLF+iN4NDLUgAaUGTKdAB0CYenu1TAgGdMg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "peerDependencies": { + "prisma": "*", + "typescript": ">=5.1.0" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@prisma/config": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.2.tgz", + "integrity": "sha512-kadBGDl+aUswv/zZMk9Mx0C8UZs1kjao8H9/JpI4Wh4SHZaM7zkTwiKn/iFLfRg+XtOAo/Z/c6pAYhijKl0nzQ==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "c12": "3.1.0", + "deepmerge-ts": "7.1.5", + "effect": "3.18.4", + "empathic": "2.0.0" + } + }, + "node_modules/@prisma/debug": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.2.tgz", + "integrity": "sha512-lFnEZsLdFLmEVCVNdskLDCL8Uup41GDfU0LUfquw+ercJC8ODTuL0WNKgOKmYxCJVvFwf0OuZBzW99DuWmoH2A==", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/engines": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.2.tgz", + "integrity": "sha512-TTkJ8r+uk/uqczX40wb+ODG0E0icVsMgwCTyTHXehaEfb0uo80M9g1aW1tEJrxmFHeOZFXdI2sTA1j1AgcHi4A==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.19.2", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/fetch-engine": "6.19.2", + "@prisma/get-platform": "6.19.2" + } + }, + "node_modules/@prisma/engines-version": { + "version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7.tgz", + "integrity": "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/fetch-engine": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.2.tgz", + "integrity": "sha512-h4Ff4Pho+SR1S8XerMCC12X//oY2bG3Iug/fUnudfcXEUnIeRiBdXHFdGlGOgQ3HqKgosTEhkZMvGM9tWtYC+Q==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.19.2", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/get-platform": "6.19.2" + } + }, + "node_modules/@prisma/get-platform": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.2.tgz", + "integrity": "sha512-PGLr06JUSTqIvztJtAzIxOwtWKtJm5WwOG6xpsgD37Rc84FpfUBGLKz65YpJBGtkRQGXTYEFie7pYALocC3MtA==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.19.2" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/c12": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz", + "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.3", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^16.6.1", + "exsolve": "^1.0.7", + "giget": "^2.0.0", + "jiti": "^2.4.2", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/confbox": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge-ts": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", + "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", + "devOptional": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "devOptional": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/effect": { + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz", + "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "fast-check": "^3.23.1" + } + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/exsolve": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/fast-check": { + "version": "3.23.2", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", + "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", + "devOptional": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^6.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/giget": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", + "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.6.0", + "pathe": "^2.0.3" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "devOptional": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/nypm": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.5.tgz", + "integrity": "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "citty": "^0.2.0", + "pathe": "^2.0.3", + "tinyexec": "^1.0.2" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/nypm/node_modules/citty": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.1.tgz", + "integrity": "sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/pkg-types": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/prisma": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.2.tgz", + "integrity": "sha512-XTKeKxtQElcq3U9/jHyxSPgiRgeYDKxWTPOf6NkXA0dNj5j40MfEsZkMbyNpwDWCUv7YBFUl7I2VK/6ALbmhEg==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/config": "6.19.2", + "@prisma/engines": "6.19.2" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=18.18" + }, + "peerDependencies": { + "typescript": ">=5.1.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "devOptional": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/members/kurihara/phase2_web/day8_with_db/package.json b/members/kurihara/phase2_web/day8_with_db/package.json new file mode 100644 index 0000000..f553040 --- /dev/null +++ b/members/kurihara/phase2_web/day8_with_db/package.json @@ -0,0 +1,20 @@ +{ + "name": "day8_with_db", + "version": "1.0.0", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@prisma/client": "^6.19.2", + "express": "^5.2.1" + }, + "devDependencies": { + "prisma": "^6.19.2" + }, + "description": "" +} diff --git a/members/kurihara/phase2_web/day8_with_db/prisma/dev.db b/members/kurihara/phase2_web/day8_with_db/prisma/dev.db new file mode 100644 index 0000000000000000000000000000000000000000..ca2be8eec8db477f5cf53df64612ea184276003e GIT binary patch literal 20480 zcmeI&J#W)M7zc1WO1*QyLPFZNx2E{K)IjO2tn>NYTFqN+M?y?g zl@K3-k&Th>g7_LNh>>&Zl)SVO0}Ivv6w5x}-E(?=XAib>^rGQMoOpwvMo}N_1UY?Jy-hemBhKeo5)I&rMuvz|@ZAEbw=8qtY?Ic3MOvLkgB-T& z&071IJU5R?tz#Y3TOvr)Y+2h^gW{PB#4=xr{>hl6g$?=G6k(O0& zn%CpWp82fSX;@^p({78I?6~#Fsx=QYo0qTU)x4s}AM9~{_Av0n9<_V^NkAii&<_{S zq-L{T>@WimOU#vVa?=j;iJo$H7LIy_*>N|Scz)jxPq}MTk@%l7AxPw|v$3yqla4n9 z><&)C=}1#ulVHK1+Z7W!l$}k_IyYq)(Lk)nbdNaHq}Srwuu%|*)wLtP$Hm~@Fqw`H zhh1L;3L`!YZ8jLiR{*)bt~#xw`hLsYTMSsrZ0@F3@-G!x^7}4-n_S{_6b;68dvW1x zW%1mSxYh2(w_8?ha&9Pz9|{B@009U<00Izz00bZa0SG_<0{=+hA}eP)7ujV^d|SU? z)|jHwic+MyTP^B3triVhtri`|Dmw-*Go9<6!4*x>J%LT3Mr-THRrW;W(n*EqR9g>ErveA8JXhlvGt!R8`kiTfAS1#tmOGA}=}j zT@pVO2tWV=5P$##AOHafKmY;|fB*#kGl54-oxgg$5P$y{fBHv(00bZa0SG_<0uX=z p1Rwwb2teQt3*h + + + + + Day8 with DB + + + +

Client / Server / Database メッセージ送信

+ +
+ + + +
+ +

+ + + + diff --git a/members/kurihara/phase2_web/day8_with_db/server.js b/members/kurihara/phase2_web/day8_with_db/server.js new file mode 100644 index 0000000..2fc3b3f --- /dev/null +++ b/members/kurihara/phase2_web/day8_with_db/server.js @@ -0,0 +1,46 @@ +const express = require('express'); +const path = require('path'); +const { PrismaClient } = require('@prisma/client'); + +const app = express(); +const prisma = new PrismaClient(); +const PORT = 3000; + +app.use(express.json()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.post('/api/messages', async (req, res) => { + const name = typeof req.body.name === 'string' ? req.body.name.trim() : ''; + const content = typeof req.body.content === 'string' ? req.body.content.trim() : ''; + + if (!name || !content) { + return res.status(400).json({ + success: false, + error: 'name と content は必須です', + }); + } + + try { + const message = await prisma.message.create({ + data: { name, content }, + }); + + console.log('[SERVER] 保存しました:', message); + return res.json({ success: true, message }); + } catch (error) { + console.error('[SERVER] 保存エラー:', error); + return res.status(500).json({ success: false, error: '保存に失敗しました' }); + } +}); + +app.listen(PORT, () => { + console.log(`[SERVER] http://localhost:${PORT} で起動しました`); +}); + +async function shutdown() { + await prisma.$disconnect(); + process.exit(0); +} + +process.on('SIGINT', shutdown); +process.on('SIGTERM', shutdown); From 548bec833dab8a84b6eb109b54626a0e735faa16 Mon Sep 17 00:00:00 2001 From: tmakkrhr-ctrl Date: Tue, 24 Feb 2026 16:02:13 +0900 Subject: [PATCH 6/6] =?UTF-8?q?phase2=E3=81=AEday9=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E6=96=BD=E3=81=97=EF=BC=8C=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92?= =?UTF-8?q?=E4=B8=80=E9=83=A8=E6=9B=B8=E3=81=8D=E6=8F=9B=E3=81=88=E3=83=AC?= =?UTF-8?q?=E3=83=9D=E3=83=BC=E3=83=88=E3=82=92=E4=BD=9C=E6=88=90=E3=81=97?= =?UTF-8?q?=E3=81=BE=E3=81=97=E3=81=9F=EF=BC=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../phase2_web/day8_with_db/day9_report.md | 97 ++++++++++++++++++ .../phase2_web/day8_with_db/prisma/dev.db | Bin 20480 -> 20480 bytes .../phase2_web/day8_with_db/public/index.html | 68 ++++++++++++ .../phase2_web/day8_with_db/server.js | 16 +++ 4 files changed, 181 insertions(+) create mode 100644 members/kurihara/phase2_web/day8_with_db/day9_report.md diff --git a/members/kurihara/phase2_web/day8_with_db/day9_report.md b/members/kurihara/phase2_web/day8_with_db/day9_report.md new file mode 100644 index 0000000..bd27e96 --- /dev/null +++ b/members/kurihara/phase2_web/day8_with_db/day9_report.md @@ -0,0 +1,97 @@ +# Day9_report + +## 実験1 + +### 方法 +1. Day8で一度dev.dbを消してデータを消去したため,day9の準備をした後,3件のメッセージを送信した. +2. 一度serverを停止させ,再起動し,1で送信したメッセージが画面に表示されていることを確認した. +3. ブラウザF12 consoleとターミナルのログを確認した. +4. 新しいメッセージを送信し,一覧に追加されることを確認した. + +### 結果 +- 画面に表示されたメッセージ(日付が2026/2/23のメッセージは方法1で送信したメッセージ.): +Tom +new message +2026/2/24 14:03:05 +Me +So data submitted previously is vanished! +2026/2/23 12:39:20 +Test test +i deleted DB used at day8 +2026/2/23 12:37:27 +Lisp-Alien +i ate a pudding +2026/2/23 12:36:37 + +- F12 console に表示されたログ: +[CLIENT] メッセージ一覧を取得します +[CLIENT] メッセージ一覧を取得しました: +Array(3) +0 +: +{id: 3, name: 'Me', content: 'So data submitted previously is vanished!', createdAt: '2026-02-23T03:39:20.368Z'} +1 +: +{id: 2, name: 'Test test', content: 'i deleted DB used at day8', createdAt: '2026-02-23T03:37:27.888Z'} +2 +: +{id: 1, name: 'Lisp-Alien', content: 'i ate a pudding', createdAt: '2026-02-23T03:36:37.150Z'} +length +: +3 +[[Prototype]] +: +Array(0) +(index):126 [CLIENT] 送信前データ: {name: 'Tom', content: 'new message'} +(index):138 [CLIENT] 送信後レスポンス: {success: true, message: {…}} +(index):95 [CLIENT] メッセージ一覧を取得します +(index):100 [CLIENT] メッセージ一覧を取得しました: +(4) [{…}, {…}, {…}, {…}] +0 +: +{id: 4, name: 'Tom', content: 'new message', createdAt: '2026-02-24T05:03:05.359Z'} +1 +: +{id: 3, name: 'Me', content: 'So data submitted previously is vanished!', createdAt: '2026-02-23T03:39:20.368Z'} +2 +: +{id: 2, name: 'Test test', content: 'i deleted DB used at day8', createdAt: '2026-02-23T03:37:27.888Z'} +3 +: +{id: 1, name: 'Lisp-Alien', content: 'i ate a pudding', createdAt: '2026-02-23T03:36:37.150Z'} +length +: +4 +[[Prototype]] +: +Array(0) + +- ターミナルに表示されたログ: +[SERVER] メッセージを取得しました: 3件 +[SERVER] 保存しました: { + id: 4, + name: 'Tom', + content: 'new message', + createdAt: 2026-02-24T05:03:05.359Z +} +[SERVER] メッセージを取得しました: 4件 + + +## 実験2 + +### 方法 +1. サーバーを停止した. +2. サーバーを再起動した. +3. ブラウザで `http://localhost:3000` を開いた. +4. 以前のメッセージが表示されるか確認した. + +### 予想 +サーバーを停止させても,データベースにはデータが残っているので以前のメッセージは表示される. + +### 結果 +ブラウザの画面には,以前に送ったメッセージが一覧に表示された. + +### 分かったこと +Read の流れは,まずクライアントがブラウザでページを読み込むと,ブラウザはfetchを使ってEpressサーバーへ,サーバーはprismaを使ってデータベースへ,データの取得を要求する.データベースが要求を受けると,dev.dbからデータを読み出し,データをprismaに送り,Expressサーバーにデータが渡される.ブラウザはfetchを使ってサーバーからres.jsonにまとめられたデータを受け取る. +Create の流れは,クライアントがブラウザでメッセージを送ると,ブラウザはfetchを使って,Expressサーバーへ,サーバーはPrismaを介してデータベースへ,データを送信する.データベースがデータを受け取ると,dev.dbにデータが保存される.保存が成功すると,データベースがPrismaを介してExpressサーバーへ返答を送り,ブラウザはfetchを使ってサーバーから返答を受け取る. +Read はclient -> server -> DBという経路で要求をし,DB -> server -> clientという経路でデータを送ったのに対し,Createはclient -> server -> DBという経路でデータを送り,DB -> server -> clientという経路で返答したので,両者ではデータの流れの方向が異なっている. \ No newline at end of file diff --git a/members/kurihara/phase2_web/day8_with_db/prisma/dev.db b/members/kurihara/phase2_web/day8_with_db/prisma/dev.db index ca2be8eec8db477f5cf53df64612ea184276003e..2b0d95d6a3dd867632a6cb5cdde2d1b0b4f6eb96 100644 GIT binary patch delta 236 zcmZozz}T>Wae_1>+e8^>Mz)O!OZ0hI_#+tjZ}G3@FXoTfEGXc?UoXkR${?)F8j_!z zms+lnn_66)n4Zcwr;oj--;9}+K`@@xH#In4AtkXSQK7grDL1pEBsE2$peVI0GrzPr zr&1xaSfMO2FS9r!HARtePREqy4Z2LM4D$A@A*sbB3MD`yQz0caCl#d4#Yv&G7)U3U z01d3P04g`0bS6NBk(EJFo7E??xIou2Co?rK6R03nAyJ{AG$kc7FCD0C5}O<^0|Nsi Z|7QmN&zl7eUh?yDGcrpv`a;~x0svarNJanv delta 45 scmZozz}T>Wae_1>(?l6(My8DkOZ1r-1U3sgJmQ}?L4u8!0SMq+03+iJSpWb4 diff --git a/members/kurihara/phase2_web/day8_with_db/public/index.html b/members/kurihara/phase2_web/day8_with_db/public/index.html index 754ed13..898d0f8 100644 --- a/members/kurihara/phase2_web/day8_with_db/public/index.html +++ b/members/kurihara/phase2_web/day8_with_db/public/index.html @@ -27,6 +27,17 @@ #status { min-height: 1.2em; } + #messageList { + margin-top: 24px; + padding-left: 20px; + } + #messageList li { + margin-bottom: 12px; + } + .meta { + color: #555; + font-size: 14px; + } @@ -40,11 +51,65 @@

Client / Server / Database メッセージ送信

+

メッセージ一覧

+
    + diff --git a/members/kurihara/phase2_web/day8_with_db/server.js b/members/kurihara/phase2_web/day8_with_db/server.js index 2fc3b3f..8eb8111 100644 --- a/members/kurihara/phase2_web/day8_with_db/server.js +++ b/members/kurihara/phase2_web/day8_with_db/server.js @@ -9,6 +9,22 @@ const PORT = 3000; app.use(express.json()); app.use(express.static(path.join(__dirname, 'public'))); +app.get('/api/messages', async (req, res) => { + try { + const messages = await prisma.message.findMany({ + orderBy: { + createdAt: 'desc', + }, + }); + + console.log(`[SERVER] メッセージを取得しました: ${messages.length}件`); + return res.json(messages); + } catch (error) { + console.error('[SERVER] 取得エラー:', error); + return res.status(500).json({ error: '取得に失敗しました' }); + } +}); + app.post('/api/messages', async (req, res) => { const name = typeof req.body.name === 'string' ? req.body.name.trim() : ''; const content = typeof req.body.content === 'string' ? req.body.content.trim() : '';