Skip to content

Commit

Permalink
Require Node.js 12 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Apr 17, 2021
1 parent 8a86ee6 commit 59517d7
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 158 deletions.
3 changes: 0 additions & 3 deletions .github/funding.yml

This file was deleted.

3 changes: 1 addition & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ jobs:
node-version:
- 14
- 12
- 10
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
124 changes: 55 additions & 69 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,74 @@
declare class InvalidNameErrorClass extends Error {}
export class InvalidNameError extends Error {}

declare namespace npmName {
interface Options {
/**
Registry URL to check name availability against.
Default: User's configured npm registry URL.
*/
readonly registryUrl: string;
}
}

declare const npmName: {
export interface Options {
/**
Check whether a package/organization name is available (not registered) on npm.
Registry URL to check name availability against.
An organization name should start with `@` and should not be a scoped package.
@param name - Name to check.
@returns Whether the given name is available.
@example
```
import npmName = require('npm-name');
Default: User's configured npm registry URL.
*/
readonly registryUrl: string;
}

(async () => {
// Check a package name
console.log(await npmName('chalk'));
//=> false
/**
Check whether a package/organization name is available (not registered) on npm.
An organization name should start with `@` and should not be a scoped package.
// Check an organization name
console.log(await npmName('@ava'));
//=> false
@param name - Name to check.
@returns Whether the given name is available.
console.log(await npmName('@abc123'));
//=> true
@example
```
import npmName from 'npm-name';
// Check a package name
console.log(await npmName('chalk'));
//=> false
try {
await npmName('_ABC');
} catch (error) {
console.log(error.message);
// Invalid package name: _ABC
// - name cannot start with an underscore
// - name can no longer contain capital letters
}
})();
```
*/
(name: string, options?: npmName.Options): Promise<boolean>;
// Check an organization name
console.log(await npmName('@ava'));
//=> false
/**
Check whether multiple package/organization names are available (not registered) on npm.
console.log(await npmName('@abc123'));
//=> true
An organization name should start with `@` and should not be a scoped package.
try {
await npmName('_ABC');
} catch (error) {
console.log(error.message);
// Invalid package name: _ABC
// - name cannot start with an underscore
// - name can no longer contain capital letters
}
```
*/
export default function npmName(name: string, options?: Options): Promise<boolean>;

@param names - Multiple names to check.
@returns A `Map` of name and status.
/**
Check whether multiple package/organization names are available (not registered) on npm.
@example
```
import npmName = require('npm-name');
An organization name should start with `@` and should not be a scoped package.
(async () => {
const result = await npmName.many(['chalk', '@sindresorhus/is', 'abc123']);
@param names - Multiple names to check.
@returns A `Map` of name and status.
console.log(result.get('chalk'));
//=> false
@example
```
import {npmNameMany} from 'npm-name';
console.log(result.get('@sindresorhus/is'));
//=> false
const result = await npmNameMany(['chalk', '@sindresorhus/is', 'abc123']);
console.log(result.get('abc123'));
//=> true
})();
```
*/
many<NameType extends string>(
names: NameType[],
options?: npmName.Options
): Promise<Map<NameType, boolean>>;
console.log(result.get('chalk'));
//=> false
InvalidNameError: typeof InvalidNameErrorClass;
};
console.log(result.get('@sindresorhus/is'));
//=> false
export = npmName;
console.log(result.get('abc123'));
//=> true
```
*/
export function npmNameMany<NameType extends string>(
names: readonly NameType[],
options?: Options
): Promise<Map<NameType, boolean>>;
45 changes: 22 additions & 23 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
'use strict';
const isUrl = require('is-url-superb');
const got = require('got');
const isScoped = require('is-scoped');
const configuredRegistryUrl = require('registry-url')();
const registryAuthToken = require('registry-auth-token');
const zip = require('lodash.zip');
const validate = require('validate-npm-package-name');
const organizationRegex = require('org-regex')({exact: true});
const pMap = require('p-map');
const {isTaken} = require('is-name-taken');

class InvalidNameError extends Error {}
import isUrl from 'is-url-superb';
import got from 'got';
import isScoped from 'is-scoped';
import registryUrl from 'registry-url';
import registryAuthToken from 'registry-auth-token';
import zip from 'lodash.zip';
import validate from 'validate-npm-package-name';
import orgRegex from 'org-regex';
import pMap from 'p-map';
import {isTaken} from 'is-name-taken';

const configuredRegistryUrl = registryUrl();
const organizationRegex = orgRegex({exact: true});

// Ensure the URL always ends in a `/`
const normalizeUrl = url => url.replace(/\/$/, '') + '/';

const npmOrganizationUrl = 'https://www.npmjs.com/org/';

Expand Down Expand Up @@ -45,6 +48,7 @@ const request = async (name, options) => {
}

try {
// eslint-disable-next-line unicorn/prefer-ternary
if (isOrganization) {
await got.head(npmOrganizationUrl + urlName.toLowerCase(), {timeout: 10000});
} else {
Expand Down Expand Up @@ -72,10 +76,7 @@ const request = async (name, options) => {
}
};

// Ensure the URL always ends in a `/`
const normalizeUrl = url => url.replace(/\/$/, '') + '/';

const npmName = async (name, options = {}) => {
export default async function npmName(name, options = {}) {
if (!(typeof name === 'string' && name.length > 0)) {
throw new Error('Package name required');
}
Expand All @@ -85,11 +86,9 @@ const npmName = async (name, options = {}) => {
}

return request(name, options);
};
}

module.exports = npmName;

module.exports.many = async (names, options = {}) => {
export async function npmNameMany(names, options = {}) {
if (!Array.isArray(names)) {
throw new TypeError(`Expected an array of names, got ${typeof names}`);
}
Expand All @@ -100,6 +99,6 @@ module.exports.many = async (names, options = {}) => {

const result = await pMap(names, name => request(name, options), {stopOnError: false});
return new Map(zip(names, result));
};
}

module.exports.InvalidNameError = InvalidNameError;
export class InvalidNameError extends Error {}
7 changes: 3 additions & 4 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import {expectType} from 'tsd';
import npmName = require('.');
import {InvalidNameError} from '.';
import npmName, {npmNameMany, InvalidNameError} from './index.js';

expectType<Promise<boolean>>(npmName('chalk'));
expectType<Promise<boolean>>(npmName('got', {
registryUrl: 'https://registry.yarnpkg.com/'
}));

const manyResult = npmName.many(['chalk', '@sindresorhus/is', 'abc123']);
const manyResult = npmNameMany(['chalk', '@sindresorhus/is', 'abc123']);
expectType<Promise<Map<'chalk' | '@sindresorhus/is' | 'abc123', boolean>>>(
manyResult
);
expectType<boolean | undefined>((await manyResult).get('chalk'));

new InvalidNameError('foo') instanceof InvalidNameError;
expectType<InvalidNameError>(new InvalidNameError('foo'));
26 changes: 14 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=10"
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd"
Expand All @@ -32,22 +34,22 @@
"taken"
],
"dependencies": {
"got": "^10.6.0",
"got": "^11.8.2",
"is-name-taken": "^2.0.0",
"is-scoped": "^2.1.0",
"is-url-superb": "^4.0.0",
"is-scoped": "^3.0.0",
"is-url-superb": "^6.0.0",
"lodash.zip": "^4.2.0",
"org-regex": "^1.0.0",
"p-map": "^3.0.0",
"registry-auth-token": "^4.0.0",
"registry-url": "^5.1.0",
"p-map": "^5.0.0",
"registry-auth-token": "^4.2.1",
"registry-url": "^6.0.0",
"validate-npm-package-name": "^3.0.0"
},
"devDependencies": {
"aggregate-error": "^3.0.1",
"ava": "^2.1.0",
"tsd": "^0.11.0",
"unique-string": "^2.0.0",
"xo": "^0.26.1"
"aggregate-error": "^4.0.0",
"ava": "^3.15.0",
"tsd": "^0.14.0",
"unique-string": "^3.0.0",
"xo": "^0.38.2"
}
}
74 changes: 37 additions & 37 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,27 @@ $ npm install npm-name
## Usage

```js
const npmName = require('npm-name');

(async () => {
// Check a package name
console.log(await npmName('chalk'));
//=> false


// Check an organization name
console.log(await npmName('@ava'));
//=> false

console.log(await npmName('@abc123'));
//=> true


const result = await npmName.many(['chalk', '@sindresorhus/is', 'abc123']);

console.log(result.get('chalk'));
//=> false

console.log(result.get('@sindresorhus/is'));
//=> false

console.log(result.get('abc123'));
//=> true

try {
await npmName('_ABC');
} catch (error) {
console.log(error.message);
// Invalid package name: _ABC
// - name cannot start with an underscore
// - name can no longer contain capital letters
}
})();
import npmName from 'npm-name';

// Check a package name
console.log(await npmName('chalk'));
//=> false

// Check an organization name
console.log(await npmName('@ava'));
//=> false

console.log(await npmName('@abc123'));
//=> true

try {
await npmName('_ABC');
} catch (error) {
console.log(error.message);
// Invalid package name: _ABC
// - name cannot start with an underscore
// - name can no longer contain capital letters
}
```

## API
Expand Down Expand Up @@ -77,12 +62,27 @@ Registry URL to check name availability against.

**Note:** You're unlikely to need this option. Most use-cases are best solved by using the default. You should only use this option if you need to check a package name against a specific registry.

### npmName.many(names, options?)
### npmNameMany(names, options?)

Check whether multiple package/organization names are available (not registered) on npm.

Returns a `Promise<Map>` of name and status.

```js
import {npmNameMany} from 'npm-name';

const result = await npmNameMany(['chalk', '@sindresorhus/is', 'abc123']);

console.log(result.get('chalk'));
//=> false

console.log(result.get('@sindresorhus/is'));
//=> false

console.log(result.get('abc123'));
//=> true
```

#### names

Type: `string[]`
Expand Down

0 comments on commit 59517d7

Please sign in to comment.