From 54424dda25e945471f04b9e044c7a2b319d4c0fc Mon Sep 17 00:00:00 2001 From: soray677 Date: Mon, 21 Jul 2025 08:30:45 +0900 Subject: [PATCH 01/28] =?UTF-8?q?=E9=96=8B=E7=99=BA=E5=85=A8=E8=88=AC?= =?UTF-8?q?=E3=83=AB=E3=83=BC=E3=83=AB=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/rules/dr001_general.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 docs/rules/dr001_general.md diff --git a/docs/rules/dr001_general.md b/docs/rules/dr001_general.md new file mode 100644 index 0000000..a65f7fe --- /dev/null +++ b/docs/rules/dr001_general.md @@ -0,0 +1,34 @@ +# 開発全般ルール + +## 命名規則 + +| 対象 | 命名規則 | 記法例 | +|------------------|----------------------|-----------------------------------| +| 変数名 | camelCase | `userName`, `itemCount` | +| 定数 | UPPER_SNAKE_CASE | `MAX_RETRY`, `API_URL` | | +| 関数名 | camelCase(動詞始まり) | `getUser()`, `fetchData()` | +| クラス名 | PascalCase | `UserService`, `AppConfig` | +| コンポーネント名 | PascalCase | `UserCard`, `LoginForm` | +| ファイル名 | PascalCase | `UserService.ts`, `LoginForm.vue` | +| ディレクトリ名 | kebab-case | `components`, `user-profile` | +| enum名 | PascalCase | `UserRole`, `HttpStatus` | +| enum値 | UPPER_SNAKE_CASE | `ADMIN`, `NOT_FOUND` | +| 型エイリアス名 | PascalCase + `Type` | `UserInfoType`, `ApiResponseType` | +| インターフェース名 | PascalCase + `Interface` | `UserInterface`, `ProductInterface` | +| URLパス | kebab-case | `/user-profile`, `/api-client` | + + +## コメント + +- 関数の先頭には以下例に示すようなJSDocのコメントを残すこと +```ts +/** + * @description テキストを分割 + * @param text テキスト + * @return 1文字ずつ分割した文字列配列 + */ +const splitText = (text: string) => { + return text.split('') +} + +``` From 4cdfa63d841b94e0813d64d05c332dedf9ab916c Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 22 Jul 2025 21:34:15 +0900 Subject: [PATCH 02/28] snipet add --- .vscode/custom.code-snippets | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .vscode/custom.code-snippets diff --git a/.vscode/custom.code-snippets b/.vscode/custom.code-snippets new file mode 100644 index 0000000..5179f10 --- /dev/null +++ b/.vscode/custom.code-snippets @@ -0,0 +1,16 @@ +{ + "vue template": { + "scope": "vue", + "prefix": "/vue-template", + "body": [ + "", + "", + "", + "", + "" + ], + } +} From 71c7f23f3fd7d93d95d80ddeb0af809e06605603 Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 22 Jul 2025 21:51:42 +0900 Subject: [PATCH 03/28] =?UTF-8?q?=E3=82=B9=E3=83=8B=E3=83=9A=E3=83=83?= =?UTF-8?q?=E3=83=88=E5=86=85=E5=AE=B9=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/custom.code-snippets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/custom.code-snippets b/.vscode/custom.code-snippets index 5179f10..159d700 100644 --- a/.vscode/custom.code-snippets +++ b/.vscode/custom.code-snippets @@ -1,5 +1,5 @@ { - "vue template": { + "vue-template": { "scope": "vue", "prefix": "/vue-template", "body": [ @@ -9,7 +9,7 @@ "", "", - "" ], } From 12aa00249183424ae2e7384d73f3f2f0f8923cf4 Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 22 Jul 2025 22:05:14 +0900 Subject: [PATCH 04/28] =?UTF-8?q?frontend=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .vscode/settings.json | 8 +- client/.dockerignore | 3 - client/Dockerfile | 8 - client/package.json | 4 +- client/public/vite.svg | 1 - client/src/App.vue | 44 ----- client/src/assets/images/app-icon-white.svg | 8 + client/src/assets/styles/index.scss | 5 + client/src/assets/vue.svg | 1 - client/src/components/00-commons/CImage.vue | 14 ++ client/src/components/01-atoms/image/Icon.vue | 21 ++ .../src/components/02-molecules/AppIcon.vue | 15 ++ .../src/components/03-orgnisms/AppSample.vue | 24 +++ .../04-templates/CommonTemplate.vue | 28 +++ client/src/components/05-pages/IndexPage.vue | 25 +++ client/src/components/App.vue | 10 + client/src/components/HelloWorld.vue | 41 ---- .../src/composables/router/RouteComponents.ts | 9 + client/src/composables/router/index.ts | 19 ++ .../src/configs/routes-config/MetaConfigs.ts | 9 + .../configs/routes-config/UrlPathConfigs.ts | 5 + client/src/main.ts | 9 +- client/src/style.css | 79 -------- client/src/types/element/ImageType.ts | 6 + client/src/types/route-types/MetaType.ts | 4 + client/tsconfig.json | 6 +- client/vite.config.ts | 13 ++ client/yarn.lock | 184 ++++++++++++++++++ doc/develop/coding-rule.md | 23 --- docker-compose.yml | 49 +---- package.json | 16 +- 32 files changed, 436 insertions(+), 256 deletions(-) delete mode 100644 client/.dockerignore delete mode 100644 client/Dockerfile delete mode 100644 client/public/vite.svg delete mode 100644 client/src/App.vue create mode 100644 client/src/assets/images/app-icon-white.svg create mode 100644 client/src/assets/styles/index.scss delete mode 100644 client/src/assets/vue.svg create mode 100644 client/src/components/00-commons/CImage.vue create mode 100644 client/src/components/01-atoms/image/Icon.vue create mode 100644 client/src/components/02-molecules/AppIcon.vue create mode 100644 client/src/components/03-orgnisms/AppSample.vue create mode 100644 client/src/components/04-templates/CommonTemplate.vue create mode 100644 client/src/components/05-pages/IndexPage.vue create mode 100644 client/src/components/App.vue delete mode 100644 client/src/components/HelloWorld.vue create mode 100644 client/src/composables/router/RouteComponents.ts create mode 100644 client/src/composables/router/index.ts create mode 100644 client/src/configs/routes-config/MetaConfigs.ts create mode 100644 client/src/configs/routes-config/UrlPathConfigs.ts delete mode 100644 client/src/style.css create mode 100644 client/src/types/element/ImageType.ts create mode 100644 client/src/types/route-types/MetaType.ts delete mode 100644 doc/develop/coding-rule.md diff --git a/.gitignore b/.gitignore index 4d3a46e..6ab5cc8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .env .tmp +.DS_Store diff --git a/.vscode/settings.json b/.vscode/settings.json index af62be0..09c7134 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,11 @@ "editor.codeActionsOnSave": { "source.fixAll.eslint": "always" }, - "github.copilot.chat.codeGeneration.useInstructionFiles": true + "github.copilot.chat.codeGeneration.useInstructionFiles": true, + "github.copilot.chat.pullRequestDescriptionGeneration.instructions": [ + { "text": "Always include a list of key changes." }, + ], + "github.copilot.chat.reviewSelection.instructions": [ + { "file": "doc/d001_general-rule.md" } + ] } diff --git a/client/.dockerignore b/client/.dockerignore deleted file mode 100644 index c4f24f4..0000000 --- a/client/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -.vscode -dist -node_modules diff --git a/client/Dockerfile b/client/Dockerfile deleted file mode 100644 index 592d47e..0000000 --- a/client/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM node:alpine - -COPY . /client -WORKDIR /client - -RUN yarn install - -EXPOSE ${CLIENT_PORT} diff --git a/client/package.json b/client/package.json index 83df283..a8a9345 100644 --- a/client/package.json +++ b/client/package.json @@ -11,12 +11,14 @@ "test": "echo 'Todo:test'" }, "dependencies": { - "vue": "^3.5.17" + "vue": "^3.5.17", + "vue-router": "^4.5.1" }, "devDependencies": { "@types/node": "^24.0.7", "@vitejs/plugin-vue": "^6.0.0", "@vue/tsconfig": "^0.7.0", + "sass-embedded": "^1.89.2", "typescript": "~5.8.3", "vite": "^7.0.0", "vue-tsc": "^2.2.10" diff --git a/client/public/vite.svg b/client/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/client/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/src/App.vue b/client/src/App.vue deleted file mode 100644 index daeb1d7..0000000 --- a/client/src/App.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/client/src/assets/images/app-icon-white.svg b/client/src/assets/images/app-icon-white.svg new file mode 100644 index 0000000..66f3c18 --- /dev/null +++ b/client/src/assets/images/app-icon-white.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/client/src/assets/styles/index.scss b/client/src/assets/styles/index.scss new file mode 100644 index 0000000..b413373 --- /dev/null +++ b/client/src/assets/styles/index.scss @@ -0,0 +1,5 @@ +* { + padding: 0; + margin: 0; + box-sizing: border-box; +} diff --git a/client/src/assets/vue.svg b/client/src/assets/vue.svg deleted file mode 100644 index 770e9d3..0000000 --- a/client/src/assets/vue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/src/components/00-commons/CImage.vue b/client/src/components/00-commons/CImage.vue new file mode 100644 index 0000000..4a7907d --- /dev/null +++ b/client/src/components/00-commons/CImage.vue @@ -0,0 +1,14 @@ + + + + + diff --git a/client/src/components/01-atoms/image/Icon.vue b/client/src/components/01-atoms/image/Icon.vue new file mode 100644 index 0000000..bdbb717 --- /dev/null +++ b/client/src/components/01-atoms/image/Icon.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/client/src/components/02-molecules/AppIcon.vue b/client/src/components/02-molecules/AppIcon.vue new file mode 100644 index 0000000..ea27b4e --- /dev/null +++ b/client/src/components/02-molecules/AppIcon.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/client/src/components/03-orgnisms/AppSample.vue b/client/src/components/03-orgnisms/AppSample.vue new file mode 100644 index 0000000..6653ad9 --- /dev/null +++ b/client/src/components/03-orgnisms/AppSample.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/client/src/components/04-templates/CommonTemplate.vue b/client/src/components/04-templates/CommonTemplate.vue new file mode 100644 index 0000000..75cef00 --- /dev/null +++ b/client/src/components/04-templates/CommonTemplate.vue @@ -0,0 +1,28 @@ + + + + + + diff --git a/client/src/components/05-pages/IndexPage.vue b/client/src/components/05-pages/IndexPage.vue new file mode 100644 index 0000000..f24e1e2 --- /dev/null +++ b/client/src/components/05-pages/IndexPage.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/client/src/components/App.vue b/client/src/components/App.vue new file mode 100644 index 0000000..6f223d8 --- /dev/null +++ b/client/src/components/App.vue @@ -0,0 +1,10 @@ + + + + + diff --git a/client/src/components/HelloWorld.vue b/client/src/components/HelloWorld.vue deleted file mode 100644 index b58e52b..0000000 --- a/client/src/components/HelloWorld.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - - - diff --git a/client/src/composables/router/RouteComponents.ts b/client/src/composables/router/RouteComponents.ts new file mode 100644 index 0000000..63fe330 --- /dev/null +++ b/client/src/composables/router/RouteComponents.ts @@ -0,0 +1,9 @@ + +import { UrlPathConfigs } from "@/configs/routes-config/UrlPathConfigs" +import type { Component } from 'vue'; +import IndexPage from '@/components/05-pages/IndexPage.vue'; + +export const RouteComponentRecord: Record = { + [UrlPathConfigs.INDEX]: IndexPage +} + diff --git a/client/src/composables/router/index.ts b/client/src/composables/router/index.ts new file mode 100644 index 0000000..56eb24c --- /dev/null +++ b/client/src/composables/router/index.ts @@ -0,0 +1,19 @@ +import { UrlPathConfigs } from "@/configs/routes-config/UrlPathConfigs" +import type { RouteRecordRaw } from "vue-router" +import { createRouter, createWebHistory } from 'vue-router' +import { MetaConfigs } from "@/configs/routes-config/MetaConfigs" +import { RouteComponentRecord } from "@composables/router/RouteComponents" + +const generateRouteRecordRaw = (path: UrlPathConfigs): RouteRecordRaw => ({ + path: path, + name: MetaConfigs[path].pageName, + component: RouteComponentRecord[path] +}) +const routeRecordRaws: RouteRecordRaw[] = Object.values(UrlPathConfigs).map((key) => generateRouteRecordRaw(key)) + + +export const router = createRouter({ + history: createWebHistory(), + routes: routeRecordRaws, +}) + diff --git a/client/src/configs/routes-config/MetaConfigs.ts b/client/src/configs/routes-config/MetaConfigs.ts new file mode 100644 index 0000000..ac5a8c6 --- /dev/null +++ b/client/src/configs/routes-config/MetaConfigs.ts @@ -0,0 +1,9 @@ +import { UrlPathConfigs } from "@/configs/routes-config/UrlPathConfigs" +import type { MetaType } from "@/types/route-types/MetaType" + +export const MetaConfigs: Record = { + [UrlPathConfigs.INDEX]: { + pageName: 'top', + description: 'トップページ' + } +} as const diff --git a/client/src/configs/routes-config/UrlPathConfigs.ts b/client/src/configs/routes-config/UrlPathConfigs.ts new file mode 100644 index 0000000..0b4d641 --- /dev/null +++ b/client/src/configs/routes-config/UrlPathConfigs.ts @@ -0,0 +1,5 @@ +export const UrlPathConfigs = { + INDEX: '/', +} as const +export type UrlPathConfigs = (typeof UrlPathConfigs)[keyof typeof UrlPathConfigs]; + diff --git a/client/src/main.ts b/client/src/main.ts index 2425c0f..0832f26 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -1,5 +1,8 @@ import { createApp } from 'vue' -import './style.css' -import App from './App.vue' +import '@assets/styles/index.scss' +import App from '@components/App.vue' +import { router } from '@composables/router' -createApp(App).mount('#app') +createApp(App) + .use(router) + .mount('#app') diff --git a/client/src/style.css b/client/src/style.css deleted file mode 100644 index f691315..0000000 --- a/client/src/style.css +++ /dev/null @@ -1,79 +0,0 @@ -:root { - font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -.card { - padding: 2em; -} - -#app { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/client/src/types/element/ImageType.ts b/client/src/types/element/ImageType.ts new file mode 100644 index 0000000..b498b48 --- /dev/null +++ b/client/src/types/element/ImageType.ts @@ -0,0 +1,6 @@ +export type ImageType = { + src: string, + width: number, + height: number, + alt: string +} diff --git a/client/src/types/route-types/MetaType.ts b/client/src/types/route-types/MetaType.ts new file mode 100644 index 0000000..0408e4d --- /dev/null +++ b/client/src/types/route-types/MetaType.ts @@ -0,0 +1,4 @@ +export type MetaType = { + pageName: string + description: string +} diff --git a/client/tsconfig.json b/client/tsconfig.json index c5e4d78..37ee1c7 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -14,7 +14,11 @@ "@/*": ["./src/*"], "@assets/*": ["./src/assets/*"], "@components/*": ["./src/components/*"], - "@types/*": ["./src/types/*"] + "@composables/*": ["./src/composables/*"], + "@configs/*": ["./src/configs/*"], + "@tests/*": ["./src/tests/*"], + "@types/*": ["./src/types/*"], + "@usecases/*": ["./src/usecases/*"] }, "baseUrl": ".", diff --git a/client/vite.config.ts b/client/vite.config.ts index 8293a05..a6dff1f 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -1,5 +1,6 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' +import path from 'path' const port = Number(process.env.CLIENT_PORT ?? 80) @@ -14,4 +15,16 @@ export default defineConfig({ interval: 1000, }, }, + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + '@assets': path.resolve(__dirname, './src/assets'), + '@components': path.resolve(__dirname, './src/components'), + '@composables': path.resolve(__dirname, './src/composables'), + '@configs': path.resolve(__dirname, './src/configs'), + '@tests': path.resolve(__dirname, './src/tests'), + '@types': path.resolve(__dirname, './src/types'), + '@usecases': path.resolve(__dirname, './src/usecases'), + }, + }, }) diff --git a/client/yarn.lock b/client/yarn.lock index eac3695..7987ee5 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -27,6 +27,11 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" +"@bufbuild/protobuf@^2.5.0": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-2.6.1.tgz#6d80aa2c0bf6a493d66609ff1ad84d1a0c15acf5" + integrity sha512-DaG6XlyKpz08bmHY5SGX2gfIllaqtDJ/KwVoxsmP22COOLYwDBe7yD3DZGwXem/Xq7QOc9cuR7R3MpAv5CFfDw== + "@esbuild/aix-ppc64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18" @@ -352,6 +357,11 @@ de-indent "^1.0.2" he "^1.2.0" +"@vue/devtools-api@^6.6.4": + version "6.6.4" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343" + integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g== + "@vue/language-core@2.2.10": version "2.2.10" resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.2.10.tgz#5ae1e71a4e16dd59d1e4bac167f4b9c8c04d9f17" @@ -426,6 +436,16 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" +buffer-builder@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/buffer-builder/-/buffer-builder-0.2.0.tgz#3322cd307d8296dab1f604618593b261a3fade8f" + integrity sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg== + +colorjs.io@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/colorjs.io/-/colorjs.io-0.5.2.tgz#63b20139b007591ebc3359932bef84628eb3fcef" + integrity sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw== + csstype@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" @@ -487,11 +507,21 @@ fsevents@~2.3.2, fsevents@~2.3.3: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +immutable@^5.0.2: + version "5.1.3" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.3.tgz#e6486694c8b76c37c063cca92399fa64098634d4" + integrity sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg== + magic-string@^0.30.17: version "0.30.17" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" @@ -569,11 +599,148 @@ rollup@^4.40.0: "@rollup/rollup-win32-x64-msvc" "4.44.1" fsevents "~2.3.2" +rxjs@^7.4.0: + version "7.8.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" + integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== + dependencies: + tslib "^2.1.0" + +sass-embedded-android-arm64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.89.2.tgz#97546fbeeae3c7461435309b6b7022db37f65ea2" + integrity sha512-+pq7a7AUpItNyPu61sRlP6G2A8pSPpyazASb+8AK2pVlFayCSPAEgpwpCE9A2/Xj86xJZeMizzKUHxM2CBCUxA== + +sass-embedded-android-arm@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-android-arm/-/sass-embedded-android-arm-1.89.2.tgz#02be468f924f2f9d6e93816507d3f3f200ff3836" + integrity sha512-oHAPTboBHRZlDBhyRB6dvDKh4KvFs+DZibDHXbkSI6dBZxMTT+Yb2ivocHnctVGucKTLQeT7+OM5DjWHyynL/A== + +sass-embedded-android-riscv64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.89.2.tgz#d15899446b035cabacb49d20689e05823a144bc8" + integrity sha512-HfJJWp/S6XSYvlGAqNdakeEMPOdhBkj2s2lN6SHnON54rahKem+z9pUbCriUJfM65Z90lakdGuOfidY61R9TYg== + +sass-embedded-android-x64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-android-x64/-/sass-embedded-android-x64-1.89.2.tgz#d76c99035a0f2835006dba6cc52f13fa41a3113a" + integrity sha512-BGPzq53VH5z5HN8de6jfMqJjnRe1E6sfnCWFd4pK+CAiuM7iw5Fx6BQZu3ikfI1l2GY0y6pRXzsVLdp/j4EKEA== + +sass-embedded-darwin-arm64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.89.2.tgz#57150b77676d4d82e84b2198f5f6983418fff04e" + integrity sha512-UCm3RL/tzMpG7DsubARsvGUNXC5pgfQvP+RRFJo9XPIi6elopY5B6H4m9dRYDpHA+scjVthdiDwkPYr9+S/KGw== + +sass-embedded-darwin-x64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.89.2.tgz#b0b1c5abb1d057daaa8f8a1e2b2497478865a22d" + integrity sha512-D9WxtDY5VYtMApXRuhQK9VkPHB8R79NIIR6xxVlN2MIdEid/TZWi1MHNweieETXhWGrKhRKglwnHxxyKdJYMnA== + +sass-embedded-linux-arm64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.89.2.tgz#f4d964d9773acd5e065513837d0412753e4a02a1" + integrity sha512-2N4WW5LLsbtrWUJ7iTpjvhajGIbmDR18ZzYRywHdMLpfdPApuHPMDF5CYzHbS+LLx2UAx7CFKBnj5LLjY6eFgQ== + +sass-embedded-linux-arm@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.89.2.tgz#e9cd53cb299e6e8cada56acc801b8477f9876fb0" + integrity sha512-leP0t5U4r95dc90o8TCWfxNXwMAsQhpWxTkdtySDpngoqtTy3miMd7EYNYd1znI0FN1CBaUvbdCMbnbPwygDlA== + +sass-embedded-linux-musl-arm64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.89.2.tgz#e501d00d9cf050fcbb261b53255af85fa7c39c73" + integrity sha512-nTyuaBX6U1A/cG7WJh0pKD1gY8hbg1m2SnzsyoFG+exQ0lBX/lwTLHq3nyhF+0atv7YYhYKbmfz+sjPP8CZ9lw== + +sass-embedded-linux-musl-arm@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.89.2.tgz#1b073158532b72597522ebffef0658374c9c04ba" + integrity sha512-Z6gG2FiVEEdxYHRi2sS5VIYBmp17351bWtOCUZ/thBM66+e70yiN6Eyqjz80DjL8haRUegNQgy9ZJqsLAAmr9g== + +sass-embedded-linux-musl-riscv64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.89.2.tgz#06542e8946885d09f2cea939092d145aeeee6d39" + integrity sha512-N6oul+qALO0SwGY8JW7H/Vs0oZIMrRMBM4GqX3AjM/6y8JsJRxkAwnfd0fDyK+aICMFarDqQonQNIx99gdTZqw== + +sass-embedded-linux-musl-x64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.89.2.tgz#2fd441597a95f57d70d0c46e0e8c18ab4f52c596" + integrity sha512-K+FmWcdj/uyP8GiG9foxOCPfb5OAZG0uSVq80DKgVSC0U44AdGjvAvVZkrgFEcZ6cCqlNC2JfYmslB5iqdL7tg== + +sass-embedded-linux-riscv64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.89.2.tgz#eeea2fbcbd5b575391a5b702092c0e8cc03f661c" + integrity sha512-g9nTbnD/3yhOaskeqeBQETbtfDQWRgsjHok6bn7DdAuwBsyrR3JlSFyqKc46pn9Xxd9SQQZU8AzM4IR+sY0A0w== + +sass-embedded-linux-x64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.89.2.tgz#9a58127a312e7c011e3a20470ff5707b9aa78536" + integrity sha512-Ax7dKvzncyQzIl4r7012KCMBvJzOz4uwSNoyoM5IV6y5I1f5hEwI25+U4WfuTqdkv42taCMgpjZbh9ERr6JVMQ== + +sass-embedded-win32-arm64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.89.2.tgz#7e9ddcb5abe3a8eca370909686da37da60f97c85" + integrity sha512-j96iJni50ZUsfD6tRxDQE2QSYQ2WrfHxeiyAXf41Kw0V4w5KYR/Sf6rCZQLMTUOHnD16qTMVpQi20LQSqf4WGg== + +sass-embedded-win32-x64@1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.89.2.tgz#9f5c71b611a8edbc40e1c8cc47bd20d8a4bdf13a" + integrity sha512-cS2j5ljdkQsb4PaORiClaVYynE9OAPZG/XjbOMxpQmjRIf7UroY4PEIH+Waf+y47PfXFX9SyxhYuw2NIKGbEng== + +sass-embedded@^1.89.2: + version "1.89.2" + resolved "https://registry.yarnpkg.com/sass-embedded/-/sass-embedded-1.89.2.tgz#bf6cd7d6ace06f0430bbf3913c95a8be83367883" + integrity sha512-Ack2K8rc57kCFcYlf3HXpZEJFNUX8xd8DILldksREmYXQkRHI879yy8q4mRDJgrojkySMZqmmmW1NxrFxMsYaA== + dependencies: + "@bufbuild/protobuf" "^2.5.0" + buffer-builder "^0.2.0" + colorjs.io "^0.5.0" + immutable "^5.0.2" + rxjs "^7.4.0" + supports-color "^8.1.1" + sync-child-process "^1.0.2" + varint "^6.0.0" + optionalDependencies: + sass-embedded-android-arm "1.89.2" + sass-embedded-android-arm64 "1.89.2" + sass-embedded-android-riscv64 "1.89.2" + sass-embedded-android-x64 "1.89.2" + sass-embedded-darwin-arm64 "1.89.2" + sass-embedded-darwin-x64 "1.89.2" + sass-embedded-linux-arm "1.89.2" + sass-embedded-linux-arm64 "1.89.2" + sass-embedded-linux-musl-arm "1.89.2" + sass-embedded-linux-musl-arm64 "1.89.2" + sass-embedded-linux-musl-riscv64 "1.89.2" + sass-embedded-linux-musl-x64 "1.89.2" + sass-embedded-linux-riscv64 "1.89.2" + sass-embedded-linux-x64 "1.89.2" + sass-embedded-win32-arm64 "1.89.2" + sass-embedded-win32-x64 "1.89.2" + source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +sync-child-process@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/sync-child-process/-/sync-child-process-1.0.2.tgz#45e7c72e756d1243e80b547ea2e17957ab9e367f" + integrity sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA== + dependencies: + sync-message-port "^1.0.0" + +sync-message-port@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sync-message-port/-/sync-message-port-1.1.3.tgz#6055c565ee8c81d2f9ee5aae7db757e6d9088c0c" + integrity sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg== + tinyglobby@^0.2.14: version "0.2.14" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.14.tgz#5280b0cf3f972b050e74ae88406c0a6a58f4079d" @@ -582,6 +749,11 @@ tinyglobby@^0.2.14: fdir "^6.4.4" picomatch "^4.0.2" +tslib@^2.1.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + typescript@~5.8.3: version "5.8.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" @@ -592,6 +764,11 @@ undici-types@~7.8.0: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.8.0.tgz#de00b85b710c54122e44fbfd911f8d70174cd294" integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw== +varint@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" + integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== + vite@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/vite/-/vite-7.0.0.tgz#5675bb4c956dd9da932583628e7758ab09fe761f" @@ -611,6 +788,13 @@ vscode-uri@^3.0.8: resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.1.0.tgz#dd09ec5a66a38b5c3fffc774015713496d14e09c" integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ== +vue-router@^4.5.1: + version "4.5.1" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.5.1.tgz#47bffe2d3a5479d2886a9a244547a853aa0abf69" + integrity sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw== + dependencies: + "@vue/devtools-api" "^6.6.4" + vue-tsc@^2.2.10: version "2.2.10" resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-2.2.10.tgz#7b51a666cb90788884efd0caedc69fc1fc9c5b78" diff --git a/doc/develop/coding-rule.md b/doc/develop/coding-rule.md deleted file mode 100644 index 318dfcd..0000000 --- a/doc/develop/coding-rule.md +++ /dev/null @@ -1,23 +0,0 @@ -
- -# コーディング規約 - -
- -## 命名規則 - -| 対象 | 命名規則 | 例 | 備考 | -| :----------------: | :--------------------: | :---------------------: | :----------------------: | -| ファイル名 | `.`つなぎ | user.usecase.ts | 役割を拡張子との間に記載 | -| 変数名 | キャメルケース | userName | | -| 定数名 | アッパースネークケース | USER_GENDER_MEN = 'men' | | -| 関数名 | キャメルケース | fetchUserData() | 動詞から始める | -| クラス名 | パスカルケース | UserService | | -| インターフェース名 | パスカルケース | UserIF | 末尾に IF | -| 型 | パスカルケース | UserType | 末尾に Type | -| enum | パスカルケース | UserEnum | 末尾に Enum | -| enum のメンバー | アッパースネークケース | USER | | -| コンポーネント名 | パスカルケース | UserCard | | -| CSS(SCSS) | ケバブケース | user-card | | -| ID 属性 (HTML) | ケバブケース | user-list | | -| ディレクトリ名 | パスカルケース | UserProfile | | diff --git a/docker-compose.yml b/docker-compose.yml index 36a0a2f..c1e2117 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,55 +6,10 @@ services: volumes: - ./:/app - /app/node_modules - env_file: - - .env - tty: true - - infra: - build: - context: './infra' - working_dir: /infra - volumes: - - ./infra:/infra - - ./common:/common - - /infra/node_modules - - ./tsconfig.json:/tsconfig.json:ro - env_file: - .env - command: yarn watch - depends_on: - - root - - server: - build: - context: './server' - working_dir: /server - volumes: - - ./server:/server - - ./common:/common - - /server/node_modules - - ./tsconfig.json:/tsconfig.json:ro - ports: - - "${SERVER_PORT}:${SERVER_PORT}" - env_file: - - .env - command: yarn dev - depends_on: - - root - - client: - build: - context: './client' - working_dir: /client - depends_on: - - server - volumes: - - ./client:/client - - /client/node_modules - - ./common:/common - - ./tsconfig.json:/tsconfig.json:ro ports: - "${CLIENT_PORT}:${CLIENT_PORT}" + - "${SERVER_PORT}:${SERVER_PORT}" env_file: - .env command: yarn dev + tty: true diff --git a/package.json b/package.json index d0effa4..9b9c35f 100644 --- a/package.json +++ b/package.json @@ -4,16 +4,26 @@ "repository": "git@github.com:SoraY677/web-dev-template.git", "author": "soray677 ", "license": "MIT", + "private": true, + "workspaces": [ + "client/*", + "server/*", + "infra/*" + ], "scripts": { - "setup": "run-s setup:*", + "setup": "run-p setup:*", "setup:client": "yarn --cwd client 'install'", "setup:server": "yarn --cwd server 'install'", "setup:infra": "yarn --cwd infra 'install'", - "build": "run-s build:*", + "dev": "run-p dev:*", + "dev:client": "yarn --cwd client 'dev'", + "dev:server": "yarn --cwd server 'dev'", + "dev:infra": "yarn --cwd infra 'watch'", + "build": "run-p build:*", "build:client": "yarn --cwd client 'build'", "build:server": "yarn --cwd server 'build'", "build:infra": "yarn --cwd infra 'build'", - "test": "run-s test:*", + "test": "run-p test:*", "test:client": "yarn --cwd client 'test'", "test:server": "yarn --cwd server 'test'", "test:infra": "yarn --cwd infra 'test'", From 3284648adfed501b17b1191ef29292a027703fd1 Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 22 Jul 2025 22:50:02 +0900 Subject: [PATCH 05/28] client add --- client/README.md | 80 +++++++++++++++++++ client/public/.gitkeep | 0 .../dr001_general.md => general-rules.md} | 1 + 3 files changed, 81 insertions(+) create mode 100644 client/README.md create mode 100644 client/public/.gitkeep rename docs/{rules/dr001_general.md => general-rules.md} (94%) diff --git a/client/README.md b/client/README.md new file mode 100644 index 0000000..58caa14 --- /dev/null +++ b/client/README.md @@ -0,0 +1,80 @@ +# クライアント開発ルール + +## コマンド + +```sh +# ローカル起動 +yarn dev + +# ビルド +yarn build + +# テスト +yarn test +``` + +## 主要なディレクトリ構成 + +- `public/`: 臨時的なデータ置き場(自動生成物など) +- `src/` + - `assets/`: アプリケーションと結合するような基本的な静的ファイル置き場 + - `components/`: アトミックデザインを基にしたコンポーネント集約 + - `00-commons` + - `01-atoms` + - `02-molecules` + - `03-orgnisms` + - `04-templates` + - `05-pages` + - `composables/`: VueComposable依存のラップ関数置き場 + - `router`: VueRouter依存 + - `state`: Vue状態遷移ライブラリ(Pinia依存) + - `configs/`: 設定値などの定義 + - `tests/`: テスト(Vitest)のファイル置き場 + - `types/`: 型 + - `usecases/`: 共通・複雑・詳細な処理等の抽出 + +## 開発ルール + +### アトミックデザインを基にしたコンポーネント分け + +
+ + アトミックデザインについて + + 参考:https://spice-factory.co.jp/web/about-atmicdesign/ + + > Lv.1 原子 / Atoms + “原子”とは、UIの最小単位となるデザインパーツを指します。当社では、最小の html タグとほぼ同等の意味で解釈しています。ボタンやアイコン、フォントなどが原子に値します。こうした最小単位からデザインを構築し、最終的なUIへと組み合わせていきます。 + + >Lv.2 分子 / Molecules + “分子”とは、いくつかの原子を組み合わせた集合体を指します。分子単位での使い回しや、原子の集合にUIパーツ的な意味づけ行うといった目的があります。また、分子はデザインや UI の観点から再利用可能な単位で汎用性が高い特徴があります。 + + > Lv.3 生体 / Organisms + “生体”とは、単体で機能するアプリケーションパーツ(widget)のことで、原子と分子を組み合わせて構築されます。特定の役割にしか使用されず、他の役割での再利用は行われないという特徴があります。生体ではサーバーとの通信やローカルストレージへのアクセスなども行われ、生体単位で役割に沿った命名を行います。 + + > Lv.4 テンプレート / Templates + “テンプレート”とは、画面のレイアウトのことです。原子と分子、生体を組み合わせて作成します。この段階では、まだ具体的なテキストや画像は挿入されません。また当社でのテンプレートは、フロントエンドフレームワークの Next.js の pages で表現しています。 + + > Lv.5 ページ / Pages +“ページ”とは、ユーザー側に表示される最終的な画面のことです。テンプレートにテキストや画像を挿入することで、実際のサービスイメージを明確にできます。また、生体やテンプレートの段階では発見できなかった抜け漏れに気づくことができます。 +
+
+ +`src/components/`配下のコンポーネント役割区分は以の通り + +|ディレクトリ名|アトミックデザインとの関連付け|参照可能|状態管理| +|:----|:---:|:----|:---:| +|`00-commons`|-||| +|`01-atoms`|ATOMS(原子)|`00`|| +|`02-molecules`|MOLECULES(分子)|`00`, `01`|| +|`03-orgnisms`|ORGANISMS(有機体)|`01`, `02`|✅| +|`04-templates`|TEMPLATE(テンプレート)|`03`|✅| +|`05-pages`|PAGE(ページ)|`03`,`04`|✅| + +### 状態管理 + +Todo + +### テスト + +Todo diff --git a/client/public/.gitkeep b/client/public/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/rules/dr001_general.md b/docs/general-rules.md similarity index 94% rename from docs/rules/dr001_general.md rename to docs/general-rules.md index a65f7fe..a21aa57 100644 --- a/docs/rules/dr001_general.md +++ b/docs/general-rules.md @@ -16,6 +16,7 @@ | 型エイリアス名 | PascalCase + `Type` | `UserInfoType`, `ApiResponseType` | | インターフェース名 | PascalCase + `Interface` | `UserInterface`, `ProductInterface` | | URLパス | kebab-case | `/user-profile`, `/api-client` | +| コンポーネント名 | PascalCase | `UserCard`, `LoginForm` | ## コメント From 1c89ab75a4bcf54a627153064050b8760dcb7bb8 Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 22 Jul 2025 22:57:13 +0900 Subject: [PATCH 06/28] =?UTF-8?q?readme=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 79ad590..d9e0966 100644 --- a/README.md +++ b/README.md @@ -22,34 +22,36 @@ #### 起動・停止 ```sh -docker compose up -d # 通常起動 -docker compose up -d --build # ビルド付起動(node_modulesの追加時等) +docker compose up -d # 起動 +docker compose up -d --build # ビルド起動 + +docker compose restart # 再起動 docker compose down # 停止 +``` -docker compose restart # 再起動 +#### コンテナログイン + +```sh +docker compose exec root sh ``` #### セットアップ ```sh -docker compose exec root yarn setup # 一括 -docker compose exec {service} yarn setup # 各サービスごと +docker compose exec root yarn setup ``` #### ビルド ```sh -docker compose exec root yarn build # 一括 -docker compose exec {service} yarn build # 各サービスごと +docker compose exec root yarn build ``` #### テスト -- 一括 ```sh -docker compose exec root yarn test # 一括 -docker compose exec {service} yarn test # 各サービスごと +docker compose exec root yarn test ``` #### リント @@ -57,7 +59,7 @@ docker compose exec {service} yarn test # 各サービスごと ```sh docker compose exec root yarn lint # チェックのみ docker compose exec root yarn lint:fix # 矯正含む -``` +`` ### 各サービスエンドポイント From 8276bec7401f93e228994b8bc773d8f37b8df39c Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 22 Jul 2025 23:17:22 +0900 Subject: [PATCH 07/28] =?UTF-8?q?pinia=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/README.md | 40 ++++++++- client/package.json | 1 + .../src/components/03-orgnisms/AppSample.vue | 8 ++ client/src/composables/state/CounterState.ts | 22 +++++ client/src/main.ts | 2 + client/src/{ => types/global}/vite-env.d.ts | 0 client/yarn.lock | 83 +++++++++++++++++++ 7 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 client/src/composables/state/CounterState.ts rename client/src/{ => types/global}/vite-env.d.ts (100%) diff --git a/client/README.md b/client/README.md index 58caa14..6f42a6b 100644 --- a/client/README.md +++ b/client/README.md @@ -26,8 +26,8 @@ yarn test - `04-templates` - `05-pages` - `composables/`: VueComposable依存のラップ関数置き場 - - `router`: VueRouter依存 - - `state`: Vue状態遷移ライブラリ(Pinia依存) + - `router/`: VueRouter依存 + - `state/`: Vue状態遷移ライブラリ(Pinia依存) - `configs/`: 設定値などの定義 - `tests/`: テスト(Vitest)のファイル置き場 - `types/`: 型 @@ -71,9 +71,43 @@ yarn test |`04-templates`|TEMPLATE(テンプレート)|`03`|✅| |`05-pages`|PAGE(ページ)|`03`,`04`|✅| +### ルーティング + +- ライブラリ: [Vue-Router](https://v3.router.vuejs.org/ja/guide/) +- `src/composables/router/RouterComponent.ts`および設定ファイルでルーティング設定を追加することでパス追加可能 + ### 状態管理 -Todo +- ライブラリ: [Pinia](https://pinia.vuejs.org/) +- `src/composables/state/` 配下に必要な状態管理ファイルを必要に応じて定義 + - ファイル名は`xxxState.ts` + - 関数名は`useXXXStore` + + +```typescript:CounterState.ts +import { defineStore } from 'pinia' + +interface CounterState { + count: number; +} + +export const useCounterStore = defineStore('counter', { + state: (): CounterState => ({ + count: 0, + }), + actions: { + increment() { + this.count++ + }, + decrement() { + this.count-- + }, + reset() { + this.count = 0 + }, + }, +}) +``` ### テスト diff --git a/client/package.json b/client/package.json index a8a9345..4c015e0 100644 --- a/client/package.json +++ b/client/package.json @@ -11,6 +11,7 @@ "test": "echo 'Todo:test'" }, "dependencies": { + "pinia": "^3.0.3", "vue": "^3.5.17", "vue-router": "^4.5.1" }, diff --git a/client/src/components/03-orgnisms/AppSample.vue b/client/src/components/03-orgnisms/AppSample.vue index 6653ad9..92a3372 100644 --- a/client/src/components/03-orgnisms/AppSample.vue +++ b/client/src/components/03-orgnisms/AppSample.vue @@ -2,12 +2,20 @@

RAXSY APPS

+

+ +

diff --git a/client/src/composables/head/Meta.ts b/client/src/composables/head/Meta.ts new file mode 100644 index 0000000..d0c6aba --- /dev/null +++ b/client/src/composables/head/Meta.ts @@ -0,0 +1,48 @@ + import type { MetaType } from '@/types/route-types/MetaType' + import { useHead } from '@unhead/vue' + + export const useMeta = (root: string) => ({ + setMeta: (meta: MetaType, path: string) => { + useHead({ + title: `${meta.title}`, + meta: [ + { + name: 'description', + content: `${meta.description}`, + }, + { + name: 'og:title', + content: `${meta.title}`, + }, + { + name: 'og:description', + content: `${meta.description}}`, + }, + { + name: 'og:image', + content: `${root}/img/ogp.png`, + }, + { + name: 'og:url', + content: `${root}${path}`, + }, + { + name: 'twitter:card', + content: 'summary_large_image', + }, + { + name: 'twitter:title', + content: `${meta.title}`, + }, + { + name: 'twitter:description', + content: `${meta.description}`, + }, + { + name: 'twitter:image', + content: `${root}/img/ogp.png`, + }, + ] + }) + } + }) diff --git a/client/src/composables/router/index.ts b/client/src/composables/router/index.ts index 56eb24c..89ee466 100644 --- a/client/src/composables/router/index.ts +++ b/client/src/composables/router/index.ts @@ -3,6 +3,7 @@ import type { RouteRecordRaw } from "vue-router" import { createRouter, createWebHistory } from 'vue-router' import { MetaConfigs } from "@/configs/routes-config/MetaConfigs" import { RouteComponentRecord } from "@composables/router/RouteComponents" +import { useRoute as _useRoute } from "vue-router" const generateRouteRecordRaw = (path: UrlPathConfigs): RouteRecordRaw => ({ path: path, @@ -17,3 +18,9 @@ export const router = createRouter({ routes: routeRecordRaws, }) +export const useRoute = () => { + const route = _useRoute() + return { + getCurrentPath: () => route.path + } +} diff --git a/client/src/configs/EnvConfig.ts b/client/src/configs/EnvConfig.ts new file mode 100644 index 0000000..a05df94 --- /dev/null +++ b/client/src/configs/EnvConfig.ts @@ -0,0 +1,3 @@ +export const envConfig = { + domain: import.meta.env.VITE_DOMAIN ?? 'http://localhost' +} diff --git a/client/src/configs/routes-config/MetaConfigs.ts b/client/src/configs/routes-config/MetaConfigs.ts index ac5a8c6..efd96e5 100644 --- a/client/src/configs/routes-config/MetaConfigs.ts +++ b/client/src/configs/routes-config/MetaConfigs.ts @@ -4,6 +4,7 @@ import type { MetaType } from "@/types/route-types/MetaType" export const MetaConfigs: Record = { [UrlPathConfigs.INDEX]: { pageName: 'top', - description: 'トップページ' + title: 'アプリトップページ(todo)', + description: 'トップページ(todo)' } } as const diff --git a/client/src/main.ts b/client/src/main.ts index 9d9f48d..b3b77cd 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -3,8 +3,10 @@ import '@assets/styles/index.scss' import App from '@components/App.vue' import { router } from '@composables/router' import { createPinia } from 'pinia' +import { createHead } from '@unhead/vue/client' createApp(App) .use(router) + .use(createHead()) .use(createPinia()) .mount('#app') diff --git a/client/src/types/route-types/MetaType.ts b/client/src/types/route-types/MetaType.ts index 0408e4d..ce32694 100644 --- a/client/src/types/route-types/MetaType.ts +++ b/client/src/types/route-types/MetaType.ts @@ -1,4 +1,5 @@ export type MetaType = { pageName: string + title: string description: string } diff --git a/client/vite.config.ts b/client/vite.config.ts index a6dff1f..6d54424 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -1,9 +1,12 @@ -import { defineConfig } from 'vite' +import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' const port = Number(process.env.CLIENT_PORT ?? 80) + +process.env.VITE_DOMAIN = process.env.DOMAIN + // https://vite.dev/config/ export default defineConfig({ plugins: [vue()], diff --git a/client/yarn.lock b/client/yarn.lock index 5cfb517..40c83aa 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -291,6 +291,14 @@ dependencies: undici-types "~7.8.0" +"@unhead/vue@^2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@unhead/vue/-/vue-2.0.12.tgz#65b4b3d61f928d6969ff33728d53311c5b31c8ee" + integrity sha512-WFaiCVbBd39FK6Bx3GQskhgT9s45Vjx6dRQegYheVwU1AnF+FAfJVgWbrl21p6fRJcLAFp0xDz6wE18JYBM0eQ== + dependencies: + hookable "^5.5.3" + unhead "2.0.12" + "@vitejs/plugin-vue@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-6.0.0.tgz#3f8c3cdeb709d9646770eebead1babe6409bf059" @@ -1047,6 +1055,13 @@ undici-types@~7.8.0: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.8.0.tgz#de00b85b710c54122e44fbfd911f8d70174cd294" integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw== +unhead@2.0.12: + version "2.0.12" + resolved "https://registry.yarnpkg.com/unhead/-/unhead-2.0.12.tgz#70ad5a098890c8de493994b3ee354bc84f173264" + integrity sha512-5oo0lwz81XDXCmrHGzgmbaNOxM8R9MZ3FkEs2ROHeW8e16xsrv7qXykENlISrcxr3RLPHQEsD1b6js9P2Oj/Ow== + dependencies: + hookable "^5.5.3" + varint@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" diff --git a/server/src/index.ts b/server/src/index.ts index bbd9a61..7c71cdb 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -11,5 +11,5 @@ serve({ fetch: app.fetch, port: Number(process.env.SERVER_PORT ?? 8000), }, (info) => { - console.log(`Server is running on http://localhost:${info.port}`) + console.info(`Server is running on http://localhost:${info.port}`) }) From 60eeceb0b03d8382b71686f8010d327f6ec490b4 Mon Sep 17 00:00:00 2001 From: soray677 Date: Wed, 23 Jul 2025 22:37:05 +0900 Subject: [PATCH 12/28] =?UTF-8?q?Vuetify=E5=B0=8E=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/.vscode/extensions.json | 2 +- client/package.json | 5 ++- .../src/components/03-orgnisms/AppSample.vue | 9 +++-- client/src/main.ts | 4 +++ client/vite.config.ts | 3 +- client/yarn.lock | 33 ++++++++++++++++++- 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/client/.vscode/extensions.json b/client/.vscode/extensions.json index a7cea0b..d180a83 100644 --- a/client/.vscode/extensions.json +++ b/client/.vscode/extensions.json @@ -1,3 +1,3 @@ { - "recommendations": ["Vue.volar"] + "recommendations": ["Vue.volar", "vuetifyjs.vuetify-vscode"] } diff --git a/client/package.json b/client/package.json index b5d4101..65b58b1 100644 --- a/client/package.json +++ b/client/package.json @@ -11,6 +11,7 @@ "test": "vitest run" }, "dependencies": { + "@mdi/font": "^7.4.47", "@unhead/vue": "^2.0.12", "pinia": "^3.0.3", "vue": "^3.5.17", @@ -23,7 +24,9 @@ "sass-embedded": "^1.89.2", "typescript": "~5.8.3", "vite": "^7.0.0", + "vite-plugin-vuetify": "^2.1.1", "vitest": "^3.2.4", - "vue-tsc": "^2.2.10" + "vue-tsc": "^2.2.10", + "vuetify": "^3.9.2" } } diff --git a/client/src/components/03-orgnisms/AppSample.vue b/client/src/components/03-orgnisms/AppSample.vue index 92a3372..b2b8a82 100644 --- a/client/src/components/03-orgnisms/AppSample.vue +++ b/client/src/components/03-orgnisms/AppSample.vue @@ -2,11 +2,10 @@

RAXSY APPS

-

- -

+ + + count: {{ counterState.count }} +
diff --git a/client/src/main.ts b/client/src/main.ts index b3b77cd..a962e83 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -4,9 +4,13 @@ import App from '@components/App.vue' import { router } from '@composables/router' import { createPinia } from 'pinia' import { createHead } from '@unhead/vue/client' +import { createVuetify } from 'vuetify' +import '@mdi/font/css/materialdesignicons.css' +import 'vuetify/styles/main.css' createApp(App) .use(router) .use(createHead()) .use(createPinia()) + .use(createVuetify()) .mount('#app') diff --git a/client/vite.config.ts b/client/vite.config.ts index 6d54424..ed3f534 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -1,4 +1,5 @@ import { defineConfig } from 'vite' +import vuetify from 'vite-plugin-vuetify' import vue from '@vitejs/plugin-vue' import path from 'path' @@ -9,7 +10,7 @@ process.env.VITE_DOMAIN = process.env.DOMAIN // https://vite.dev/config/ export default defineConfig({ - plugins: [vue()], + plugins: [vue(), vuetify({ autoImport: true }),], server: { host: true, port, diff --git a/client/yarn.lock b/client/yarn.lock index 40c83aa..afee6e7 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -162,6 +162,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.2.tgz#4f25c8f17f28ccf70ed16e03f8fbf6d3998cb8fd" integrity sha512-gKYheCylLIedI+CSZoDtGkFV9YEBxRRVcfCH7OfAqh4TyUyRjEE6WVE/aXDXX0p8BIe/QgLcaAoI0220KRRFgg== +"@mdi/font@^7.4.47": + version "7.4.47" + resolved "https://registry.yarnpkg.com/@mdi/font/-/font-7.4.47.tgz#2ae522867da3a5c88b738d54b403eb91471903af" + integrity sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw== + "@rolldown/pluginutils@1.0.0-beta.19": version "1.0.0-beta.19" resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz#fc3b95145a8e7a3bf92754269d8e4f40eea8a244" @@ -527,6 +532,13 @@ resolved "https://registry.yarnpkg.com/@vue/tsconfig/-/tsconfig-0.7.0.tgz#67044c847b7a137b8cbfd6b23104c36dbaf80d1d" integrity sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg== +"@vuetify/loader-shared@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@vuetify/loader-shared/-/loader-shared-2.1.0.tgz#29410dce04a78fa9cd40c4d9bc417b8d61ce5103" + integrity sha512-dNE6Ceym9ijFsmJKB7YGW0cxs7xbYV8+1LjU6jd4P14xOt/ji4Igtgzt0rJFbxu+ZhAzqz853lhB0z8V9Dy9cQ== + dependencies: + upath "^2.0.1" + alien-signals@^1.0.3: version "1.0.13" resolved "https://registry.yarnpkg.com/alien-signals/-/alien-signals-1.0.13.tgz#8d6db73462f742ee6b89671fbd8c37d0b1727a7e" @@ -602,7 +614,7 @@ de-indent@^1.0.2: resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== -debug@^4.4.1: +debug@^4.3.3, debug@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== @@ -1062,6 +1074,11 @@ unhead@2.0.12: dependencies: hookable "^5.5.3" +upath@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" + integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== + varint@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" @@ -1078,6 +1095,15 @@ vite-node@3.2.4: pathe "^2.0.3" vite "^5.0.0 || ^6.0.0 || ^7.0.0-0" +vite-plugin-vuetify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/vite-plugin-vuetify/-/vite-plugin-vuetify-2.1.1.tgz#31c958f0c64c436a3165462b81196a7c2ae3a2ff" + integrity sha512-Pb7bKhQH8qPMzURmEGq2aIqCJkruFNsyf1NcrrtnjsOIkqJPMcBbiP0oJoO8/uAmyB5W/1JTbbUEsyXdMM0QHQ== + dependencies: + "@vuetify/loader-shared" "^2.1.0" + debug "^4.3.3" + upath "^2.0.1" + "vite@^5.0.0 || ^6.0.0 || ^7.0.0-0": version "7.0.5" resolved "https://registry.yarnpkg.com/vite/-/vite-7.0.5.tgz#deb2d3b777378f6d3e47c3d41b59f3c93f485738" @@ -1166,6 +1192,11 @@ vue@^3.5.17: "@vue/server-renderer" "3.5.17" "@vue/shared" "3.5.17" +vuetify@^3.9.2: + version "3.9.2" + resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-3.9.2.tgz#7458886c6e5922c9499a6d75001c3af2240cc374" + integrity sha512-Pax7YCgbE5SArY8CDM0A9dTVHnG1oU79eIBA+FEEg3dDFV7bc+0AppJJLfG2+aoaBlJf2UH7tOCflJ/U23YU1Q== + why-is-node-running@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04" From fa795506d23052feab32159c2aabdfa6c49c2300 Mon Sep 17 00:00:00 2001 From: soray677 Date: Sun, 27 Jul 2025 19:30:30 +0900 Subject: [PATCH 13/28] =?UTF-8?q?infra=E6=A7=8B=E7=AF=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.template | 4 +- client/tsconfig.json | 5 +- client/vite.config.ts | 9 +- common/src/env.ts | 4 + docker-compose.yml | 7 ++ infra/.gitignore | 1 + infra/bin/main.ts | 16 +++- infra/lib/certification-stack.ts | 22 +++++ infra/lib/main-stack.ts | 143 ++++++++++++++++++++++++++++++- infra/tsconfig.json | 19 ++-- server/tsconfig.json | 6 +- tsconfig.json | 12 +-- 12 files changed, 222 insertions(+), 26 deletions(-) create mode 100644 common/src/env.ts create mode 100644 infra/lib/certification-stack.ts diff --git a/.env.template b/.env.template index 1953c3b..d105e4c 100644 --- a/.env.template +++ b/.env.template @@ -1,7 +1,8 @@ # app APP_ID= APP_NAME= -DOMAIN=http://localhost +DOMAIN_BASE= +DOMAIN_HEAD= # # client @@ -16,7 +17,6 @@ SERVER_PORT=8000 # # infra # -INFRA_AWS_STACK_NAME= INFRA_AWS_ACCESS_KEY_ID= INFRA_AWS_SECRET_ACCESS_KEY= INFRA_AWS_DEFAULT_ACCOUNT= diff --git a/client/tsconfig.json b/client/tsconfig.json index 37ee1c7..08f2158 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -12,16 +12,17 @@ "noUncheckedSideEffectImports": true, "paths": { "@/*": ["./src/*"], + "@common/*": ["../common/src/*"], "@assets/*": ["./src/assets/*"], "@components/*": ["./src/components/*"], "@composables/*": ["./src/composables/*"], "@configs/*": ["./src/configs/*"], "@tests/*": ["./src/tests/*"], "@types/*": ["./src/types/*"], - "@usecases/*": ["./src/usecases/*"] + "@usecases/*": ["./src/usecases/*"], }, "baseUrl": ".", }, - "include": ["src/**/*.ts", "src/**/*.vue", "vite.config.ts"], + "include": ["src/**/*.ts", "src/**/*.vue", "vite.config.ts", "../common/**/*.ts"], } diff --git a/client/vite.config.ts b/client/vite.config.ts index ed3f534..6fb5f15 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -2,18 +2,16 @@ import { defineConfig } from 'vite' import vuetify from 'vite-plugin-vuetify' import vue from '@vitejs/plugin-vue' import path from 'path' +import { DOMAIN } from '../common/src/env' -const port = Number(process.env.CLIENT_PORT ?? 80) - - -process.env.VITE_DOMAIN = process.env.DOMAIN +process.env.VITE_DOMAIN = DOMAIN ? `https://${DOMAIN}` : 'http://localhost' // https://vite.dev/config/ export default defineConfig({ plugins: [vue(), vuetify({ autoImport: true }),], server: { host: true, - port, + port: Number(process.env.CLIENT_PORT ?? 80), watch: { usePolling: true, interval: 1000, @@ -22,6 +20,7 @@ export default defineConfig({ resolve: { alias: { '@': path.resolve(__dirname, './src'), + '@common': path.resolve(__dirname, './../common/src'), '@assets': path.resolve(__dirname, './src/assets'), '@components': path.resolve(__dirname, './src/components'), '@composables': path.resolve(__dirname, './src/composables'), diff --git a/common/src/env.ts b/common/src/env.ts new file mode 100644 index 0000000..ff3f5b7 --- /dev/null +++ b/common/src/env.ts @@ -0,0 +1,4 @@ +export const DOMAIN_BASE = process.env.DOMAIN_BASE ?? '' +export const DOMAIN_HEAD = process.env.DOMAIN_HEAD ?? '' + +export const DOMAIN = DOMAIN_HEAD && DOMAIN_BASE ? [DOMAIN_HEAD, DOMAIN_BASE].join('.') : '' diff --git a/docker-compose.yml b/docker-compose.yml index c1e2117..e9e2b09 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,5 +11,12 @@ services: - "${SERVER_PORT}:${SERVER_PORT}" env_file: - .env + environment: + AWS_STACK_NAME: ${INFRA_AWS_STACK_NAME} + AWS_ACCESS_KEY_ID: ${INFRA_AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${INFRA_AWS_SECRET_ACCESS_KEY} + AWS_DEFAULT_ACCOUNT: ${INFRA_AWS_DEFAULT_ACCOUNT} + AWS_DEFAULT_REGION: ${INFRA_AWS_DEFAULT_REGION} + AWS_DEFAULT_OUTPUT: ${INFRA_AWS_DEFAULT_OUTPUT} command: yarn dev tty: true diff --git a/infra/.gitignore b/infra/.gitignore index f2309fa..a9ea1f9 100644 --- a/infra/.gitignore +++ b/infra/.gitignore @@ -7,3 +7,4 @@ node_modules .cdk.staging cdk.out dist +cdk.context.json diff --git a/infra/bin/main.ts b/infra/bin/main.ts index f536ef0..d84e893 100644 --- a/infra/bin/main.ts +++ b/infra/bin/main.ts @@ -1,15 +1,25 @@ import * as cdk from 'aws-cdk-lib' -import { MainStack } from '@stacks/main-stack' +import { MainStack } from '../lib/main-stack' +import { CertificateStack } from '../lib/certification-stack' const app = new cdk.App() -const stackName = process.env.INFRA_AWS_STACK_NAME +const stackName = process.env.STACK_NAME if (!stackName) process.exit(1) -/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */ +const certificateStack = new CertificateStack(app, `${stackName}-certification`, { + env: { + account: process.env.INFRA_AWS_DEFAULT_ACCOUNT, + region: 'us-east-1', + }, + crossRegionReferences: true +}) + new MainStack(app, stackName, { env: { account: process.env.INFRA_AWS_DEFAULT_ACCOUNT, region: process.env.INFRA_AWS_DEFAULT_REGION, }, + crossRegionReferences: true, + certificateArn: certificateStack.certificateArn }) diff --git a/infra/lib/certification-stack.ts b/infra/lib/certification-stack.ts new file mode 100644 index 0000000..4e4d62d --- /dev/null +++ b/infra/lib/certification-stack.ts @@ -0,0 +1,22 @@ +import * as cdk from 'aws-cdk-lib'; +import * as certificatemanager from 'aws-cdk-lib/aws-certificatemanager'; +import * as route53 from 'aws-cdk-lib/aws-route53'; +import { Construct } from 'constructs'; +import { DOMAIN, DOMAIN_BASE } from '../../common/src/env'; + +export class CertificateStack extends cdk.Stack { + public readonly certificateArn: string; + + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, { ...props, env: { ...props?.env, region: 'us-east-1' } }); + + const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', { domainName: DOMAIN_BASE }); + + const certificate = new certificatemanager.Certificate(this, 'SiteCertificate', { + domainName: DOMAIN, + validation: certificatemanager.CertificateValidation.fromDns(hostedZone), + }); + + this.certificateArn = certificate.certificateArn; + } +} diff --git a/infra/lib/main-stack.ts b/infra/lib/main-stack.ts index f57e38a..0abb7cb 100644 --- a/infra/lib/main-stack.ts +++ b/infra/lib/main-stack.ts @@ -1,8 +1,149 @@ import * as cdk from 'aws-cdk-lib' +import * as s3 from 'aws-cdk-lib/aws-s3' +import * as cloudfront from 'aws-cdk-lib/aws-cloudfront' +import * as cloudfront_origins from 'aws-cdk-lib/aws-cloudfront-origins' +import * as route53 from 'aws-cdk-lib/aws-route53'; +import * as route53_targets from 'aws-cdk-lib/aws-route53-targets'; +import * as certificatemanager from 'aws-cdk-lib/aws-certificatemanager'; import { Construct } from 'constructs' +import { DOMAIN, DOMAIN_BASE } from '../../common/src/env'; + +export interface MainStackProps extends cdk.StackProps { + certificateArn: string; +} export class MainStack extends cdk.Stack { - constructor(scope: Construct, id: string, props?: cdk.StackProps) { + constructor(scope: Construct, id: string, props: MainStackProps) { super(scope, id, props) + const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', { + domainName: DOMAIN_BASE, + }); + + const acm = this.getAcmCertificate(props.certificateArn) + const mainBucket = this.createS3MainBucket(); + const oac = this.createCloudFrontOac(); + const distribution = this.createCloudFrontDistribution(DOMAIN, mainBucket, oac, acm); + this.createRoute53Record(DOMAIN, hostedZone, distribution); + } + + // S3 MainBucket + private createS3MainBucket = (): s3.Bucket => { + return new s3.Bucket(this, 'MainBucket', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + autoDeleteObjects: true, + publicReadAccess: false, + blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, + encryption: s3.BucketEncryption.S3_MANAGED, + cors: [ + { + allowedMethods: [s3.HttpMethods.GET], + allowedOrigins: ['*'], + allowedHeaders: ['*'], + }, + ], + }); + } + + // CloudFront + private createCloudFrontOac = (): cloudfront.CfnOriginAccessControl => { + /** + * @type {cloudfront.CfnOriginAccessControl} + */ + return new cloudfront.CfnOriginAccessControl(this, 'CloudFrontOAC', { + originAccessControlConfig: { + name: `${DOMAIN.replace(/./g, '-')}-oac`, + originAccessControlOriginType: 's3', + signingBehavior: 'always', + signingProtocol: 'sigv4', + description: 'OAC for S3 bucket access', + }, + }); + } + private createCloudFrontFunction = (): cloudfront.Function => { + /** + * @type {cloudfront.Function} + */ + return new cloudfront.Function(this, 'SpaIndexFunction', { + code: cloudfront.FunctionCode.fromInline(` + function handler(event) { + var request = event.request; + var uri = request.uri; + if (uri.endsWith('/')) { + request.uri += 'index.html'; + } else if (!uri.includes('.')) { + request.uri += '/index.html'; + } + return request; + } + `), + }); + } + private createCloudFrontDistribution = ( + domainName: string, + mainBucket: s3.Bucket, + oac: cloudfront.CfnOriginAccessControl, + acm: certificatemanager.ICertificate + ): cloudfront.Distribution => { + const spaIndexFunction = this.createCloudFrontFunction(); + const distribution = new cloudfront.Distribution(this, 'CloudFrontDistribution', { + defaultRootObject: 'index.html', + defaultBehavior: { + origin: cloudfront_origins.S3BucketOrigin.withOriginAccessControl(mainBucket), + viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, + cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED, + functionAssociations: [ + { + function: spaIndexFunction, + eventType: cloudfront.FunctionEventType.VIEWER_REQUEST, + }, + ], + }, + domainNames: [domainName], + certificate: acm, + minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021, + httpVersion: cloudfront.HttpVersion.HTTP2, + enableIpv6: false, + errorResponses: [ + { + httpStatus: 403, + responseHttpStatus: 404, + responsePagePath: '/404.html', + ttl: cdk.Duration.seconds(5), + }, + { + httpStatus: 404, + responseHttpStatus: 404, + responsePagePath: '/404.html', + ttl: cdk.Duration.seconds(5), + }, + ], + }); + const cfnDistribution = distribution.node.defaultChild as cloudfront.CfnDistribution; + cfnDistribution.addPropertyOverride( + 'DistributionConfig.Origins.0.OriginAccessControlId', + oac.attrId + ); + return distribution; + } + + // ACM + private getAcmCertificate = (certificateArn: string): certificatemanager.ICertificate => { + const acm = certificatemanager.Certificate.fromCertificateArn(this, 'ImportedCertificate', certificateArn); + return acm + } + + // Route53 + private createRoute53Record = ( + domainName: string, + hostedZone: cdk.aws_route53.IHostedZone, + distribution: cloudfront.Distribution + ): void => { + new route53.ARecord(this, 'AliasRecord', { + zone: hostedZone, + recordName: domainName, + target: route53.RecordTarget.fromAlias( + new route53_targets.CloudFrontTarget(distribution) + ), + }) } } diff --git a/infra/tsconfig.json b/infra/tsconfig.json index 120fc3a..ca61ca7 100644 --- a/infra/tsconfig.json +++ b/infra/tsconfig.json @@ -1,17 +1,22 @@ { - - "extends": ["../tsconfig.json"], "compilerOptions": { - "baseUrl": ".", - "paths": { - "@stacks/*": ["./lib/*"] - }, + "target": "ES2015", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": [ + "es2015" + ], + "typeRoots": [ + "./node_modules/@types" + ], "outDir": "./dist", }, - "include": ["**/*.ts"], "exclude": [ "node_modules", "cdk.out", "dist" ], + "references": [ + { "path": "../tsconfig.json" } + ] } diff --git a/server/tsconfig.json b/server/tsconfig.json index b4eda54..8462c70 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -3,7 +3,11 @@ "compilerOptions": { "outDir": "./dist" }, + "paths": { + "@common/*": ["../common/src/*"] + }, "include": [ - "src/**/*.ts" + "src/**/*.ts", + "../common/src/**/*.ts" ] } diff --git a/tsconfig.json b/tsconfig.json index 64749aa..ca6649d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,8 +11,10 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "target": "es2024", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "lib": [ + "es2024" + ], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "libReplacement": true, /* Enable lib replacement. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ @@ -27,8 +29,8 @@ /* Modules */ "module": "commonjs", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ @@ -52,7 +54,7 @@ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ From 2c0651f6389b89db5f171736feccd3dc81913828 Mon Sep 17 00:00:00 2001 From: soray677 Date: Sun, 27 Jul 2025 21:01:16 +0900 Subject: [PATCH 14/28] =?UTF-8?q?=E9=87=8D=E8=A4=87=E3=81=97=E3=81=AA?= =?UTF-8?q?=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3=E3=81=97?= =?UTF-8?q?=E3=80=81=E5=89=8A=E9=99=A4=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- infra/bin/main.ts | 3 +- infra/lib/main-stack.ts | 8 +- infra/package.json | 7 +- infra/yarn.lock | 166 +++++++++++++++++++++++++++++++++++- package.json | 5 ++ yarn.lock | 181 +++++++++++++++++++++++++++++++++++++++- 7 files changed, 365 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d9e0966..c8c03e7 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,13 @@ docker compose exec root yarn setup #### ビルド ```sh -docker compose exec root yarn build +docker compose exec root DOMAIN_HEAD=${ドメイン先頭} yarn build +``` + +#### デプロイ(インフラのみ) + +```sh +docker compose exec root DOMAIN_HEAD=${ドメイン先頭} yarn deploy ``` #### テスト diff --git a/infra/bin/main.ts b/infra/bin/main.ts index d84e893..41c67e5 100644 --- a/infra/bin/main.ts +++ b/infra/bin/main.ts @@ -1,10 +1,11 @@ import * as cdk from 'aws-cdk-lib' import { MainStack } from '../lib/main-stack' import { CertificateStack } from '../lib/certification-stack' +import { DOMAIN } from '../../common/src/env' const app = new cdk.App() -const stackName = process.env.STACK_NAME +const stackName = DOMAIN.replace(/\./g, '-') if (!stackName) process.exit(1) const certificateStack = new CertificateStack(app, `${stackName}-certification`, { diff --git a/infra/lib/main-stack.ts b/infra/lib/main-stack.ts index 0abb7cb..b559a88 100644 --- a/infra/lib/main-stack.ts +++ b/infra/lib/main-stack.ts @@ -49,9 +49,9 @@ export class MainStack extends cdk.Stack { /** * @type {cloudfront.CfnOriginAccessControl} */ - return new cloudfront.CfnOriginAccessControl(this, 'CloudFrontOAC', { + return new cloudfront.CfnOriginAccessControl(this, `${this.stackName}-CloudFrontOAC`, { originAccessControlConfig: { - name: `${DOMAIN.replace(/./g, '-')}-oac`, + name: `${this.stackName}-oac`, originAccessControlOriginType: 's3', signingBehavior: 'always', signingProtocol: 'sigv4', @@ -63,7 +63,7 @@ export class MainStack extends cdk.Stack { /** * @type {cloudfront.Function} */ - return new cloudfront.Function(this, 'SpaIndexFunction', { + return new cloudfront.Function(this, `${this.stackName}-SpaIndexFunction`, { code: cloudfront.FunctionCode.fromInline(` function handler(event) { var request = event.request; @@ -85,7 +85,7 @@ export class MainStack extends cdk.Stack { acm: certificatemanager.ICertificate ): cloudfront.Distribution => { const spaIndexFunction = this.createCloudFrontFunction(); - const distribution = new cloudfront.Distribution(this, 'CloudFrontDistribution', { + const distribution = new cloudfront.Distribution(this, `${this.stackName}-CloudFrontDistribution`, { defaultRootObject: 'index.html', defaultBehavior: { origin: cloudfront_origins.S3BucketOrigin.withOriginAccessControl(mainBucket), diff --git a/infra/package.json b/infra/package.json index bc13d93..979d09d 100644 --- a/infra/package.json +++ b/infra/package.json @@ -6,10 +6,12 @@ "main": "dist/bin/main.js" }, "scripts": { - "build": "tsc", "watch": "nodemon", "test": "jest", - "cdk": "cdk" + "clean": "rimraf cdk.context.json && rimraf cdk.out", + "build": "yarn clean && cdk bootstrap", + "deploy": "yarn clean && cdk deploy --all", + "destroy": "cdk destroy --all" }, "devDependencies": { "@types/jest": "^29.5.14", @@ -17,6 +19,7 @@ "aws-cdk": "2.1019.2", "jest": "^29.7.0", "nodemon": "^3.1.10", + "rimraf": "^6.0.1", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typescript": "~5.6.3" diff --git a/infra/yarn.lock b/infra/yarn.lock index cf4d661..a838008 100644 --- a/infra/yarn.lock +++ b/infra/yarn.lock @@ -303,6 +303,30 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@isaacs/balanced-match@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz#3081dadbc3460661b751e7591d7faea5df39dd29" + integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ== + +"@isaacs/brace-expansion@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz#4b3dabab7d8e75a429414a96bd67bf4c1d13e0f3" + integrity sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA== + dependencies: + "@isaacs/balanced-match" "^4.0.1" + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -716,6 +740,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== + ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -728,6 +757,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -1036,7 +1070,7 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.3: +cross-spawn@^7.0.3, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -1077,6 +1111,11 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ejs@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" @@ -1099,6 +1138,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -1196,6 +1240,14 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +foreground-child@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" + integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== + dependencies: + cross-spawn "^7.0.6" + signal-exit "^4.0.1" + fs-extra@^11.3.0: version "11.3.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d" @@ -1252,6 +1304,18 @@ glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" +glob@^11.0.0: + version "11.0.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.3.tgz#9d8087e6d72ddb3c4707b1d2778f80ea3eaefcd6" + integrity sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA== + dependencies: + foreground-child "^3.3.1" + jackspeak "^4.1.1" + minimatch "^10.0.3" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" + glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -1446,6 +1510,13 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jackspeak@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.1.1.tgz#96876030f450502047fc7e8c7fcf8ce8124e43ae" + integrity sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + jake@^10.8.5: version "10.9.2" resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" @@ -1898,6 +1969,11 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== +lru-cache@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.1.0.tgz#afafb060607108132dbc1cf8ae661afb69486117" + integrity sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -1954,6 +2030,13 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +minimatch@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" + integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== + dependencies: + "@isaacs/brace-expansion" "^5.0.0" + minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -1968,6 +2051,11 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" @@ -2056,6 +2144,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -2086,6 +2179,14 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -2188,6 +2289,14 @@ resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +rimraf@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.0.1.tgz#ffb8ad8844dd60332ab15f52bc104bc3ed71ea4e" + integrity sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A== + dependencies: + glob "^11.0.0" + package-json-from-dist "^1.0.0" + semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" @@ -2215,6 +2324,11 @@ signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + simple-update-notifier@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" @@ -2274,6 +2388,15 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -2283,6 +2406,22 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2290,6 +2429,13 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -2478,6 +2624,15 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -2487,6 +2642,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/package.json b/package.json index 9b9c35f..e3b48d5 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,10 @@ "build:client": "yarn --cwd client 'build'", "build:server": "yarn --cwd server 'build'", "build:infra": "yarn --cwd infra 'build'", + "deploy": "run-p deploy:*", + "deploy:infra": "yarn --cwd infra 'deploy'", + "destroy": "run-p destroy:*", + "destroy:infra": "yarn --cwd infra 'destroy'", "test": "run-p test:*", "test:client": "yarn --cwd client 'test'", "test:server": "yarn --cwd server 'test'", @@ -41,6 +45,7 @@ "globals": "^16.0.0", "lint-staged": "^15.5.1", "npm-run-all": "^4.1.5", + "rimraf": "^6.0.1", "tsx": "^4.19.3", "typescript": "^5.8.3", "typescript-eslint": "^8.31.0", diff --git a/yarn.lock b/yarn.lock index 5854bbc..27e50e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -235,6 +235,30 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.2.tgz#1860473de7dfa1546767448f333db80cb0ff2161" integrity sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ== +"@isaacs/balanced-match@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz#3081dadbc3460661b751e7591d7faea5df39dd29" + integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ== + +"@isaacs/brace-expansion@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz#4b3dabab7d8e75a429414a96bd67bf4c1d13e0f3" + integrity sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA== + dependencies: + "@isaacs/balanced-match" "^4.0.1" + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -396,6 +420,11 @@ ansi-escapes@^7.0.0: dependencies: environment "^1.0.0" +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-regex@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" @@ -408,14 +437,14 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" -ansi-styles@^6.0.0, ansi-styles@^6.2.1: +ansi-styles@^6.0.0, ansi-styles@^6.1.0, ansi-styles@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== @@ -788,6 +817,11 @@ dunder-proto@^1.0.0, dunder-proto@^1.0.1: es-errors "^1.3.0" gopd "^1.2.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + electron-to-chromium@^1.5.73: version "1.5.141" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.141.tgz#11776289d95385ca26d8cf95f31692ee58ee3a06" @@ -798,6 +832,16 @@ emoji-regex@^10.3.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.4.0.tgz#03553afea80b3975749cfcb36f776ca268e413d4" integrity sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw== +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + environment@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/environment/-/environment-1.1.0.tgz#8e86c66b180f363c7ab311787e0259665f45a9f1" @@ -1292,6 +1336,14 @@ for-each@^0.3.3, for-each@^0.3.5: dependencies: is-callable "^1.2.7" +foreground-child@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" + integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== + dependencies: + cross-spawn "^7.0.6" + signal-exit "^4.0.1" + fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -1383,6 +1435,18 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" +glob@^11.0.0: + version "11.0.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.3.tgz#9d8087e6d72ddb3c4707b1d2778f80ea3eaefcd6" + integrity sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA== + dependencies: + foreground-child "^3.3.1" + jackspeak "^4.1.1" + minimatch "^10.0.3" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" + globals@^14.0.0: version "14.0.0" resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" @@ -1606,6 +1670,11 @@ is-finalizationregistry@^1.1.0: dependencies: call-bound "^1.0.3" +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + is-fullwidth-code-point@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" @@ -1739,6 +1808,13 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +jackspeak@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.1.1.tgz#96876030f450502047fc7e8c7fcf8ce8124e43ae" + integrity sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -1879,6 +1955,11 @@ lru-cache@^10.0.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.1.0.tgz#afafb060607108132dbc1cf8ae661afb69486117" + integrity sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A== + math-intrinsics@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" @@ -1922,6 +2003,13 @@ min-indent@^1.0.1: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +minimatch@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" + integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== + dependencies: + "@isaacs/brace-expansion" "^5.0.0" + minimatch@^3.0.4, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -1941,6 +2029,11 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" @@ -2109,6 +2202,11 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -2158,6 +2256,14 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -2327,6 +2433,14 @@ rfdc@^1.4.1: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== +rimraf@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.0.1.tgz#ffb8ad8844dd60332ab15f52bc104bc3ed71ea4e" + integrity sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A== + dependencies: + glob "^11.0.0" + package-json-from-dist "^1.0.0" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -2482,7 +2596,7 @@ side-channel@^1.1.0: side-channel-map "^1.0.1" side-channel-weakmap "^1.0.2" -signal-exit@^4.1.0: +signal-exit@^4.0.1, signal-exit@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== @@ -2542,6 +2656,33 @@ string-argv@^0.3.2: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string-width@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" @@ -2593,7 +2734,21 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -strip-ansi@^7.1.0: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== @@ -2877,6 +3032,24 @@ word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrap-ansi@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz#1a3dc8b70d85eeb8398ddfb1e4a02cd186e58b3e" From 728fc26db551d542be2fa6303621418d25324c73 Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 29 Jul 2025 23:42:47 +0900 Subject: [PATCH 15/28] =?UTF-8?q?Pipeline=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++- infra/README.md | 35 ++++++++---- infra/buildspec.yml | 16 ++++++ infra/lib/context.ts | 10 ++++ infra/lib/main-stack.ts | 114 ++++++++++++++++++++++++++++++++++++---- infra/package.json | 8 +-- 6 files changed, 165 insertions(+), 26 deletions(-) create mode 100644 infra/buildspec.yml create mode 100644 infra/lib/context.ts diff --git a/README.md b/README.md index c8c03e7..f57034b 100644 --- a/README.md +++ b/README.md @@ -45,13 +45,17 @@ docker compose exec root yarn setup #### ビルド ```sh -docker compose exec root DOMAIN_HEAD=${ドメイン先頭} yarn build +docker compose exec root "DOMAIN_HEAD=${ドメイン先頭} yarn build:${env}" ``` #### デプロイ(インフラのみ) ```sh -docker compose exec root DOMAIN_HEAD=${ドメイン先頭} yarn deploy +# 作成 +docker compose exec root "DOMAIN_HEAD=${ドメイン先頭} yarn deploy:${env}" + +# 削除 +docker compose exec root "DOMAIN_HEAD=${ドメイン先頭} yarn destroy:${env}" ``` #### テスト diff --git a/infra/README.md b/infra/README.md index 9315fe5..dfcced1 100644 --- a/infra/README.md +++ b/infra/README.md @@ -1,14 +1,29 @@ -# Welcome to your CDK TypeScript project +# インフラ -This is a blank project for CDK development with TypeScript. +## デプロイ方法 -The `cdk.json` file tells the CDK Toolkit how to execute your app. +(1回目のみ) -## Useful commands +```sh +DOMAIN_HEAD=web-dev-template yarn build:${env} +``` -* `npm run build` compile typescript to js -* `npm run watch` watch for changes and compile -* `npm run test` perform the jest unit tests -* `npx cdk deploy` deploy this stack to your default AWS account/region -* `npx cdk diff` compare deployed stack with current state -* `npx cdk synth` emits the synthesized CloudFormation template +## コンテキスト設定 + +以下のように、`cdk.context.json`にコンテキスト情報を記述 + +```json +{ + "context": { + "dev": { + // コンテキスト情報 + } + } +} +``` + +## デプロイ + +```sh +DOMAIN_HEAD=web-dev-template yarn deploy:${env} +``` diff --git a/infra/buildspec.yml b/infra/buildspec.yml new file mode 100644 index 0000000..2b038ea --- /dev/null +++ b/infra/buildspec.yml @@ -0,0 +1,16 @@ +version: 0.2 + +phases: + install: + runtime-versions: + nodejs: 20 + commands: + - npm install -g yarn + - yarn + build: + commands: + - yarn build +artifacts: + files: + - '**/*' + base-directory: client/dist diff --git a/infra/lib/context.ts b/infra/lib/context.ts new file mode 100644 index 0000000..79b07ef --- /dev/null +++ b/infra/lib/context.ts @@ -0,0 +1,10 @@ +/** + * コンテキスト情報 + */ +export const Context = { + GITHUB_REPO_OWNER: 'githubRepoOwner', + GITHUB_REPO: 'githubRepo', + GITHUB_BRANCH: 'githubBranch', + GITHUB_CONNECTION_ARN: 'githubConnectionArn' +} as const +export type Context = (typeof Context)[keyof typeof Context]; diff --git a/infra/lib/main-stack.ts b/infra/lib/main-stack.ts index b559a88..99cb482 100644 --- a/infra/lib/main-stack.ts +++ b/infra/lib/main-stack.ts @@ -1,4 +1,3 @@ -import * as cdk from 'aws-cdk-lib' import * as s3 from 'aws-cdk-lib/aws-s3' import * as cloudfront from 'aws-cdk-lib/aws-cloudfront' import * as cloudfront_origins from 'aws-cdk-lib/aws-cloudfront-origins' @@ -7,12 +6,14 @@ import * as route53_targets from 'aws-cdk-lib/aws-route53-targets'; import * as certificatemanager from 'aws-cdk-lib/aws-certificatemanager'; import { Construct } from 'constructs' import { DOMAIN, DOMAIN_BASE } from '../../common/src/env'; +import { aws_codebuild, aws_codepipeline, aws_codepipeline_actions, aws_iam, aws_route53, Duration, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib'; +import { Context } from './context'; -export interface MainStackProps extends cdk.StackProps { +export interface MainStackProps extends StackProps { certificateArn: string; } -export class MainStack extends cdk.Stack { +export class MainStack extends Stack { constructor(scope: Construct, id: string, props: MainStackProps) { super(scope, id, props) const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', { @@ -24,12 +25,13 @@ export class MainStack extends cdk.Stack { const oac = this.createCloudFrontOac(); const distribution = this.createCloudFrontDistribution(DOMAIN, mainBucket, oac, acm); this.createRoute53Record(DOMAIN, hostedZone, distribution); + this.createCodePipeline(DOMAIN, mainBucket) } // S3 MainBucket private createS3MainBucket = (): s3.Bucket => { return new s3.Bucket(this, 'MainBucket', { - removalPolicy: cdk.RemovalPolicy.DESTROY, + removalPolicy: RemovalPolicy.DESTROY, autoDeleteObjects: true, publicReadAccess: false, blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, @@ -46,9 +48,6 @@ export class MainStack extends cdk.Stack { // CloudFront private createCloudFrontOac = (): cloudfront.CfnOriginAccessControl => { - /** - * @type {cloudfront.CfnOriginAccessControl} - */ return new cloudfront.CfnOriginAccessControl(this, `${this.stackName}-CloudFrontOAC`, { originAccessControlConfig: { name: `${this.stackName}-oac`, @@ -108,13 +107,13 @@ export class MainStack extends cdk.Stack { httpStatus: 403, responseHttpStatus: 404, responsePagePath: '/404.html', - ttl: cdk.Duration.seconds(5), + ttl: Duration.seconds(5), }, { httpStatus: 404, responseHttpStatus: 404, responsePagePath: '/404.html', - ttl: cdk.Duration.seconds(5), + ttl: Duration.seconds(5), }, ], }); @@ -135,7 +134,7 @@ export class MainStack extends cdk.Stack { // Route53 private createRoute53Record = ( domainName: string, - hostedZone: cdk.aws_route53.IHostedZone, + hostedZone: aws_route53.IHostedZone, distribution: cloudfront.Distribution ): void => { new route53.ARecord(this, 'AliasRecord', { @@ -146,4 +145,99 @@ export class MainStack extends cdk.Stack { ), }) } + + // CodePipeline + private createCodePipeline = ( + domainName: string, + mainBucket: s3.Bucket + ) => { + const sourceOutput = new aws_codepipeline.Artifact(); + const buildOutput = new aws_codepipeline.Artifact(); + const codeBuildProject = this.createCodeBuild(domainName) + const artifactsS3Bucket = this.createArtifactsS3Bucket() + + return new aws_codepipeline.Pipeline(this, `${this.stackName}-CodePipeline`, { + artifactBucket: artifactsS3Bucket, + pipelineName: `${this.stackName}-Pipeline`, + stages: [ + { + stageName: 'Source', + actions: [ + new aws_codepipeline_actions.CodeStarConnectionsSourceAction({ + actionName: 'GitHub_Source', + owner: this.getContext(Context.GITHUB_REPO_OWNER), + repo: this.getContext(Context.GITHUB_REPO), + branch: this.getContext(Context.GITHUB_BRANCH), + connectionArn: this.getContext(Context.GITHUB_CONNECTION_ARN), + output: sourceOutput, + }), + ], + }, + { + stageName: 'Build', + actions: [ + new aws_codepipeline_actions.CodeBuildAction({ + actionName: 'CodeBuild', + project: codeBuildProject, + input: sourceOutput, + outputs: [buildOutput], + }), + ], + }, + { + stageName: 'Deploy', + actions: [ + new aws_codepipeline_actions.S3DeployAction({ + actionName: 'S3_Deploy', + bucket: mainBucket, + input: buildOutput, + extract: true, + }), + ], + }, + ], + }); + } + private createArtifactsS3Bucket = () => { + return new s3.Bucket(this, `${this.stackName}-ArtifactsBucket`, { + removalPolicy: RemovalPolicy.DESTROY, + autoDeleteObjects: true, + lifecycleRules: [{ expiration: Duration.days(30) }], + encryption: s3.BucketEncryption.S3_MANAGED, + }); + } + // Code Build + private createCodeBuild = ( + domainName: string + ) => { + const codeBuildIamRole = this.createCodeBuildIamRole() + + return new aws_codebuild.PipelineProject(this, `${this.stackName}-CodeBuild`, { + environment: { + buildImage: aws_codebuild.LinuxBuildImage.AMAZON_LINUX_2_ARM_3, + computeType: aws_codebuild.ComputeType.SMALL, + privileged: false, + }, + environmentVariables: { + DOMAIN: { value: domainName }, + ENV_MODE: { value: 'production' }, + }, + buildSpec: aws_codebuild.BuildSpec.fromSourceFilename('infra/buildspec.yml'), + role: codeBuildIamRole, + }) + } + private createCodeBuildIamRole = () => { + const codeBuildRole = new aws_iam.Role(this, `${this.stackName}-CodeBuildRole`, { + assumedBy: new aws_iam.ServicePrincipal('codebuild.amazonaws.com'), + }); + codeBuildRole.addManagedPolicy(aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3FullAccess')); + codeBuildRole.addManagedPolicy(aws_iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLogsFullAccess')); + return codeBuildRole + } + + private getContext = (context: Context) => { + const env = this.node.tryGetContext('env') + const value = this.node.tryGetContext('context')?.[env]?.[context] + return value ?? '' + } } diff --git a/infra/package.json b/infra/package.json index 979d09d..e3845c0 100644 --- a/infra/package.json +++ b/infra/package.json @@ -8,10 +8,10 @@ "scripts": { "watch": "nodemon", "test": "jest", - "clean": "rimraf cdk.context.json && rimraf cdk.out", - "build": "yarn clean && cdk bootstrap", - "deploy": "yarn clean && cdk deploy --all", - "destroy": "cdk destroy --all" + "clean": "rimraf cdk.out", + "build:dev": "yarn clean && cdk bootstrap --context env=dev", + "deploy:dev": "yarn clean && cdk deploy --all --context env=dev", + "destroy": "cdk destroy --all --context env=dev" }, "devDependencies": { "@types/jest": "^29.5.14", From eba0cad1826f8b8f31c83b76e32b74238e1feea5 Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 29 Jul 2025 23:44:16 +0900 Subject: [PATCH 16/28] =?UTF-8?q?`=E6=8A=9C=E3=81=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f57034b..a197f6e 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ docker compose exec root yarn test ```sh docker compose exec root yarn lint # チェックのみ docker compose exec root yarn lint:fix # 矯正含む -`` +``` ### 各サービスエンドポイント From 87edaecf4048bcce1691165aa18e5c2b677e1468 Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 29 Jul 2025 23:52:54 +0900 Subject: [PATCH 17/28] =?UTF-8?q?infra=E3=81=AF=E5=88=A5=E7=89=A9=E3=81=AA?= =?UTF-8?q?=E3=81=AE=E3=81=A7build=E3=81=8B=E3=82=89=E5=A4=96=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e3b48d5..8fb9432 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "build": "run-p build:*", "build:client": "yarn --cwd client 'build'", "build:server": "yarn --cwd server 'build'", - "build:infra": "yarn --cwd infra 'build'", + "bootstrap:infra": "yarn --cwd infra 'build:dev'", "deploy": "run-p deploy:*", "deploy:infra": "yarn --cwd infra 'deploy'", "destroy": "run-p destroy:*", From 3289c3b54e2bcacc28e3fe8dae9b874fbc211caa Mon Sep 17 00:00:00 2001 From: soray677 Date: Tue, 29 Jul 2025 23:58:38 +0900 Subject: [PATCH 18/28] =?UTF-8?q?yarn=20setup=E3=82=92=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infra/buildspec.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/infra/buildspec.yml b/infra/buildspec.yml index 2b038ea..0ce840f 100644 --- a/infra/buildspec.yml +++ b/infra/buildspec.yml @@ -7,6 +7,7 @@ phases: commands: - npm install -g yarn - yarn + - yarn:setup build: commands: - yarn build From 11b642637a978905fca583467bacdc95f6a0f68c Mon Sep 17 00:00:00 2001 From: soray677 Date: Wed, 30 Jul 2025 00:00:45 +0900 Subject: [PATCH 19/28] =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=83=9F=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infra/buildspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/buildspec.yml b/infra/buildspec.yml index 0ce840f..f7b27c9 100644 --- a/infra/buildspec.yml +++ b/infra/buildspec.yml @@ -7,7 +7,7 @@ phases: commands: - npm install -g yarn - yarn - - yarn:setup + - yarn setup build: commands: - yarn build From 62650c81e323f3ab2d0ffbe3b5840b9459dcdc30 Mon Sep 17 00:00:00 2001 From: soray677 Date: Wed, 30 Jul 2025 00:04:03 +0900 Subject: [PATCH 20/28] =?UTF-8?q?node=E3=81=AE=E3=83=90=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=82=92=E4=B8=8A=E3=81=92=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infra/buildspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/buildspec.yml b/infra/buildspec.yml index f7b27c9..47e5afa 100644 --- a/infra/buildspec.yml +++ b/infra/buildspec.yml @@ -3,7 +3,7 @@ version: 0.2 phases: install: runtime-versions: - nodejs: 20 + nodejs: 24 commands: - npm install -g yarn - yarn From be09fa26b614c96b611f9957e67acb9a9ab7977e Mon Sep 17 00:00:00 2001 From: soray677 Date: Wed, 30 Jul 2025 22:27:55 +0900 Subject: [PATCH 21/28] =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a197f6e..f30f0cb 100644 --- a/README.md +++ b/README.md @@ -45,17 +45,17 @@ docker compose exec root yarn setup #### ビルド ```sh -docker compose exec root "DOMAIN_HEAD=${ドメイン先頭} yarn build:${env}" +docker compose exec root "yarn build:${env}" ``` #### デプロイ(インフラのみ) ```sh # 作成 -docker compose exec root "DOMAIN_HEAD=${ドメイン先頭} yarn deploy:${env}" +docker compose exec root "yarn deploy:${env}" # 削除 -docker compose exec root "DOMAIN_HEAD=${ドメイン先頭} yarn destroy:${env}" +docker compose exec root "yarn destroy:${env}" ``` #### テスト From e63876e3a02109dde6b592956c3036274a918af2 Mon Sep 17 00:00:00 2001 From: soray677 Date: Wed, 30 Jul 2025 23:21:27 +0900 Subject: [PATCH 22/28] =?UTF-8?q?=E7=92=B0=E5=A2=83=E5=A4=89=E6=95=B0?= =?UTF-8?q?=E3=81=A7env=E3=82=92=E5=8F=96=E5=BE=97=E3=81=A7=E3=81=8D?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.template | 14 ++++++++++---- .gitignore | 3 ++- README.md | 11 +++++++---- common/src/env.ts | 17 ++++++++++++---- docker-compose.yml | 1 - infra/README.md | 22 ++++----------------- infra/bin/main.ts | 9 ++++++--- infra/lib/certification-stack.ts | 24 +++++++++++++++-------- infra/lib/context.ts | 10 ---------- infra/lib/main-stack.ts | 33 +++++++++++++++----------------- infra/package.json | 9 +++++---- infra/test/main.test.ts | 10 ---------- infra/yarn.lock | 5 +++++ package.json | 8 +++----- 14 files changed, 86 insertions(+), 90 deletions(-) delete mode 100644 infra/lib/context.ts delete mode 100644 infra/test/main.test.ts diff --git a/.env.template b/.env.template index d105e4c..182882e 100644 --- a/.env.template +++ b/.env.template @@ -1,8 +1,10 @@ -# app +# +# root +# APP_ID= -APP_NAME= -DOMAIN_BASE= +## Domain DOMAIN_HEAD= +DOMAIN_BASE= # # client @@ -22,5 +24,9 @@ INFRA_AWS_SECRET_ACCESS_KEY= INFRA_AWS_DEFAULT_ACCOUNT= INFRA_AWS_DEFAULT_REGION=ap-northeast-1 INFRA_AWS_DEFAULT_OUTPUT=json - +## GitHub Connection +INFRA_GITHUB_REPO_OWNER= +INFRA_GITHUB_REPO_NAME= +INFRA_GITHUB_REPO_BRANCH= +INFRA_GITHUB_CONNECTION_ARN= diff --git a/.gitignore b/.gitignore index 6ab5cc8..ba1f813 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules -.env +.env* +!.env.template .tmp .DS_Store diff --git a/README.md b/README.md index f30f0cb..3da821e 100644 --- a/README.md +++ b/README.md @@ -45,17 +45,20 @@ docker compose exec root yarn setup #### ビルド ```sh -docker compose exec root "yarn build:${env}" +docker compose exec root yarn build ``` #### デプロイ(インフラのみ) ```sh -# 作成 -docker compose exec root "yarn deploy:${env}" +# 検証 +docker compose exec root yarn bootstrap env=${env} + +# 生成 +docker compose exec root yarn deploy env=${env} # 削除 -docker compose exec root "yarn destroy:${env}" +docker compose exec root yarn destroy env=${env} ``` #### テスト diff --git a/common/src/env.ts b/common/src/env.ts index ff3f5b7..bbdbe3e 100644 --- a/common/src/env.ts +++ b/common/src/env.ts @@ -1,4 +1,13 @@ -export const DOMAIN_BASE = process.env.DOMAIN_BASE ?? '' -export const DOMAIN_HEAD = process.env.DOMAIN_HEAD ?? '' - -export const DOMAIN = DOMAIN_HEAD && DOMAIN_BASE ? [DOMAIN_HEAD, DOMAIN_BASE].join('.') : '' +export const getEnv = () => { + const DOMAIN_HEAD = process.env.DOMAIN_HEAD ?? '' + const DOMAIN_BASE = process.env.DOMAIN_BASE ?? '' + return { + DOMAIN_HEAD, + DOMAIN_BASE, + DOMAIN: [DOMAIN_HEAD, DOMAIN_BASE].join('.'), + INFRA_GITHUB_REPO_OWNER: process.env.INFRA_GITHUB_REPO_OWNER ?? '', + INFRA_GITHUB_REPO_NAME: process.env.INFRA_GITHUB_REPO_OWNER ?? '', + INFRA_GITHUB_REPO_BRANCH:process.env.INFRA_GITHUB_REPO_OWNER ?? '', + INFRA_GITHUB_CONNECTION_ARN: process.env.INFRA_GITHUB_REPO_OWNER ?? '' + } +} diff --git a/docker-compose.yml b/docker-compose.yml index e9e2b09..f74419a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,6 @@ services: env_file: - .env environment: - AWS_STACK_NAME: ${INFRA_AWS_STACK_NAME} AWS_ACCESS_KEY_ID: ${INFRA_AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY: ${INFRA_AWS_SECRET_ACCESS_KEY} AWS_DEFAULT_ACCOUNT: ${INFRA_AWS_DEFAULT_ACCOUNT} diff --git a/infra/README.md b/infra/README.md index dfcced1..b91beac 100644 --- a/infra/README.md +++ b/infra/README.md @@ -1,29 +1,15 @@ # インフラ -## デプロイ方法 +## コマンド一覧 -(1回目のみ) +### ビルド ```sh -DOMAIN_HEAD=web-dev-template yarn build:${env} -``` - -## コンテキスト設定 - -以下のように、`cdk.context.json`にコンテキスト情報を記述 - -```json -{ - "context": { - "dev": { - // コンテキスト情報 - } - } -} +yarn bootstrap env=${env} ``` ## デプロイ ```sh -DOMAIN_HEAD=web-dev-template yarn deploy:${env} +yarn deploy env=${env} ``` diff --git a/infra/bin/main.ts b/infra/bin/main.ts index 41c67e5..29d7dcb 100644 --- a/infra/bin/main.ts +++ b/infra/bin/main.ts @@ -1,12 +1,15 @@ import * as cdk from 'aws-cdk-lib' +import dotenv from 'dotenv'; import { MainStack } from '../lib/main-stack' import { CertificateStack } from '../lib/certification-stack' -import { DOMAIN } from '../../common/src/env' +import { getEnv } from '../../common/src/env'; +import path from 'path'; const app = new cdk.App() +const env = app.node.tryGetContext('env') +dotenv.config({ path: path.join(__dirname,`../../.env.${env}`) }); -const stackName = DOMAIN.replace(/\./g, '-') -if (!stackName) process.exit(1) +const stackName = getEnv().DOMAIN.replace(/\./g, '-') const certificateStack = new CertificateStack(app, `${stackName}-certification`, { env: { diff --git a/infra/lib/certification-stack.ts b/infra/lib/certification-stack.ts index 4e4d62d..2214692 100644 --- a/infra/lib/certification-stack.ts +++ b/infra/lib/certification-stack.ts @@ -1,22 +1,30 @@ -import * as cdk from 'aws-cdk-lib'; import * as certificatemanager from 'aws-cdk-lib/aws-certificatemanager'; import * as route53 from 'aws-cdk-lib/aws-route53'; import { Construct } from 'constructs'; -import { DOMAIN, DOMAIN_BASE } from '../../common/src/env'; +import { Stack, StackProps } from 'aws-cdk-lib'; +import { getEnv } from '../../common/src/env'; -export class CertificateStack extends cdk.Stack { - public readonly certificateArn: string; - constructor(scope: Construct, id: string, props?: cdk.StackProps) { + +export class CertificateStack extends Stack { + private readonly _certificateArn: string; + private env: ReturnType; + + constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, { ...props, env: { ...props?.env, region: 'us-east-1' } }); + this.env = getEnv() - const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', { domainName: DOMAIN_BASE }); + const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', { + domainName: this.env.DOMAIN_BASE + }); const certificate = new certificatemanager.Certificate(this, 'SiteCertificate', { - domainName: DOMAIN, + domainName: this.env.DOMAIN, validation: certificatemanager.CertificateValidation.fromDns(hostedZone), }); - this.certificateArn = certificate.certificateArn; + this._certificateArn = certificate.certificateArn; } + + get certificateArn() { return this._certificateArn } } diff --git a/infra/lib/context.ts b/infra/lib/context.ts deleted file mode 100644 index 79b07ef..0000000 --- a/infra/lib/context.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * コンテキスト情報 - */ -export const Context = { - GITHUB_REPO_OWNER: 'githubRepoOwner', - GITHUB_REPO: 'githubRepo', - GITHUB_BRANCH: 'githubBranch', - GITHUB_CONNECTION_ARN: 'githubConnectionArn' -} as const -export type Context = (typeof Context)[keyof typeof Context]; diff --git a/infra/lib/main-stack.ts b/infra/lib/main-stack.ts index 99cb482..e714970 100644 --- a/infra/lib/main-stack.ts +++ b/infra/lib/main-stack.ts @@ -5,27 +5,30 @@ import * as route53 from 'aws-cdk-lib/aws-route53'; import * as route53_targets from 'aws-cdk-lib/aws-route53-targets'; import * as certificatemanager from 'aws-cdk-lib/aws-certificatemanager'; import { Construct } from 'constructs' -import { DOMAIN, DOMAIN_BASE } from '../../common/src/env'; import { aws_codebuild, aws_codepipeline, aws_codepipeline_actions, aws_iam, aws_route53, Duration, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib'; -import { Context } from './context'; +import {getEnv } from '../../common/src/env'; export interface MainStackProps extends StackProps { certificateArn: string; } export class MainStack extends Stack { + private env: ReturnType; constructor(scope: Construct, id: string, props: MainStackProps) { super(scope, id, props) + this.env = getEnv() + + const domain = this.env.DOMAIN const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', { - domainName: DOMAIN_BASE, + domainName: this.env.DOMAIN_BASE, }); const acm = this.getAcmCertificate(props.certificateArn) const mainBucket = this.createS3MainBucket(); const oac = this.createCloudFrontOac(); - const distribution = this.createCloudFrontDistribution(DOMAIN, mainBucket, oac, acm); - this.createRoute53Record(DOMAIN, hostedZone, distribution); - this.createCodePipeline(DOMAIN, mainBucket) + const distribution = this.createCloudFrontDistribution(domain, mainBucket, oac, acm); + this.createRoute53Record(domain, hostedZone, distribution); + this.createCodePipeline(domain, mainBucket) } // S3 MainBucket @@ -131,7 +134,7 @@ export class MainStack extends Stack { return acm } - // Route53 + // // Route53 private createRoute53Record = ( domainName: string, hostedZone: aws_route53.IHostedZone, @@ -146,7 +149,7 @@ export class MainStack extends Stack { }) } - // CodePipeline + // // CodePipeline private createCodePipeline = ( domainName: string, mainBucket: s3.Bucket @@ -165,10 +168,10 @@ export class MainStack extends Stack { actions: [ new aws_codepipeline_actions.CodeStarConnectionsSourceAction({ actionName: 'GitHub_Source', - owner: this.getContext(Context.GITHUB_REPO_OWNER), - repo: this.getContext(Context.GITHUB_REPO), - branch: this.getContext(Context.GITHUB_BRANCH), - connectionArn: this.getContext(Context.GITHUB_CONNECTION_ARN), + owner: this.env.INFRA_GITHUB_REPO_OWNER, + repo: this.env.INFRA_GITHUB_REPO_NAME, + branch: this.env.INFRA_GITHUB_REPO_BRANCH, + connectionArn: this.env.INFRA_GITHUB_CONNECTION_ARN, output: sourceOutput, }), ], @@ -234,10 +237,4 @@ export class MainStack extends Stack { codeBuildRole.addManagedPolicy(aws_iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLogsFullAccess')); return codeBuildRole } - - private getContext = (context: Context) => { - const env = this.node.tryGetContext('env') - const value = this.node.tryGetContext('context')?.[env]?.[context] - return value ?? '' - } } diff --git a/infra/package.json b/infra/package.json index e3845c0..774a2cb 100644 --- a/infra/package.json +++ b/infra/package.json @@ -9,9 +9,9 @@ "watch": "nodemon", "test": "jest", "clean": "rimraf cdk.out", - "build:dev": "yarn clean && cdk bootstrap --context env=dev", - "deploy:dev": "yarn clean && cdk deploy --all --context env=dev", - "destroy": "cdk destroy --all --context env=dev" + "bootstrap": "yarn clean && cdk bootstrap --context", + "deploy": "yarn clean && cdk deploy --all --context", + "destroy": "yarn clean && cdk destroy --all --context" }, "devDependencies": { "@types/jest": "^29.5.14", @@ -26,6 +26,7 @@ }, "dependencies": { "aws-cdk-lib": "2.201.0", - "constructs": "^10.0.0" + "constructs": "^10.0.0", + "dotenv": "^17.2.1" } } diff --git a/infra/test/main.test.ts b/infra/test/main.test.ts deleted file mode 100644 index 4c75a24..0000000 --- a/infra/test/main.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as cdk from 'aws-cdk-lib' -import { Template } from 'aws-cdk-lib/assertions' -import { MainStack } from '@stacks/main-stack' - -test('Sample Test', () => { - const app = new cdk.App() - const stack = new MainStack(app, 'MyTestStack') - const template = Template.fromStack(stack) - expect(template).not.toBeNull() -}) diff --git a/infra/yarn.lock b/infra/yarn.lock index a838008..820a1c6 100644 --- a/infra/yarn.lock +++ b/infra/yarn.lock @@ -1111,6 +1111,11 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dotenv@^17.2.1: + version "17.2.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-17.2.1.tgz#6f32e10faf014883515538dc922a0fb8765d9b32" + integrity sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" diff --git a/package.json b/package.json index 8fb9432..f37dd1f 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,9 @@ "build": "run-p build:*", "build:client": "yarn --cwd client 'build'", "build:server": "yarn --cwd server 'build'", - "bootstrap:infra": "yarn --cwd infra 'build:dev'", - "deploy": "run-p deploy:*", - "deploy:infra": "yarn --cwd infra 'deploy'", - "destroy": "run-p destroy:*", - "destroy:infra": "yarn --cwd infra 'destroy'", + "bootstrap": "yarn --cwd infra 'bootstrap'", + "deploy": "yarn --cwd infra 'deploy'", + "destroy": "yarn --cwd infra 'destroy'", "test": "run-p test:*", "test:client": "yarn --cwd client 'test'", "test:server": "yarn --cwd server 'test'", From 4bc9314445f82d3b5daa4ffeee62ada55aeafc76 Mon Sep 17 00:00:00 2001 From: soray677 Date: Wed, 30 Jul 2025 23:24:36 +0900 Subject: [PATCH 23/28] =?UTF-8?q?DOMAIN=E3=81=AE=E5=8F=96=E5=BE=97?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/vite.config.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/vite.config.ts b/client/vite.config.ts index 6fb5f15..0b00340 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -2,9 +2,10 @@ import { defineConfig } from 'vite' import vuetify from 'vite-plugin-vuetify' import vue from '@vitejs/plugin-vue' import path from 'path' -import { DOMAIN } from '../common/src/env' +import { getEnv } from '../common/src/env' -process.env.VITE_DOMAIN = DOMAIN ? `https://${DOMAIN}` : 'http://localhost' +const domain = getEnv().DOMAIN +process.env.VITE_DOMAIN = domain ? `https://${domain}` : 'http://localhost' // https://vite.dev/config/ export default defineConfig({ From 3edb4e4e60e8edf3a3c6cc5d40a9ce807e5917e4 Mon Sep 17 00:00:00 2001 From: soray677 Date: Wed, 30 Jul 2025 23:26:34 +0900 Subject: [PATCH 24/28] =?UTF-8?q?=E3=83=95=E3=83=AD=E3=83=B3=E3=83=88?= =?UTF-8?q?=E5=81=B4=E3=81=AE=E7=92=B0=E5=A2=83=E5=A4=89=E6=95=B0=E3=82=92?= =?UTF-8?q?=E6=98=8E=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/App.vue | 4 ++-- client/src/configs/{EnvConfig.ts => ClientEnvConfig.ts} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename client/src/configs/{EnvConfig.ts => ClientEnvConfig.ts} (65%) diff --git a/client/src/components/App.vue b/client/src/components/App.vue index ce3bad1..b20227f 100644 --- a/client/src/components/App.vue +++ b/client/src/components/App.vue @@ -7,12 +7,12 @@