From c2d139d1b02515be7ebe6efce8a21bf51925ea14 Mon Sep 17 00:00:00 2001 From: Eugen Hildt Date: Sat, 21 Mar 2026 13:10:21 +0100 Subject: [PATCH] 0030: fixed shieldio url in status badges --- .changeset/fix-scoped-package-names.md | 5 + AGENTS.md | 215 ------------------ depbadgerc.yml | 8 + package.json | 4 +- pnpm-lock.yaml | 146 ++++++------ .../map-status-badges-to-markdown.spec.ts | 4 +- src/shared/encode-label.spec.ts | 15 +- src/shared/encode-label.ts | 2 +- 8 files changed, 102 insertions(+), 297 deletions(-) create mode 100644 .changeset/fix-scoped-package-names.md delete mode 100644 AGENTS.md diff --git a/.changeset/fix-scoped-package-names.md b/.changeset/fix-scoped-package-names.md new file mode 100644 index 0000000..d524a76 --- /dev/null +++ b/.changeset/fix-scoped-package-names.md @@ -0,0 +1,5 @@ +--- +"@ehildt/depbadge": patch +--- + +fix encodeLabel for scoped package names: strip @ prefix and convert / to - for correct shield.io badge URLs diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index db95cf7..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,215 +0,0 @@ -# AGENTS.md - -This document provides guidelines and commands for agents working in this repository. - -## Project Overview - -This is a TypeScript project that generates shield.io badges from package manifests (package.json, pyproject.toml, Cargo.toml). - -## Build Commands - -| Command | Description | -| --------------------- | ------------------------------------------------------------ | -| `pnpm install` | Install dependencies (use `--frozen-lockfile` in CI) | -| `pnpm prepare` | Set up husky hooks | -| `pnpm build` | Build the project (runs tsup, outputs to `dist/`) | -| `pnpm prepublishOnly` | Build before publishing | -| `pnpm depbadge` | Run the CLI tool (`rimraf .depbadge && node dist/index.mjs`) | - -## Lint & Format Commands - -| Command | Description | -| ------------------ | ------------------------------- | -| `pnpm lint` | Run ESLint on `./src` | -| `pnpm format` | Format all files with Prettier | -| `pnpm depcruise` | Run dependency-cruiser analysis | -| `pnpm depcheck` | Check for unused dependencies | -| `pnpm lint:unused` | Check for unused exports | -| `pnpm lint-staged` | Run linters on staged files | - -### Pre-commit Hook - -Husky runs `pnpm lint-staged` on commit. The pre-commit hook is in `.husky/_/pre-commit`. - -## Test Commands - -| Command | Description | -| ----------------- | ------------------------------- | -| `pnpm test` | Run all tests once (vitest run) | -| `pnpm test:watch` | Run tests in watch mode | -| `pnpm test:cov` | Run tests with coverage report | - -### Running a Single Test - -Use vitest's `--` filter option: - -```bash -# By test name (partial match) -pnpm test -- encodeLabel -pnpm test -- "get-dependencies" -pnpm test -- "Status badge markdown mapping" - -# By file path -pnpm test -- "src/shared/encode-label.spec.ts" -pnpm test -- "src/store/ctx-store.spec.ts" - -# By file name -pnpm test -- "ctx-store.spec.ts" -``` - -## Code Style - -### TypeScript Configuration - -- Strict mode enabled (`strict: true` in tsconfig.json) -- Module resolution: `nodenext` -- Target: `esnext` -- No implicit `any` (but `any` is allowed with opt-out via `@ts-ignore` or `eslint-disable`) -- Build config: `tsconfig.build.json` (generates declarations, excludes spec files) - -### Formatting (Prettier) - -| Option | Value | -| --------------- | ------- | -| Print width | 120 | -| Single quotes | `true` | -| Trailing commas | `all` | -| Semicolons | `true` | -| Use tabs | `false` | -| End of line | `lf` | -| Bracket spacing | `true` | - -### ESLint Rules - -- `no-console`: warning (use `console.error` for errors in CLI) -- `@typescript-eslint/no-unused-vars`: warn -- `@typescript-eslint/no-floating-promises`: warn -- `@typescript-eslint/no-explicit-any`: off -- `sonarjs/cognitive-complexity`: warn -- `sonarjs/no-identical-expressions`: warn - -### Import Sorting (simple-import-sort) - -Order groups (strict): - -1. `node:` imports (e.g., `node:fs`) -2. External packages (`@?\w`) -3. Internal packages (`@app`, `@modules`, `@services`) -4. Side-effect imports (`\u0000`) -5. Parent imports (`\.\.(?!/?$)`, `\.\./?$`) -6. Relative imports (same directory) -7. Type imports -8. CSS/SCSS files - -### Naming Conventions - -| Type | Convention | Example | -| ------------------ | -------------------------- | -------------------------------- | -| Files | kebab-case | `ctx-store.ts`, `get-version.ts` | -| Test files | `*.spec.ts` suffix | `encode-label.spec.ts` | -| Types/Interfaces | PascalCase, descriptive | `CtxStore` | -| Type aliases | `type` keyword, PascalCase | `type UserId = string` | -| Functions | camelCase, verb-prefixed | `getDependencies`, `useCtxStore` | -| Methods | camelCase | `increment`, `getDependencies` | -| Store state types | `CtxState` suffix | `DepbadgeRCState` | -| Store method types | `CtxMethods` suffix | `DepbadgeRCMethods` | - -### Error Handling - -CLI entry points must use try/catch: - -```typescript -try { - // ... main logic - process.exit(0); -} catch (error) { - const message = error instanceof Error ? error.message : String(error); - console.error(`::error::${message}`); - process.exit(1); -} -``` - -### Type Patterns - -- Use `type` for simple type aliases -- Use `export type` for types that need to be imported -- Generic types with meaningful names (e.g., `CtxStore`) -- Optional properties use `?` modifier -- Avoid `any` unless necessary; prefer `unknown` for truly unknown types - -### Store Pattern (ctx-store) - -The project uses a custom immutable store pattern: - -```typescript -import { useCtxCallback, useCtxStore } from "./ctx-store.ts"; - -// State and methods are separate types -type CtxState = { count: number }; -type CtxMethods = { increment: (delta: number) => number }; - -// Create store with frozen state -const store = useCtxStore( - { count: 5 }, - { - increment: (s) => (delta: number) => s.count + delta, - } -); - -// Stores are frozen (immutable) -Object.isFrozen(store); // true - -// Use useCtxCallback to bind callbacks -const callback = useCtxCallback((s) => () => console.log(s.count)); -``` - -## Development Workflow - -1. **Before committing**: Run `pnpm lint-staged` (auto-runs on pre-commit via husky) -2. **Before pushing**: Run `pnpm test` and `pnpm build` -3. **CI Pipeline**: Lint → Build → Test (in that order) - -## Directory Structure - -``` -src/ -├── index.ts # CLI entry point -├── depbadgerc/ # Main business logic -│ ├── *.store.ts # Store definitions -│ └── *.type.ts # Type definitions -├── manifest/ # Manifest parsers -│ ├── package-json/ -│ ├── pyproject-toml/ -│ └── cargo.toml/ -├── shared/ # Utility functions -│ ├── encode-label.ts -│ ├── find-file.ts -│ └── *.spec.ts -└── store/ # Store implementation - ├── ctx-store.ts - └── ctx-store.spec.ts -``` - -## Key Dependencies - -| Package | Purpose | -| ----------- | -------------------- | -| yargs | CLI argument parsing | -| js-yaml | YAML parsing | -| colord | Color manipulation | -| @iarna/toml | TOML parsing | -| vitest | Testing | -| tsup | Build tool | - -## Configuration Files - -| File | Purpose | -| --------------------- | -------------------------------- | -| `eslint.config.ts` | ESLint configuration | -| `prettier.config.mjs` | Prettier configuration | -| `vitest.config.ts` | Test configuration | -| `tsconfig.json` | TypeScript configuration | -| `tsconfig.build.json` | Build-specific TypeScript config | -| `cspell.config.yml` | Spell checker configuration | -| `tsup.config.ts` | Build tool configuration | -| `.lintstagedrc` | Lint-staged configuration | diff --git a/depbadgerc.yml b/depbadgerc.yml index 6721365..993b6e0 100644 --- a/depbadgerc.yml +++ b/depbadgerc.yml @@ -35,6 +35,9 @@ dependencies: - name: "@iarna/toml" namedLogo: toml link: https://github.com/iarna/iarna-toml + - name: yaml + namedLogo: npm + link: https://github.com/eemeli/yaml devDependencies: layout: *DEPENDENCIES_LAYOUT @@ -102,6 +105,11 @@ statusBadges: showHeader: false badgeStyle: *STATUS_BADGES_STYLE items: + - name: tile + message: NPM + label: depbadge + namedLogo: npm + link: https://www.npmjs.com/package/@ehildt/depbadge - name: github metric: release user: ehildt diff --git a/package.json b/package.json index c7d5070..b722872 100755 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "dependencies": { "@iarna/toml": "^2.2.5", "colord": "^2.9.3", - "yaml": "^2.8.2" + "yaml": "^2.8.3" }, "devDependencies": { "@changesets/cli": "^2.30.0", @@ -58,7 +58,7 @@ "depcheck": "^1.4.7", "dependency-cruiser": "^17.3.9", "dotenv-cli": "^11.0.0", - "eslint": "^10.0.3", + "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-simple-import-sort": "^12.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2820e97..fa335a9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,15 +15,15 @@ importers: specifier: ^2.9.3 version: 2.9.3 yaml: - specifier: ^2.8.2 - version: 2.8.2 + specifier: ^2.8.3 + version: 2.8.3 devDependencies: '@changesets/cli': specifier: ^2.30.0 version: 2.30.0(@types/node@25.5.0) '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@10.0.3(jiti@2.6.1)) + version: 10.0.1(eslint@10.1.0(jiti@2.6.1)) '@types/eslint': specifier: ^9.6.1 version: 9.6.1 @@ -32,7 +32,7 @@ importers: version: 25.5.0 '@vitest/coverage-v8': specifier: 4.1.0 - version: 4.1.0(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2))) + version: 4.1.0(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3))) depcheck: specifier: ^1.4.7 version: 1.4.7 @@ -43,20 +43,20 @@ importers: specifier: ^11.0.0 version: 11.0.0 eslint: - specifier: ^10.0.3 - version: 10.0.3(jiti@2.6.1) + specifier: ^10.1.0 + version: 10.1.0(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.0.3(jiti@2.6.1)) + version: 10.1.8(eslint@10.1.0(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.5 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(prettier@2.8.8) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@2.6.1)))(eslint@10.1.0(jiti@2.6.1))(prettier@2.8.8) eslint-plugin-simple-import-sort: specifier: ^12.1.1 - version: 12.1.1(eslint@10.0.3(jiti@2.6.1)) + version: 12.1.1(eslint@10.1.0(jiti@2.6.1)) eslint-plugin-sonarjs: specifier: ^4.0.2 - version: 4.0.2(eslint@10.0.3(jiti@2.6.1)) + version: 4.0.2(eslint@10.1.0(jiti@2.6.1)) globals: specifier: ^17.4.0 version: 17.4.0 @@ -89,16 +89,16 @@ importers: version: 11.0.1(typescript@5.9.3) tsup: specifier: ^8.5.1 - version: 8.5.1(jiti@2.6.1)(postcss@8.5.8)(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(jiti@2.6.1)(postcss@8.5.8)(typescript@5.9.3)(yaml@2.8.3) typescript: specifier: ^5.9.3 version: 5.9.3 typescript-eslint: specifier: ^8.57.1 - version: 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + version: 8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) vitest: specifier: ^4.1.0 - version: 4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)) + version: 4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3)) packages: @@ -385,8 +385,8 @@ packages: resolution: {integrity: sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/config-helpers@0.5.2': - resolution: {integrity: sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==} + '@eslint/config-helpers@0.5.3': + resolution: {integrity: sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/core@1.1.1': @@ -1354,8 +1354,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.0.3: - resolution: {integrity: sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==} + eslint@10.1.0: + resolution: {integrity: sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -1364,8 +1364,8 @@ packages: jiti: optional: true - espree@11.1.1: - resolution: {integrity: sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==} + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} esprima@4.0.1: @@ -2632,8 +2632,8 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + yaml@2.8.3: + resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} engines: {node: '>= 14.6'} hasBin: true @@ -2947,9 +2947,9 @@ snapshots: '@esbuild/win32-x64@0.27.3': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.0.3(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.1.0(jiti@2.6.1))': dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -2962,7 +2962,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.5.2': + '@eslint/config-helpers@0.5.3': dependencies: '@eslint/core': 1.1.1 @@ -2970,9 +2970,9 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.0.3(jiti@2.6.1))': + '@eslint/js@10.0.1(eslint@10.1.0(jiti@2.6.1))': optionalDependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) '@eslint/object-schema@3.0.3': {} @@ -3240,15 +3240,15 @@ snapshots: '@types/parse-json@4.0.2': {} - '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.57.1 - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.4.0(typescript@5.9.3) @@ -3256,14 +3256,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.57.1 '@typescript-eslint/types': 8.57.1 '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3 - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3286,13 +3286,13 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.57.1 '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -3315,13 +3315,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.57.1 '@typescript-eslint/types': 8.57.1 '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3331,7 +3331,7 @@ snapshots: '@typescript-eslint/types': 8.57.1 eslint-visitor-keys: 5.0.1 - '@vitest/coverage-v8@4.1.0(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)))': + '@vitest/coverage-v8@4.1.0(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3)))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.0 @@ -3343,7 +3343,7 @@ snapshots: obug: 2.1.1 std-env: 4.0.0 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)) + vitest: 4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3)) '@vitest/expect@4.1.0': dependencies: @@ -3354,13 +3354,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2))': + '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2) + vite: 8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3) '@vitest/pretty-format@4.1.0': dependencies: @@ -3861,30 +3861,30 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.0.3(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@2.6.1)): dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) - eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(prettier@2.8.8): + eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@2.6.1)))(eslint@10.1.0(jiti@2.6.1))(prettier@2.8.8): dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) prettier: 2.8.8 prettier-linter-helpers: 1.0.1 synckit: 0.11.12 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@10.0.3(jiti@2.6.1)) + eslint-config-prettier: 10.1.8(eslint@10.1.0(jiti@2.6.1)) - eslint-plugin-simple-import-sort@12.1.1(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-simple-import-sort@12.1.1(eslint@10.1.0(jiti@2.6.1)): dependencies: - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) - eslint-plugin-sonarjs@4.0.2(eslint@10.0.3(jiti@2.6.1)): + eslint-plugin-sonarjs@4.0.2(eslint@10.1.0(jiti@2.6.1)): dependencies: '@eslint-community/regexpp': 4.12.2 builtin-modules: 3.3.0 bytes: 3.1.2 - eslint: 10.0.3(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1) functional-red-black-tree: 1.0.1 globals: 17.4.0 jsx-ast-utils-x: 0.1.0 @@ -3911,12 +3911,12 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.0.3(jiti@2.6.1): + eslint@10.1.0(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.3 - '@eslint/config-helpers': 0.5.2 + '@eslint/config-helpers': 0.5.3 '@eslint/core': 1.1.1 '@eslint/plugin-kit': 0.6.1 '@humanfs/node': 0.16.7 @@ -3929,7 +3929,7 @@ snapshots: escape-string-regexp: 4.0.0 eslint-scope: 9.1.2 eslint-visitor-keys: 5.0.1 - espree: 11.1.1 + espree: 11.2.0 esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -3948,7 +3948,7 @@ snapshots: transitivePeerDependencies: - supports-color - espree@11.1.1: + espree@11.2.0: dependencies: acorn: 8.16.0 acorn-jsx: 5.3.2(acorn@8.16.0) @@ -4325,7 +4325,7 @@ snapshots: picomatch: 4.0.3 string-argv: 0.3.2 tinyexec: 1.0.4 - yaml: 2.8.2 + yaml: 2.8.3 listr2@9.0.5: dependencies: @@ -4549,13 +4549,13 @@ snapshots: dependencies: semver-compare: 1.0.0 - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(yaml@2.8.2): + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(yaml@2.8.3): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 2.6.1 postcss: 8.5.8 - yaml: 2.8.2 + yaml: 2.8.3 postcss@8.5.6: dependencies: @@ -4946,7 +4946,7 @@ snapshots: tslib@2.8.1: optional: true - tsup@8.5.1(jiti@2.6.1)(postcss@8.5.8)(typescript@5.9.3)(yaml@2.8.2): + tsup@8.5.1(jiti@2.6.1)(postcss@8.5.8)(typescript@5.9.3)(yaml@2.8.3): dependencies: bundle-require: 5.1.0(esbuild@0.27.3) cac: 6.7.14 @@ -4957,7 +4957,7 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(yaml@2.8.2) + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(yaml@2.8.3) resolve-from: 5.0.0 rollup: 4.59.0 source-map: 0.7.6 @@ -4978,13 +4978,13 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - eslint: 10.0.3(jiti@2.6.1) + '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + eslint: 10.1.0(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -5009,7 +5009,7 @@ snapshots: v8-compile-cache-lib@3.0.1: {} - vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2): + vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3): dependencies: '@oxc-project/runtime': 0.115.0 lightningcss: 1.32.0 @@ -5023,12 +5023,12 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 terser: 5.46.0 - yaml: 2.8.2 + yaml: 2.8.3 - vitest@4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)): + vitest@4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)) + '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -5045,7 +5045,7 @@ snapshots: tinyexec: 1.0.4 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2) + vite: 8.0.0(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.5.0 @@ -5124,7 +5124,7 @@ snapshots: yaml@1.10.2: {} - yaml@2.8.2: {} + yaml@2.8.3: {} yargs-parser@20.2.9: {} diff --git a/src/depbadgerc/map-status-badges-to-markdown.spec.ts b/src/depbadgerc/map-status-badges-to-markdown.spec.ts index ecb602a..fc83a53 100644 --- a/src/depbadgerc/map-status-badges-to-markdown.spec.ts +++ b/src/depbadgerc/map-status-badges-to-markdown.spec.ts @@ -29,7 +29,7 @@ describe("Status badge markdown mapping", () => { const result = run(badges); expect(result.section1).toHaveLength(1); - expect(result.section1[0]).toContain("img.shields.io/github/stars/octocat/hello--world"); + expect(result.section1[0]).toContain("img.shields.io/github/stars/octocat/hello-world"); }); it("maps GitHub badge correctly with link", () => { @@ -92,7 +92,7 @@ describe("Status badge markdown mapping", () => { expect(result.codecovSection[0]).toContain("img.shields.io/codecov"); expect(result.codecovSection[0]).toContain("octocat"); - expect(result.codecovSection[0]).toContain("hello--world"); // dash -> underscore + expect(result.codecovSection[0]).toContain("hello-world"); }); it("filters out unknown badge types", () => { diff --git a/src/shared/encode-label.spec.ts b/src/shared/encode-label.spec.ts index 81a1824..5f8d571 100644 --- a/src/shared/encode-label.spec.ts +++ b/src/shared/encode-label.spec.ts @@ -1,8 +1,8 @@ import { encodeLabel } from "./encode-label.ts"; describe("encodeLabel", () => { - test("should double existing dashes", () => { - expect(encodeLabel("my-label")).toBe("my--label"); + test("should preserve dashes in URL paths", () => { + expect(encodeLabel("my-label")).toBe("my-label"); }); test("should double existing underscores", () => { @@ -17,11 +17,18 @@ describe("encodeLabel", () => { expect(encodeLabel("my label")).toBe("my_label"); }); + test("should convert scoped package names to display format", () => { + expect(encodeLabel("@scope/pkg")).toBe("scope-pkg"); + expect(encodeLabel("@ehildt/ckir-helpers")).toBe("ehildt-ckir-helpers"); + }); + test("should handle a combination of all rules", () => { - // "-" -> "--" + // "@" -> "" + // "/" -> "-" // "_" -> "__" // " " -> "_" - expect(encodeLabel("a-b_c d")).toBe("a--b__c_d"); + expect(encodeLabel("a-b_c d")).toBe("a-b__c_d"); + expect(encodeLabel("@scope/my-package")).toBe("scope-my-package"); }); test("should return an empty string when given an empty string", () => { diff --git a/src/shared/encode-label.ts b/src/shared/encode-label.ts index 07f6435..58561b1 100644 --- a/src/shared/encode-label.ts +++ b/src/shared/encode-label.ts @@ -1,3 +1,3 @@ export const encodeLabel = (s: string) => { - return (s ?? "").replace(/-/g, "--").replace(/_/g, "__").replace(/\s+/g, "_"); + return (s ?? "").replace(/^@/, "").replace(/_/g, "__").replace(/\//g, "-").replace(/\s+/g, "_"); };