diff --git a/.env.example b/.env.example index 55f67a0..0e00796 100644 --- a/.env.example +++ b/.env.example @@ -39,4 +39,4 @@ SCREENSHOTONE_BASE_URL=https://shot.wr.do GITHUB_TOKEN= - +SKIP_DB_CHECK=false \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e4c8c54..e504615 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,6 +38,8 @@ RUN npm install -g pnpm ENV NODE_ENV=production ENV IS_DOCKER=true +RUN pnpm add npm-run-all dotenv @prisma/client@5.17.0 + COPY --from=builder /app/public ./public COPY --from=builder /app/prisma ./prisma @@ -47,12 +49,12 @@ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static # Check db -COPY scripts/entrypoint.sh /app/scripts/entrypoint.sh -RUN chmod +x /app/scripts/entrypoint.sh +COPY scripts/check-db.js /app/scripts/check-db.js EXPOSE 3000 ENV HOSTNAME=0.0.0.0 ENV PORT=3000 -CMD ["node", "server.js"] \ No newline at end of file +# CMD ["node", "server.js"] +CMD ["pnpm", "start-docker"] \ No newline at end of file diff --git a/README.md b/README.md index c4ed68d..c61149b 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,15 @@ Remember to fill in the necessary environment variables. ### Deploy with Docker Compose -Create a new folder and copy the `docker-compose.yml` file to the folder. +Create a new folder and copy the `docker-compose.yml`、`.env` file to the folder. -Touch a `.env` file at the same level and fill in the environment variables, then: +```yml +- wrdo + | - docker-compose.yml + | - .env +``` + +Fill in the environment variables in the `.env` file, then: ```bash docker compose up -d diff --git a/app/(protected)/dashboard/records/record-list.tsx b/app/(protected)/dashboard/records/record-list.tsx index e38a252..0f8d032 100644 --- a/app/(protected)/dashboard/records/record-list.tsx +++ b/app/(protected)/dashboard/records/record-list.tsx @@ -140,12 +140,12 @@ export default function UserRecordsList({ user, action }: RecordListProps) { {action.includes("/admin") ? ( - Total Records:{" "} + Total Subdomains:{" "} {data && data.total} ) : (
- DNS Records + Subdomains Please read the{" "} { - console.log("[Runtime Env]", isVercel ? "Vercel" : "Other"); + // console.log("[Runtime Env]", isVercel ? "Vercel" : "Other"); if (isVercel) { return geolocation(req); diff --git a/package.json b/package.json index 0f8b629..d145c60 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,15 @@ "postbuild": "next-sitemap", "turbo": "next dev --turbo", "start": "next start", + "start-docker": "npm-run-all check-db start-server", + "start-server": "node server.js", "lint": "next lint", "preview": "next build && next start", "postinstall": "prisma generate", "db:push": "npx prisma migrate deploy", "email": "email dev --dir emails --port 3333", - "remove-content": "node ./setup.mjs" + "remove-content": "node ./setup.mjs", + "check-db": "node scripts/check-db.js" }, "prisma": { "schema": "./prisma/schema.prisma" @@ -71,6 +74,7 @@ "@vercel/functions": "^1.4.0", "@vercel/og": "^0.6.2", "cheerio": "1.0.0-rc.12", + "chalk": "^4.1.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "^1.0.0", @@ -80,6 +84,7 @@ "d3-scale": "^4.0.2", "d3-scale-chromatic": "^3.1.0", "date-fns": "^3.6.0", + "dotenv": "^10.0.0", "framer-motion": "^12.5.0", "globe.gl": "^2.41.4", "lodash": "^4.17.21", @@ -96,6 +101,7 @@ "next-themes": "^0.3.0", "next-view-transitions": "^0.3.0", "nodemailer": "^6.9.14", + "npm-run-all": "^4.1.5", "peerjs": "^1.5.4", "prop-types": "^15.8.1", "react": "18.3.1", @@ -115,6 +121,7 @@ "shiki": "^1.11.0", "sonner": "^1.5.0", "swr": "^2.2.5", + "semver": "^7.5.4", "tailwind-merge": "^2.4.0", "tailwindcss-animate": "^1.0.7", "three": "^0.176.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e683c9..c4d8584 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -152,6 +152,9 @@ importers: '@vercel/og': specifier: ^0.6.2 version: 0.6.2 + chalk: + specifier: ^4.1.1 + version: 4.1.2 cheerio: specifier: 1.0.0-rc.12 version: 1.0.0-rc.12 @@ -182,6 +185,9 @@ importers: date-fns: specifier: ^3.6.0 version: 3.6.0 + dotenv: + specifier: ^10.0.0 + version: 10.0.0 framer-motion: specifier: ^12.5.0 version: 12.5.0(@emotion/is-prop-valid@0.8.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -230,6 +236,9 @@ importers: nodemailer: specifier: ^6.9.14 version: 6.9.14 + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 peerjs: specifier: ^1.5.4 version: 1.5.4 @@ -275,6 +284,9 @@ importers: resend: specifier: ^3.4.0 version: 3.4.0 + semver: + specifier: ^7.5.4 + version: 7.6.3 sharp: specifier: ^0.33.4 version: 0.33.4 @@ -4053,6 +4065,10 @@ packages: countup.js@2.8.0: resolution: {integrity: sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ==} + cross-spawn@6.0.6: + resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} + engines: {node: '>=4.8'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -4411,6 +4427,10 @@ packages: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} + dotenv@10.0.0: + resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} + engines: {node: '>=10'} + dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} @@ -5114,6 +5134,9 @@ packages: resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==} engines: {node: '>=6'} + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + html-to-text@9.0.5: resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==} engines: {node: '>=14'} @@ -5465,6 +5488,9 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -5549,6 +5575,10 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} @@ -5635,10 +5665,6 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - lucide-react@0.414.0: resolution: {integrity: sha512-Krr/MHg9AWoJc52qx8hyJ64X9++JNfS1wjaJviLM1EP/68VNB7Tv0VMldLCB1aUe6Ka9QxURPhQm/eB6cqOM3A==} peerDependencies: @@ -5742,6 +5768,10 @@ packages: resolution: {integrity: sha512-f16coDZlTG1jskq3mxarwB+fGRrd0uXWt+o1WIhRfOwbXQZqUDsTVxQBFK9JjRQHblg8eAG2JSbprDXKjc7ijQ==} engines: {node: '>= 4.0.0'} + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + meow@12.1.1: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} engines: {node: '>=16.10'} @@ -6034,6 +6064,9 @@ packages: sass: optional: true + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -6052,6 +6085,9 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -6060,6 +6096,11 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} + npm-run-all@4.1.5: + resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} + engines: {node: '>= 4'} + hasBin: true + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -6186,6 +6227,10 @@ packages: parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -6223,6 +6268,10 @@ packages: path-is-inside@1.0.2: resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -6238,6 +6287,10 @@ packages: resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} engines: {node: '>=16 || 14 >=14.17'} + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -6277,10 +6330,19 @@ packages: resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==} engines: {node: '>=10'} + pidtree@0.3.1: + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} + engines: {node: '>=0.10'} + hasBin: true + pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} @@ -6638,6 +6700,10 @@ packages: read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + read-pkg@3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -6854,13 +6920,12 @@ packages: selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true - semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} - engines: {node: '>=10'} + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true semver@7.6.3: @@ -6892,10 +6957,18 @@ packages: resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==} engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} @@ -7004,6 +7077,18 @@ packages: spawn-command@0.0.2: resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -7034,6 +7119,10 @@ packages: resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} engines: {node: '>= 0.4'} + string.prototype.padend@3.1.6: + resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} + engines: {node: '>= 0.4'} + string.prototype.repeat@1.0.0: resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} @@ -7521,6 +7610,9 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -7707,9 +7799,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -9016,7 +9105,7 @@ snapshots: '@babel/traverse': 7.24.6 '@babel/types': 7.24.6 prettier: 3.3.3 - semver: 7.6.0 + semver: 7.6.3 transitivePeerDependencies: - supports-color @@ -11989,6 +12078,14 @@ snapshots: countup.js@2.8.0: {} + cross-spawn@6.0.6: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -12370,6 +12467,8 @@ snapshots: dependencies: is-obj: 2.0.0 + dotenv@10.0.0: {} + dotenv@16.0.3: {} dunder-proto@1.0.1: @@ -13361,6 +13460,8 @@ snapshots: hex-rgb@4.3.0: {} + hosted-git-info@2.8.9: {} + html-to-text@9.0.5: dependencies: '@selderee/plugin-htmlparser2': 0.11.0 @@ -13665,6 +13766,8 @@ snapshots: json-buffer@3.0.1: {} + json-parse-better-errors@1.0.2: {} + json-parse-even-better-errors@2.3.1: {} json-schema-traverse@0.4.1: {} @@ -13736,6 +13839,13 @@ snapshots: lines-and-columns@1.2.4: {} + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + loader-runner@4.3.0: {} loader-utils@2.0.4: @@ -13809,10 +13919,6 @@ snapshots: dependencies: yallist: 3.1.1 - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - lucide-react@0.414.0(react@18.3.1): dependencies: react: 18.3.1 @@ -14072,6 +14178,8 @@ snapshots: sonic-forest: 1.0.2(tslib@2.8.1) tslib: 2.8.1 + memorystream@0.3.1: {} + meow@12.1.1: {} merge-stream@2.0.0: {} @@ -14531,6 +14639,8 @@ snapshots: - '@babel/core' - babel-plugin-macros + nice-try@1.0.5: {} + no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -14546,10 +14656,29 @@ snapshots: dependencies: abbrev: 2.0.0 + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} normalize-range@0.1.2: {} + npm-run-all@4.1.5: + dependencies: + ansi-styles: 3.2.1 + chalk: 2.4.2 + cross-spawn: 6.0.6 + memorystream: 0.3.1 + minimatch: 3.1.2 + pidtree: 0.3.1 + read-pkg: 3.0.0 + shell-quote: 1.8.1 + string.prototype.padend: 3.1.6 + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -14699,6 +14828,11 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse-json@4.0.0: + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.24.6 @@ -14737,6 +14871,8 @@ snapshots: path-is-inside@1.0.2: {} + path-key@2.0.1: {} + path-key@3.1.1: {} path-key@4.0.0: {} @@ -14748,6 +14884,10 @@ snapshots: lru-cache: 10.0.2 minipass: 7.0.4 + path-type@3.0.0: + dependencies: + pify: 3.0.0 + path-type@4.0.0: {} pbf@3.3.0: @@ -14782,8 +14922,12 @@ snapshots: picomatch@3.0.1: {} + pidtree@0.3.1: {} + pify@2.3.0: {} + pify@3.0.0: {} + pify@4.0.1: {} pinkie-promise@2.0.1: @@ -15179,6 +15323,12 @@ snapshots: dependencies: pify: 2.3.0 + read-pkg@3.0.0: + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -15493,11 +15643,9 @@ snapshots: dependencies: parseley: 0.12.1 - semver@6.3.1: {} + semver@5.7.2: {} - semver@7.6.0: - dependencies: - lru-cache: 6.0.0 + semver@6.3.1: {} semver@7.6.3: {} @@ -15533,7 +15681,7 @@ snapshots: dependencies: color: 4.2.3 detect-libc: 2.0.3 - semver: 7.6.0 + semver: 7.6.3 optionalDependencies: '@img/sharp-darwin-arm64': 0.33.4 '@img/sharp-darwin-x64': 0.33.4 @@ -15555,10 +15703,16 @@ snapshots: '@img/sharp-win32-ia32': 0.33.4 '@img/sharp-win32-x64': 0.33.4 + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 + shebang-regex@1.0.0: {} + shebang-regex@3.0.0: {} shell-quote@1.8.1: {} @@ -15672,6 +15826,20 @@ snapshots: spawn-command@0.0.2: {} + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.21 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.21 + + spdx-license-ids@3.0.21: {} + split2@4.2.0: {} sprintf-js@1.0.3: {} @@ -15711,6 +15879,13 @@ snapshots: set-function-name: 2.0.2 side-channel: 1.0.6 + string.prototype.padend@3.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.1.1 + string.prototype.repeat@1.0.0: dependencies: define-properties: 1.2.1 @@ -15721,19 +15896,19 @@ snapshots: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string.prototype.trimend@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string_decoder@1.3.0: dependencies: @@ -16257,6 +16432,11 @@ snapshots: uuid@9.0.1: {} + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + vary@1.1.2: {} vaul@0.9.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -16571,8 +16751,6 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} - yaml@1.10.2: {} yaml@2.3.4: {} diff --git a/scripts/check-db.js b/scripts/check-db.js new file mode 100644 index 0000000..4fd746c --- /dev/null +++ b/scripts/check-db.js @@ -0,0 +1,96 @@ +/* eslint-disable no-console */ +require("dotenv").config(); +const { PrismaClient } = require("@prisma/client"); +const chalk = require("chalk"); +const { execSync } = require("child_process"); +const semver = require("semver"); + +if (process.env.SKIP_DB_CHECK === "true") { + console.log("Skipping database check."); + process.exit(0); +} + +function getDatabaseType(url = process.env.DATABASE_URL) { + const type = url && url.split(":")[0]; + + if (type === "postgres") { + return "postgresql"; + } + + return type; +} + +const prisma = new PrismaClient(); + +function success(msg) { + console.log(chalk.greenBright(`✓ ${msg}`)); +} + +function error(msg) { + console.log(chalk.redBright(`✗ ${msg}`)); +} + +async function checkEnv() { + if (!process.env.DATABASE_URL) { + throw new Error("DATABASE_URL is not defined."); + } else { + success("DATABASE_URL is defined."); + } +} + +async function checkConnection() { + try { + await prisma.$connect(); + + success("Database connection successful."); + } catch (e) { + throw new Error("Unable to connect to the database: " + e.message); + } +} + +async function checkDatabaseVersion() { + const query = await prisma.$queryRaw`select version() as version`; + const version = semver.valid(semver.coerce(query[0].version)); + + const databaseType = getDatabaseType(); + const minVersion = databaseType === "postgresql" ? "9.4.0" : "5.7.0"; + + if (semver.lt(version, minVersion)) { + throw new Error( + `Database version is not compatible. Please upgrade ${databaseType} version to ${minVersion} or greater`, + ); + } + + success("Database version check successful."); +} + +async function applyMigration() { + if (process.env.SKIP_DB_MIGRATION === "false") { + console.log(execSync("prisma generate").toString()); + console.log(execSync("prisma migrate deploy").toString()); + + success("Database is up to date."); + } +} + +(async () => { + let err = false; + for (let fn of [ + checkEnv, + checkConnection, + checkDatabaseVersion, + applyMigration, + ]) { + try { + await fn(); + } catch (e) { + error(e.message); + err = true; + } finally { + await prisma.$disconnect(); + if (err) { + process.exit(1); + } + } + } +})(); diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh deleted file mode 100644 index 58452c7..0000000 --- a/scripts/entrypoint.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# scripts/entrypoint.sh - -# 数据库初始化 - -retries=3 # 重试次数 -count=0 -echo "Running database initialization..." -until pnpm db:push || [ $count -ge $retries ]; do - echo "Database initialization failed, retrying ($((count + 1))/$retries)..." - count=$((count + 1)) - sleep 5 -done - -# 检查是否成功 -if [ $count -ge $retries ]; then - echo "Database initialization failed after $retries attempts." - exit 1 -fi - -echo "Database initialization successful." - -# 执行原始的启动命令 -echo "Starting the application..." -exec "$@" \ No newline at end of file