diff --git a/.env.example b/.env.example index beff9e50c4..dd95e80fa1 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ -#secure password, can use openssl rand -hex 32 +# secure password, can use `openssl rand -hex 32` NUXT_SESSION_PASSWORD="" -#HMAC secret for image proxy URL signing, can use openssl rand -hex 32 -NUXT_IMAGE_PROXY_SECRET="" \ No newline at end of file +# HMAC secret for image-proxy and OG image URL signing, can use `openssl rand -hex 32` +NUXT_IMAGE_PROXY_SECRET="" diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 9e9a183b22..20598ffe2d 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,5 +1,7 @@ name: "\U0001F41E Bug report" description: Create a report to help us improve npmx +type: bug +labels: ['pending triage'] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index 3d1d430bd1..20ad6fce08 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -1,5 +1,6 @@ name: '๐Ÿš€ Feature request' description: Suggest a feature that will improve npmx +type: feature labels: ['pending triage'] body: - type: markdown diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index d4df4beaa9..bf77cb7d6a 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -9,6 +9,10 @@ on: branches: - main +concurrency: + group: ${{ github.workflow }}-${{ github.event.number || github.ref }} + cancel-in-progress: true + permissions: contents: read @@ -19,8 +23,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true @@ -37,4 +43,4 @@ jobs: - name: ๐Ÿ”  Fix lint errors run: vp run lint:fix - - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 # 635ffb0c9798bd160680f18fd73371e355b85f27 + - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 # v1.3.2 diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index df3a3ea8b0..8361c6237d 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -25,8 +25,9 @@ jobs: fetch-depth: 0 repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} ref: ${{ github.event.pull_request.head.sha || github.sha }} + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 654a07fc0e..5fb1196b7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,8 +27,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* run-install: false @@ -45,8 +47,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true @@ -60,8 +64,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true @@ -81,8 +87,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true @@ -109,12 +117,17 @@ jobs: name: ๐Ÿ–ฅ๏ธ Browser tests runs-on: ubuntu-24.04-arm container: - image: mcr.microsoft.com/playwright:v1.58.2-noble + image: mcr.microsoft.com/playwright:v1.58.2-noble@sha256:6446946a1d9fd62d9ae501312a2d76a43ee688542b21622056a372959b65d63d steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - name: ๐Ÿ‘‘ Fix Git ownership + run: git config --global --add safe.directory /__w/npmx.dev/npmx.dev + + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true @@ -136,8 +149,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true @@ -157,8 +172,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true @@ -172,8 +189,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* run-install: false diff --git a/.github/workflows/dependency-diff-comment.yml b/.github/workflows/dependency-diff-comment.yml index 8cb277bde7..4295dfb772 100644 --- a/.github/workflows/dependency-diff-comment.yml +++ b/.github/workflows/dependency-diff-comment.yml @@ -6,15 +6,20 @@ on: types: - completed -permissions: - pull-requests: write - actions: read +concurrency: + group: ${{ github.workflow }}-${{ github.event.workflow_run.id }} + cancel-in-progress: true + +permissions: {} jobs: dependency-diff-comment: name: ๐Ÿ’ฌ Dependency diff comment runs-on: ubuntu-slim if: github.event.workflow_run.conclusion == 'success' + permissions: + pull-requests: write # post dependency diff comments on pull requests + actions: read # download artifacts from dependency-diff runs steps: - name: ๐Ÿ“ฅ Download artifact diff --git a/.github/workflows/dependency-diff.yml b/.github/workflows/dependency-diff.yml index afc1070f9c..ef8984539f 100644 --- a/.github/workflows/dependency-diff.yml +++ b/.github/workflows/dependency-diff.yml @@ -28,6 +28,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: ๐Ÿ”Ž Compare dependencies id: analyze @@ -35,7 +36,8 @@ jobs: with: mode: artifact detect-replacements: 'true' - duplicate-threshold: '4' + # Too noisy. Disabling until this can report on duplicate CHANGES in this PR. + duplicate-threshold: '999' dependency-threshold: '15' size-threshold: '200000' diff --git a/.github/workflows/deploy-canary.yml b/.github/workflows/deploy-canary.yml new file mode 100644 index 0000000000..d938f749e1 --- /dev/null +++ b/.github/workflows/deploy-canary.yml @@ -0,0 +1,34 @@ +name: Deploy canary + +on: + push: + branches: [main] + +permissions: + contents: read + +concurrency: + group: deploy-canary-${{ github.ref }} + cancel-in-progress: true + +jobs: + deploy-canary: + if: github.repository == 'npmx-dev/npmx.dev' + name: ๐Ÿš€ Deploy to canary (main.npmx.dev) + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 + with: + node-version: lts/* + run-install: false + + - run: vp install -g vercel + - run: vercel deploy --target=canary + env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} diff --git a/.github/workflows/lunaria.yml b/.github/workflows/lunaria.yml index 51f83389d0..633a455289 100644 --- a/.github/workflows/lunaria.yml +++ b/.github/workflows/lunaria.yml @@ -10,15 +10,15 @@ concurrency: group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.ref }} cancel-in-progress: true -# Allow this job to clone the repository and comment on the pull request -permissions: - contents: read - pull-requests: write +permissions: {} jobs: lunaria-overview: name: ๐ŸŒ Generate Lunaria Overview runs-on: ubuntu-24.04-arm + permissions: + contents: read + pull-requests: write # post Lunaria overview comments on pull requests steps: - name: Checkout @@ -27,11 +27,12 @@ jobs: # Necessary for Lunaria to work properly # Makes the action clone the entire git history fetch-depth: 0 + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* cache: true - name: Generate Lunaria Overview - uses: lunariajs/action@4911ad0736d1e3b20af4cb70f5079aea2327ed8e # v1-prerelease + uses: lunariajs/action@4911ad0736d1e3b20af4cb70f5079aea2327ed8e # astro-docs diff --git a/.github/workflows/mirror-tangled.yml b/.github/workflows/mirror-tangled.yml index 8759487d06..adae34ae0c 100644 --- a/.github/workflows/mirror-tangled.yml +++ b/.github/workflows/mirror-tangled.yml @@ -7,6 +7,10 @@ on: tags: - '*' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read @@ -20,6 +24,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: ๐Ÿ”‘ Configure SSH env: diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 6ab11c41d8..23a517c374 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -5,22 +5,28 @@ on: branches: - main -permissions: - contents: read - pull-requests: write +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: {} jobs: release-pr: name: ๐Ÿš€ Create or update release PR runs-on: ubuntu-slim if: github.repository == 'npmx-dev/npmx.dev' + permissions: + contents: read + pull-requests: write # create or update the release pull request steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* run-install: false diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index 659042c5ab..703e3e575e 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -5,6 +5,10 @@ on: branches: - release +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: {} jobs: @@ -13,7 +17,7 @@ jobs: runs-on: ubuntu-slim if: github.repository == 'npmx-dev/npmx.dev' permissions: - contents: write + contents: write # create release tags and GitHub releases outputs: version: ${{ steps.version.outputs.next }} skipped: ${{ steps.check.outputs.skip }} @@ -22,8 +26,9 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: true - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* run-install: false @@ -87,15 +92,16 @@ jobs: if: needs.tag.outputs.skipped == 'false' permissions: contents: read - id-token: write + id-token: write # authenticate npm trusted publishing via OIDC environment: npm-publish steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: release + persist-credentials: false - - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1 + - uses: voidzero-dev/setup-vp@8ecb39174989ce55af90f45cf55b02738599831d # v1.6.0 with: node-version: lts/* registry-url: https://registry.npmjs.org diff --git a/.github/workflows/semantic-pull-requests.yml b/.github/workflows/semantic-pull-requests.yml index ebbad4f932..c1718123bf 100644 --- a/.github/workflows/semantic-pull-requests.yml +++ b/.github/workflows/semantic-pull-requests.yml @@ -7,6 +7,10 @@ on: - edited - synchronize +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + permissions: {} jobs: diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000000..8367d2614f --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,49 @@ +name: Stale Issues and PRs + +on: + schedule: + # Run daily at 2 AM UTC + - cron: '0 2 * * *' + workflow_dispatch: # Allow manual trigger + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +permissions: {} + +jobs: + stale-bugs: + name: ๐Ÿงน Mark stale bug issues + runs-on: ubuntu-latest + permissions: + issues: write # mark and close stale bug issues + steps: + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 + with: + days-before-issue-stale: 30 + days-before-issue-close: 7 + days-before-pr-stale: -1 + days-before-pr-close: -1 + remove-stale-when-updated: true + only-issue-types: 'bug' + stale-issue-label: 'stale' + close-issue-label: 'stale' + operations-per-run: 500 + + stale-prs: + name: ๐Ÿงน Mark stale pull requests + runs-on: ubuntu-latest + permissions: + pull-requests: write # mark and close stale pull requests + steps: + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 + with: + days-before-issue-stale: -1 + days-before-issue-close: -1 + days-before-pr-stale: 30 + days-before-pr-close: 7 + remove-stale-when-updated: true + stale-pr-label: 'stale' + close-pr-label: 'stale' + operations-per-run: 500 diff --git a/.github/workflows/welcome-close.yml b/.github/workflows/welcome-close.yml index 8dcae51db0..a29ab4fec3 100644 --- a/.github/workflows/welcome-close.yml +++ b/.github/workflows/welcome-close.yml @@ -5,6 +5,10 @@ on: types: - closed +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + permissions: {} jobs: diff --git a/.github/workflows/welcome-open.yml b/.github/workflows/welcome-open.yml index ccdb5f8cbd..544592b124 100644 --- a/.github/workflows/welcome-open.yml +++ b/.github/workflows/welcome-open.yml @@ -5,16 +5,21 @@ on: branches: [main] types: [opened] -permissions: - pull-requests: write +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: {} jobs: greeting: name: Greet First-Time Contributors if: github.repository == 'npmx-dev/npmx.dev' runs-on: ubuntu-latest + permissions: + pull-requests: write # post first-time contributor greeting comments steps: - - uses: zephyrproject-rtos/action-first-interaction@58853996b1ac504b8e0f6964301f369d2bb22e5c + - uses: zephyrproject-rtos/action-first-interaction@58853996b1ac504b8e0f6964301f369d2bb22e5c # tag=v1.1.1+zephyr.6 with: repo-token: ${{ secrets.GITHUB_TOKEN }} pr-opened-message: | diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000000..e3454a5dbe --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,38 @@ +# https://docs.zizmor.sh/ +name: zizmor + +on: + pull_request: + branches: + - main + push: + branches: + - main + merge_group: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.number || github.sha }} + cancel-in-progress: true + +permissions: {} + +jobs: + zizmor: + name: ๐ŸŒˆ GitHub Actions security analysis + runs-on: ubuntu-24.04-arm + permissions: + contents: read # checkout repository + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 + with: + persona: pedantic + # Use annotations instead of SARIF as this doesn't need special permissions + annotations: true + advanced-security: false diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000000..0190ff6e67 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,14 @@ +# Existing privileged PR automation is intentionally isolated to these workflows: +# they do not checkout pull request head code, and they only comment or set status. +rules: + stale-action-refs: + ignore: + # lunariajs/action has no tag refs; keep the branch commit hash-pinned. + - lunaria.yml:38 + dangerous-triggers: + ignore: + - dependency-diff-comment.yml + - lunaria.yml + - semantic-pull-requests.yml + - welcome-close.yml + - welcome-open.yml diff --git a/.nuxtrc b/.nuxtrc index 1e1fe8339e..640f280a3b 100644 --- a/.nuxtrc +++ b/.nuxtrc @@ -1 +1 @@ -setups.@nuxt/test-utils="4.0.0" \ No newline at end of file +setups.@nuxt/test-utils="4.0.3" \ No newline at end of file diff --git a/.storybook/main.ts b/.storybook/main.ts index 8e14495eb5..e7f7270185 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -5,8 +5,7 @@ import { resolve } from 'node:path' const config = { stories: [ // List welcome first in sidebar - '../.storybook/docs/welcome.mdx', - '../.storybook/docs/*.mdx', + '../app/storybook/welcome.mdx', '../app/**/*.@(mdx|stories.@(js|ts))', ], addons: [ diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html index f644bb7435..c626f23ef8 100644 --- a/.storybook/preview-head.html +++ b/.storybook/preview-head.html @@ -61,3 +61,19 @@ background-color: var(--bg, oklch(0.171 0 0)) !important; } + diff --git a/.storybook/preview.ts b/.storybook/preview.ts index 30d8f6cfcb..e64a50168e 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -10,18 +10,8 @@ import npmxDark from './theme' initialize() -// related: https://github.com/npmx-dev/npmx.dev/blob/1431d24be555bca5e1ae6264434d49ca15173c43/test/nuxt/setup.ts#L12-L26 -// Stub Nuxt specific globals // @ts-expect-error - dynamic global name -globalThis['__NUXT_COLOR_MODE__'] ??= { - preference: 'system', - value: 'dark', - getColorScheme: fn(() => 'dark'), - addColorScheme: fn(), - removeColorScheme: fn(), -} -// @ts-expect-error - dynamic global name -globalThis.defineOgImageComponent = fn() +globalThis.defineOgImage = fn() // Subscribe to locale changes from storybook-i18n addon (once, outside decorator) let currentI18nInstance: any = null diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b6cd39f1c8..ed7189c6ca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -123,6 +123,7 @@ pnpm mock-connector # Start the mock connector (no npm login needed) pnpm vp run lint # Run linter (oxlint + oxfmt) pnpm lint:fix # Auto-fix lint issues pnpm test:types # TypeScript type checking +pnpm vp run zizmor # GitHub Actions security analysis # Testing pnpm test # Run all Vitest tests @@ -133,6 +134,28 @@ pnpm test:a11y # Lighthouse accessibility audits pnpm test:perf # Lighthouse performance audits (CLS) ``` +### GitHub Actions security analysis + +CI runs [zizmor](https://docs.zizmor.sh/) against the repository's GitHub Actions workflows. The shared policy lives in `.github/zizmor.yml`, and the `zizmor` task uses the same pedantic persona as CI. + +You may run it locally by [installing `zizmor`](https://docs.zizmor.sh/installation/) and running: + +```bash +pnpm vp run zizmor +``` + +Some audits resolve action refs and vulnerability metadata through GitHub. To run those online checks locally, authenticate with the GitHub CLI and pass its token: + +```bash +GH_TOKEN="$(gh auth token)" pnpm vp run zizmor +``` + +To fix audit findings automatically, run: + +```bash +GH_TOKEN="$(gh auth token)" pnpm vp run zizmor:fix +``` + ### Clearing caches during development Nitro persists `defineCachedEventHandler` results to disk at `.nuxt/cache/nitro/`. This cache **survives dev server restarts**. If you're iterating on a cached API route and want fresh results, delete the relevant cache directory: @@ -348,7 +371,7 @@ Ideally, extract utilities into separate files so they can be unit tested. ๐Ÿ™ ### Internal linking -Always use **object syntax with named routes** for internal navigation. This makes links resilient to URL structure changes and provides type safety via `unplugin-vue-router`. +Always use **object syntax with named routes** for internal navigation. This makes links resilient to URL structure changes and provides type safety with the [typedPages Nuxt option](https://nuxt.com/docs/4.x/guide/going-further/experimental-features#typedpages). ```vue diff --git a/app/app.vue b/app/app.vue index 510fb719ed..34fc1d5c01 100644 --- a/app/app.vue +++ b/app/app.vue @@ -127,6 +127,10 @@ if (import.meta.client) { useEventListener(document, 'click', handleModalLightDismiss) } } + +// title and description will be inferred +// this will be overridden by upstream pages that use different templates +defineOgImage('Page.takumi', {}, { alt: 'npmx โ€” a fast, modern browser for the npm registry' })