@jayf0x/npm-exists 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,20 +1,14 @@
1
1
  # npm-exists
2
2
 
3
- > Check if an npm package name is taken. Zero dependencies, uses native `fetch`.
3
+ > Check if an npm package name is taken.
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/@jayf0x/npm-exists.svg)](https://npmjs.com/package/@jayf0x/npm-exists)
6
- [![npm downloads](https://img.shields.io/npm/dm/@jayf0x/npm-exists.svg)](https://npmjs.com/package/@jayf0x/npm-exists)
7
- [![license](https://img.shields.io/npm/l/@jayf0x/npm-exists.svg)](LICENSE)
8
- [![node](https://img.shields.io/node/v/@jayf0x/npm-exists.svg)](package.json)
5
+ [![npm version](https://img.shields.io/npm/v/@jayf0x/npm-exists)](https://www.npmjs.com/package/@jayf0x/npm-exists)
6
+ [![npm downloads](https://img.shields.io/npm/dm/@jayf0x/npm-exists)](https://www.npmjs.com/package/@jayf0x/npm-exists)
7
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@jayf0x/npm-exists)](https://bundlephobia.com/package/@jayf0x/npm-exists)
8
+ [![license](https://img.shields.io/npm/l/@jayf0x/npm-exists)](./LICENSE)
9
+ [![CI](https://github.com/jayf0x/npm-exists/actions/workflows/release.yml/badge.svg)](https://github.com/jayf0x/npm-exists/actions/workflows/release.yml)
9
10
 
10
- ## Features
11
-
12
- - **Zero dependencies** — uses native `fetch` (Node 18+)
13
- - **Returns full metadata** — not just a boolean; get version, description, author, etc.
14
- - **Custom registry** — point at any npm-compatible registry
15
- - **CLI included** — `npm-exists <package-name>`
16
- - **Dual ESM/CJS** — works in both module systems
17
- - **TypeScript types** included
11
+ Zero dependencies. Returns the npm package URL or `false`.
18
12
 
19
13
  ## Install
20
14
 
@@ -24,97 +18,55 @@ npm install @jayf0x/npm-exists
24
18
 
25
19
  ## Usage
26
20
 
27
- ### API
28
-
29
21
  ```js
30
22
  import npmExists from '@jayf0x/npm-exists'
31
23
 
32
- // Check if a package exists — returns metadata or false
33
- const details = await npmExists('react')
34
- if (details) {
35
- console.log(`react@${details['dist-tags'].latest} exists`)
36
- } else {
37
- console.log('Package name is free!')
38
- }
24
+ const url = await npmExists('react')
25
+ // 'https://www.npmjs.com/package/react' | false
39
26
  ```
40
27
 
41
28
  ```js
42
- // With a custom registry
43
- const details = await npmExists('my-pkg', 'https://my.private.registry.io')
29
+ // Custom registry
30
+ const url = await npmExists('my-pkg', 'https://my.private.registry.io')
44
31
  ```
45
32
 
46
33
  ```js
47
- // Build your own fetch getNpmUrl lets you use axios, ky, etc.
48
- import { getNpmUrl } from '@jayf0x/npm-exists'
49
- import axios from 'axios'
50
-
51
- const url = getNpmUrl('react')
52
- const { data } = await axios.get(url)
34
+ // Suppress errors (network failures return false instead of throwing)
35
+ const url = await npmExists('react', { silent: true })
53
36
  ```
54
37
 
55
- ### Exports
56
-
57
- | Export | Description |
58
- |---|---|
59
- | `npmExists(pkg, registry?)` | Returns package metadata (`object`) or `false` |
60
- | `getNpmUrl(pkg, registry?)` | Returns the registry URL for a package |
38
+ ```js
39
+ // Build your own fetch
40
+ import { getNpmUrl } from '@jayf0x/npm-exists'
41
+ const url = getNpmUrl('react') // https://registry.npmjs.org/react
42
+ ```
61
43
 
62
- ### CLI
44
+ ## CLI
63
45
 
64
46
  ```sh
65
- # Global install
66
- npm install -g npm-exists
67
-
68
- npm-exists react
47
+ npx @jayf0x/npm-exists react
69
48
  # ✓ react@19.1.0 exists on npm
70
49
 
71
- npm-exists my-unique-package-name-xyz
72
- # ✗ my-unique-package-name-xyz is not registered on npm
73
-
74
- # Exit codes: 0 = exists, 1 = not found, 2 = bad usage
75
-
76
- # Custom registry
77
50
  npm-exists my-pkg https://my.private.registry.io
78
51
  ```
79
52
 
80
- ### One-off via npx
53
+ Exit codes: `0` exists · `1` not found · `2` bad usage
81
54
 
82
- ```sh
83
- npx @jayf0x/npm-exists react
84
- ```
85
-
86
- ## API Reference
87
-
88
- ### `npmExists(pkg, registry?)`
89
-
90
- | Param | Type | Default | Description |
91
- |---|---|---|---|
92
- | `pkg` | `string` | — | Package name (scoped names like `@scope/pkg` are supported) |
93
- | `registry` | `string` | `https://registry.npmjs.org` | Registry base URL |
55
+ ## API
94
56
 
95
- **Returns:** `Promise<object \| false>`
96
- - `object` — full registry metadata (includes `name`, `dist-tags`, `versions`, `description`, …)
97
- - `false` — package does not exist
57
+ ### `npmExists(pkg, registryOrOptions?, options?)`
98
58
 
99
- **Throws** if the registry returns an unexpected non-404 error (network issue, auth failure, etc.).
59
+ | Param | Type | Description |
60
+ |---|---|---|
61
+ | `pkg` | `string` | Package name |
62
+ | `registryOrOptions` | `string \| { registry?, silent? }` | Registry URL or options object |
63
+ | `options` | `{ silent? }` | When `silent: true`, errors return `false` instead of throwing |
100
64
 
101
- ---
65
+ Returns `Promise<string \| false>` — the npm page URL or `false` if not found.
102
66
 
103
67
  ### `getNpmUrl(pkg, registry?)`
104
68
 
105
- Returns the full URL used to query the registry. Useful when you want to make the request yourself.
106
-
107
- ```js
108
- getNpmUrl('react')
109
- // → 'https://registry.npmjs.org/react'
110
-
111
- getNpmUrl('@scope/pkg')
112
- // → 'https://registry.npmjs.org/%40scope%2Fpkg'
113
- ```
114
-
115
- ## Requirements
116
-
117
- Node 18+ (uses native `fetch`).
69
+ Returns the registry API URL. Useful with custom HTTP clients like axios or ky.
118
70
 
119
71
  ## License
120
72
 
package/dist/index.cjs CHANGED
@@ -1,15 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const DEFAULT_REGISTRY = "https://registry.npmjs.org";
4
+ const NPM_PAGE_BASE = "https://www.npmjs.com/package";
4
5
  function getNpmUrl(pkg, registry = DEFAULT_REGISTRY) {
5
6
  return `${registry.replace(/\/$/, "")}/${encodeURIComponent(pkg)}`;
6
7
  }
7
- async function npmExists(pkg, registry) {
8
- const url = getNpmUrl(pkg, registry);
9
- const res = await fetch(url);
10
- if (res.status === 404) return false;
11
- if (!res.ok) throw new Error(`npm registry error: HTTP ${res.status}`);
12
- return res.json();
8
+ function getPageUrl(pkg, registry) {
9
+ const base = !registry || registry === DEFAULT_REGISTRY ? NPM_PAGE_BASE : `${registry.replace(/\/$/, "")}/package`;
10
+ return `${base}/${pkg}`;
11
+ }
12
+ async function npmExists(pkg, registryOrOptions, options) {
13
+ let registry = DEFAULT_REGISTRY;
14
+ let silent = false;
15
+ if (typeof registryOrOptions === "string") {
16
+ registry = registryOrOptions;
17
+ silent = options?.silent ?? false;
18
+ } else if (registryOrOptions != null) {
19
+ registry = registryOrOptions.registry ?? DEFAULT_REGISTRY;
20
+ silent = registryOrOptions.silent ?? false;
21
+ }
22
+ try {
23
+ const res = await fetch(getNpmUrl(pkg, registry));
24
+ if (res.status === 404) return false;
25
+ if (!res.ok) throw new Error(`npm registry error: HTTP ${res.status}`);
26
+ return getPageUrl(pkg, registry);
27
+ } catch (err) {
28
+ if (silent) return false;
29
+ throw err;
30
+ }
13
31
  }
14
32
  exports.default = npmExists;
15
33
  exports.getNpmUrl = getNpmUrl;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,14 @@
1
1
  export declare function getNpmUrl(pkg: string, registry?: string): string
2
2
 
3
- export declare function npmExists(pkg: string, registry?: string): Promise<Record<string, unknown> | false>
3
+ export interface NpmExistsOptions {
4
+ registry?: string
5
+ silent?: boolean
6
+ }
7
+
8
+ export declare function npmExists(
9
+ pkg: string,
10
+ registryOrOptions?: string | NpmExistsOptions,
11
+ options?: Pick<NpmExistsOptions, 'silent'>
12
+ ): Promise<string | false>
4
13
 
5
14
  export default npmExists
package/dist/index.js CHANGED
@@ -1,13 +1,31 @@
1
1
  const DEFAULT_REGISTRY = "https://registry.npmjs.org";
2
+ const NPM_PAGE_BASE = "https://www.npmjs.com/package";
2
3
  function getNpmUrl(pkg, registry = DEFAULT_REGISTRY) {
3
4
  return `${registry.replace(/\/$/, "")}/${encodeURIComponent(pkg)}`;
4
5
  }
5
- async function npmExists(pkg, registry) {
6
- const url = getNpmUrl(pkg, registry);
7
- const res = await fetch(url);
8
- if (res.status === 404) return false;
9
- if (!res.ok) throw new Error(`npm registry error: HTTP ${res.status}`);
10
- return res.json();
6
+ function getPageUrl(pkg, registry) {
7
+ const base = !registry || registry === DEFAULT_REGISTRY ? NPM_PAGE_BASE : `${registry.replace(/\/$/, "")}/package`;
8
+ return `${base}/${pkg}`;
9
+ }
10
+ async function npmExists(pkg, registryOrOptions, options) {
11
+ let registry = DEFAULT_REGISTRY;
12
+ let silent = false;
13
+ if (typeof registryOrOptions === "string") {
14
+ registry = registryOrOptions;
15
+ silent = options?.silent ?? false;
16
+ } else if (registryOrOptions != null) {
17
+ registry = registryOrOptions.registry ?? DEFAULT_REGISTRY;
18
+ silent = registryOrOptions.silent ?? false;
19
+ }
20
+ try {
21
+ const res = await fetch(getNpmUrl(pkg, registry));
22
+ if (res.status === 404) return false;
23
+ if (!res.ok) throw new Error(`npm registry error: HTTP ${res.status}`);
24
+ return getPageUrl(pkg, registry);
25
+ } catch (err) {
26
+ if (silent) return false;
27
+ throw err;
28
+ }
11
29
  }
12
30
  export {
13
31
  npmExists as default,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jayf0x/npm-exists",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Check if an npm package name is taken. Zero dependencies, uses native fetch.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",