From aba54cfc1f88c4145b9c42a104492a7fcd9568df Mon Sep 17 00:00:00 2001 From: Eugen Hildt Date: Wed, 18 Mar 2026 23:59:41 +0100 Subject: [PATCH] 0023: added socket badge support --- .changeset/add-socket-badge.md | 17 ++ .github/workflows/non-release.ci.yml | 2 +- .github/workflows/release.ci.yml | 18 +-- .wiki/depbadgerc-full-example.md | 46 +++--- .wiki/depbadgerc-layouts.md | 15 +- .wiki/depbadgerc-root.md | 8 +- .wiki/depbadgerc-sections.md | 21 ++- .wiki/depbadgerc-styles.md | 9 +- .wiki/extend-manifest-support.md | 29 ++-- .wiki/quick-start.md | 25 +-- .wiki/status-badges/codecov-badges.md | 60 +++++++ .wiki/status-badges/docker-badges.md | 68 ++++++++ .wiki/status-badges/github-badges.md | 75 +++++++++ .wiki/status-badges/socket-badges.md | 70 ++++++++ .wiki/status-badges/tile-badges.md | 60 +++++++ AGENTS.md | 153 ++++++++++++++++++ EULA.md | 28 ++-- README.md | 7 +- action.yml | 2 +- depbadgerc.schema.json | 63 +++++++- depbadgerc.yml | 29 ++-- dist/index.mjs | 11 ++ eslint.config.ts | 10 +- package.json | 6 +- pnpm-lock.yaml | 138 ++++++++-------- .../apply-markdown-to-target.spec.ts | 28 +++- .../compute-state-integrity.spec.ts | 4 +- src/depbadgerc/depbadgerc.type.ts | 13 +- src/depbadgerc/get-dependnecies.spec.ts | 6 +- src/depbadgerc/get-status-badges.spec.ts | 11 +- ...ap-socket-status-badge-to-markdown.spec.ts | 60 +++++++ .../map-socket-status-badge-to-markdown.ts | 10 ++ .../map-status-badges-to-markdown.ts | 3 + .../output-markdown-preview.spec.ts | 16 +- .../output-shieldio-badges-json.spec.ts | 8 +- .../read-depbadgerc-with-defaults.spec.ts | 4 +- src/store/ctx-store.spec.ts | 14 +- tsconfig.exclude.json | 2 +- tsconfig.json | 5 +- tsup.config.ts | 14 +- 40 files changed, 949 insertions(+), 219 deletions(-) create mode 100644 .changeset/add-socket-badge.md create mode 100644 .wiki/status-badges/codecov-badges.md create mode 100644 .wiki/status-badges/docker-badges.md create mode 100644 .wiki/status-badges/github-badges.md create mode 100644 .wiki/status-badges/socket-badges.md create mode 100644 .wiki/status-badges/tile-badges.md create mode 100644 AGENTS.md create mode 100644 src/depbadgerc/map-socket-status-badge-to-markdown.spec.ts create mode 100644 src/depbadgerc/map-socket-status-badge-to-markdown.ts diff --git a/.changeset/add-socket-badge.md b/.changeset/add-socket-badge.md new file mode 100644 index 0000000..07841ea --- /dev/null +++ b/.changeset/add-socket-badge.md @@ -0,0 +1,17 @@ +--- +"@ehildt/depbadge": minor +--- + +Add Socket badge support for npm packages + +- Added Socket badge type with package and version fields +- Uses Socket's native badge service at badge.socket.dev +- Links to npm package page by default +- Supports scoped packages like @babel/core +- Removed unused metric field from Socket badge type +- Created dedicated status-badges documentation for all badge types: + - github-badges.md + - codecov-badges.md + - docker-badges.md + - tile-badges.md + - socket-badges.md diff --git a/.github/workflows/non-release.ci.yml b/.github/workflows/non-release.ci.yml index 2ab2604..abb7040 100644 --- a/.github/workflows/non-release.ci.yml +++ b/.github/workflows/non-release.ci.yml @@ -40,4 +40,4 @@ jobs: - name: Test run: | pnpm test - pnpm test:cov \ No newline at end of file + pnpm test:cov diff --git a/.github/workflows/release.ci.yml b/.github/workflows/release.ci.yml index 852fa7c..b9f01dd 100644 --- a/.github/workflows/release.ci.yml +++ b/.github/workflows/release.ci.yml @@ -144,32 +144,32 @@ jobs: if: github.event_name == 'push' needs: [repo-update, wiki] runs-on: ubuntu-latest - + steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # ensure we can see the latest commits - + fetch-depth: 0 # ensure we can see the latest commits + - uses: pnpm/action-setup@v4 with: version: 10 - + - uses: actions/setup-node@v4 with: node-version: 22 registry-url: https://registry.npmjs.org - + - run: pnpm install --frozen-lockfile - + - name: Version bump & publish run: | # Apply changeset version bump locally pnpm changeset version - + # Reinstall to update lockfile after version bump pnpm install --frozen-lockfile - + # Publish to npm directly using the bumped version pnpm publish --no-git-checks env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.wiki/depbadgerc-full-example.md b/.wiki/depbadgerc-full-example.md index 5d69281..2876abe 100644 --- a/.wiki/depbadgerc-full-example.md +++ b/.wiki/depbadgerc-full-example.md @@ -19,7 +19,7 @@ target: README.md manifest: package.json # Dependency source file; usually package.json for Node.js projects -output: ['json', 'markdown'] +output: ["json", "markdown"] # 'json' → machine-readable preview for debugging # 'markdown' → badge-ready preview for verification @@ -28,11 +28,11 @@ output: ['json', 'markdown'] # ========================= dependenciesLayout: &DEP_LAYOUT - position: center # Alignment of badges: left, center, right - showHeader: true # Render a section header + position: center # Alignment of badges: left, center, right + showHeader: true # Render a section header devDependenciesLayout: &DEV_LAYOUT - <<: *DEP_LAYOUT # Inherit defaults from DEP_LAYOUT + <<: *DEP_LAYOUT # Inherit defaults from DEP_LAYOUT position: left showHeader: false header: Development @@ -50,12 +50,12 @@ statusBadgesLayout: &STATUS_LAYOUT # ============================== baseStyle: &BASE_STYLE - labelColor: '#333' # Left segment color - isError: false # Force error style - logoSvg: '' # Optional custom SVG logo - logoWidth: 40 # Width of logo in pixels + labelColor: "#333" # Left segment color + isError: false # Force error style + logoSvg: "" # Optional custom SVG logo + logoWidth: 40 # Width of logo in pixels style: for-the-badge # Shields style: flat, flat-square, for-the-badge - cacheSeconds: 3600 # CDN cache duration + cacheSeconds: 3600 # CDN cache duration # ==================== # Dependencies Section @@ -71,11 +71,11 @@ dependencies: - name: chalk # Uses section-level badgeStyle (npm logo, for-the-badge) - name: colord - labelColor: '#ff4500' # Override label color per item + labelColor: "#ff4500" # Override label color per item - name: js-yaml - style: flat-square # Override style per item + style: flat-square # Override style per item - name: "@iarna/toml" - namedLogo: toml # Use a different logo per item + namedLogo: toml # Use a different logo per item # ======================= # DevDependencies Section @@ -90,11 +90,11 @@ devDependencies: style: flat-square items: - name: jest - namedLogo: jest # Override logo for this package + namedLogo: jest # Override logo for this package - name: typescript - link: https://www.typescriptlang.org/ # Override link + link: https://www.typescriptlang.org/ # Override link - name: eslint - style: for-the-badge # Override style + style: for-the-badge # Override style # ========================= # Peer Dependencies Section @@ -108,7 +108,7 @@ peerDependencies: style: flat items: - name: react - namedLogo: react # Per-item logo + namedLogo: react # Per-item logo # =================================== # Status Badges Section (Independent) @@ -123,25 +123,27 @@ statusBadges: namedLogo: github items: - name: github - metric: release # Badge shows latest release + metric: release # Badge shows latest release user: ehildt repo: depbadge branch: main # Uses section-level badgeStyle - name: github - metric: stars # Badge shows stars count + metric: stars # Badge shows stars count user: ehildt repo: depbadge branch: main - labelColor: '#ffcc00' # Override label color + labelColor: "#ffcc00" # Override label color - name: codecov user: ehildt repo: depbadge branch: main flag: c - style: flat-square # Override style for this badge + style: flat-square # Override style for this badge - name: tile - label: 'I Love' + label: "I Love" message: COOKIES + - name: socket + package: express + version: "4.18.2" ``` - diff --git a/.wiki/depbadgerc-layouts.md b/.wiki/depbadgerc-layouts.md index 4324918..a5f781b 100644 --- a/.wiki/depbadgerc-layouts.md +++ b/.wiki/depbadgerc-layouts.md @@ -11,12 +11,11 @@ dependenciesLayout: &DEPENDENCIES_LAYOUT # header: 'My Dependencies' ``` - -| Property | Type | Description | -| :--- | :--- | :--- | -| **position** | string | Alignment in the document (left, center, right) | -| **showHeader** | boolean | Whether a Markdown header is rendered above the section | -| **header** | string | Optional custom header title (falls back to section name) | +| Property | Type | Description | +| :------------- | :------ | :-------------------------------------------------------- | +| **position** | string | Alignment in the document (left, center, right) | +| **showHeader** | boolean | Whether a Markdown header is rendered above the section | +| **header** | string | Optional custom header title (falls back to section name) | ### Reusing Layouts via YAML Anchors @@ -29,7 +28,9 @@ devDependenciesLayout: &DEV_DEPENDENCIES_LAYOUT showHeader: true header: Development Dependencies ``` + YAML merge (<<) allows: + - DRY configuration - Targeted overrides - Consistent styling across sections @@ -42,4 +43,4 @@ dependencies: <<: *DEPENDENCIES_LAYOUT ``` -If no layout is provided, Depbadge will fall back to its internal defaults. \ No newline at end of file +If no layout is provided, Depbadge will fall back to its internal defaults. diff --git a/.wiki/depbadgerc-root.md b/.wiki/depbadgerc-root.md index 6cc82b4..4bdf338 100644 --- a/.wiki/depbadgerc-root.md +++ b/.wiki/depbadgerc-root.md @@ -5,7 +5,7 @@ integrity: 838e9da83c5b73c2de43b87b950428403a090d7dc926145640c1576d7c313820 target: README.md manifest: package.json -output: ['json', 'markdown'] +output: ["json", "markdown"] ``` `# yaml-language-server` @@ -36,8 +36,6 @@ Depbadge reads dependency sections from this file: Defines which output artifacts Depbadge generates (primarily for previewing and debugging). -* `json` → Generates machine-readable files for each badge under `.depbadge/
/.json` (e.g. `.depbadge/dependencies/react.json`). Useful for inspecting resolved configuration and computed badge data. - -* `markdown` → Generates rendered badge previews as Markdown under `.depbadge/`. This allows you to verify layout and styling before writing to the target file. - +- `json` → Generates machine-readable files for each badge under `.depbadge/
/.json` (e.g. `.depbadge/dependencies/react.json`). Useful for inspecting resolved configuration and computed badge data. +- `markdown` → Generates rendered badge previews as Markdown under `.depbadge/`. This allows you to verify layout and styling before writing to the target file. diff --git a/.wiki/depbadgerc-sections.md b/.wiki/depbadgerc-sections.md index 449d164..f782db0 100644 --- a/.wiki/depbadgerc-sections.md +++ b/.wiki/depbadgerc-sections.md @@ -3,6 +3,7 @@ Dependency sections are tied to the manifest file (e.g., package.json). Supported sections: + - dependencies - devDependencies - peerDependencies @@ -19,24 +20,21 @@ dependencies: ``` Behavior + - Only explicitly listed items are rendered. - Other manifest dependencies are ignored. - Items must exist in the manifest section. - Each item may override any style property. -# Status Badges (Separate from Dependencies) +# Status Badges -Status badges are not connected to manifest files. +Status badges are documented in dedicated files: -They represent external metrics such as: -- GitHub releases -- GitHub stars -- License -- Code coverage -- Docker pulls (if enabled) -- Future providers - -### Status Badge Section +- [GitHub Badges](./status-badges/github-badges.md) +- [Codecov Badges](./status-badges/codecov-badges.md) +- [Docker Badges](./status-badges/docker-badges.md) +- [Tile Badges](./status-badges/tile-badges.md) +- [Socket Badges](./status-badges/socket-badges.md) ```yaml statusBadges: @@ -49,4 +47,3 @@ statusBadges: user: ehildt repo: depbadge ``` - diff --git a/.wiki/depbadgerc-styles.md b/.wiki/depbadgerc-styles.md index fc5d4e7..cc9d527 100644 --- a/.wiki/depbadgerc-styles.md +++ b/.wiki/depbadgerc-styles.md @@ -7,10 +7,10 @@ It controls visual appearance, logo handling, linking, and caching. Like layouts ```yaml dependenciesStyle: &DEPENDENCIES_STYLE - labelColor: '#333' + labelColor: "#333" isError: false namedLogo: npm - logoSvg: '' + logoSvg: "" logoWidth: 40 style: for-the-badge cacheSeconds: 3600 @@ -28,7 +28,6 @@ dependenciesStyle: &DEPENDENCIES_STYLE | `cacheSeconds` | number | CDN cache duration | | `link` | string | Target URL when clicking badge | - ### Applying a Style to a Section ```yaml @@ -47,9 +46,9 @@ Every item may override any badgeStyle property: dependencies: items: - name: vue - labelColor: '#42b883' + labelColor: "#42b883" namedLogo: vue link: https://vuejs.org/ ``` -Per-item configuration always takes precedence over section-level style. \ No newline at end of file +Per-item configuration always takes precedence over section-level style. diff --git a/.wiki/extend-manifest-support.md b/.wiki/extend-manifest-support.md index 8eb7d53..cff38bf 100644 --- a/.wiki/extend-manifest-support.md +++ b/.wiki/extend-manifest-support.md @@ -4,13 +4,14 @@ Adding a manifest to depbadge is straightforward. First, create a folder for you ### Read and Parse the Manifest -Define a manifest interface. Full type safety isn’t required; it just needs enough typing to enable linting for versions and dependencies. Save the interface in a file such as `manifest.type.ts`. Then create `manifest.read.ts`. This module is responsible for loading and parsing the manifest, returning the result typed according to the defined interface. +Define a manifest interface. Full type safety isn’t required; it just needs enough typing to enable linting for versions and dependencies. Save the interface in a file such as `manifest.type.ts`. Then create `manifest.read.ts`. This module is responsible for loading and parsing the manifest, returning the result typed according to the defined interface. A working example is available in the following files: -- `src/manifest/package-json/manifest.type.ts` + +- `src/manifest/package-json/manifest.type.ts` - `src/manifest/package-json/manifest.read.ts` -### Manifest Context Store +### Manifest Context Store Each manifest file has its own context store. Use the useCtxStore hook to create this context store. The context store must implement the manifest contract—an interface that defines two required functions: @@ -22,7 +23,7 @@ getDependencies(): Record>; - `getVersion` - returns the version of the app ```ts -getVersion() // v1.0.9 +getVersion(); // v1.0.9 ``` - `getDependencies` - returns an object of sections and its key/value-pairs @@ -30,8 +31,8 @@ getVersion() // v1.0.9 ```ts getDependencies(); -/** - * { +/** + * { * dependencies: { react: "^19.2.0", vite: "v7.3.1"}, * devDependencies: {}, // empty object if unused * peerDependencies: {}, // empty object if unused @@ -41,20 +42,20 @@ getDependencies(); It doesn’t matter how your manifest files are structured; the only requirement is that they implement the manifest contract. A working example can be found in: - - `src/manifest/package-json/get-version.ts`. - - `src/manifest/package-json/get-dependencies.ts` - - `src/manifest/package-json/manifest.store.ts` +- `src/manifest/package-json/get-version.ts`. +- `src/manifest/package-json/get-dependencies.ts` +- `src/manifest/package-json/manifest.store.ts` ### Manifest Map Each manifest context store must be registered in the manifest map located in `src/index.ts`. The map is a plain object where the key represents the manifest file name and the value references the corresponding manifest context store responsible for handling that manifest. ```ts - const manifestMap = { - "package.json": PackageJsonCtx, - "pyproject.toml": PyProjectCtx, - "Cargo.toml": CargoTomlCtx, - } as const; +const manifestMap = { + "package.json": PackageJsonCtx, + "pyproject.toml": PyProjectCtx, + "Cargo.toml": CargoTomlCtx, +} as const; ``` ### DepbadgeRC Schema diff --git a/.wiki/quick-start.md b/.wiki/quick-start.md index 5007015..d765b0a 100644 --- a/.wiki/quick-start.md +++ b/.wiki/quick-start.md @@ -1,19 +1,22 @@ # Quick Start + depbadge is a platform-agnostic tool designed to run anywhere JavaScript is available. Whether you're running it locally or integrated into a CI/CD pipeline, setup is designed to be minimal and fast. ## Installation & Usage + ### 📦 Via NPM + You can run depbadge directly using npx or add it to your project's development dependencies. -- Run once without installing -`npx @ehildt/depbadge` +- Run once without installing + `npx @ehildt/depbadge` -- Or add to your project -`npm install -D @ehildt/depbadge` +- Or add to your project + `npm install -D @ehildt/depbadge` -- Or add globally -`npm install -g @ehildt/depbadge` then run -`npx depbadge` +- Or add globally + `npm install -g @ehildt/depbadge` then run + `npx depbadge` depbadge accepts the `--generate` (or `-g`) option, which can take `json` or `markdown` as arguments. This allows generating badges JSON files or previewing Markdown when the output section is not set in depbadgerc.yml. @@ -22,6 +25,7 @@ npx depbadge -g json -g markdown ``` ### ▶️ Via GitHub Actions + Automate your badge updates by adding this workflow to `.github/workflows/depbadge.yml`. This example uses pnpm and automatically commits changes back to your branch. ```yml @@ -86,7 +90,8 @@ jobs: ``` ## 🛠️ Minimal Configuration -To get started, create a `.depbadgerc.yml` file in your project root. + +To get started, create a `.depbadgerc.yml` file in your project root. Define which packages to track by listing them under `dependencies.items`. ```yaml @@ -96,10 +101,12 @@ dependencies: - name: js-yaml - name: "@iarna/toml" ``` + ## ↕️ Badge Injection Markers + Finally, add the following markers to your README.md. The badges will be automatically injected between them: ```markdown -``` \ No newline at end of file +``` diff --git a/.wiki/status-badges/codecov-badges.md b/.wiki/status-badges/codecov-badges.md new file mode 100644 index 0000000..adfb920 --- /dev/null +++ b/.wiki/status-badges/codecov-badges.md @@ -0,0 +1,60 @@ +# Codecov Badges + +Display code coverage from Codecov using shields.io. + +### Badge URL Structure + +`https://img.shields.io/codecov/c/{token}/{user}/{repo}/{branch}` + +### Configuration + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `name` | string | Yes | Must be `"codecov"` | +| `user` | string | Yes | Codecov username or organization | +| `repo` | string | Yes | Repository name | +| `branch` | string | No | Branch name | +| `flag` | string | No | Specific coverage flag (e.g., `unit`, `integration`) | +| `token` | string | No | Codecov upload token (required for private repos) | +| `link` | string | No | Custom link URL | +| `style` | string | No | Badge style: `flat`, `flat-square`, `plastic`, `for-the-badge`, `social` | +| `color` | string | No | Badge color (hex or named color) | +| `labelColor` | string | No | Label background color | + +### Examples + +#### Basic Coverage Badge + +```yaml +- name: codecov + user: ehildt + repo: depbadge +``` + +#### With Branch + +```yaml +- name: codecov + user: ehildt + repo: depbadge + branch: main +``` + +#### With Flag + +```yaml +- name: codecov + user: ehildt + repo: depbadge + flag: unit +``` + +#### Private Repository (with token) + +```yaml +- name: codecov + user: ehildt + repo: depbadge + token: your-upload-token + branch: main +``` diff --git a/.wiki/status-badges/docker-badges.md b/.wiki/status-badges/docker-badges.md new file mode 100644 index 0000000..8379bcb --- /dev/null +++ b/.wiki/status-badges/docker-badges.md @@ -0,0 +1,68 @@ +# Docker Badges + +Display Docker Hub metrics using shields.io. + +### Badge URL Structure + +`https://img.shields.io/docker/{metric}/{user}/{image}` + +### Configuration + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `name` | string | Yes | Must be `"docker"` | +| `metric` | string | Yes | One of: `pulls`, `stars`, `v` | +| `user` | string | Yes | Docker Hub username or organization | +| `image` | string | Yes | Image name | +| `tag` | string | No | Image tag | +| `link` | string | No | Custom link URL | +| `style` | string | No | Badge style: `flat`, `flat-square`, `plastic`, `for-the-badge`, `social` | +| `color` | string | No | Badge color (hex or named color) | +| `labelColor` | string | No | Label background color | + +### Metrics + +| Metric | Description | +|--------|-------------| +| `pulls` | Number of pulls | +| `stars` | Number of stars | +| `v` | Latest version/tag | + +### Examples + +#### Pulls Badge + +```yaml +- name: docker + metric: pulls + user: library + image: nginx +``` + +#### Stars Badge + +```yaml +- name: docker + metric: stars + user: library + image: nginx +``` + +#### Version Badge + +```yaml +- name: docker + metric: v + user: library + image: nginx +``` + +#### With Tag + +```yaml +- name: docker + metric: v + user: library + image: nginx + tag: alpine +``` diff --git a/.wiki/status-badges/github-badges.md b/.wiki/status-badges/github-badges.md new file mode 100644 index 0000000..c1d6ecd --- /dev/null +++ b/.wiki/status-badges/github-badges.md @@ -0,0 +1,75 @@ +# GitHub Badges + +Display GitHub metrics for repositories using shields.io. + +### Badge URL Structure + +`https://img.shields.io/github/{metric}/{user}/{repo}` + +### Configuration + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `name` | string | Yes | Must be `"github"` | +| `metric` | string | Yes | One of: `stars`, `license`, `release`, `issues`, `forks`, `watchers`, `actions` | +| `user` | string | Yes | GitHub username or organization | +| `repo` | string | Yes | Repository name | +| `branch` | string | No | Branch name | +| `workflow` | string | Conditional | Required when `metric` is `actions` | +| `link` | string | No | Custom link URL | +| `style` | string | No | Badge style: `flat`, `flat-square`, `plastic`, `for-the-badge`, `social` | +| `color` | string | No | Badge color (hex or named color) | +| `labelColor` | string | No | Label background color | + +### Metrics + +| Metric | Description | +|--------|-------------| +| `stars` | Number of stars | +| `forks` | Number of forks | +| `issues` | Number of open issues | +| `watchers` | Number of watchers | +| `license` | Repository license | +| `release` | Latest release version | +| `actions` | Workflow status | + +### Examples + +#### Stars Badge + +```yaml +- name: github + metric: stars + user: ehildt + repo: depbadge +``` + +#### Latest Release Badge + +```yaml +- name: github + metric: release + user: ehildt + repo: depbadge + branch: main +``` + +#### License Badge + +```yaml +- name: github + metric: license + user: ehildt + repo: depbadge +``` + +#### Actions Workflow Badge + +```yaml +- name: github + metric: actions + user: ehildt + repo: depbadge + workflow: ci + branch: main +``` diff --git a/.wiki/status-badges/socket-badges.md b/.wiki/status-badges/socket-badges.md new file mode 100644 index 0000000..2fc13cb --- /dev/null +++ b/.wiki/status-badges/socket-badges.md @@ -0,0 +1,70 @@ +# Socket Badges + +Display supply chain security scores from [Socket.dev](https://socket.dev/) for npm packages. + +### Badge URL Structure + +`https://badge.socket.dev/npm/package/{package}/{version}` + +### Configuration + +| Property | Type | Required | Default | Description | +|----------|------|----------|---------|-------------| +| `name` | string | Yes | - | Must be `"socket"` | +| `package` | string | Yes | - | npm package name (e.g., `"express"`, `"@babel/core"`) | +| `version` | string | No | `"*"` | Package version or `"*"` for latest | +| `link` | string | No | npm package URL | Custom link URL | + +### What the Badge Shows + +Socket analyzes npm packages for supply chain security risks and displays an overall grade: + +- **A** - Excellent supply chain security +- **B** - Good supply chain security +- **C** - Moderate risk +- **D** - High risk +- **F** - Critical risk + +### Why Not Shields.io? + +We attempted to route Socket badges through shields.io's endpoint badge feature to enable consistent styling with other badges. However, this approach was not viable because: + +1. **CORS Restrictions**: Socket's API (`socket.dev/api/npm/package-info/score`) does not include CORS headers that allow shields.io's servers to fetch the data directly. + +2. **API Response Time**: Socket performs real-time analysis of npm packages which can take 30+ seconds for first-time analysis. Shields.io has strict timeout limits (~3-5 seconds) for endpoint badges. + +3. **Native Badge Service**: Socket provides its own badge service (`badge.socket.dev`) that works reliably without external dependencies. + +For these reasons, Socket badges use Socket's native badge service directly. + +### Examples + +#### Basic Usage + +```yaml +- name: socket + package: express +``` + +#### With Specific Version + +```yaml +- name: socket + package: express + version: "4.18.2" +``` + +#### Scoped Package + +```yaml +- name: socket + package: @babel/core +``` + +#### With Custom Link + +```yaml +- name: socket + package: express + link: https://socket.dev/npm/package/express +``` diff --git a/.wiki/status-badges/tile-badges.md b/.wiki/status-badges/tile-badges.md new file mode 100644 index 0000000..f1c0cae --- /dev/null +++ b/.wiki/status-badges/tile-badges.md @@ -0,0 +1,60 @@ +# Tile Badges + +Display custom static badges with arbitrary text using shields.io. + +### Badge URL Structure + +`https://img.shields.io/badge/{label}-{message}-{color}` + +### Configuration + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `name` | string | Yes | Must be `"tile"` | +| `label` | string | Yes | Left side text | +| `message` | string | Yes | Right side text | +| `color` | string | No | Badge color (hex or named color like `brightgreen`, `orange`, `red`) | +| `labelColor` | string | No | Label background color | +| `isError` | boolean | No | Force error-style rendering | +| `link` | string | No | Custom link URL | +| `style` | string | No | Badge style: `flat`, `flat-square`, `plastic`, `for-the-badge`, `social` | + +### Examples + +#### Build Status Badge + +```yaml +- name: tile + label: Build + message: Passing + color: brightgreen +``` + +#### Custom Message Badge + +```yaml +- name: tile + label: I Love + message: COOKIES + color: orange +``` + +#### With Link + +```yaml +- name: tile + label: CI + message: OK + color: blue + link: https://ci.example.com +``` + +#### Error Style Badge + +```yaml +- name: tile + label: Status + message: Failed + color: red + isError: true +``` diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..222ce6e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,153 @@ +# 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 build` | Build the project (runs tsup) | +| `pnpm prepublishOnly` | Build before publishing | + +## 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 lint:unused` | Check for unused exports | +| `pnpm lint-staged` | Run linters on staged files | + +## 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 +pnpm test -- encodeLabel +pnpm test -- "get-dependencies" +pnpm test -- "src/shared/encode-label.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) + +### Formatting (Prettier) + +- Print width: 120 characters +- 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 +- `sonarjs/cognitive-complexity`: warn +- `sonarjs/no-identical-expressions`: warn + +### Import Sorting (simple-import-sort) + +Order groups: + +1. `node:` imports +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 + +- Files: kebab-case (e.g., `ctx-store.ts`, `get-version.ts`) +- Types/Interfaces: PascalCase with descriptive names +- Functions: camelCase, verb-prefixed (e.g., `getDependencies`, `useCtxStore`) +- Test files: `*.spec.ts` suffix + +### Error Handling + +- Use try/catch in CLI entry points +- Always handle caught errors: + ```typescript + const message = error instanceof Error ? error.message : String(error); + ``` +- Exit with `process.exit(1)` on error +- Use `console.error` with `::error::` prefix for GitHub Actions + +### 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 + +### Store Pattern (ctx-store) + +The project uses a custom immutable store pattern: + +- `useCtxStore()` - creates frozen store +- `useCtxCallback()` - binds callbacks to store +- All stores are frozen with `Object.freeze()` + +## Development Workflow + +1. **Before committing**: Run `pnpm lint-staged` (automatically 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 +└── store/ # Store implementation +``` + +## Key Dependencies + +- **yargs**: CLI argument parsing +- **js-yaml**: YAML parsing +- **colord**: Color manipulation +- **@iarna/toml**: TOML parsing + +## Configuration Files + +- `eslint.config.ts` - ESLint configuration +- `prettier.config.mjs` - Prettier configuration +- `vitest.config.ts` - Test configuration +- `tsconfig.json` - TypeScript configuration +- `cspell.config.yml` - Spell checker configuration +- `tsup.config.ts` - Build tool configuration diff --git a/EULA.md b/EULA.md index 38f2ea0..cbcbc0e 100644 --- a/EULA.md +++ b/EULA.md @@ -1,8 +1,8 @@ # End User License Agreement (EULA) for Depbadge -**Copyright (c) [2026] Eugen Hildt** +**Copyright (c) [2026] Eugen Hildt** -By using, modifying, or distributing this software, you agree to be bound by the terms of this EULA. +By using, modifying, or distributing this software, you agree to be bound by the terms of this EULA. --- @@ -10,38 +10,38 @@ By using, modifying, or distributing this software, you agree to be bound by the You are granted a non-exclusive, worldwide, royalty-free license to **use, modify, and distribute** this software, subject to the following conditions: -1. **Attribution** – You must credit `Eugen Hildt` in any distribution or derivative work. -2. **No Forking** – You may **not** fork this project into a separate public repository or claim it as an independent project. -3. **Contribution Requirement** – If you develop a new feature or fix a bug that is missing from the current project and use it in your deployment, you **must contribute it back** via pull request or patch to the original repository. +1. **Attribution** – You must credit `Eugen Hildt` in any distribution or derivative work. +2. **No Forking** – You may **not** fork this project into a separate public repository or claim it as an independent project. +3. **Contribution Requirement** – If you develop a new feature or fix a bug that is missing from the current project and use it in your deployment, you **must contribute it back** via pull request or patch to the original repository. --- ## 2. Warranty Disclaimer -This software is provided **"as-is"**, without warranty of any kind. The author is not liable for any damages arising from its use, including but not limited to direct, indirect, incidental, or consequential damages. +This software is provided **"as-is"**, without warranty of any kind. The author is not liable for any damages arising from its use, including but not limited to direct, indirect, incidental, or consequential damages. --- ## 3. Compliance -By using this software, you agree to: +By using this software, you agree to: -- Follow all terms listed above. -- Respect privacy and intellectual property rights. -- Submit contributions to the original repository when required. +- Follow all terms listed above. +- Respect privacy and intellectual property rights. +- Submit contributions to the original repository when required. -Non-compliance constitutes a **breach of this EULA**, which may result in legal action. +Non-compliance constitutes a **breach of this EULA**, which may result in legal action. --- ## 4. GitHub Marketplace Notice -This product is published on **GitHub Marketplace**. -By installing, using, or accessing this product via GitHub Marketplace, you acknowledge that you have read and accept this EULA. +This product is published on **GitHub Marketplace**. +By installing, using, or accessing this product via GitHub Marketplace, you acknowledge that you have read and accept this EULA. --- ## 5. Contact For questions or reporting issues, please contact: -**Eugen Hildt / eugen.hildt@gmail.com / [ehildt](https://github.com/ehildt)** +**Eugen Hildt / eugen.hildt@gmail.com / [ehildt](https://github.com/ehildt)** diff --git a/README.md b/README.md index 1832438..ef9ee31 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Depbadge is a CLI tool that automatically generates and maintains dependency and **`package.json`** – Node.js / JavaScript / TypeScript projects **`pyproject.toml`** – Python projects (PEP 621) -**`Cargo.toml`** – Rust projects +**`Cargo.toml`** – Rust projects
@@ -29,6 +29,7 @@ Depbadge is a CLI tool that automatically generates and maintains dependency and ![github](https://img.shields.io/github/license/ehildt/depbadge?labelColor=333&style=for-the-badge&cacheSeconds=3600&color=b16425&logo=github&logoColor=b16425&logoWidth=40&branch=main) [![codecov](https://img.shields.io/codecov/c/github/ehildt/depbadge?labelColor=333&cacheSeconds=3600&logo=npm&logoColor=4021b0&logoWidth=40&style=for-the-badge&color=4021b0&branch=main)](https://about.codecov.io/) [![My_favorite](https://img.shields.io/badge/My_favorite-🍪🍪🍪-777?labelColor=333&cacheSeconds=3600&logo=npm&logoColor=b4cf2a&logoWidth=40&style=for-the-badge)](https://sallysbakingaddiction.com/chewy-chocolate-chip-cookies/) +[![socket](https://badge.socket.dev/npm/package/@ehildt/depbadge/1.1.4)](https://www.npmjs.com/package/@ehildt/depbadge) @@ -80,11 +81,9 @@ Depbadge is a CLI tool that automatically generates and maintains dependency and
-
[E-MAIL](mailto:eugen.hildt@gmail.com)  —  [WIKI](https://github.com/ehildt/depbadge/wiki)  —  [ISSUES](https://github.com/ehildt/depbadge/issues)  —  [DONATE](https://github.com/sponsors/ehildt) -
-
\ No newline at end of file +
diff --git a/action.yml b/action.yml index 4d3d452..fbfc9de 100644 --- a/action.yml +++ b/action.yml @@ -14,4 +14,4 @@ outputs: badges-json: description: "Path to the `.depbadge` folder containing badge.json files and preview" badges-readme: - description: "Path to the updated README.md" \ No newline at end of file + description: "Path to the updated README.md" diff --git a/depbadgerc.schema.json b/depbadgerc.schema.json index 10dc7d1..da4702a 100644 --- a/depbadgerc.schema.json +++ b/depbadgerc.schema.json @@ -67,7 +67,9 @@ "description": "Hex color code without the # prefix" }, "logoWidth": { "type": "number" }, - "style": { "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] }, + "style": { + "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] + }, "cacheSeconds": { "type": "number" }, "link": { "type": "string" } } @@ -111,7 +113,9 @@ "description": "Hex color code without the # prefix" }, "logoWidth": { "type": "number" }, - "style": { "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] }, + "style": { + "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] + }, "cacheSeconds": { "type": "number" }, "link": { "type": "string" } } @@ -168,7 +172,9 @@ "description": "Hex color code without the # prefix" }, "logoWidth": { "type": "number" }, - "style": { "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] }, + "style": { + "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] + }, "cacheSeconds": { "type": "number" }, "link": { "type": "string" } } @@ -210,7 +216,9 @@ "description": "Hex color code without the # prefix" }, "logoWidth": { "type": "number" }, - "style": { "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] }, + "style": { + "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] + }, "cacheSeconds": { "type": "number" }, "link": { "type": "string" } } @@ -248,7 +256,9 @@ "description": "Hex color code without the # prefix" }, "logoWidth": { "type": "number" }, - "style": { "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] }, + "style": { + "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] + }, "cacheSeconds": { "type": "number" }, "link": { "type": "string" } } @@ -281,7 +291,45 @@ "description": "Hex color code without the # prefix" }, "logoWidth": { "type": "number" }, - "style": { "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] }, + "style": { + "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] + }, + "cacheSeconds": { "type": "number" }, + "link": { "type": "string" } + } + }, + + "SocketStatusBadge": { + "type": "object", + "required": ["name", "package"], + "additionalProperties": false, + "properties": { + "name": { "const": "socket" }, + "package": { "type": "string" }, + "version": { "type": "string" }, + "message": { "type": "string" }, + "color": { + "type": "string", + "pattern": "^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", + "description": "Hex color code without the # prefix" + }, + "labelColor": { + "type": "string", + "pattern": "^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", + "description": "Hex color code without the # prefix" + }, + "isError": { "type": "boolean" }, + "namedLogo": { "type": "string" }, + "logoSvg": { "type": "string" }, + "logoColor": { + "type": "string", + "pattern": "^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", + "description": "Hex color code without the # prefix" + }, + "logoWidth": { "type": "number" }, + "style": { + "enum": ["flat", "flat-square", "plastic", "for-the-badge", "social"] + }, "cacheSeconds": { "type": "number" }, "link": { "type": "string" } } @@ -292,7 +340,8 @@ { "$ref": "#/$defs/GitHubStatusBadge" }, { "$ref": "#/$defs/DockerHubStatusBadge" }, { "$ref": "#/$defs/CodecovStatusBadge" }, - { "$ref": "#/$defs/TileStatusBadge" } + { "$ref": "#/$defs/TileStatusBadge" }, + { "$ref": "#/$defs/SocketStatusBadge" } ] }, diff --git a/depbadgerc.yml b/depbadgerc.yml index 870fb3f..543261c 100644 --- a/depbadgerc.yml +++ b/depbadgerc.yml @@ -1,5 +1,5 @@ # yaml-language-server: $schema=./depbadgerc.schema.json -integrity: 11eb46cd419fa4124f9e5b83dbb43dc1ab17d2f8b4e7b550649bd7e2ce05851c +integrity: bc5a33d7d59170f0090e8314ab2c69f7cdcfe507a07b5b94c5377073cf1cd54c target: README.md manifest: package.json output: @@ -10,15 +10,15 @@ dependenciesLayout: &DEPENDENCIES_LAYOUT showHeader: false dependenciesStyle: &DEPENDENCIES_STYLE - labelColor: '333' + labelColor: "333" isError: false namedLogo: npm logoWidth: 40 style: for-the-badge cacheSeconds: 3600 -statusBadgesStyle: &STATUS_BADGES_STYLE - labelColor: '333' +statusBadgesStyle: &STATUS_BADGES_STYLE + labelColor: "333" isError: false namedLogo: npm logoWidth: 40 @@ -43,18 +43,18 @@ dependencies: link: https://github.com/yargs/yargs devDependencies: - layout: *DEPENDENCIES_LAYOUT - badgeStyle: + layout: *DEPENDENCIES_LAYOUT + badgeStyle: <<: *DEPENDENCIES_STYLE style: flat-square items: - - name: '@changesets/cli' + - name: "@changesets/cli" namedLogo: npm - - name: '@eslint/js' + - name: "@eslint/js" namedLogo: eslint - - name: '@types/eslint' + - name: "@types/eslint" namedLogo: eslint - - name: '@types/node' + - name: "@types/node" namedLogo: node - name: depcheck namedLogo: npm @@ -136,5 +136,10 @@ statusBadges: - name: tile message: 🍪🍪🍪 label: My favorite - color: '777' - link: https://sallysbakingaddiction.com/chewy-chocolate-chip-cookies/ \ No newline at end of file + color: "777" + link: https://sallysbakingaddiction.com/chewy-chocolate-chip-cookies/ + - name: socket + package: '@ehildt/depbadge' + metric: quality + version: 1.1.4 + style: for-the-badge diff --git a/dist/index.mjs b/dist/index.mjs index 8a6870b..988d030 100755 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -4968,6 +4968,16 @@ function mapGithubStatusBadgeToMarkdown(badge) { return badge?.link ? `[![${label}](${url})](${badge.link})` : `![${label}](${url})`; } +// src/depbadgerc/map-socket-status-badge-to-markdown.ts +init_esm_shims(); +function mapSocketStatusBadgeToMarkdown(badge) { + const label = badge.name; + const version = badge.version ?? "*"; + const url = `https://badge.socket.dev/npm/package/${badge.package}/${version}`; + const link = badge.link ?? `https://www.npmjs.com/package/${badge.package}`; + return `[![${label}](${url})](${link})`; +} + // src/depbadgerc/map-tile-status-badge-to-markdown.ts init_esm_shims(); function mapTileStatusBadgeToMarkdown(badge) { @@ -5000,6 +5010,7 @@ var mapStatusBadgesToMarkdown = useCtxCallback( if (item.name === "docker") return mapDockerHubStatusBadgeToMarkdown(item); if (item.name === "codecov") return mapCodecovStatusBadgeToMarkdown(item); if (item.name === "tile") return mapTileStatusBadgeToMarkdown(item); + if (item.name === "socket") return mapSocketStatusBadgeToMarkdown(item); }).filter((x2) => Boolean(x2)) ]) ) diff --git a/eslint.config.ts b/eslint.config.ts index a7efaf1..e10875e 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -9,7 +9,15 @@ import tseslint from "typescript-eslint"; export default defineConfig([ { - ignores: [".husky", ".gitlab", ".vscode", ".json", ".depcruise.mjs", "dist", "node_modules"], + ignores: [ + ".husky", + ".gitlab", + ".vscode", + ".json", + ".depcruise.mjs", + "dist", + "node_modules", + ], }, pluginJs.configs.recommended, ...tseslint.configs.recommended, diff --git a/package.json b/package.json index 86e3dca..74411a6 100755 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "husky": "^9.1.7", "jiti": "^2.6.1", "lint-staged": "^16.4.0", - "npm-check-updates": "^19.6.3", + "npm-check-updates": "^19.6.5", "rimraf": "^6.1.3", "source-map-support": "^0.5.21", "ts-loader": "^9.5.4", @@ -77,7 +77,7 @@ "ts-unused-exports": "^11.0.1", "tsup": "^8.5.1", "typescript": "^5.9.3", - "typescript-eslint": "^8.57.0", + "typescript-eslint": "^8.57.1", "vitest": "^4.1.0" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 946d268..bcf9b54 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -76,8 +76,8 @@ importers: specifier: ^16.4.0 version: 16.4.0 npm-check-updates: - specifier: ^19.6.3 - version: 19.6.3 + specifier: ^19.6.5 + version: 19.6.5 rimraf: specifier: ^6.1.3 version: 6.1.3 @@ -100,8 +100,8 @@ importers: specifier: ^5.9.3 version: 5.9.3 typescript-eslint: - specifier: ^8.57.0 - version: 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.57.1 + version: 8.57.1(eslint@10.0.3(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)) @@ -791,63 +791,63 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@typescript-eslint/eslint-plugin@8.57.0': - resolution: {integrity: sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==} + '@typescript-eslint/eslint-plugin@8.57.1': + resolution: {integrity: sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.57.0 + '@typescript-eslint/parser': ^8.57.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.57.0': - resolution: {integrity: sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==} + '@typescript-eslint/parser@8.57.1': + resolution: {integrity: sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.57.0': - resolution: {integrity: sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==} + '@typescript-eslint/project-service@8.57.1': + resolution: {integrity: sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.57.0': - resolution: {integrity: sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==} + '@typescript-eslint/scope-manager@8.57.1': + resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.57.0': - resolution: {integrity: sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==} + '@typescript-eslint/tsconfig-utils@8.57.1': + resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.57.0': - resolution: {integrity: sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==} + '@typescript-eslint/type-utils@8.57.1': + resolution: {integrity: sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.57.0': - resolution: {integrity: sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==} + '@typescript-eslint/types@8.57.1': + resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.57.0': - resolution: {integrity: sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==} + '@typescript-eslint/typescript-estree@8.57.1': + resolution: {integrity: sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.57.0': - resolution: {integrity: sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==} + '@typescript-eslint/utils@8.57.1': + resolution: {integrity: sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.57.0': - resolution: {integrity: sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==} + '@typescript-eslint/visitor-keys@8.57.1': + resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@vitest/coverage-v8@4.1.0': @@ -1957,8 +1957,8 @@ packages: node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - npm-check-updates@19.6.3: - resolution: {integrity: sha512-VAt9Bp26eLaymZ0nZyh5n/by+YZIuegXlvWR0yv1zBqd984f8VnEnBbn+1lS3nN5LyEjn62BJ+yYgzNSpb6Gzg==} + npm-check-updates@19.6.5: + resolution: {integrity: sha512-XlBUMC30relXfEerrnX239W9iB30U6Woz0Hj42Sv6iSF4EGOvj2mS2r45sZ3RglH0VPBxXOWooMxObZ/SMZhrw==} engines: {node: '>=20.0.0', npm: '>=8.12.1'} hasBin: true @@ -2479,8 +2479,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.57.0: - resolution: {integrity: sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==} + typescript-eslint@8.57.1: + resolution: {integrity: sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3270,14 +3270,14 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(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.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/type-utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/parser': 8.57.1(eslint@10.0.3(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/visitor-keys': 8.57.1 eslint: 10.0.3(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -3286,41 +3286,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.0(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)': dependencies: - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.0 + '@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) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.57.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) - '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.57.0': + '@typescript-eslint/scope-manager@8.57.1': dependencies: - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 - '@typescript-eslint/tsconfig-utils@8.57.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) + '@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) debug: 4.4.3 eslint: 10.0.3(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) @@ -3328,14 +3328,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.57.0': {} + '@typescript-eslint/types@8.57.1': {} - '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.57.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/project-service': 8.57.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.4 @@ -3345,20 +3345,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.0(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)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) + '@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) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.57.0': + '@typescript-eslint/visitor-keys@8.57.1': dependencies: - '@typescript-eslint/types': 8.57.0 + '@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)))': @@ -4486,7 +4486,7 @@ snapshots: node-releases@2.0.27: {} - npm-check-updates@19.6.3: {} + npm-check-updates@19.6.5: {} object-assign@4.1.1: {} @@ -5014,12 +5014,12 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.57.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(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.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(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.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/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: 5.9.3 transitivePeerDependencies: diff --git a/src/depbadgerc/apply-markdown-to-target.spec.ts b/src/depbadgerc/apply-markdown-to-target.spec.ts index 94d81ef..a638805 100644 --- a/src/depbadgerc/apply-markdown-to-target.spec.ts +++ b/src/depbadgerc/apply-markdown-to-target.spec.ts @@ -19,10 +19,30 @@ describe("applyMarkdownToTarget", () => { target: "README.md", // Each section includes layout for headers - dependencies: { items: [], layout: { showHeader: true, header: "Dependencies", position: "left" } }, - devDependencies: { items: [], layout: { showHeader: true, header: "Dev Dependencies", position: "center" } }, - peerDependencies: { items: [], layout: { showHeader: false, header: "Peer Dependencies", position: "right" } }, - statusBadges: { items: [], layout: { showHeader: true, header: "Status Badges", position: "center" } }, + dependencies: { + items: [], + layout: { showHeader: true, header: "Dependencies", position: "left" }, + }, + devDependencies: { + items: [], + layout: { + showHeader: true, + header: "Dev Dependencies", + position: "center", + }, + }, + peerDependencies: { + items: [], + layout: { + showHeader: false, + header: "Peer Dependencies", + position: "right", + }, + }, + statusBadges: { + items: [], + layout: { showHeader: true, header: "Status Badges", position: "center" }, + }, output: undefined, // methods mocked diff --git a/src/depbadgerc/compute-state-integrity.spec.ts b/src/depbadgerc/compute-state-integrity.spec.ts index b2a944e..3dbd595 100644 --- a/src/depbadgerc/compute-state-integrity.spec.ts +++ b/src/depbadgerc/compute-state-integrity.spec.ts @@ -87,7 +87,9 @@ describe("computeStateIntegrity", () => { it("produces different hashes for different store states", () => { const store1 = makeMockStore(); - const store2 = makeMockStore({ dependencies: { items: [{ name: "x", message: "ok" }] } }); + const store2 = makeMockStore({ + dependencies: { items: [{ name: "x", message: "ok" }] }, + }); const hash1 = computeStateIntegrity(store1)(); const hash2 = computeStateIntegrity(store2)(); diff --git a/src/depbadgerc/depbadgerc.type.ts b/src/depbadgerc/depbadgerc.type.ts index 8a9ddca..6512eef 100644 --- a/src/depbadgerc/depbadgerc.type.ts +++ b/src/depbadgerc/depbadgerc.type.ts @@ -63,7 +63,18 @@ export type TileStatusBadge = DependencyItem & { label: string; }; -export type StatusBadgeItem = GitHubStatusBadge | DockerHubStatusBadge | CodecovStatusBadge | TileStatusBadge; +export type SocketStatusBadge = DependencyItem & { + name: "socket"; + package: string; + version?: string; +}; + +export type StatusBadgeItem = + | GitHubStatusBadge + | DockerHubStatusBadge + | CodecovStatusBadge + | TileStatusBadge + | SocketStatusBadge; export type StatusBadges = { layout?: Layout; diff --git a/src/depbadgerc/get-dependnecies.spec.ts b/src/depbadgerc/get-dependnecies.spec.ts index ab0008f..55afaa3 100644 --- a/src/depbadgerc/get-dependnecies.spec.ts +++ b/src/depbadgerc/get-dependnecies.spec.ts @@ -31,7 +31,11 @@ describe("getDependencies", () => { const devDeps: Dependencies = { items: [] }; const peerDeps: Dependencies = { items: [] }; - const run = bind({ dependencies: deps, devDependencies: devDeps, peerDependencies: peerDeps }); + const run = bind({ + dependencies: deps, + devDependencies: devDeps, + peerDependencies: peerDeps, + }); const result = run(); expect(result.dependencies).toBe(deps); diff --git a/src/depbadgerc/get-status-badges.spec.ts b/src/depbadgerc/get-status-badges.spec.ts index 23659bf..e56860a 100644 --- a/src/depbadgerc/get-status-badges.spec.ts +++ b/src/depbadgerc/get-status-badges.spec.ts @@ -18,7 +18,16 @@ describe("getStatusBadges", () => { it("returns object with statusBadges if store.statusBadges exists", () => { const mockStatusBadges: StatusBadges = { - items: [{ name: "github", user: "octocat", repo: "hello-world", metric: "stars", message: "100", color: "blue" }], + items: [ + { + name: "github", + user: "octocat", + repo: "hello-world", + metric: "stars", + message: "100", + color: "blue", + }, + ], }; const run = bind({ statusBadges: mockStatusBadges }); diff --git a/src/depbadgerc/map-socket-status-badge-to-markdown.spec.ts b/src/depbadgerc/map-socket-status-badge-to-markdown.spec.ts new file mode 100644 index 0000000..b4e3ee2 --- /dev/null +++ b/src/depbadgerc/map-socket-status-badge-to-markdown.spec.ts @@ -0,0 +1,60 @@ +import { SocketStatusBadge } from "./depbadgerc.type.ts"; +import { mapSocketStatusBadgeToMarkdown } from "./map-socket-status-badge-to-markdown.ts"; + +describe("mapSocketStatusBadgeToMarkdown", () => { + const baseSocketBadge: SocketStatusBadge = { + name: "socket", + package: "express", + message: "irrelevant", + }; + + it("should use badge.socket.dev URL with latest version by default", () => { + const result = mapSocketStatusBadgeToMarkdown(baseSocketBadge); + + expect(result).toContain("https://badge.socket.dev/npm/package/express/*"); + expect(result).toContain("https://www.npmjs.com/package/express"); + }); + + it("should use provided version", () => { + const badgeWithVersion: SocketStatusBadge = { + ...baseSocketBadge, + version: "4.18.2", + }; + + const result = mapSocketStatusBadgeToMarkdown(badgeWithVersion); + + expect(result).toContain("https://badge.socket.dev/npm/package/express/4.18.2"); + }); + + it("should handle scoped package names", () => { + const scopedBadge: SocketStatusBadge = { + ...baseSocketBadge, + package: "@babel/core", + }; + + const result = mapSocketStatusBadgeToMarkdown(scopedBadge); + + expect(result).toContain("https://badge.socket.dev/npm/package/@babel/core/*"); + expect(result).toContain("https://www.npmjs.com/package/@babel/core"); + }); + + it("should allow custom link override", () => { + const badgeWithLink: SocketStatusBadge = { + ...baseSocketBadge, + link: "https://custom-link.example.com", + }; + + const result = mapSocketStatusBadgeToMarkdown(badgeWithLink); + + expect(result).toContain("https://badge.socket.dev/npm/package/express/*"); + expect(result).toContain("](https://custom-link.example.com)"); + }); + + it("should always return a linked image", () => { + const result = mapSocketStatusBadgeToMarkdown(baseSocketBadge); + + expect(result).toMatch( + /^\[!\[socket\]\(https:\/\/badge\.socket\.dev\/npm\/package\/.*\*\)\]\(https:\/\/www\.npmjs\.com\/package\/.*\)$/, + ); + }); +}); diff --git a/src/depbadgerc/map-socket-status-badge-to-markdown.ts b/src/depbadgerc/map-socket-status-badge-to-markdown.ts new file mode 100644 index 0000000..7f83511 --- /dev/null +++ b/src/depbadgerc/map-socket-status-badge-to-markdown.ts @@ -0,0 +1,10 @@ +import { SocketStatusBadge } from "./depbadgerc.type.ts"; + +export function mapSocketStatusBadgeToMarkdown(badge: SocketStatusBadge): string { + const label = badge.name; + const version = badge.version ?? "*"; + const url = `https://badge.socket.dev/npm/package/${badge.package}/${version}`; + const link = badge.link ?? `https://www.npmjs.com/package/${badge.package}`; + + return `[![${label}](${url})](${link})`; +} diff --git a/src/depbadgerc/map-status-badges-to-markdown.ts b/src/depbadgerc/map-status-badges-to-markdown.ts index a4306a1..5aac6bf 100644 --- a/src/depbadgerc/map-status-badges-to-markdown.ts +++ b/src/depbadgerc/map-status-badges-to-markdown.ts @@ -6,12 +6,14 @@ import { DepbadgeRC, DockerHubStatusBadge, GitHubStatusBadge, + SocketStatusBadge, TileStatusBadge, } from "./depbadgerc.type.ts"; import { HydratedStatusBadgeMap } from "./hydrate-status-badges.ts"; import { mapCodecovStatusBadgeToMarkdown } from "./map-codecov-status-badge-to-markdown.ts"; import { mapDockerHubStatusBadgeToMarkdown } from "./map-dockerhub-status-badge-to-markdown.ts"; import { mapGithubStatusBadgeToMarkdown } from "./map-github-status-badge-to-markdown.ts"; +import { mapSocketStatusBadgeToMarkdown } from "./map-socket-status-badge-to-markdown.ts"; import { mapTileStatusBadgeToMarkdown } from "./map-tile-status-badge-to-markdown.ts"; export const mapStatusBadgesToMarkdown = useCtxCallback>( @@ -25,6 +27,7 @@ export const mapStatusBadgesToMarkdown = useCtxCallback Boolean(x)), ]), diff --git a/src/depbadgerc/output-markdown-preview.spec.ts b/src/depbadgerc/output-markdown-preview.spec.ts index eba1099..47a354a 100644 --- a/src/depbadgerc/output-markdown-preview.spec.ts +++ b/src/depbadgerc/output-markdown-preview.spec.ts @@ -26,12 +26,16 @@ describe("outputMarkdownPreview", () => { const run = bind(); run("BADGES", { dependencies: ["badge1", "badge2"] }); - expect(mockedFs.mkdirSync).toHaveBeenCalledWith(".depbadge", { recursive: true }); + expect(mockedFs.mkdirSync).toHaveBeenCalledWith(".depbadge", { + recursive: true, + }); expect(mockedFs.writeFileSync).toHaveBeenCalledWith(".depbadge/BADGES.md", "badge1\nbadge2"); }); it("adds header when showHeader is true", () => { - const run = bind({ dependencies: { layout: { showHeader: true, header: "Deps" } } }); + const run = bind({ + dependencies: { layout: { showHeader: true, header: "Deps" } }, + }); run("BADGES", { dependencies: ["badge"] }); // Matches exact newlines from implementation @@ -50,7 +54,9 @@ describe("outputMarkdownPreview", () => { it("wraps content with header + alignment div", () => { const run = bind({ - dependencies: { layout: { showHeader: true, header: "Deps", position: "center" } }, + dependencies: { + layout: { showHeader: true, header: "Deps", position: "center" }, + }, }); run("BADGES", { dependencies: ["badge"] }); @@ -64,7 +70,9 @@ describe("outputMarkdownPreview", () => { const run = bind(); run("BADGES", { dependencies: ["badge"] }, "preview"); - expect(mockedFs.mkdirSync).toHaveBeenCalledWith("preview", { recursive: true }); + expect(mockedFs.mkdirSync).toHaveBeenCalledWith("preview", { + recursive: true, + }); expect(mockedFs.writeFileSync).toHaveBeenCalledWith("preview/BADGES.md", "badge"); }); diff --git a/src/depbadgerc/output-shieldio-badges-json.spec.ts b/src/depbadgerc/output-shieldio-badges-json.spec.ts index 3a54bff..fc70d3b 100644 --- a/src/depbadgerc/output-shieldio-badges-json.spec.ts +++ b/src/depbadgerc/output-shieldio-badges-json.spec.ts @@ -32,7 +32,9 @@ describe("outputShieldioBadgesJson", () => { run(map as any); - expect(mockedFs.mkdirSync).toHaveBeenCalledWith(".depbadge/dependencies", { recursive: true }); + expect(mockedFs.mkdirSync).toHaveBeenCalledWith(".depbadge/dependencies", { + recursive: true, + }); }); test("writes badge files", () => { @@ -80,7 +82,9 @@ describe("outputShieldioBadgesJson", () => { run(map as any, "custom"); - expect(mockedFs.mkdirSync).toHaveBeenCalledWith("custom/dependencies", { recursive: true }); + expect(mockedFs.mkdirSync).toHaveBeenCalledWith("custom/dependencies", { + recursive: true, + }); }); test("handles multiple sections", () => { diff --git a/src/depbadgerc/read-depbadgerc-with-defaults.spec.ts b/src/depbadgerc/read-depbadgerc-with-defaults.spec.ts index 6de52b9..02374b6 100644 --- a/src/depbadgerc/read-depbadgerc-with-defaults.spec.ts +++ b/src/depbadgerc/read-depbadgerc-with-defaults.spec.ts @@ -39,7 +39,9 @@ describe("read-depbadgerc-with-defaults", () => { it("applySectionDefaults applies defaults and calls hashStringToHex", () => { hashMock.mockImplementation((s) => `hash-${s}`); - const section = { items: [{ name: "foo", message: "bar" }] as DependencyItem[] }; + const section = { + items: [{ name: "foo", message: "bar" }] as DependencyItem[], + }; const result = applySectionDefaults(section); expect(result.items[0].color).toBe("hash-foo"); expect(result.items[0].logoColor).toBe("hash-foo"); diff --git a/src/store/ctx-store.spec.ts b/src/store/ctx-store.spec.ts index 7b4b4a0..23990eb 100644 --- a/src/store/ctx-store.spec.ts +++ b/src/store/ctx-store.spec.ts @@ -1,4 +1,4 @@ -import { useCtxCallback, useCtxStore } from "./ctx-store"; +import { useCtxCallback, useCtxStore } from "./ctx-store.ts"; describe("CtxStore / useCtxCallback strict tests", () => { type State = { count: number; text: string }; @@ -39,7 +39,11 @@ describe("CtxStore / useCtxCallback strict tests", () => { it("multiple callbacks bound independently", () => { const store = useCtxStore( { count: 4, text: "y" }, - { increment: (s) => (d) => s.count + d, double: (s) => () => s.count * 2, append: (s) => (str) => s.text + str }, + { + increment: (s) => (d) => s.count + d, + double: (s) => () => s.count * 2, + append: (s) => (str) => s.text + str, + }, ); const cb1 = useCtxCallback((s) => s.count * 2)(store); @@ -60,7 +64,11 @@ describe("CtxStore / useCtxCallback strict tests", () => { it("callbacks still work even with frozen store", () => { const store = useCtxStore( { count: 7, text: "z" }, - { increment: (s) => (d) => s.count + d, double: (s) => () => s.count * 2, append: (s) => (str) => s.text + str }, + { + increment: (s) => (d) => s.count + d, + double: (s) => () => s.count * 2, + append: (s) => (str) => s.text + str, + }, ); const fn = useCtxCallback((s, delta: number) => s.count + delta)(store); diff --git a/tsconfig.exclude.json b/tsconfig.exclude.json index d1a2614..ad081ee 100755 --- a/tsconfig.exclude.json +++ b/tsconfig.exclude.json @@ -11,7 +11,7 @@ "src/**/*.stories.?sx", "**/read-depbadgerc-with-defaults.ts", "**/depbadgerc.type.ts", - "**/vitest.config.ts", + "**/vitest.config.ts" ], "extends": "./tsconfig.json" } diff --git a/tsconfig.json b/tsconfig.json index 5fed6ef..e52269e 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,10 +19,7 @@ "noImplicitThis": true, "noEmit": true, "allowImportingTsExtensions": true, - "types": [ - "node", - "vitest/globals" - ] + "types": ["node", "vitest/globals"] }, "include": [ "src/", diff --git a/tsup.config.ts b/tsup.config.ts index 3211622..b12781e 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -21,7 +21,19 @@ const require = __createRequire(import.meta.url); }, esbuildOptions(options) { options.platform = "node"; - options.external = ["node:*", "net", "http", "https", "tls", "crypto", "path", "fs", "os", "url", "child_process"]; + options.external = [ + "node:*", + "net", + "http", + "https", + "tls", + "crypto", + "path", + "fs", + "os", + "url", + "child_process", + ]; }, treeshake: true, });