diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 619b8e4..0a9c591 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -31,3 +31,7 @@ jobs: - run: pnpm install --frozen-lockfile - run: pnpm run lint + + - name: Check formatting + if: always() + run: pnpm run format:check diff --git a/.gitignore b/.gitignore index 8d052cc..b47c4fa 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,9 @@ # misc .DS_Store *.pem -.vscode +.vscode/* +!.vscode/settings.json +!.vscode/extensions.json .venv # debug diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..699ed73 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["biomejs.biome"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a845516 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "biomejs.biome", + "[javascript]": { "editor.defaultFormatter": "biomejs.biome" }, + "[javascriptreact]": { "editor.defaultFormatter": "biomejs.biome" }, + "[typescript]": { "editor.defaultFormatter": "biomejs.biome" }, + "[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" }, + "[json]": { "editor.defaultFormatter": "biomejs.biome" }, + "[jsonc]": { "editor.defaultFormatter": "biomejs.biome" }, + "[css]": { "editor.defaultFormatter": "biomejs.biome" } +} diff --git a/biome.json b/biome.json index 774dc75..a3680fb 100644 --- a/biome.json +++ b/biome.json @@ -1,13 +1,13 @@ { "$schema": "https://biomejs.dev/schemas/2.1.2/schema.json", "vcs": { - "enabled": false, + "enabled": true, "clientKind": "git", - "useIgnoreFile": false + "useIgnoreFile": true }, "files": { - "ignoreUnknown": false, - "includes": ["./**/*.ts", "./**/*.tsx"] + "ignoreUnknown": true, + "includes": ["**", "!**/lib/app_localization/**", "!**/locales/**", "!contentful/export.json"] }, "formatter": { "enabled": true, @@ -87,5 +87,10 @@ "organizeImports": "on" } } + }, + "css": { + "formatter": { + "quoteStyle": "single" + } } } diff --git a/knip.config.js b/knip.config.js index d3ea7fd..9f1194e 100644 --- a/knip.config.js +++ b/knip.config.js @@ -1,8 +1,4 @@ export default { - entry: [ - 'pages/**/*.{js,ts,tsx}', - 'app/**/*.{js,ts,tsx}', - 'src/pages/**/*.{js,ts,tsx}', - ], + entry: ['pages/**/*.{js,ts,tsx}', 'app/**/*.{js,ts,tsx}', 'src/pages/**/*.{js,ts,tsx}'], project: ['**/*.{js,ts,tsx}', '!node_modules/**'], }; diff --git a/next.config.js b/next.config.js index 3b0bc68..12d9446 100644 --- a/next.config.js +++ b/next.config.js @@ -2,51 +2,50 @@ const withSvgr = require('@newhighsco/next-plugin-svgr'); const isDev = process.env.NODE_ENV === 'development'; -const baseCsp = (isDev) => [ - "default-src 'self'", - `script-src 'self' ${isDev ? "'unsafe-eval' 'unsafe-inline'" : "'unsafe-inline'"} *.ctfassets.net *.youtube.com *.twitter.com donorbox.org`, - "child-src 'self' *.ctfassets.net *.youtube.com player.vimeo.com *.twitter.com donorbox.org", - "style-src 'self' 'unsafe-inline' *.googleapis.com", - "img-src 'self' blob: data: *.ctfassets.net *.youtube.com *.twitter.com", - "media-src 'self' *.youtube.com", - "connect-src *", - "font-src 'self' blob: data: fonts.gstatic.com maxcdn.bootstrapcdn.com", - "worker-src 'self' blob:", -].join('; '); +const baseCsp = (isDev) => + [ + "default-src 'self'", + `script-src 'self' ${isDev ? "'unsafe-eval' 'unsafe-inline'" : "'unsafe-inline'"} *.ctfassets.net *.youtube.com *.twitter.com donorbox.org`, + "child-src 'self' *.ctfassets.net *.youtube.com player.vimeo.com *.twitter.com donorbox.org", + "style-src 'self' 'unsafe-inline' *.googleapis.com", + "img-src 'self' blob: data: *.ctfassets.net *.youtube.com *.twitter.com", + "media-src 'self' *.youtube.com", + 'connect-src *', + "font-src 'self' blob: data: fonts.gstatic.com maxcdn.bootstrapcdn.com", + "worker-src 'self' blob:", + ].join('; '); // Donate page uses a wide-open CSP — Donorbox dynamically loads PayPal, Stripe, // Google Maps, reCAPTCHA, FingerprintJS and other SDKs at runtime that are // impossible to fully enumerate. We lock down only what we can safely restrict // (no arbitrary workers, no data: scripts) and leave the rest open. -const donateCsp = (isDev) => [ - "default-src *", - `script-src * 'unsafe-inline' ${isDev ? "'unsafe-eval'" : ""}`, - "style-src * 'unsafe-inline'", - "img-src * blob: data:", - "font-src * blob: data:", - "frame-src *", - "connect-src *", - "child-src * blob:", - "worker-src 'self' blob:", -].join('; '); +const donateCsp = (isDev) => + [ + 'default-src *', + `script-src * 'unsafe-inline' ${isDev ? "'unsafe-eval'" : ''}`, + "style-src * 'unsafe-inline'", + 'img-src * blob: data:', + 'font-src * blob: data:', + 'frame-src *', + 'connect-src *', + 'child-src * blob:', + "worker-src 'self' blob:", + ].join('; '); const redirects = [ { source: '/android', - destination: - 'https://play.google.com/store/apps/details?id=network.loki.messenger', + destination: 'https://play.google.com/store/apps/details?id=network.loki.messenger', permanent: true, }, { source: '/apk', - destination: - 'https://github.com/session-foundation/session-android/releases', + destination: 'https://github.com/session-foundation/session-android/releases', permanent: true, }, { source: '/iphone', - destination: - 'https://apps.apple.com/app/session-private-messenger/id1470168868?ls=1', + destination: 'https://apps.apple.com/app/session-private-messenger/id1470168868?ls=1', permanent: true, }, { @@ -58,27 +57,29 @@ const redirects = [ const isTranslateMode = process.env.NEXT_PUBLIC_TRANSLATION_MODE === 'true'; -process.env.ENVIRONMENT_FALLBACK = 'en' +process.env.ENVIRONMENT_FALLBACK = 'en'; // TODO: enable all available locales as we get them fully translated -const locales = !isTranslateMode ? [ - 'en', // English - 'zh-CN', // Chinese Simplified - // 'zh-TW', // Chinese Traditional - 'cs', // Czech - 'nl', // Dutch - 'fr', // French - 'de', // German - 'hi', // Hindi - // 'hu', // Hungarian - 'it', // Italian - 'ja', // Japanese - 'pl', // Polish - // 'pt', // Portuguese - // 'ro', // Romanian - 'es', // Spanish - // 'sv', // Swedish -] : ['ach']; +const locales = !isTranslateMode + ? [ + 'en', // English + 'zh-CN', // Chinese Simplified + // 'zh-TW', // Chinese Traditional + 'cs', // Czech + 'nl', // Dutch + 'fr', // French + 'de', // German + 'hi', // Hindi + // 'hu', // Hungarian + 'it', // Italian + 'ja', // Japanese + 'pl', // Polish + // 'pt', // Portuguese + // 'ro', // Romanian + 'es', // Spanish + // 'sv', // Swedish + ] + : ['ach']; // @ts-check /** @type {import('next').NextConfig} */ @@ -108,10 +109,8 @@ const nextConfig = { CONTENTFUL_PREVIEW_TOKEN: process.env.CONTENTFUL_PREVIEW_TOKEN, CAMPAIGN_MONITOR_CLIENT_ID: process.env.CAMPAIGN_MONITOR_CLIENT_ID, CAMPAIGN_MONITOR_API_KEY: process.env.CAMPAIGN_MONITOR_API_KEY, - CAMPAIGN_MONITOR_LIST_SESSION_ID: - process.env.CAMPAIGN_MONITOR_LIST_SESSION_ID, - CAMPAIGN_MONITOR_LIST_MARKET_RESEARCH_ID: - process.env.CAMPAIGN_MONITOR_LIST_MARKET_RESEARCH_ID, + CAMPAIGN_MONITOR_LIST_SESSION_ID: process.env.CAMPAIGN_MONITOR_LIST_SESSION_ID, + CAMPAIGN_MONITOR_LIST_MARKET_RESEARCH_ID: process.env.CAMPAIGN_MONITOR_LIST_MARKET_RESEARCH_ID, MAILERLITE_API_KEY: process.env.MAILERLITE_API_KEY, MAILERLITE_GROUP_ID: process.env.MAILERLITE_GROUP_ID, NEXT_PUBLIC_TRANSLATION_MODE: process.env.NEXT_PUBLIC_TRANSLATION_MODE, diff --git a/package.json b/package.json index eb1ed1e..ea2a339 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "lint": "biome lint", "lint:fix": "biome lint --write", "format": "biome format --write", + "format:check": "biome format", "check": "biome check", "check:fix": "biome check --write" }, diff --git a/pages/[slug].tsx b/pages/[slug].tsx index 9fcff81..301d303 100644 --- a/pages/[slug].tsx +++ b/pages/[slug].tsx @@ -43,8 +43,6 @@ function shouldBuildSlug(slug: string): boolean { } } - console.log(forbiddenWords) - for (const w of forbiddenWords) { if (slug.includes(w)) { return false; diff --git a/styles/globals.css b/styles/globals.css index 0a19a0e..c58af94 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -14,7 +14,7 @@ --gray-light: #55595c; --gray-DEFAULT: #3a3a3a; --gray-dark: #333132; - --border: #DFDFDF; + --border: #dfdfdf; --radius: 0.625rem; --background: oklch(1 0 0); --foreground: oklch(0.145 0 0); @@ -52,8 +52,7 @@ @font-face { font-family: 'PublicSans'; font-display: swap; - src: url('../public/assets/fonts/PublicSans/PublicSans-VariableFont_wght.ttf') - format('truetype'); + src: url('../public/assets/fonts/PublicSans/PublicSans-VariableFont_wght.ttf') format('truetype'); font-weight: 100 900; font-style: normal; } @@ -72,8 +71,7 @@ @font-face { font-family: 'SpaceMono'; font-display: swap; - src: url('../public/assets/fonts/SpaceMono/SpaceMono-Regular.ttf') - format('truetype'); + src: url('../public/assets/fonts/SpaceMono/SpaceMono-Regular.ttf') format('truetype'); font-weight: 400; font-style: normal; } @@ -82,8 +80,7 @@ @font-face { font-family: 'SpaceMono'; font-display: swap; - src: url('../public/assets/fonts/SpaceMono/SpaceMono-Bold.ttf') - format('truetype'); + src: url('../public/assets/fonts/SpaceMono/SpaceMono-Bold.ttf') format('truetype'); font-weight: 700; font-style: normal; } @@ -92,8 +89,7 @@ @font-face { font-family: 'SpaceMono'; font-display: swap; - src: url('../public/assets/fonts/SpaceMono/SpaceMono-Italic.ttf') - format('truetype'); + src: url('../public/assets/fonts/SpaceMono/SpaceMono-Italic.ttf') format('truetype'); font-weight: 400; font-style: italic; } @@ -102,8 +98,7 @@ @font-face { font-family: 'SpaceMono'; font-display: swap; - src: url('../public/assets/fonts/SpaceMono/SpaceMono-BoldItalic.ttf') - format('truetype'); + src: url('../public/assets/fonts/SpaceMono/SpaceMono-BoldItalic.ttf') format('truetype'); font-weight: 700; font-style: italic; } @@ -111,8 +106,8 @@ /** Icon font * Current: Lucide v0.488.0 * Download from https://github.com/lucide-icons/lucide/releases -* NOTE Make sure the lucide-react package is the same version -*/ + * NOTE Make sure the lucide-react package is the same version + */ @font-face { font-family: 'Lucide'; src: url('../public/assets/fonts/lucide.ttf') format('truetype'); diff --git a/tailwind.config.js b/tailwind.config.js index 586450e..4575a3f 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -49,8 +49,8 @@ module.exports = { dark: 'var(--gray-dark)', }, border: { - DEFAULT: 'var(--border)' - } + DEFAULT: 'var(--border)', + }, }, height: { 120: '30rem', // for larger images @@ -80,8 +80,5 @@ module.exports = { transitionDuration: ['group-hover'], }, }, - plugins: [ - require('@tailwindcss/forms'), - require('tailwindcss-selection-variant'), - ], + plugins: [require('@tailwindcss/forms'), require('tailwindcss-selection-variant')], }; diff --git a/tsconfig.json b/tsconfig.json index b9ea7c4..bc56881 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,8 +21,6 @@ // "noUnusedParameters": true, /* report errors on unused parameters (again, suggested for clean code writing) */ "incremental": true }, - "include": [ - "global.d.ts", - "next-env.d.ts", "additional.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["global.d.ts", "next-env.d.ts", "additional.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules", ".next", "out"] }