diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 8c62cd4eaa..f2e5180bc6 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -20,26 +20,21 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - - - name: 📦 Install dependencies - run: pnpm install + cache: true - name: 🎨 Check for non-RTL/non-a11y CSS classes - run: pnpm vp run lint:css + run: vp run lint:css - name: 🌐 Compare translations - run: pnpm vp run i18n:check + run: vp run i18n:check - name: 🌍 Update lunaria data - run: pnpm vp run build:lunaria + run: vp run build:lunaria - name: 🔠 Fix lint errors - run: pnpm vp run lint:fix + run: vp run lint:fix - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 # 635ffb0c9798bd160680f18fd73371e355b85f27 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23963aed01..b200db6654 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,18 +28,16 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm + run-install: false - name: 📦 Install dependencies (root only, no scripts) - run: pnpm install --filter . --ignore-scripts + run: vp install --filter . --ignore-scripts - name: 🔠 Lint project - run: pnpm vp run lint + run: vp run lint types: name: 💪 Type check @@ -48,18 +46,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - - - name: 📦 Install dependencies - run: pnpm install + cache: true - name: 💪 Type check - run: pnpm vp run test:types + run: vp run test:types unit: name: 🧪 Unit tests @@ -68,18 +61,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - - - name: 📦 Install dependencies - run: pnpm install + cache: true - name: 🧪 Unit tests - run: pnpm vp test --project unit --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml + run: vp test --project unit --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml - name: ⬆︎ Upload test results to Codecov if: ${{ !cancelled() }} @@ -94,31 +82,26 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - - - name: 📦 Install dependencies - run: pnpm install + cache: true - name: 🌐 Install browser - run: pnpm vp exec playwright install chromium-headless-shell + run: vp exec playwright install chromium-headless-shell - name: 🧪 Component tests - run: pnpm vp test --project nuxt --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml + run: vp test --project nuxt --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml - name: ⬆︎ Upload coverage reports to Codecov - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 + uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 with: report_type: test_results env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: ⬆︎ Upload coverage reports to Codecov - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 + uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} @@ -131,23 +114,18 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - - - name: 📦 Install dependencies - run: pnpm install + cache: true - name: 🏗️ Build project - run: pnpm vp run build:test + run: vp run build:test env: VALIDATE_HTML: true - name: 🖥️ Test project (browser) - run: pnpm vp run test:browser:prebuilt + run: vp run test:browser:prebuilt a11y: name: ♿ Accessibility audit @@ -159,21 +137,16 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - - - name: 📦 Install dependencies - run: pnpm install + cache: true - name: 🏗️ Build project - run: pnpm vp run build:test + run: vp run build:test - name: ♿ Accessibility audit (Lighthouse - ${{ matrix.mode }} mode) - run: pnpm vp run test:a11y:prebuilt + run: vp run test:a11y:prebuilt env: LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }} LIGHTHOUSE_COLOR_MODE: ${{ matrix.mode }} @@ -185,18 +158,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - - - name: 📦 Install dependencies - run: pnpm install + cache: true - name: 🧹 Check for unused code - run: pnpm vp run knip + run: vp run knip i18n: name: 🌐 i18n validation @@ -205,20 +173,18 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm + run-install: false - name: 📦 Install dependencies (root only, no scripts) - run: pnpm install --filter . --ignore-scripts + run: vp install --filter . --ignore-scripts - name: 🌐 Check for missing or dynamic i18n keys - run: pnpm vp run i18n:report + run: vp run i18n:report - name: 🌐 Check i18n schema is up to date run: | - pnpm vp run i18n:schema + vp run i18n:schema git diff --exit-code i18n/schema.json diff --git a/.github/workflows/lunaria.yml b/.github/workflows/lunaria.yml index b2bc818360..5755c01952 100644 --- a/.github/workflows/lunaria.yml +++ b/.github/workflows/lunaria.yml @@ -28,15 +28,10 @@ jobs: # Makes the action clone the entire git history fetch-depth: 0 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - - - name: 📦 Install dependencies - run: pnpm install + cache: true - name: Generate Lunaria Overview uses: lunariajs/action@4911ad0736d1e3b20af4cb70f5079aea2327ed8e # v1-prerelease diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index fc244db18e..ac5d2e81e4 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -20,9 +20,10 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* + run-install: false - name: 🔍 Check for unreleased commits id: check diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index 331540e6d9..9a1cbeeaf5 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -23,9 +23,10 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* + run-install: false - name: 🔢 Determine next version id: version @@ -58,13 +59,9 @@ jobs: git tag -a "$VERSION" -m "Release $VERSION" git push origin "$VERSION" - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - if: steps.check.outputs.skip == 'false' - name: 🟧 Install pnpm - - name: 📦 Install dependencies if: steps.check.outputs.skip == 'false' - run: pnpm vp install --filter . --ignore-scripts + run: vp install --filter . --ignore-scripts - name: 📝 Generate release notes if: steps.check.outputs.skip == 'false' @@ -98,18 +95,14 @@ jobs: with: ref: release - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: voidzero-dev/setup-vp@73e69397a8b289de4b1d017ced18e18004183bb1 # v1 with: node-version: lts/* registry-url: https://registry.npmjs.org - - - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c - name: 🟧 Install pnpm - with: - cache: false + run-install: false - name: 📦 Install dependencies - run: pnpm install --filter npmx-connector... + run: vp install --filter npmx-connector... - name: 🔢 Set connector version env: @@ -122,7 +115,7 @@ jobs: echo "Publishing npmx-connector@${PKG_VERSION}" - name: 🏗️ Build connector - run: pnpm --filter npmx-connector build + run: vp run --filter npmx-connector build - name: 📤 Publish to npm with provenance # Uses OIDC trusted publishing — no NPM_TOKEN needed. diff --git a/.storybook/main.ts b/.storybook/main.ts index 04f806021c..14b9305e21 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,8 +1,13 @@ import type { StorybookConfig } from '@storybook-vue/nuxt' const config = { - stories: ['../app/**/*.stories.@(js|ts)'], - addons: ['@storybook/addon-a11y', '@storybook/addon-docs', '@storybook/addon-themes'], + stories: ['../.storybook/*.mdx', '../app/**/*.stories.@(js|ts)'], + addons: [ + '@storybook/addon-a11y', + '@storybook/addon-docs', + '@storybook/addon-themes', + 'storybook-i18n', + ], framework: '@storybook-vue/nuxt', staticDirs: ['./.public'], features: { @@ -11,6 +16,33 @@ const config = { async viteFinal(newConfig) { newConfig.plugins ??= [] + // Bridge compatibility between Storybook v10 core and v9 @storybook-vue/nuxt + // v10 expects module federation globals that v9 doesn't provide + newConfig.plugins.push({ + name: 'storybook-v10-compat', + transformIndexHtml: { + order: 'pre', + handler(html) { + const script = ` +` + return html.replace(/ + + diff --git a/app/components/BlueskyComment.vue b/app/components/BlueskyComment.vue index 12fe336a1f..c9078f0e06 100644 --- a/app/components/BlueskyComment.vue +++ b/app/components/BlueskyComment.vue @@ -38,16 +38,27 @@ function getHostname(uri: string): string { return uri } } + +let segmenter: Intl.Segmenter | null = null +function firstChar(str: string): string { + segmenter ??= new Intl.Segmenter(undefined, { granularity: 'grapheme' }) + return Array.from(segmenter.segment(str))[0]?.segment ?? '' +}