diff --git a/app/about/license/ThirdPartyLicenses.tsx b/app/about/license/ThirdPartyLicenses.tsx index 4b051e1..40c5617 100644 --- a/app/about/license/ThirdPartyLicenses.tsx +++ b/app/about/license/ThirdPartyLicenses.tsx @@ -1,18 +1,9 @@ "use client"; import { FallbackPre } from "@/markdown/styledSyntaxHighlighter"; +import { LicenseEntry } from "next-license-list"; import { useState } from "react"; -export interface LicenseEntry { - name: string; - version: string; - author?: string; - repository?: string; - source?: string; - license: string; - licenseText?: string; -} - export function ThirdPartyLicenses({ licenses }: { licenses: LicenseEntry[] }) { const [expanded, setExpanded] = useState(null); @@ -21,30 +12,6 @@ export function ThirdPartyLicenses({ licenses }: { licenses: LicenseEntry[] }) { {licenses.map((pkg) => { const key = `${pkg.name}@${pkg.version}`; const isOpen = expanded === key; - let repositoryURL: string | undefined = undefined; - if (pkg.repository?.startsWith("http")) { - repositoryURL = pkg.repository; - } else if (pkg.repository?.startsWith("git+http")) { - repositoryURL = pkg.repository?.slice(4); - } else if (pkg.repository?.startsWith("git@")) { - repositoryURL = - "https://" + - pkg.repository - .slice(4) - .replace(":", "/") - .replace(/\.git$/, ""); - } else if ( - pkg.repository && - /github:[\w-]+\/[\w-]+/.test(pkg.repository) - ) { - repositoryURL = `https://github.com/${pkg.repository.slice(7)}`; - } else if (pkg.repository && /[\w-]+\/[\w-]+/.test(pkg.repository)) { - // assume github username/repository - repositoryURL = `https://github.com/${pkg.repository}`; - } else { - // fallback to source url - // repositoryURL = pkg.source ?? ""; - } return (
)} - {repositoryURL && ( + {pkg.repository && (

Repository: - {repositoryURL} + {pkg.repository}

)} diff --git a/app/about/license/page.tsx b/app/about/license/page.tsx index 5d5515f..9a5cb01 100644 --- a/app/about/license/page.tsx +++ b/app/about/license/page.tsx @@ -1,11 +1,9 @@ import { Metadata } from "next"; import licenseText from "@/../LICENSE?raw"; -import { LicenseEntry, ThirdPartyLicenses } from "./ThirdPartyLicenses"; -import { isCloudflare } from "@/lib/detectCloudflare"; -import { getCloudflareContext } from "@opennextjs/cloudflare"; -import { readFile } from "node:fs/promises"; -import { join } from "node:path"; +import { ThirdPartyLicenses } from "./ThirdPartyLicenses"; import { StyledMarkdown } from "@/markdown/markdown"; +import { getLicenses, LicenseEntry } from "next-license-list"; +import { headers } from "next/headers"; export const metadata: Metadata = { title: "ライセンス", @@ -30,26 +28,8 @@ my.code(); は以下のオープンソースライブラリを使用していま `; export default async function LicensePage() { - let licenses: LicenseEntry[]; - if (isCloudflare()) { - const cfAssets = getCloudflareContext().env.ASSETS; - const res = await cfAssets!.fetch( - `https://assets.local/_next/static/oss-licenses.json` - ); - licenses = await res.json(); - } else { - licenses = JSON.parse( - await readFile( - join( - process.cwd(), - process.env.NODE_ENV === "development" - ? ".next/dev/static/oss-licenses.json" - : ".next/static/oss-licenses.json" - ), - "utf-8" - ) - ); - } + await headers(); + const licenses: LicenseEntry[] = await getLicenses(); return (
diff --git a/next.config.ts b/next.config.ts index ff1378c..3354e8c 100644 --- a/next.config.ts +++ b/next.config.ts @@ -2,13 +2,13 @@ import type { NextConfig } from "next"; import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare"; import { PyodidePlugin } from "@pyodide/webpack-plugin"; import { version as pyodideVersion } from "pyodide/package.json"; -import LicensePlugin from "webpack-license-plugin"; import { dirname } from "node:path"; import { withSentryConfig } from "@sentry/nextjs"; +import { withLicense } from "next-license-list/config"; initOpenNextCloudflareForDev(); -const nextConfig: NextConfig = { +let nextConfig: NextConfig = { /* config options here */ output: "standalone", experimental: { @@ -59,7 +59,7 @@ const nextConfig: NextConfig = { }, ]; }, - webpack: (config, { isServer }) => { + webpack: (config) => { config.plugins.push( new PyodidePlugin({ // public/ 以下に書き出すと404 @@ -85,28 +85,6 @@ const nextConfig: NextConfig = { resourceQuery: /raw/, type: "asset/source", }); - // クライアントビルドのみサードパーティライセンスを /_next/static/oss-licenses.json に出力 - if (!isServer) { - config.plugins.push( - new LicensePlugin({ - outputFilename: "static/oss-licenses.json", - includeNoticeText: true, - excludedPackageTest: (packageName /*, version*/) => { - return ( - packageName.startsWith("@my-code") || packageName === "my-code" - ); - }, - licenseOverrides: { - "@better-auth/core@1.4.20": "MIT", - "@better-fetch/fetch@1.1.21": "MIT", - }, - includePackages: () => - ["tailwindcss", "daisyui", "@fontsource/m-plus-rounded-1c"].map( - (pkg) => dirname(import.meta.resolve(`${pkg}/package.json`)) - ), - }) - ); - } return config; }, async redirects() { @@ -183,7 +161,21 @@ const nextConfig: NextConfig = { }, }; -export default withSentryConfig(nextConfig, { +nextConfig = withLicense(nextConfig, { + includeNoticeText: true, + excludedPackageTest: (packageName /*, version*/) => { + return packageName.startsWith("@my-code") || packageName === "my-code"; + }, + licenseOverrides: { + "@better-auth/core@1.4.20": "MIT", + "@better-fetch/fetch@1.1.21": "MIT", + }, + includePackages: () => + ["tailwindcss", "daisyui", "@fontsource/m-plus-rounded-1c"].map((pkg) => + dirname(import.meta.resolve(`${pkg}/package.json`)) + ), +}); +nextConfig = withSentryConfig(nextConfig, { org: process.env.SENTRY_ORG, project: process.env.SENTRY_PROJECT, sentryUrl: process.env.SENTRY_URL, @@ -210,3 +202,5 @@ export default withSentryConfig(nextConfig, { excludeReplayWorker: true, }, }); + +export default nextConfig; diff --git a/package-lock.json b/package-lock.json index 714008b..75af1d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "js-yaml": "^4.1.1", "mocha": "^11.7.4", "next": "^16.2.3", + "next-license-list": "^1.0.0", "pg": "^8.16.3", "prismjs": "^1.30.0", "react": "^19", @@ -5568,8 +5569,7 @@ "optional": true, "os": [ "android" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-android-arm64": { "version": "4.59.0", @@ -5582,8 +5582,7 @@ "optional": true, "os": [ "android" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.59.0", @@ -5596,8 +5595,7 @@ "optional": true, "os": [ "darwin" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-darwin-x64": { "version": "4.59.0", @@ -5610,8 +5608,7 @@ "optional": true, "os": [ "darwin" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-freebsd-arm64": { "version": "4.59.0", @@ -5624,8 +5621,7 @@ "optional": true, "os": [ "freebsd" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-freebsd-x64": { "version": "4.59.0", @@ -5638,8 +5634,7 @@ "optional": true, "os": [ "freebsd" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { "version": "4.59.0", @@ -5652,8 +5647,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { "version": "4.59.0", @@ -5666,8 +5660,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.59.0", @@ -5680,8 +5673,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { "version": "4.59.0", @@ -5694,8 +5686,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { "version": "4.59.0", @@ -5708,8 +5699,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { "version": "4.59.0", @@ -5722,8 +5712,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { "version": "4.59.0", @@ -5736,8 +5725,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { "version": "4.59.0", @@ -5750,8 +5738,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.59.0", @@ -5764,8 +5751,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { "version": "4.59.0", @@ -5778,8 +5764,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.59.0", @@ -5792,8 +5777,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.59.0", @@ -5806,8 +5790,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.59.0", @@ -5820,8 +5803,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-openbsd-x64": { "version": "4.59.0", @@ -5834,8 +5816,7 @@ "optional": true, "os": [ "openbsd" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-openharmony-arm64": { "version": "4.59.0", @@ -5848,8 +5829,7 @@ "optional": true, "os": [ "openharmony" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.59.0", @@ -5862,8 +5842,7 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { "version": "4.59.0", @@ -5876,8 +5855,7 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { "version": "4.59.0", @@ -5890,8 +5868,7 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.59.0", @@ -5904,8 +5881,7 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@rtsao/scc": { "version": "1.1.0", @@ -15554,7 +15530,6 @@ "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", - "devOptional": true, "license": "MIT" }, "node_modules/lodash.clonedeep": { @@ -17298,7 +17273,6 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/needle/-/needle-3.5.0.tgz", "integrity": "sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==", - "dev": true, "license": "MIT", "dependencies": { "iconv-lite": "^0.6.3", @@ -17315,7 +17289,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -17403,6 +17376,15 @@ } } }, + "node_modules/next-license-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-license-list/-/next-license-list-1.0.0.tgz", + "integrity": "sha512-0hYMohlSJ9xjwePTVhjxl82PaJ/2I2mXFRENDm3sCqJ4QfECjdMwqNJbfWCeR+dND04T5PSnGXrapi9v53Xccg==", + "license": "0BSD", + "dependencies": { + "webpack-license-plugin": "^4" + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -19496,7 +19478,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", - "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=11.0.0" @@ -19999,14 +19980,12 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", @@ -20017,7 +19996,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz", "integrity": "sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==", - "dev": true, "license": "(MIT AND CC-BY-3.0)", "dependencies": { "spdx-expression-parse": "^3.0.0" @@ -20027,7 +20005,6 @@ "version": "3.0.23", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", - "dev": true, "license": "CC0-1.0" }, "node_modules/split2": { @@ -21815,7 +21792,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=18" } @@ -21832,7 +21808,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -21849,7 +21824,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -21866,7 +21840,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -21883,7 +21856,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=18" } @@ -21900,7 +21872,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=18" } @@ -21917,7 +21888,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -21934,7 +21904,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -21951,7 +21920,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -21968,7 +21936,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -21985,7 +21952,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -22002,7 +21968,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -22019,7 +21984,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -22036,7 +22000,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -22053,7 +22016,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -22070,7 +22032,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -22087,7 +22048,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -22104,7 +22064,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -22121,7 +22080,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -22138,7 +22096,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -22155,7 +22112,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -22172,7 +22128,6 @@ "os": [ "openharmony" ], - "peer": true, "engines": { "node": ">=18" } @@ -22189,7 +22144,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=18" } @@ -22206,7 +22160,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -22223,7 +22176,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -22240,7 +22192,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -22592,7 +22543,6 @@ "version": "4.5.1", "resolved": "https://registry.npmjs.org/webpack-license-plugin/-/webpack-license-plugin-4.5.1.tgz", "integrity": "sha512-WbjMSMPHzFePCSQJqP0qFskGPSwdf3JxIoXa1SK3d1hCXQee7KUrIb+riyXUId71kcHOSyE12pTyrhMl1ozszA==", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^5.3.0", diff --git a/package.json b/package.json index 7a937fa..b0accfe 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "js-yaml": "^4.1.1", "mocha": "^11.7.4", "next": "^16.2.3", + "next-license-list": "^1.0.0", "pg": "^8.16.3", "prismjs": "^1.30.0", "react": "^19",