From 2a441069e4db79c0b77d874d60b21a48e4b6f56e Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 20:51:40 +0000 Subject: [PATCH 01/14] test: add wasm case for `detectModuleFormat` --- test/unit/shared/utils/package-analysis.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/unit/shared/utils/package-analysis.spec.ts b/test/unit/shared/utils/package-analysis.spec.ts index b4a572ac4a..9be81e232d 100644 --- a/test/unit/shared/utils/package-analysis.spec.ts +++ b/test/unit/shared/utils/package-analysis.spec.ts @@ -122,6 +122,10 @@ describe('detectModuleFormat', () => { }), ).toBe('esm') }) + + it('detects WASM from main field', () => { + expect(detectModuleFormat({ main: 'main.wasm' })).toBe('wasm') + }) }) describe('detectTypesStatus', () => { From 43d3244a34524509041a440a5901cc93af1bef46 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 20:56:39 +0000 Subject: [PATCH 02/14] feat: add `wasm` detection --- shared/utils/package-analysis.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared/utils/package-analysis.ts b/shared/utils/package-analysis.ts index 57ed391d82..f79c27717f 100644 --- a/shared/utils/package-analysis.ts +++ b/shared/utils/package-analysis.ts @@ -2,7 +2,7 @@ * Package analysis utilities for detecting module format and TypeScript support */ -export type ModuleFormat = 'esm' | 'cjs' | 'dual' | 'unknown' +export type ModuleFormat = 'esm' | 'cjs' | 'dual' | 'wasm' | 'unknown' export type TypesStatus = | { kind: 'included' } @@ -87,6 +87,11 @@ export function detectModuleFormat(pkg: ExtendedPackageJson): ModuleFormat { return mainIsCJS ? 'dual' : 'esm' } + + const mainIsWASM = pkg.main?.endsWith('.wasm') + if (mainIsWASM) { + return 'wasm' + } if (hasModule || isTypeModule) { return 'esm' From bf9f754db3557f9f42d1d0b35b35a2fb96280a49 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 20:57:32 +0000 Subject: [PATCH 03/14] chore: format files --- shared/utils/package-analysis.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/utils/package-analysis.ts b/shared/utils/package-analysis.ts index f79c27717f..18908c3832 100644 --- a/shared/utils/package-analysis.ts +++ b/shared/utils/package-analysis.ts @@ -87,7 +87,7 @@ export function detectModuleFormat(pkg: ExtendedPackageJson): ModuleFormat { return mainIsCJS ? 'dual' : 'esm' } - + const mainIsWASM = pkg.main?.endsWith('.wasm') if (mainIsWASM) { return 'wasm' From 1c8e4f8182dbb26485ed750bd01500394fdfd1ff Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 21:15:10 +0000 Subject: [PATCH 04/14] feat: add WASM badge fix: Update CONTRIBUTING.md i18n: add `package.metrics.wasm` key --- CONTRIBUTING.md | 5 +- app/components/Package/MetricsBadges.vue | 71 ++++++++++++++---------- i18n/locales/en.json | 3 +- i18n/schema.json | 3 + 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cc6afeb794..4034b8df58 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -462,11 +462,8 @@ The following scripts help manage translation files. `en.json` is the reference | Command | Description | | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `pnpm i18n:check [locale]` | Compares `en.json` with other locale files. Shows missing and extra keys. Optionally filter output by locale (e.g. `pnpm i18n:check ja-JP`). | -| `pnpm i18n:check:fix [locale]` | Same as check, but adds missing keys to other locales with English placeholders. | -| `pnpm i18n:report` | Audits translation keys against code usage in `.vue` and `.ts` files. Reports missing keys (used in code but not in locale), unused keys (in locale but not in code), and dynamic keys. | +| `pnpm i18n:check:fix [locale]` | Adds missing keys to other locales with English placeholders. | | `pnpm i18n:report:fix` | Removes unused keys from `en.json` and all other locale files. | -| `pnpm i18n:schema` | Generates a JSON Schema from `en.json` at `i18n/schema.json`. Locale files reference this schema for IDE validation and autocompletion. | ### Adding a new locale diff --git a/app/components/Package/MetricsBadges.vue b/app/components/Package/MetricsBadges.vue index b749df5288..4c07a29fea 100644 --- a/app/components/Package/MetricsBadges.vue +++ b/app/components/Package/MetricsBadges.vue @@ -26,6 +26,11 @@ const hasCjs = computed(() => { return analysis.value.moduleFormat === 'cjs' || analysis.value.moduleFormat === 'dual' }) +const isWasm = computed(() => { + if (!analysis.value) return false + return analysis.value.moduleFormat === 'wasm' +}) + // Types support const hasTypes = computed(() => { if (!analysis.value) return false @@ -80,35 +85,45 @@ const typesHref = computed(() => { - -
  • - - - ESM - - -
  • + - -
  • - - + +
  • + - CJS - - -
  • + + ESM + + + + + +
  • + + + CJS + + +
  • + diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 4d241f522d..2ab5640c25 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -530,8 +530,9 @@ }, "metrics": { "esm": "ES Modules supported", - "cjs": "CommonJS supported", + "cjs": "CommonJS supported",, "no_esm": "ES Modules unsupported", + "wasm": "Has Web Assembly" "types_label": "Types", "types_included": "Types included", "types_available": "Types available via {package}", diff --git a/i18n/schema.json b/i18n/schema.json index ff41df4289..b0a4076d62 100644 --- a/i18n/schema.json +++ b/i18n/schema.json @@ -1600,6 +1600,9 @@ "no_esm": { "type": "string" }, + "wasm": { + "type": "string" + }, "types_label": { "type": "string" }, From 8c3e7ef656c9559aa4f60121ecb2fd20bb823556 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 21:20:58 +0000 Subject: [PATCH 05/14] fix --- i18n/locales/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 2ab5640c25..c6e874f541 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -530,9 +530,9 @@ }, "metrics": { "esm": "ES Modules supported", - "cjs": "CommonJS supported",, + "cjs": "CommonJS supported", "no_esm": "ES Modules unsupported", - "wasm": "Has Web Assembly" + "wasm": "Has Web Assembly", "types_label": "Types", "types_included": "Types included", "types_available": "Types available via {package}", From 6a53f8bcaa76b3d85ee606507a61e78d37ca3bb2 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 21:22:26 +0000 Subject: [PATCH 06/14] [autofix.ci] apply automated fixes --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4034b8df58..11073ec915 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -460,10 +460,10 @@ npmx.dev uses [@nuxtjs/i18n](https://i18n.nuxtjs.org/) for internationalization. The following scripts help manage translation files. `en.json` is the reference locale. -| Command | Description | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `pnpm i18n:check:fix [locale]` | Adds missing keys to other locales with English placeholders. | -| `pnpm i18n:report:fix` | Removes unused keys from `en.json` and all other locale files. | +| Command | Description | +| ------------------------------ | -------------------------------------------------------------- | +| `pnpm i18n:check:fix [locale]` | Adds missing keys to other locales with English placeholders. | +| `pnpm i18n:report:fix` | Removes unused keys from `en.json` and all other locale files. | ### Adding a new locale From f6fbdc90464fb2d88edec1cb3f1b2571eab0e979 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 22:25:26 +0000 Subject: [PATCH 07/14] Update en.json --- i18n/locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/locales/en.json b/i18n/locales/en.json index c6e874f541..ef4fa618fb 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -532,7 +532,7 @@ "esm": "ES Modules supported", "cjs": "CommonJS supported", "no_esm": "ES Modules unsupported", - "wasm": "Has Web Assembly", + "wasm": "Has WebAssembly", "types_label": "Types", "types_included": "Types included", "types_available": "Types available via {package}", From 670cdb7c3386e58f025a0bb167e616677acff2e6 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 22:29:11 +0000 Subject: [PATCH 08/14] Update CONTRIBUTING.md --- CONTRIBUTING.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 11073ec915..eb69954592 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -460,10 +460,13 @@ npmx.dev uses [@nuxtjs/i18n](https://i18n.nuxtjs.org/) for internationalization. The following scripts help manage translation files. `en.json` is the reference locale. -| Command | Description | -| ------------------------------ | -------------------------------------------------------------- | -| `pnpm i18n:check:fix [locale]` | Adds missing keys to other locales with English placeholders. | -| `pnpm i18n:report:fix` | Removes unused keys from `en.json` and all other locale files. | +| Command | Description | +| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `pnpm vp run i18n:check [locale]` | Compares `en.json` with other locale files. Shows missing and extra keys. Optionally filter output by locale (e.g. `pnpm i18n:check ja-JP`). | +| `pnpm vp run i18n:check:fix [locale]` | Same as check, but adds missing keys to other locales with English placeholders. | +| `pnpm vp run i18n:report` | Audits translation keys against code usage in `.vue` and `.ts` files. Reports missing keys (used in code but not in locale), unused keys (in locale but not in code), and dynamic keys. | +| `pnpm vp run i18n:report:fix` | Removes unused keys from `en.json` and all other locale files. | +| `pnpm vp run i18n:schema` | Generates a JSON Schema from `en.json` at `i18n/schema.json`. Locale files reference this schema for IDE validation and autocompletion. | ### Adding a new locale From 4cafe3b9d4de4d7269b2f73209c8993fbe8f0fe7 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:30:43 +0000 Subject: [PATCH 09/14] [autofix.ci] apply automated fixes --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb69954592..3af9d98c41 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -460,7 +460,7 @@ npmx.dev uses [@nuxtjs/i18n](https://i18n.nuxtjs.org/) for internationalization. The following scripts help manage translation files. `en.json` is the reference locale. -| Command | Description | +| Command | Description | | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `pnpm vp run i18n:check [locale]` | Compares `en.json` with other locale files. Shows missing and extra keys. Optionally filter output by locale (e.g. `pnpm i18n:check ja-JP`). | | `pnpm vp run i18n:check:fix [locale]` | Same as check, but adds missing keys to other locales with English placeholders. | From 3da41dff759f8a0ddeaa5c135fe79bea8ca8facf Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 22:57:40 +0000 Subject: [PATCH 10/14] test: add `MetricsBadges` component test --- .../LikeCard.spec.ts} | 0 .../components/Package/MetricsBadges.spec.ts | 47 +++++++++++++++++++ .../Sidebar.spec.ts} | 0 .../Versions.spec.ts} | 0 .../WeeklyDownloadStats.spec.ts} | 0 5 files changed, 47 insertions(+) rename test/nuxt/components/{PackageLikeCard.spec.ts => Package/LikeCard.spec.ts} (100%) create mode 100644 test/nuxt/components/Package/MetricsBadges.spec.ts rename test/nuxt/components/{PackageSidebar.spec.ts => Package/Sidebar.spec.ts} (100%) rename test/nuxt/components/{PackageVersions.spec.ts => Package/Versions.spec.ts} (100%) rename test/nuxt/components/{PackageWeeklyDownloadStats.spec.ts => Package/WeeklyDownloadStats.spec.ts} (100%) diff --git a/test/nuxt/components/PackageLikeCard.spec.ts b/test/nuxt/components/Package/LikeCard.spec.ts similarity index 100% rename from test/nuxt/components/PackageLikeCard.spec.ts rename to test/nuxt/components/Package/LikeCard.spec.ts diff --git a/test/nuxt/components/Package/MetricsBadges.spec.ts b/test/nuxt/components/Package/MetricsBadges.spec.ts new file mode 100644 index 0000000000..1518a0372e --- /dev/null +++ b/test/nuxt/components/Package/MetricsBadges.spec.ts @@ -0,0 +1,47 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { mountSuspended } from '@nuxt/test-utils/runtime' +import type { VueWrapper } from '@vue/test-utils' +import { ref } from 'vue' +import PackageMetricsBadges from '~/components/Package/MetricsBadges.vue' + +const mockUsePackageAnalysis = vi.fn() + +vi.mock('~/composables/usePackageAnalysis', () => ({ + usePackageAnalysis: mockUsePackageAnalysis, +})) + +describe('PackageMetricsBadges', () => { + let wrapper: VueWrapper + + afterEach(() => wrapper?.unmount()) + + it('renders the badges', async () => { + mockUsePackageAnalysis.mockReturnValue({ + data: ref({ moduleFormat: 'dual', types: { kind: 'included' } }), + status: ref('success'), + }) + + wrapper = await mountSuspended(PackageMetricsBadges, { + props: { packageName: 'test-pkg' }, + }) + + const text = wrapper.text() + expect(text).toContain('Types') + expect(text).toContain('ESM') + expect(text).toContain('CJS') + }) + + it('renders the wasm label', async () => { + mockUsePackageAnalysis.mockReturnValue({ + data: ref({ moduleFormat: 'wasm' }), + status: ref('success'), + }) + + wrapper = await mountSuspended(PackageMetricsBadges, { + props: { packageName: 'wasm-pkg' }, + }) + + const text = wrapper.text() + expect(text).toContain('WASM') + }) +}) diff --git a/test/nuxt/components/PackageSidebar.spec.ts b/test/nuxt/components/Package/Sidebar.spec.ts similarity index 100% rename from test/nuxt/components/PackageSidebar.spec.ts rename to test/nuxt/components/Package/Sidebar.spec.ts diff --git a/test/nuxt/components/PackageVersions.spec.ts b/test/nuxt/components/Package/Versions.spec.ts similarity index 100% rename from test/nuxt/components/PackageVersions.spec.ts rename to test/nuxt/components/Package/Versions.spec.ts diff --git a/test/nuxt/components/PackageWeeklyDownloadStats.spec.ts b/test/nuxt/components/Package/WeeklyDownloadStats.spec.ts similarity index 100% rename from test/nuxt/components/PackageWeeklyDownloadStats.spec.ts rename to test/nuxt/components/Package/WeeklyDownloadStats.spec.ts From d5efa7297491102b48f1947f79f735b89c9cddac Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 23:04:00 +0000 Subject: [PATCH 11/14] fix: use `mockNuxtImport` --- test/nuxt/components/Package/MetricsBadges.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/nuxt/components/Package/MetricsBadges.spec.ts b/test/nuxt/components/Package/MetricsBadges.spec.ts index 1518a0372e..7aedb2fdda 100644 --- a/test/nuxt/components/Package/MetricsBadges.spec.ts +++ b/test/nuxt/components/Package/MetricsBadges.spec.ts @@ -4,12 +4,12 @@ import type { VueWrapper } from '@vue/test-utils' import { ref } from 'vue' import PackageMetricsBadges from '~/components/Package/MetricsBadges.vue' -const mockUsePackageAnalysis = vi.fn() - -vi.mock('~/composables/usePackageAnalysis', () => ({ - usePackageAnalysis: mockUsePackageAnalysis, +const { mockUsePackageAnalysis } = vi.hoisted(() => ({ + mockUsePackageAnalysis: vi.fn(), })) +mockNuxtImport('usePackageAnalysis', () => mockUsePackageAnalysis) + describe('PackageMetricsBadges', () => { let wrapper: VueWrapper @@ -22,7 +22,7 @@ describe('PackageMetricsBadges', () => { }) wrapper = await mountSuspended(PackageMetricsBadges, { - props: { packageName: 'test-pkg' }, + props: { packageName: 'ufo' }, }) const text = wrapper.text() @@ -38,7 +38,7 @@ describe('PackageMetricsBadges', () => { }) wrapper = await mountSuspended(PackageMetricsBadges, { - props: { packageName: 'wasm-pkg' }, + props: { packageName: 'swc-plugin-transform-webpack-context' }, }) const text = wrapper.text() From 093180b6264c6ddc275632de9ef183ad83935be1 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 23:10:13 +0000 Subject: [PATCH 12/14] Update MetricsBadges.spec.ts --- .../components/Package/MetricsBadges.spec.ts | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/test/nuxt/components/Package/MetricsBadges.spec.ts b/test/nuxt/components/Package/MetricsBadges.spec.ts index 7aedb2fdda..e8abf2ad1e 100644 --- a/test/nuxt/components/Package/MetricsBadges.spec.ts +++ b/test/nuxt/components/Package/MetricsBadges.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { mountSuspended } from '@nuxt/test-utils/runtime' +import { mockNuxtImport, mountSuspended } from '@nuxt/test-utils/runtime' import type { VueWrapper } from '@vue/test-utils' import { ref } from 'vue' import PackageMetricsBadges from '~/components/Package/MetricsBadges.vue' @@ -29,6 +29,7 @@ describe('PackageMetricsBadges', () => { expect(text).toContain('Types') expect(text).toContain('ESM') expect(text).toContain('CJS') + expect(text).not.toContain('WASM') }) it('renders the wasm label', async () => { @@ -43,5 +44,23 @@ describe('PackageMetricsBadges', () => { const text = wrapper.text() expect(text).toContain('WASM') + expect(text).not.toContain('Types') + }) + + it('does not render the CJS label when no CJS', async () => { + mockUsePackageAnalysis.mockReturnValue({ + data: ref({ moduleFormat: 'esm', types: { kind: 'included' } }), + status: ref('success'), + }) + + wrapper = await mountSuspended(PackageMetricsBadges, { + props: { packageName: '@nuxt/kit' }, + }) + + const text = wrapper.text() + expect(text).toContain('Types') + expect(text).toContain('ESM') + expect(text).not.toContain('CJS') + expect(text).not.toContain('WASM') }) }) From c185537566df0c4810d5f13b58a041e15889a335 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 23:16:18 +0000 Subject: [PATCH 13/14] Update MetricsBadges.spec.ts --- test/nuxt/components/Package/MetricsBadges.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nuxt/components/Package/MetricsBadges.spec.ts b/test/nuxt/components/Package/MetricsBadges.spec.ts index e8abf2ad1e..5f7b528d3d 100644 --- a/test/nuxt/components/Package/MetricsBadges.spec.ts +++ b/test/nuxt/components/Package/MetricsBadges.spec.ts @@ -44,7 +44,7 @@ describe('PackageMetricsBadges', () => { const text = wrapper.text() expect(text).toContain('WASM') - expect(text).not.toContain('Types') + expect(text).not.toContain('ESM') }) it('does not render the CJS label when no CJS', async () => { From 112a4d7959032d93960a76d73e54281f1a48fc6d Mon Sep 17 00:00:00 2001 From: "Willow (GHOST)" Date: Fri, 20 Mar 2026 19:29:56 -0700 Subject: [PATCH 14/14] chore: undo contributing.md changes I think these aren't intentional, please make a follow up PR if I'm wrong --- CONTRIBUTING.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3af9d98c41..cc6afeb794 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -460,13 +460,13 @@ npmx.dev uses [@nuxtjs/i18n](https://i18n.nuxtjs.org/) for internationalization. The following scripts help manage translation files. `en.json` is the reference locale. -| Command | Description | -| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `pnpm vp run i18n:check [locale]` | Compares `en.json` with other locale files. Shows missing and extra keys. Optionally filter output by locale (e.g. `pnpm i18n:check ja-JP`). | -| `pnpm vp run i18n:check:fix [locale]` | Same as check, but adds missing keys to other locales with English placeholders. | -| `pnpm vp run i18n:report` | Audits translation keys against code usage in `.vue` and `.ts` files. Reports missing keys (used in code but not in locale), unused keys (in locale but not in code), and dynamic keys. | -| `pnpm vp run i18n:report:fix` | Removes unused keys from `en.json` and all other locale files. | -| `pnpm vp run i18n:schema` | Generates a JSON Schema from `en.json` at `i18n/schema.json`. Locale files reference this schema for IDE validation and autocompletion. | +| Command | Description | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `pnpm i18n:check [locale]` | Compares `en.json` with other locale files. Shows missing and extra keys. Optionally filter output by locale (e.g. `pnpm i18n:check ja-JP`). | +| `pnpm i18n:check:fix [locale]` | Same as check, but adds missing keys to other locales with English placeholders. | +| `pnpm i18n:report` | Audits translation keys against code usage in `.vue` and `.ts` files. Reports missing keys (used in code but not in locale), unused keys (in locale but not in code), and dynamic keys. | +| `pnpm i18n:report:fix` | Removes unused keys from `en.json` and all other locale files. | +| `pnpm i18n:schema` | Generates a JSON Schema from `en.json` at `i18n/schema.json`. Locale files reference this schema for IDE validation and autocompletion. | ### Adding a new locale