example-package
+A short description of what this package does.
+diff --git a/.github/agentscan.yml b/.github/agentscan.yml new file mode 100644 index 0000000000..0104707937 --- /dev/null +++ b/.github/agentscan.yml @@ -0,0 +1,20 @@ +version: 1 +trusted-author-associations: + - owner + - member +honeypot: true +mode: labels +messages: + honeypot-first-time: |- + Hello! Thank you for opening your **first PR** to npmx, **@{username}**! ๐ + + Here's what will happen next: + + 1. Our GitHub bots will run to check your changes.\ + If they spot any issues, you will see some error messages on this PR.\ + Don't hesitate to ask any questions if you're not sure what these mean! + + 2. In a few minutes, you'll be able to see a preview of your changes on Vercel + + 3. One or more of our maintainers will take a look and may ask you to make changes.\ + We try to be responsive, but don't worry if this takes a few days. diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 00b98ae8e7..a2a42daf2b 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -22,11 +22,11 @@ jobs: runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 72795a3b3c..55bab726b7 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -20,21 +20,21 @@ jobs: steps: - name: โ๏ธ Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: 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@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true sfw: true - name: ๐งช Run Chromatic Visual and Accessibility Tests - uses: chromaui/action@94713c544284a14195de3b50ef24301579f1877e # v18.0.1 + uses: chromaui/action@14cfaef73576e69f95f47f60058063f46ca38719 # v18.1.0 with: buildCommand: vp run build-storybook outputDir: storybook-static diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 123cb48fc8..63df86eecf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,11 +26,11 @@ jobs: runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* sfw: true @@ -46,11 +46,11 @@ jobs: runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true @@ -64,11 +64,11 @@ jobs: runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true @@ -103,11 +103,11 @@ jobs: runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true @@ -144,17 +144,24 @@ jobs: name: ๐ฅ๏ธ Browser tests runs-on: ubuntu-24.04-arm container: - image: mcr.microsoft.com/playwright:v1.61.1-noble@sha256:5b8f294aff9041b7191c34a4bab3ac270157a28774d4b0660e9743297b697e48 + image: mcr.microsoft.com/playwright:v1.62.1-noble@sha256:dcc5531e97840b9b5e794f2814476b21571c5124a3fca2267d73041f56e7580e steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: ๐ Fix Git ownership run: git config --global --add safe.directory /__w/npmx.dev/npmx.dev - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + # Required to build better-sqlite3 for docs presumably because of the + # use of the playwright container. We should remove this if we stop having + # to build better-sqlite3 and the prebuilt binary starts working. + - name: ๐ง Install build tools + run: apt-get update && apt-get install --yes build-essential + shell: bash + + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true @@ -188,11 +195,11 @@ jobs: mode: [dark, light] steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true @@ -212,11 +219,11 @@ jobs: runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true @@ -230,11 +237,11 @@ jobs: runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* sfw: true diff --git a/.github/workflows/dependency-diff.yml b/.github/workflows/dependency-diff.yml index bd64e8ba7d..4a04d8766a 100644 --- a/.github/workflows/dependency-diff.yml +++ b/.github/workflows/dependency-diff.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/deploy-canary.yml b/.github/workflows/deploy-canary.yml index 679a918fa7..50e4132738 100644 --- a/.github/workflows/deploy-canary.yml +++ b/.github/workflows/deploy-canary.yml @@ -17,12 +17,12 @@ jobs: name: ๐ Deploy to canary (main.npmx.dev) runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false fetch-depth: 2 - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* run-install: false diff --git a/.github/workflows/lunaria.yml b/.github/workflows/lunaria.yml index 8ef40235c4..65dc1f1dc9 100644 --- a/.github/workflows/lunaria.yml +++ b/.github/workflows/lunaria.yml @@ -22,14 +22,14 @@ jobs: steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # 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@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* cache: true diff --git a/.github/workflows/mirror-tangled.yml b/.github/workflows/mirror-tangled.yml index 2e6e083e6b..cfabd9ea83 100644 --- a/.github/workflows/mirror-tangled.yml +++ b/.github/workflows/mirror-tangled.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index f208d99a52..c869505852 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -21,12 +21,12 @@ jobs: pull-requests: write # create or update the release pull request steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* run-install: false diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index e9690fbc82..be5fb70fe6 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -23,12 +23,12 @@ jobs: skipped: ${{ steps.check.outputs.skip }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: true - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* run-install: false @@ -66,7 +66,7 @@ jobs: - name: ๐ฆ Install dependencies if: steps.check.outputs.skip == 'false' - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: sfw: true run-install: | @@ -100,19 +100,19 @@ jobs: environment: npm-publish steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: release persist-credentials: false - - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + - uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: node-version: lts/* registry-url: https://registry.npmjs.org run-install: false - name: ๐ฆ Install dependencies - uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1.15.0 + uses: voidzero-dev/setup-vp@313600b80b104eadebb9111787d37a2e83e014ca # v1.17.0 with: sfw: true run-install: | diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 82e13a418c..a02e7eea3e 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -19,7 +19,7 @@ jobs: permissions: issues: write # mark and close stale bug issues steps: - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 with: days-before-issue-stale: 30 days-before-issue-close: 7 @@ -37,7 +37,7 @@ jobs: permissions: pull-requests: write # mark and close stale pull requests steps: - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 with: days-before-issue-stale: -1 days-before-issue-close: -1 diff --git a/.github/workflows/welcome-open.yml b/.github/workflows/welcome-open.yml deleted file mode 100644 index 544592b124..0000000000 --- a/.github/workflows/welcome-open.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Welcome Message - -on: - pull_request_target: - branches: [main] - types: [opened] - -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 # tag=v1.1.1+zephyr.6 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - pr-opened-message: | - Hello! Thank you for opening your **first PR** to npmx, @${{ github.event.pull_request.user.login }}! ๐ - - Hereโs what will happen next: - - 1. Our GitHub bots will run to check your changes. - If they spot any issues you will see some error messages on this PR. - Donโt hesitate to ask any questions if youโre not sure what these mean! - - 2. In a few minutes, youโll be able to see a preview of your changes on Vercel - - 3. One or more of our maintainers will take a look and may ask you to make changes. - We try to be responsive, but donโt worry if this takes a few days. diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 55d7a59ab0..6135e3efbe 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -26,11 +26,11 @@ jobs: contents: read # checkout repository steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7 + - uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2 with: persona: pedantic # Use annotations instead of SARIF as this doesn't need special permissions diff --git a/.storybook/main.ts b/.storybook/main.ts index e7f7270185..98ce1928ed 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -13,6 +13,7 @@ const config = { '@storybook/addon-docs', '@storybook/addon-themes', 'storybook-i18n', + 'msw-storybook-addon', ], framework: '@storybook-vue/nuxt', staticDirs: ['./.public', { from: '../public', to: '/' }], diff --git a/.storybook/preview.ts b/.storybook/preview.ts index e64a50168e..291056cc4b 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -4,12 +4,10 @@ import { addons } from 'storybook/preview-api' import { currentLocales } from '../config/i18n' import { fn } from 'storybook/test' import { ACCENT_COLORS } from '../shared/utils/constants' -import { initialize, mswLoader } from 'msw-storybook-addon' +import { mswLoader } from 'msw-storybook-addon/csf3' import npmxDark from './theme' -initialize() - // @ts-expect-error - dynamic global name globalThis.defineOgImage = fn() @@ -69,11 +67,16 @@ const preview: Preview = { attributeName: 'data-theme', }), (story, context) => { - const { accentColor, locale } = context.globals as { + const { accentColor, locale, theme } = context.globals as { accentColor?: string locale?: string + theme?: string } + const themeClass = theme === 'Light' ? 'light' : 'dark' + document.documentElement.classList.remove('light', 'dark') + document.documentElement.classList.add(themeClass) + // Set accent color from globals if (accentColor) { document.documentElement.style.setProperty('--accent-color', `var(--swatch-${accentColor})`) @@ -95,7 +98,7 @@ const preview: Preview = { } }, ], - loaders: [mswLoader], + loaders: [mswLoader()], } export default preview diff --git a/.vscode/settings.json b/.vscode/settings.json index ead94c6acf..d03f13095a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,5 +7,20 @@ "explorer.fileNesting.enabled": true, "explorer.fileNesting.patterns": { "*.vue": "${capture}.stories.ts" + }, + "[json]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + }, + "[jsonc]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + }, + "[vue]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + }, + "[yaml]": { + "editor.defaultFormatter": "oxc.oxc-vscode" } } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 237d15a28d..9eb942b099 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,7 +63,6 @@ This focus helps guide our project decisions as a community and what we choose t - [Test fixtures (mocking external APIs)](#test-fixtures-mocking-external-apis) - [Storybook](#storybook) - [Component categories](#component-categories) - - [Coverage guidelines](#coverage-guidelines) - [Project conventions](#project-conventions) - [Configuration](#configuration) - [Global app settings](#global-app-settings) @@ -82,8 +81,10 @@ This focus helps guide our project decisions as a community and what we choose t ### Prerequisites -- [Node.js](https://nodejs.org/) (LTS version recommended) -- [pnpm](https://pnpm.io/) v10.28.1 or later +- [Node.js](https://nodejs.org/) +- [pnpm](https://pnpm.io/) + +Please use the version pinned in the `engines.node` and `packageManager` field of [package.json](./package.json). ### Setup @@ -100,7 +101,13 @@ This focus helps guide our project decisions as a community and what we choose t pnpm dev ``` -4. (optional) if you want to test the admin UI/flow, you can run the local connector: +4. start the connector with mock data: + + ```bash + pnpm mock-connector + ``` + + or with real data (requires npm login): ```bash pnpm npmx-connector @@ -169,7 +176,7 @@ rm -rf .nuxt/cache/nitro/handlers/ rm -rf .nuxt/cache/nitro/handlers/npmx-picks/ ``` -Alternatively, you can bypass the cache entirely in development by adding `shouldBypassCache: () => import.meta.dev` to your `defineCachedEventHandler` options: +Alternatively, you can bypass the cache for a specific API entirely in development by adding `shouldBypassCache: () => import.meta.dev` to your `defineCachedEventHandler` options: ```ts export default defineCachedEventHandler( @@ -227,7 +234,7 @@ The connector will check your npm authentication, generate a connection token, a ### Mock connector (for local development) -If you're working on admin features (org management, package access controls, operations queue) and don't want to use your real npm account, you can run the mock connector instead: +If you don't want to use your real npm account, you can run the mock connector instead: ```bash pnpm mock-connector @@ -257,11 +264,9 @@ pnpm mock-connector --empty # start with no prepopulated data ## Code style -When committing changes, try to keep an eye out for unintended formatting updates. These can make a pull request look noisier than it really is and slow down the review process. Sometimes IDEs automatically reformat files on save, which can unintentionally introduce extra changes. - -To help with this, the project uses `oxfmt` to handle formatting via a pre-commit hook. The hook will automatically reformat files when needed. If something canโt be fixed automatically, it will let you know what needs to be updated before you can commit. +When committing changes, try to keep an eye out for unintended formatting updates. These can make a pull request look noisier than it really is and slow down the review process. Sometimes IDEs automatically reformat files on save, which can unintentionally introduce extra changes if your formatter is not configured correctly. To prevent this, you can configure your IDE to use `oxc` as the formatter, which is aligned with the linter used inside the workflows for this project. -If you want to get ahead of any formatting issues, you can also run `pnpm lint:fix` before committing to fix formatting across the whole project. +Before you commit, staged files will automatically be linted and formatted using a [pre-commit hook](#pre-commit-hooks). Alternatively, you can manually run `pnpm lint:fix` before committing to fix formatting across the whole project. ### npmx name @@ -706,9 +711,7 @@ import { MyComponent } from '#components' describe('MyComponent', () => { it('should have no accessibility violations', async () => { const component = await mountSuspended(MyComponent, { - props: { - /* required props */ - }, + props: {/* required props */}, }) const results = await runAxe(component) expect(results.violations).toEqual([]) @@ -798,7 +801,7 @@ docker run --rm \ -e NODE_OPTIONS="--max-old-space-size=4096" \ -v $(pwd):/work \ -w /work \ - mcr.microsoft.com/playwright:v1.58.2-noble \ + mcr.microsoft.com/playwright:v1.62.1-noble \ sh -c "npm install -g pnpm && pnpm install && pnpm vp run build:test && pnpm vp run test:browser:prebuilt --update-snapshots" ``` @@ -829,6 +832,16 @@ Fixtures are stored in `test/fixtures/` with this structure: ``` test/fixtures/ +โโโ algolia/ +โ โโโ search/ # Algolia search results +โโโ esm-sh/ +โ โโโ doc-nodes/ # Parsed documentation nodes (exports, types, functions) +โ โโโ headers/ # esm.sh response headers (used to resolve type declarations) +โ โโโ types/ # TypeScript type declaration files +โโโ github/ # GitHub API responses (contributor stats) +โโโ jsdelivr/ # jsDelivr Data API responses (package file lists) +โโโ jsdelivr-cdn/ # jsDelivr CDN responses (raw package file content) +โโโ microlink/ # Microlink API responses (homepage link previews) โโโ npm-registry/ โ โโโ packuments/ # Package metadata (vue.json, @nuxt/kit.json) โ โโโ search/ # Search results (vue.json, nuxt.json) @@ -885,7 +898,6 @@ cli/src/ โโโ mock-app.ts # H3 mock app + MockConnectorServer class โโโ mock-server.ts # CLI entry point (pnpm mock-connector) -test/test-utils/ # Re-exports from cli/src/ for test convenience test/e2e/helpers/ # E2E-specific wrappers (fixtures, global setup) ``` @@ -974,14 +986,10 @@ Single-use components that encapsulate one feature. - **Testing focus:** Layout, responsive behavior, integration testing - **Coverage:** Critical user flows and breakpoints -### Coverage guidelines - -#### Which Components Need Stories? - -TBD - ### Project conventions +Stories should follow the [Component Story Format (CSF)](https://storybook.js.org/docs/api/csf). + #### Place `.stories.ts` files next to the component ```sh @@ -1228,7 +1236,16 @@ This provides the following benefits: ## Pre-commit hooks -The project uses `lint-staged` with `simple-git-hooks` to automatically lint files on commit. +Before committing, the following things will run against staged files: + +- **`*.{js,ts,mjs,cjs,vue}`** - `vp lint --fix` (auto-fix lint errors) +- **`*.vue`** - UnoCSS class checker +- **`*.{js,ts,mjs,cjs,vue,json,yml,md,html,css}`** - `vp fmt` (auto-format) +- **`i18n/locales/*`** - regenerate Lunaria tracking data and `i18n/schema.json` + +If something can't be fixed automatically, the commit will be blocked. Run `pnpm lint:fix` beforehand to resolve any issues proactively. + +The configuration for the pre-commit hook is defined in the [`staged` block of vite.config.ts](vite.config.ts#L168-L174) and is automatically installed by running `vp config`, which will run any time you run `pnpm install`. ## Using AI diff --git a/app/app.vue b/app/app.vue index 03fc939fb5..738d278529 100644 --- a/app/app.vue +++ b/app/app.vue @@ -154,7 +154,9 @@ if (!isBlogPostRoute.value) { {{ route.name === 'search' ? `${$t('search.title_packages')} - npmx` : message }} -
A short description of what this package does.
+{{ $t('changelog.error.p1', { package: pkgName }) }}
diff --git a/app/components/Changelog/Markdown.vue b/app/components/Changelog/Markdown.vue index a81fd86541..7c5dc9558e 100644 --- a/app/components/Changelog/Markdown.vue +++ b/app/components/Changelog/Markdown.vue @@ -8,9 +8,14 @@ const { info, goToVersion, tpTarget, resolveVersionPending } = defineProps<{ const route = useRoute() -const { data, error, pending } = useLazyFetch( - () => `/api/changelog/md/${info.provider}/${info.repo}/${info.path}`, -) +const url = computed(() => `/api/changelog/md/${info.provider}/${info.repo}/${info.path}` as const) +const host = computed(() => info.host) + +const { data, error, pending } = useLazyFetch(url, { + query: { + host, + }, +}) if (import.meta.client) { const { settings } = useSettings() @@ -18,7 +23,7 @@ if (import.meta.client) { // doing this server side can make it that we go to the homepage const stopWatching = watchEffect( () => { - if (resolveVersionPending) { + if (resolveVersionPending || typeof data.value == 'string') { return // need to wait till resolving is finished } const toc = data.value?.toc @@ -50,11 +55,33 @@ if (import.meta.client) { // stops watchEffect from trigger just before navigating onBeforeRouteLeave(stopWatching) } + +// fetch raw markdown to copy +const { + data: rawMarkdown, + execute: fetchMarkdown, + status: mdStatus, +} = useLazyFetchA mock package.
', + playgroundLinks: [], + toc: [], + }, +} + +const meta = { + component: Header, + tags: ['autodocs'], + args: { + loading: false, + isViewingFile: true, + isBinaryFile: false, + fileContent, + filePath: 'src/utils/format.ts', + markdownViewMode: 'preview', + selectedLines: null, + getCodeUrlWithPath, + packageName: 'mock-package', + version: '1.0.0', + }, +} satisfies Meta
+ This drawer only renders below the md breakpoint. Switch to a narrow viewport to see it.
+
with one
+// `.line` span per line. Inline color styles keep the sample self-contained.
+const lines = [
+ `export function greet(name: string) {`,
+ ` return \`Hello, \${name}!\``,
+ `}`,
+]
+
+const html = `${lines
+ .map(line => `${line}`)
+ .join('\n')}
`
+
+const meta = {
+ component: Viewer,
+ tags: ['autodocs'],
+ args: {
+ html,
+ lines: lines.length,
+ selectedLines: null,
+ },
+ decorators: [
+ () => ({
+ template: ' ',
+ }),
+ ],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+/** Syntax-highlighted file with line numbers. */
+export const Default: Story = {}
+
+/** A range of lines highlighted, as when linking to a permalink. */
+export const WithSelectedLines: Story = {
+ args: {
+ selectedLines: { start: 2, end: 2 },
+ },
+}
diff --git a/app/components/CollapsibleSection.stories.ts b/app/components/CollapsibleSection.stories.ts
new file mode 100644
index 0000000000..dd2b613ee9
--- /dev/null
+++ b/app/components/CollapsibleSection.stories.ts
@@ -0,0 +1,69 @@
+import type { Meta, StoryObj } from '@storybook-vue/nuxt'
+import CollapsibleSection from './CollapsibleSection.vue'
+
+const meta = {
+ component: CollapsibleSection,
+ tags: ['autodocs'],
+ args: {
+ id: 'demo-section',
+ title: 'Dependencies',
+ },
+ render: args => ({
+ components: { CollapsibleSection },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+ - vue@3.4.0
+ - vue-router@4.2.0
+ - pinia@2.1.0
+
+
+ `,
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+/** Expanded section with a heading, anchor link and collapse toggle. */
+export const Default: Story = {}
+
+/** A secondary line of context beneath the title. */
+export const WithSubtitle: Story = {
+ args: {
+ id: 'demo-section-subtitle',
+ subtitle: '3 direct dependencies',
+ },
+}
+
+/** Spinner in place of the chevron while content is being fetched. */
+export const Loading: Story = {
+ args: {
+ id: 'demo-section-loading',
+ isLoading: true,
+ },
+}
+
+/** The `actions` slot renders controls on the right of the header. */
+export const WithActions: Story = {
+ render: args => ({
+ components: { CollapsibleSection },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+
+ Section body content.
+
+ `,
+ }),
+ args: {
+ id: 'demo-section-actions',
+ },
+}
diff --git a/app/components/Compare/FacetBarChart.vue b/app/components/Compare/FacetBarChart.vue
index 181786f1f0..276770dc46 100644
--- a/app/components/Compare/FacetBarChart.vue
+++ b/app/components/Compare/FacetBarChart.vue
@@ -11,6 +11,7 @@ import { createPatternDef } from 'vue-data-ui/utils'
import { drawSmallNpmxLogoAndTaglineWatermark } from '~/composables/useChartWatermark'
import { useColors } from '~/composables/useColors'
import { downloadFileLink } from '~/utils/download'
+import { useCopyChartPng } from '~/composables/useCopyChartPng'
import {
insertLineBreaks,
@@ -35,6 +36,8 @@ const resolvedMode = shallowRef<'light' | 'dark'>('light')
const rootEl = shallowRef(null)
const { width } = useElementSize(rootEl)
const { copy, copied } = useClipboard()
+const chartRef = useTemplateRef('chartRef')
+const { copiedPng, isCopyingPng, copyChartPng } = useCopyChartPng(chartRef)
const mobileBreakpointWidth = 640
const isMobile = computed(() => width.value > 0 && width.value < mobileBreakpointWidth)
@@ -271,7 +274,7 @@ const config = computed(() => {