Skip to content

Commit

Permalink
add types
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Jan 27, 2024
1 parent 64c570d commit 61aeadc
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 18 deletions.
10 changes: 10 additions & 0 deletions deprecations.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type NonZeroDigit = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
type Digit = '0' | NonZeroDigit;
type Digits = `${NonZeroDigit}${Digit | string}`;

type Triple = `${Digits}.${Digits}.${Digits}`;
type PreRelease = `-${string}`;

export type Semver = `${Triple}${PreRelease | ''}`;

export type DeprecationsByVersion = { [version: Semver]: string };
37 changes: 26 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,43 @@ const fromEntries = require('object.fromentries');
const entries = require('object.entries');
const pacote = require('pacote');

const isString = (str) => typeof str === 'string';
const isString = /** @type {(str: unknown) => str is string} */ (str) => typeof str === 'string';

const { from } = Array;

/** @typedef {import('./deprecations').DeprecationsByVersion} DeprecationsByVersion */

/** @type {<T extends string = string>(...packageNames: T[]) => Promise<Record<T, DeprecationsByVersion>>} */
module.exports = function deprecations(packageName, ...morePackageNames) {
if (arguments.length < 1) {
throw new TypeError('at least 1 package name is required');
}

// @ts-expect-error https://github.com/microsoft/TypeScript/issues/57164
if (!every(arguments, isString)) {
throw new TypeError('module names must all be strings');
}

return Promise.all(from(arguments, async (name) => {
const { versions } = await pacote.packument(name, { fullMetadata: true });
return [
name,
fromEntries(entries(versions).map(([version, { deprecated }]) => [
version,
deprecated,
])),
];
})).then(fromEntries);
const depEntries = Promise.all(from(
arguments,
/** @type {(name: string) => Promise<[name, DeprecationsByVersion]>} */ async (name) => {
const { versions } = await pacote.packument(name, { fullMetadata: true });
// eslint-disable-next-line no-extra-parens
const obj = /** @type {DeprecationsByVersion} */ (
fromEntries(entries(versions).map(([
version,
{ deprecated },
]) => [
version,
deprecated,
]))
);
return [
name,
obj,
];
},
));
return depEntries.then(fromEntries);
};

8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,19 @@
},
"devDependencies": {
"@ljharb/eslint-config": "^21.1.0",
"@types/array.prototype.every": "^1.1.0",
"@types/object.entries": "^1.1.0",
"@types/object.fromentries": "^2.0.4",
"@types/pacote": "^11.1.8",
"@types/tape": "^5.6.4",
"aud": "^2.0.4",
"eslint": "=8.8.0",
"in-publish": "^2.0.1",
"npmignore": "^0.3.1",
"nyc": "^15.1.0",
"safe-publish-latest": "^2.0.0",
"tape": "^5.7.4"
"tape": "^5.7.4",
"typescript": "^5.4.0-dev.20240127"
},
"engines": {
"node": "^18.17.0 || >=20.5.0"
Expand Down
12 changes: 6 additions & 6 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

const deprecations = require('../');
const test = require('tape');
const fromEntries = require('object.fromentries');

/** @type {<T extends object>(obj: T) => Partial<T>} */
const compact = function (obj) {
return Object.keys(obj).reduce((map, key) => {
if (obj[key]) {
map[key] = obj[key]; // eslint-disable-line no-param-reassign
}
return map;
}, {});
return fromEntries(Object.entries(obj).filter(([, value]) => value));
};

test('errors', (t) => {
t.throws(deprecations, new TypeError('at least 1 package name is required'));
// @ts-expect-error
t.throws(() => { deprecations(3); }, new TypeError('module names must all be strings'));
// @ts-expect-error
t.throws(() => { deprecations('foo', 3); }, new TypeError('module names must all be strings'));
// @ts-expect-error
t.throws(() => { deprecations(3, 'foo'); }, new TypeError('module names must all be strings'));
t.end();
});
Expand Down
49 changes: 49 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */

/* Projects */

/* Language and Environment */
"target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
"useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */

/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": ["types"], /* Specify multiple folders that act like `./node_modules/@types`. */
"resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */

/* JavaScript Support */
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
"checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
"maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */

/* Emit */
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
"declarationMap": true, /* Create sourcemaps for d.ts files. */
"noEmit": true, /* Disable emitting files from a compilation. */

/* Interop Constraints */
"allowSyntheticDefaultImports": true, /* Allow `import x from y` when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */

/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */

/* Completeness */
// "skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"exclude": [
"coverage",
],
}

0 comments on commit 61aeadc

Please sign in to comment.