@jayf0x/npm-exists 2.0.1 → 2.0.3

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,13 @@
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
9
 
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
10
+ Zero dependencies. Returns the npm package URL or `false`.
18
11
 
19
12
  ## Install
20
13
 
@@ -24,97 +17,55 @@ npm install @jayf0x/npm-exists
24
17
 
25
18
  ## Usage
26
19
 
27
- ### API
28
-
29
20
  ```js
30
21
  import npmExists from '@jayf0x/npm-exists'
31
22
 
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
- }
23
+ const url = await npmExists('react')
24
+ // 'https://www.npmjs.com/package/react' | false
39
25
  ```
40
26
 
41
27
  ```js
42
- // With a custom registry
43
- const details = await npmExists('my-pkg', 'https://my.private.registry.io')
28
+ // Custom registry
29
+ const url = await npmExists('my-pkg', 'https://my.private.registry.io')
44
30
  ```
45
31
 
46
32
  ```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)
33
+ // Suppress errors (network failures return false instead of throwing)
34
+ const url = await npmExists('react', { silent: true })
53
35
  ```
54
36
 
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 |
37
+ ```js
38
+ // Build your own fetch
39
+ import { getNpmUrl } from '@jayf0x/npm-exists'
40
+ const url = getNpmUrl('react') // https://registry.npmjs.org/react
41
+ ```
61
42
 
62
- ### CLI
43
+ ## CLI
63
44
 
64
45
  ```sh
65
- # Global install
66
- npm install -g npm-exists
67
-
68
- npm-exists react
46
+ npx @jayf0x/npm-exists react
69
47
  # ✓ react@19.1.0 exists on npm
70
48
 
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
49
  npm-exists my-pkg https://my.private.registry.io
78
50
  ```
79
51
 
80
- ### One-off via npx
52
+ Exit codes: `0` exists · `1` not found · `2` bad usage
81
53
 
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 |
54
+ ## API
94
55
 
95
- **Returns:** `Promise<object \| false>`
96
- - `object` — full registry metadata (includes `name`, `dist-tags`, `versions`, `description`, …)
97
- - `false` — package does not exist
56
+ ### `npmExists(pkg, registryOrOptions?, options?)`
98
57
 
99
- **Throws** if the registry returns an unexpected non-404 error (network issue, auth failure, etc.).
58
+ | Param | Type | Description |
59
+ |---|---|---|
60
+ | `pkg` | `string` | Package name |
61
+ | `registryOrOptions` | `string \| { registry?, silent? }` | Registry URL or options object |
62
+ | `options` | `{ silent? }` | When `silent: true`, errors return `false` instead of throwing |
100
63
 
101
- ---
64
+ Returns `Promise<string \| false>` — the npm page URL or `false` if not found.
102
65
 
103
66
  ### `getNpmUrl(pkg, registry?)`
104
67
 
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`).
68
+ Returns the registry API URL. Useful with custom HTTP clients like axios or ky.
118
69
 
119
70
  ## License
120
71
 
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.3",
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",