Skip to content

Refactor TypeScript codebase for improved maintainability #307

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 100 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,75 @@
[![npm version](https://badge.fury.io/js/npm-stats-api.svg)](https://badge.fury.io/js/npm-stats-api)
[![Code Climate](https://codeclimate.com/github/kkeeth/npm-stats-api/badges/gpa.svg)](https://codeclimate.com/github/kkeeth/npm-stats-api)
![node](https://img.shields.io/badge/node-%3E%3D%2020.18.3-brightgreen.svg?style=social)
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)

# npm-stats-api

Node Package's Statistics API

Our functions will provide statistics of node package.

This is a Node.js API wrapper for the NPM API and Registry.

`npm-stats-api` is based on the original `npm-stat-api`. `npm-stats-api` includes all the additional features from `npm-stat-api`.

# Installation
Node Package's Statistics API | Our functions will provide statistics of node package | This is a Node.js API wrapper for the NPM API and Registry. Based on the original npm-stat-api.

Install via NPM
## Description

```js
This library provides a simple way to fetch npm package download statistics and package details from the npm registry.

$ npm install npm-stats-api --save
## Installation

```bash
npm install npm-stats-api
# or
yarn add npm-stats-api
# or
pnpm add npm-stats-api
```

# Usage
## Usage

### CommonJS

i. Get package's stats
```javascript
const { stat, details } = require("npm-stats-api");

```js
const npm = require("npm-stats-api");
// Get package download statistics
stat("npm-stats-api", "2022-01-01", "2022-02-15")
.then(res => {
console.log(res);
})
.catch(err => {
console.error(err);
});

// Parameters:
// 1. Package Name
// 2. Start Date
// 3. End Date
npm.stat("npm-stats-api", "2022-01-01", "2022-02-15")
// Get package details
details("npm-stats-api")
.then(res => {
console.log(res);
})
.catch(err => {
console.error(err);
});
```

### ESM

```javascript
import { stat, details } from "npm-stats-api";

// Using async/await
async function getStats() {
try {
// Get package download statistics
const statsResult = await stat("npm-stats-api", "2022-01-01", "2022-02-15");
console.log(statsResult);

// Get package details
const detailsResult = await details("npm-stats-api");
console.log(detailsResult);
} catch (error) {
console.error(error);
}
}

getStats();
```

// if you use async/await
import npm from "npm-stats-api";
(async () => {
const res = await npm.stat("npm-stats-api", "2022-01-01", "2022-02-15");
console.log(res);
})();
## Response Formats

### `stat` function response

// response format
```javascript
{
statusCode: 200,
body: {
Expand All @@ -59,57 +81,63 @@ import npm from "npm-stats-api";
}
```

ii. Get package's details
### `details` function response

```js
const npm = require("npm-stats-api");

// Parameters:
// Package name
npm.details("npm-stats-api").then(res => {
console.log(res);
});
```javascript
{
statusCode: 200,
body: {
_id: 'npm-stats-api',
name: 'npm-stats-api',
description: '...',
version: '2.1.2',
// Other package details...
}
}
```

iii. Error handling
## Error Handling

```js
npm
.stat("npm-stats-api", "2022-01-01", "2022-02-15")
.then(res => console.log(res))
.catch(err => {
console.log(err);
});
All functions throw a `NpmException` with the following structure:

// use es module
const res = await npm.stat("npm-stats-api", "2022-01-01", "2022-02-15");
if (res.statusCode === 400) {
// some kind of processing
```javascript
{
name: 'NpmException',
message: 'Error message',
statusCode: 400, // HTTP status code
body: {
// Error details
}
}
```

If you want to try it easily at hand, please clone this repository and run the `app.js` file on `nodejs`.

```bash
$ node app.js
Example of catching errors:

```javascript
import { stat, NpmException } from 'npm-stats-api';

try {
const result = await stat('non-existent-package', '2022-01-01', '2022-01-31');
console.log(result);
} catch (error) {
if (error instanceof NpmException) {
console.log(`Status code: ${error.statusCode}`);
console.log(`Error message: ${error.message}`);
console.log(`Error body:`, error.body);
} else {
console.error('Unexpected error:', error);
}
}
```

# ⚠ Limits ⚠

Bulk queries are limited to at most 128 packages at a time and at most 365 days of data.

All other queries are limited to at most 18 months of data. The earliest date for which data will be returned is January 10, 2015.

source (e.g. quotation): https://github.com/npm/registry/blob/master/docs/download-counts.md#limits
## Limitations

# License
Quote from npm registry documentation:

[MIT](https://github.com/kkeeth/npm-stats-api/blob/master/LICENSE)
> Bulk queries are limited to at most 128 packages at a time and at most 365 days of data. All other queries are limited to at most 18 months of data. The earliest date for which data will be returned is January 10, 2015.

# Any issue or want more features? Contact me!
Source: [npm registry documentation](https://github.com/npm/registry/blob/master/docs/download-counts.md#limits)

This module has been tested under limited scenarios. If you find any issue please feel free to report via one of the below platforms:
## License

GitHub: <a href="https://github.com/kkeeth/npm-stats-api/issues">npm-stats-api</a><br>
Email: [email protected]<br>
Twitter: <a href="https://twitter.com/kuwahara_jsri" target="_blank">@kuwahara_jsri</a>
MIT
106 changes: 84 additions & 22 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,86 @@
export type ErrorType = {
message: string;
name: string;
statusCode: number;
body: {
path: string;
error: string;
/**
* Error response structure
*/
export interface ErrorResponse {
message: string;
name: string;
statusCode: number;
body: {
path?: string;
error?: string;
message?: string;
[key: string]: any;
};
}

/**
* Package download statistics response
*/
export interface StatResponse {
statusCode: number;
body: {
downloads: number;
start: string;
end: string;
package: string;
};
}

/**
* Package details response
*/
export interface DetailResponse {
statusCode: number;
body: {
_id?: string;
name?: string;
description?: string;
version?: string;
author?: {
name?: string;
email?: string;
url?: string;
};
};
export type StatType = Promise<{
statusCode: number;
body: {
downloads: number;
start: Date;
end: Date;
package: string;
homepage?: string;
license?: string;
repository?: {
type?: string;
url?: string;
};
}>;
export type DetailType = Promise<{
statusCode: number;
body: object;
}>;
export declare const stat: (pkg: string, start: string, end: string) => StatType;
export declare const details: (pkg: string) => DetailType;
versions?: Record<string, any>;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
[key: string]: any;
};
}

/**
* Custom error class for npm-stats-api errors
*/
export class NpmException extends Error {
statusCode: number;
body: {
path?: string;
error?: string;
message?: string;
[key: string]: any;
};

constructor(error: any);
}

/**
* Get package download statistics
*
* @param packageName - NPM package name
* @param startDate - Start date in YYYY-MM-DD format
* @param endDate - End date in YYYY-MM-DD format
*/
export function stat(packageName: string, startDate: string, endDate: string): Promise<StatResponse>;

/**
* Get package details
*
* @param packageName - NPM package name
*/
export function details(packageName: string): Promise<DetailResponse>;
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
],
"types": "index.d.ts",
"dependencies": {
"babel-polyfill": "^6.26.0",
"superagent": "^10.0.0"
},
"devDependencies": {
Expand Down Expand Up @@ -74,4 +73,4 @@
"volta": {
"node": "22.14.0"
}
}
}
13 changes: 11 additions & 2 deletions rollup.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { RollupOptions } from "rollup";
import babel from "@rollup/plugin-babel";
import typescript from "@rollup/plugin-typescript";
import commonjs from "@rollup/plugin-commonjs";

const config: RollupOptions = {
input: "src/index.ts",
Expand All @@ -12,8 +13,15 @@ const config: RollupOptions = {
},
external: ['superagent'],
plugins: [
typescript(),
typescript({
tsconfig: "./tsconfig.json",
declaration: false, // ここを変更:d.tsファイルはTypeScriptコンパイラで生成する
sourceMap: true,
inlineSources: true
}),
commonjs(),
babel({
babelHelpers: 'bundled',
presets: [
[
"@babel/preset-env",
Expand All @@ -24,7 +32,8 @@ const config: RollupOptions = {
}
}
]
]
],
extensions: ['.js', '.ts']
})
]
};
Expand Down
11 changes: 10 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
export * as npm from "./lib/npm";
import * as npmFunctions from './lib/npm';
import { NpmException } from './lib/npmException';

// Export functions
export const stat = npmFunctions.stat;
export const details = npmFunctions.details;

// Export types and exception
export { NpmException };
export * from '../index.d';
Loading