@mcptoolshop/registry-stats 0.4.0 → 1.0.0
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.es.md +110 -60
- package/README.fr.md +151 -63
- package/README.hi.md +113 -63
- package/README.it.md +111 -61
- package/README.ja.md +109 -59
- package/README.md +37 -3
- package/README.pt-BR.md +107 -57
- package/README.zh.md +109 -59
- package/assets/logo.png +0 -0
- package/package.json +1 -1
package/README.es.md
CHANGED
|
@@ -3,30 +3,35 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<img src="
|
|
6
|
+
<img src="https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/registry-stats/readme.png" alt="registry-stats logo" width="400" />
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
-
<
|
|
9
|
+
<p align="center">
|
|
10
|
+
One command. Five registries. All your download stats.
|
|
11
|
+
</p>
|
|
10
12
|
|
|
11
13
|
<p align="center">
|
|
12
|
-
|
|
14
|
+
<a href="https://github.com/mcp-tool-shop-org/registry-stats/actions/workflows/pages.yml"><img src="https://github.com/mcp-tool-shop-org/registry-stats/actions/workflows/pages.yml/badge.svg" alt="CI"></a>
|
|
15
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License"></a>
|
|
16
|
+
<a href="https://www.npmjs.com/package/@mcptoolshop/registry-stats"><img src="https://img.shields.io/npm/v/@mcptoolshop/registry-stats" alt="npm version"></a>
|
|
17
|
+
<a href="https://mcp-tool-shop-org.github.io/registry-stats/"><img src="https://img.shields.io/badge/Landing_Page-live-blue" alt="Landing Page"></a>
|
|
13
18
|
</p>
|
|
14
19
|
|
|
15
20
|
<p align="center">
|
|
16
21
|
<a href="https://mcp-tool-shop-org.github.io/registry-stats/">Docs</a> ·
|
|
17
|
-
<a href="#
|
|
22
|
+
<a href="#install">Install</a> ·
|
|
18
23
|
<a href="#cli">CLI</a> ·
|
|
19
|
-
<a href="#
|
|
20
|
-
<a href="#api
|
|
21
|
-
<a href="#
|
|
22
|
-
<a href="#
|
|
24
|
+
<a href="#config-file">Config</a> ·
|
|
25
|
+
<a href="#programmatic-api">API</a> ·
|
|
26
|
+
<a href="#rest-api-server">REST Server</a> ·
|
|
27
|
+
<a href="#license">License</a>
|
|
23
28
|
</p>
|
|
24
29
|
|
|
25
30
|
---
|
|
26
31
|
|
|
27
|
-
Si publicas en npm, PyPI, NuGet, VS Code
|
|
32
|
+
Si publicas en npm, PyPI, NuGet, el Marketplace de VS Code o Docker Hub, actualmente necesitas cinco API diferentes para responder a la pregunta "¿cuántas descargas he tenido este mes?". Esta biblioteca te proporciona una única interfaz para todas ellas, ya sea como una herramienta de línea de comandos (CLI) o como una API programática.
|
|
28
33
|
|
|
29
|
-
Sin dependencias.
|
|
34
|
+
Sin dependencias. Utiliza la función nativa `fetch()`. Node 18+.
|
|
30
35
|
|
|
31
36
|
## Instalación
|
|
32
37
|
|
|
@@ -37,44 +42,58 @@ npm install @mcptoolshop/registry-stats
|
|
|
37
42
|
## CLI
|
|
38
43
|
|
|
39
44
|
```bash
|
|
40
|
-
#
|
|
45
|
+
# Query a single registry
|
|
41
46
|
registry-stats express -r npm
|
|
47
|
+
# npm | express
|
|
48
|
+
# month: 283,472,710 week: 67,367,773 day: 11,566,113
|
|
42
49
|
|
|
43
|
-
#
|
|
50
|
+
# Query all registries at once
|
|
44
51
|
registry-stats express
|
|
45
52
|
|
|
46
|
-
#
|
|
53
|
+
# Time series with monthly breakdown + trend
|
|
47
54
|
registry-stats express -r npm --range 2025-01-01:2025-06-30
|
|
55
|
+
# 2025-01 142,359,021
|
|
56
|
+
# 2025-02 147,522,528
|
|
57
|
+
# ...
|
|
58
|
+
# Total: 448,383,383 Avg/day: 4,982,038 Trend: flat (-0.46%)
|
|
48
59
|
|
|
49
|
-
#
|
|
60
|
+
# Raw JSON output
|
|
50
61
|
registry-stats express -r npm --json
|
|
51
62
|
|
|
52
|
-
#
|
|
63
|
+
# Other registries
|
|
53
64
|
registry-stats requests -r pypi
|
|
54
65
|
registry-stats Newtonsoft.Json -r nuget
|
|
55
66
|
registry-stats esbenp.prettier-vscode -r vscode
|
|
56
67
|
registry-stats library/node -r docker
|
|
57
68
|
|
|
58
|
-
#
|
|
69
|
+
# Create a config file
|
|
59
70
|
registry-stats --init
|
|
60
71
|
|
|
61
|
-
#
|
|
72
|
+
# Run with config — fetches all tracked packages
|
|
62
73
|
registry-stats
|
|
63
74
|
|
|
64
|
-
#
|
|
75
|
+
# Compare across registries
|
|
65
76
|
registry-stats express --compare
|
|
66
|
-
|
|
67
|
-
#
|
|
77
|
+
# express — comparison
|
|
78
|
+
#
|
|
79
|
+
# Metric npm pypi
|
|
80
|
+
# ─────────────────────────────────
|
|
81
|
+
# Total - -
|
|
82
|
+
# Month 283,472 47,201
|
|
83
|
+
# Week 67,367 11,800
|
|
84
|
+
# Day 11,566 1,686
|
|
85
|
+
|
|
86
|
+
# Export as CSV or chart-friendly JSON
|
|
68
87
|
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format csv
|
|
69
88
|
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format chart
|
|
70
89
|
|
|
71
|
-
#
|
|
90
|
+
# Start a REST API server
|
|
72
91
|
registry-stats serve --port 3000
|
|
73
92
|
```
|
|
74
93
|
|
|
75
|
-
## Archivo de
|
|
94
|
+
## Archivo de configuración
|
|
76
95
|
|
|
77
|
-
Crea un `registry-stats.config.json` en la raíz de tu proyecto (o ejecuta `registry-stats --init`):
|
|
96
|
+
Crea un archivo `registry-stats.config.json` en la raíz de tu proyecto (o ejecuta `registry-stats --init`):
|
|
78
97
|
|
|
79
98
|
```json
|
|
80
99
|
{
|
|
@@ -95,91 +114,110 @@ Crea un `registry-stats.config.json` en la raíz de tu proyecto (o ejecuta `regi
|
|
|
95
114
|
}
|
|
96
115
|
```
|
|
97
116
|
|
|
98
|
-
Ejecuta `registry-stats` sin argumentos para obtener estadísticas de todos los paquetes configurados.
|
|
117
|
+
Ejecuta `registry-stats` sin argumentos para obtener las estadísticas de todos los paquetes configurados. La CLI busca el archivo de configuración desde el directorio actual.
|
|
118
|
+
|
|
119
|
+
La configuración también está disponible de forma programática:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { loadConfig, defaultConfig, starterConfig } from '@mcptoolshop/registry-stats';
|
|
123
|
+
|
|
124
|
+
const config = loadConfig(); // finds nearest config file, or null
|
|
125
|
+
const defaults = defaultConfig(); // returns default Config object
|
|
126
|
+
const template = starterConfig(); // returns starter JSON string
|
|
127
|
+
```
|
|
99
128
|
|
|
100
|
-
## API
|
|
129
|
+
## API programática
|
|
101
130
|
|
|
102
131
|
```typescript
|
|
103
132
|
import { stats, calc, createCache } from '@mcptoolshop/registry-stats';
|
|
104
133
|
|
|
105
|
-
//
|
|
134
|
+
// Single registry
|
|
106
135
|
const npm = await stats('npm', 'express');
|
|
107
136
|
const pypi = await stats('pypi', 'requests');
|
|
137
|
+
const nuget = await stats('nuget', 'Newtonsoft.Json');
|
|
138
|
+
const vscode = await stats('vscode', 'esbenp.prettier-vscode');
|
|
139
|
+
const docker = await stats('docker', 'library/node');
|
|
108
140
|
|
|
109
|
-
//
|
|
141
|
+
// All registries at once (uses Promise.allSettled — never throws)
|
|
110
142
|
const all = await stats.all('express');
|
|
111
143
|
|
|
112
|
-
//
|
|
144
|
+
// Bulk — multiple packages, concurrency-limited (default: 5)
|
|
113
145
|
const bulk = await stats.bulk('npm', ['express', 'koa', 'fastify']);
|
|
114
146
|
|
|
115
|
-
//
|
|
147
|
+
// Time series (npm + pypi only)
|
|
116
148
|
const daily = await stats.range('npm', 'express', '2025-01-01', '2025-06-30');
|
|
117
149
|
|
|
118
|
-
//
|
|
119
|
-
calc.total(daily); //
|
|
120
|
-
calc.avg(daily); //
|
|
150
|
+
// Calculations
|
|
151
|
+
calc.total(daily); // sum of all downloads
|
|
152
|
+
calc.avg(daily); // daily average
|
|
153
|
+
calc.groupTotals(calc.monthly(daily)); // { '2025-01': 134982, ... }
|
|
121
154
|
calc.trend(daily); // { direction: 'up', changePercent: 8.3 }
|
|
122
|
-
calc.movingAvg(daily, 7); //
|
|
123
|
-
calc.popularity(daily); //
|
|
155
|
+
calc.movingAvg(daily, 7); // 7-day moving average
|
|
156
|
+
calc.popularity(daily); // 0-100 log-scale score
|
|
124
157
|
|
|
125
|
-
//
|
|
126
|
-
calc.toCSV(daily); //
|
|
127
|
-
calc.toChartData(daily, 'express'); // { labels: [...], datasets: [
|
|
158
|
+
// Export formats
|
|
159
|
+
calc.toCSV(daily); // "date,downloads\n2025-01-01,1234\n..."
|
|
160
|
+
calc.toChartData(daily, 'express'); // { labels: [...], datasets: [{ label, data }] }
|
|
128
161
|
|
|
129
|
-
//
|
|
162
|
+
// Comparison — same package across registries
|
|
130
163
|
const comparison = await stats.compare('express');
|
|
131
|
-
|
|
164
|
+
// → { package: 'express', registries: { npm: {...}, pypi: {...} }, fetchedAt: '...' }
|
|
165
|
+
await stats.compare('express', ['npm', 'pypi']); // specific registries only
|
|
132
166
|
|
|
133
|
-
//
|
|
167
|
+
// Caching (5 min TTL, in-memory)
|
|
134
168
|
const cache = createCache();
|
|
135
|
-
await stats('npm', 'express', { cache });
|
|
169
|
+
await stats('npm', 'express', { cache }); // fetches
|
|
170
|
+
await stats('npm', 'express', { cache }); // cache hit
|
|
136
171
|
```
|
|
137
172
|
|
|
138
|
-
## Soporte
|
|
173
|
+
## Soporte para registros
|
|
139
174
|
|
|
140
|
-
| Registro | Formato
|
|
141
|
-
|
|
142
|
-
| `npm` | `express`, `@scope/pkg` | Sí (549 días) |
|
|
143
|
-
| `pypi` | `requests` | Sí (180 días) |
|
|
175
|
+
| Registro | Formato del paquete | Series de tiempo | Datos disponibles |
|
|
176
|
+
| ---------- | --------------- | ------------- | ---------------- |
|
|
177
|
+
| `npm` | `express`, `@scope/pkg` | Sí (549 días) | último día, última semana, último mes |
|
|
178
|
+
| `pypi` | `requests` | Sí (180 días) | último día, última semana, último mes, total |
|
|
144
179
|
| `nuget` | `Newtonsoft.Json` | No | total |
|
|
145
|
-
| `vscode` | `publisher.extension` | No | total (instalaciones),
|
|
146
|
-
| `docker` | `namespace/repo` | No | total (
|
|
180
|
+
| `vscode` | `publisher.extension` | No | total (instalaciones), calificación, tendencias |
|
|
181
|
+
| `docker` | `namespace/repo` | No | total (descargas), estrellas |
|
|
147
182
|
|
|
148
|
-
## Fiabilidad
|
|
183
|
+
## Fiabilidad integrada
|
|
149
184
|
|
|
150
|
-
-
|
|
151
|
-
- Respeta
|
|
152
|
-
- Limitación de concurrencia para solicitudes masivas
|
|
153
|
-
- Caché TTL opcional (
|
|
185
|
+
- Reintentos automáticos con retroceso exponencial en caso de errores 429/5xx.
|
|
186
|
+
- Respeta los encabezados `Retry-After`.
|
|
187
|
+
- Limitación de concurrencia para solicitudes masivas.
|
|
188
|
+
- Caché TTL opcional (plug-in: proporciona tu propio backend de Redis/archivo a través de la interfaz `StatsCache`).
|
|
154
189
|
|
|
155
|
-
## Servidor
|
|
190
|
+
## Servidor de API REST
|
|
156
191
|
|
|
157
|
-
|
|
192
|
+
Ejecútalo como un microservicio o intégralo en tu propio servidor:
|
|
158
193
|
|
|
159
194
|
```bash
|
|
195
|
+
# CLI
|
|
160
196
|
registry-stats serve --port 3000
|
|
161
197
|
```
|
|
162
198
|
|
|
163
199
|
```
|
|
164
|
-
GET /stats/:package #
|
|
165
|
-
GET /stats/:registry/:package #
|
|
200
|
+
GET /stats/:package # all registries
|
|
201
|
+
GET /stats/:registry/:package # single registry
|
|
166
202
|
GET /compare/:package?registries=npm,pypi
|
|
167
203
|
GET /range/:registry/:package?start=YYYY-MM-DD&end=YYYY-MM-DD&format=json|csv|chart
|
|
168
204
|
```
|
|
169
205
|
|
|
206
|
+
Uso programático para servidores personalizados o sin servidor:
|
|
207
|
+
|
|
170
208
|
```typescript
|
|
171
209
|
import { createHandler, serve } from '@mcptoolshop/registry-stats';
|
|
172
210
|
|
|
173
|
-
//
|
|
211
|
+
// Option 1: Quick start
|
|
174
212
|
serve({ port: 3000 });
|
|
175
213
|
|
|
176
|
-
//
|
|
214
|
+
// Option 2: Bring your own server
|
|
177
215
|
import { createServer } from 'node:http';
|
|
178
216
|
const handler = createHandler();
|
|
179
217
|
createServer(handler).listen(3000);
|
|
180
218
|
```
|
|
181
219
|
|
|
182
|
-
## Registros
|
|
220
|
+
## Registros personalizados
|
|
183
221
|
|
|
184
222
|
```typescript
|
|
185
223
|
import { registerProvider, type RegistryProvider } from '@mcptoolshop/registry-stats';
|
|
@@ -202,6 +240,18 @@ registerProvider(cargo);
|
|
|
202
240
|
await stats('cargo', 'serde');
|
|
203
241
|
```
|
|
204
242
|
|
|
243
|
+
## Sitio web
|
|
244
|
+
|
|
245
|
+
La documentación y la página de inicio se encuentran en el directorio `site/`.
|
|
246
|
+
|
|
247
|
+
- Desarrollo: `npm run site:dev`
|
|
248
|
+
- Compilación: `npm run site:build`
|
|
249
|
+
- Previsualización: `npm run site:preview`
|
|
250
|
+
|
|
205
251
|
## Licencia
|
|
206
252
|
|
|
207
253
|
MIT
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
Creado por <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a>
|
package/README.fr.md
CHANGED
|
@@ -3,32 +3,37 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<img src="
|
|
6
|
+
<img src="https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/registry-stats/readme.png" alt="registry-stats logo" width="400" />
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
-
<
|
|
9
|
+
<p align="center">
|
|
10
|
+
One command. Five registries. All your download stats.
|
|
11
|
+
</p>
|
|
10
12
|
|
|
11
13
|
<p align="center">
|
|
12
|
-
|
|
14
|
+
<a href="https://github.com/mcp-tool-shop-org/registry-stats/actions/workflows/pages.yml"><img src="https://github.com/mcp-tool-shop-org/registry-stats/actions/workflows/pages.yml/badge.svg" alt="CI"></a>
|
|
15
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License"></a>
|
|
16
|
+
<a href="https://www.npmjs.com/package/@mcptoolshop/registry-stats"><img src="https://img.shields.io/npm/v/@mcptoolshop/registry-stats" alt="npm version"></a>
|
|
17
|
+
<a href="https://mcp-tool-shop-org.github.io/registry-stats/"><img src="https://img.shields.io/badge/Landing_Page-live-blue" alt="Landing Page"></a>
|
|
13
18
|
</p>
|
|
14
19
|
|
|
15
20
|
<p align="center">
|
|
16
21
|
<a href="https://mcp-tool-shop-org.github.io/registry-stats/">Docs</a> ·
|
|
17
|
-
<a href="#
|
|
22
|
+
<a href="#install">Install</a> ·
|
|
18
23
|
<a href="#cli">CLI</a> ·
|
|
19
|
-
<a href="#
|
|
20
|
-
<a href="#api
|
|
21
|
-
<a href="#
|
|
22
|
-
<a href="#
|
|
24
|
+
<a href="#config-file">Config</a> ·
|
|
25
|
+
<a href="#programmatic-api">API</a> ·
|
|
26
|
+
<a href="#rest-api-server">REST Server</a> ·
|
|
27
|
+
<a href="#license">License</a>
|
|
23
28
|
</p>
|
|
24
29
|
|
|
25
30
|
---
|
|
26
31
|
|
|
27
|
-
Si vous publiez sur npm, PyPI, NuGet, VS Code
|
|
32
|
+
Si vous publiez sur npm, PyPI, NuGet, le marché de VS Code ou Docker Hub, vous avez actuellement besoin de cinq API différentes pour répondre à la question : "Combien de téléchargements ai-je eu ce mois-ci ?" Cette bibliothèque vous offre une interface unique pour tous ces services, sous forme d'interface en ligne de commande ou d'API programmatique.
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
Aucune dépendance. Utilise la fonction native `fetch()`. Compatible avec Node 18 et versions ultérieures.
|
|
30
35
|
|
|
31
|
-
##
|
|
36
|
+
## Installer
|
|
32
37
|
|
|
33
38
|
```bash
|
|
34
39
|
npm install @mcptoolshop/registry-stats
|
|
@@ -37,44 +42,58 @@ npm install @mcptoolshop/registry-stats
|
|
|
37
42
|
## CLI
|
|
38
43
|
|
|
39
44
|
```bash
|
|
40
|
-
#
|
|
45
|
+
# Query a single registry
|
|
41
46
|
registry-stats express -r npm
|
|
47
|
+
# npm | express
|
|
48
|
+
# month: 283,472,710 week: 67,367,773 day: 11,566,113
|
|
42
49
|
|
|
43
|
-
#
|
|
50
|
+
# Query all registries at once
|
|
44
51
|
registry-stats express
|
|
45
52
|
|
|
46
|
-
#
|
|
53
|
+
# Time series with monthly breakdown + trend
|
|
47
54
|
registry-stats express -r npm --range 2025-01-01:2025-06-30
|
|
55
|
+
# 2025-01 142,359,021
|
|
56
|
+
# 2025-02 147,522,528
|
|
57
|
+
# ...
|
|
58
|
+
# Total: 448,383,383 Avg/day: 4,982,038 Trend: flat (-0.46%)
|
|
48
59
|
|
|
49
|
-
#
|
|
60
|
+
# Raw JSON output
|
|
50
61
|
registry-stats express -r npm --json
|
|
51
62
|
|
|
52
|
-
#
|
|
63
|
+
# Other registries
|
|
53
64
|
registry-stats requests -r pypi
|
|
54
65
|
registry-stats Newtonsoft.Json -r nuget
|
|
55
66
|
registry-stats esbenp.prettier-vscode -r vscode
|
|
56
67
|
registry-stats library/node -r docker
|
|
57
68
|
|
|
58
|
-
#
|
|
69
|
+
# Create a config file
|
|
59
70
|
registry-stats --init
|
|
60
71
|
|
|
61
|
-
#
|
|
72
|
+
# Run with config — fetches all tracked packages
|
|
62
73
|
registry-stats
|
|
63
74
|
|
|
64
|
-
#
|
|
75
|
+
# Compare across registries
|
|
65
76
|
registry-stats express --compare
|
|
66
|
-
|
|
67
|
-
#
|
|
77
|
+
# express — comparison
|
|
78
|
+
#
|
|
79
|
+
# Metric npm pypi
|
|
80
|
+
# ─────────────────────────────────
|
|
81
|
+
# Total - -
|
|
82
|
+
# Month 283,472 47,201
|
|
83
|
+
# Week 67,367 11,800
|
|
84
|
+
# Day 11,566 1,686
|
|
85
|
+
|
|
86
|
+
# Export as CSV or chart-friendly JSON
|
|
68
87
|
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format csv
|
|
69
88
|
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format chart
|
|
70
89
|
|
|
71
|
-
#
|
|
90
|
+
# Start a REST API server
|
|
72
91
|
registry-stats serve --port 3000
|
|
73
92
|
```
|
|
74
93
|
|
|
75
|
-
## Fichier de
|
|
94
|
+
## Fichier de configuration
|
|
76
95
|
|
|
77
|
-
Créez un `registry-stats.config.json` à la racine de votre projet (ou exécutez `registry-stats --init`) :
|
|
96
|
+
Créez un fichier `registry-stats.config.json` à la racine de votre projet (ou exécutez la commande `registry-stats --init`) :
|
|
78
97
|
|
|
79
98
|
```json
|
|
80
99
|
{
|
|
@@ -95,91 +114,148 @@ Créez un `registry-stats.config.json` à la racine de votre projet (ou exécute
|
|
|
95
114
|
}
|
|
96
115
|
```
|
|
97
116
|
|
|
98
|
-
Exécutez `registry-stats` sans arguments pour obtenir les statistiques de tous les paquets configurés.
|
|
117
|
+
Exécutez la commande `registry-stats` sans arguments pour obtenir les statistiques de tous les paquets configurés. L'interface en ligne de commande (CLI) remonte à partir du répertoire de travail actuel (cwd) pour trouver le fichier de configuration le plus proche.
|
|
118
|
+
|
|
119
|
+
La configuration est également accessible par programmation :
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { loadConfig, defaultConfig, starterConfig } from '@mcptoolshop/registry-stats';
|
|
123
|
+
|
|
124
|
+
const config = loadConfig(); // finds nearest config file, or null
|
|
125
|
+
const defaults = defaultConfig(); // returns default Config object
|
|
126
|
+
const template = starterConfig(); // returns starter JSON string
|
|
127
|
+
```
|
|
99
128
|
|
|
100
|
-
## API
|
|
129
|
+
## API programmable
|
|
101
130
|
|
|
102
131
|
```typescript
|
|
103
132
|
import { stats, calc, createCache } from '@mcptoolshop/registry-stats';
|
|
104
133
|
|
|
105
|
-
//
|
|
134
|
+
// Single registry
|
|
106
135
|
const npm = await stats('npm', 'express');
|
|
107
136
|
const pypi = await stats('pypi', 'requests');
|
|
137
|
+
const nuget = await stats('nuget', 'Newtonsoft.Json');
|
|
138
|
+
const vscode = await stats('vscode', 'esbenp.prettier-vscode');
|
|
139
|
+
const docker = await stats('docker', 'library/node');
|
|
108
140
|
|
|
109
|
-
//
|
|
141
|
+
// All registries at once (uses Promise.allSettled — never throws)
|
|
110
142
|
const all = await stats.all('express');
|
|
111
143
|
|
|
112
|
-
//
|
|
144
|
+
// Bulk — multiple packages, concurrency-limited (default: 5)
|
|
113
145
|
const bulk = await stats.bulk('npm', ['express', 'koa', 'fastify']);
|
|
114
146
|
|
|
115
|
-
//
|
|
147
|
+
// Time series (npm + pypi only)
|
|
116
148
|
const daily = await stats.range('npm', 'express', '2025-01-01', '2025-06-30');
|
|
117
149
|
|
|
118
|
-
//
|
|
119
|
-
calc.total(daily); //
|
|
120
|
-
calc.avg(daily); //
|
|
150
|
+
// Calculations
|
|
151
|
+
calc.total(daily); // sum of all downloads
|
|
152
|
+
calc.avg(daily); // daily average
|
|
153
|
+
calc.groupTotals(calc.monthly(daily)); // { '2025-01': 134982, ... }
|
|
121
154
|
calc.trend(daily); // { direction: 'up', changePercent: 8.3 }
|
|
122
|
-
calc.movingAvg(daily, 7); //
|
|
123
|
-
calc.popularity(daily); //
|
|
155
|
+
calc.movingAvg(daily, 7); // 7-day moving average
|
|
156
|
+
calc.popularity(daily); // 0-100 log-scale score
|
|
124
157
|
|
|
125
|
-
//
|
|
126
|
-
calc.toCSV(daily); //
|
|
127
|
-
calc.toChartData(daily, 'express'); // { labels: [...], datasets: [
|
|
158
|
+
// Export formats
|
|
159
|
+
calc.toCSV(daily); // "date,downloads\n2025-01-01,1234\n..."
|
|
160
|
+
calc.toChartData(daily, 'express'); // { labels: [...], datasets: [{ label, data }] }
|
|
128
161
|
|
|
129
|
-
//
|
|
162
|
+
// Comparison — same package across registries
|
|
130
163
|
const comparison = await stats.compare('express');
|
|
131
|
-
|
|
164
|
+
// → { package: 'express', registries: { npm: {...}, pypi: {...} }, fetchedAt: '...' }
|
|
165
|
+
await stats.compare('express', ['npm', 'pypi']); // specific registries only
|
|
132
166
|
|
|
133
|
-
//
|
|
167
|
+
// Caching (5 min TTL, in-memory)
|
|
134
168
|
const cache = createCache();
|
|
135
|
-
await stats('npm', 'express', { cache });
|
|
169
|
+
await stats('npm', 'express', { cache }); // fetches
|
|
170
|
+
await stats('npm', 'express', { cache }); // cache hit
|
|
136
171
|
```
|
|
137
172
|
|
|
138
|
-
## Support
|
|
173
|
+
## Support technique pour les registres
|
|
174
|
+
|
|
175
|
+
| Registre. | Format du paquet. | Séries temporelles. | Données disponibles. |
|
|
176
|
+
| Bien sûr, veuillez me fournir le texte que vous souhaitez que je traduise. | "The quick brown fox jumps over the lazy dog."
|
|
177
|
+
"This is a sample text."
|
|
178
|
+
"Please provide more context."
|
|
179
|
+
"Thank you for your cooperation."
|
|
180
|
+
"We look forward to hearing from you soon."
|
|
181
|
+
"The meeting will be held on Tuesday."
|
|
182
|
+
"The deadline is Friday."
|
|
183
|
+
"Please contact us if you have any questions."
|
|
184
|
+
"We are committed to providing excellent service."
|
|
185
|
+
"Your satisfaction is our priority."
|
|
186
|
+
---------------
|
|
187
|
+
"Le rapide renard brun saute par-dessus le chien paresseux."
|
|
188
|
+
"Ceci est un exemple de texte."
|
|
189
|
+
"Veuillez fournir plus de contexte."
|
|
190
|
+
"Nous vous remercions de votre coopération."
|
|
191
|
+
"Nous espérons avoir de vos nouvelles prochainement."
|
|
192
|
+
"La réunion se tiendra le mardi."
|
|
193
|
+
"La date limite est le vendredi."
|
|
194
|
+
"N'hésitez pas à nous contacter si vous avez des questions."
|
|
195
|
+
"Nous nous engageons à fournir un excellent service."
|
|
196
|
+
"Votre satisfaction est notre priorité." | "Please provide the text you would like me to translate." | "The company is committed to providing high-quality products and services."
|
|
197
|
+
|
|
198
|
+
"We are looking for a motivated and experienced candidate."
|
|
199
|
+
|
|
200
|
+
"The meeting will take place on Tuesday at 2:00 PM."
|
|
201
|
+
|
|
202
|
+
"Please submit your application by the end of the week."
|
|
139
203
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
| `pypi` | `requests` | Oui (180 jours) | lastDay, lastWeek, lastMonth, total |
|
|
144
|
-
| `nuget` | `Newtonsoft.Json` | Non | total |
|
|
145
|
-
| `vscode` | `publisher.extension` | Non | total (installations), rating, trends |
|
|
146
|
-
| `docker` | `namespace/repo` | Non | total (pulls), stars |
|
|
204
|
+
"For more information, please contact us."
|
|
205
|
+
----------------
|
|
206
|
+
"L'entreprise s'engage à fournir des produits et services de haute qualité."
|
|
147
207
|
|
|
148
|
-
|
|
208
|
+
"Nous recherchons un candidat motivé et expérimenté."
|
|
149
209
|
|
|
150
|
-
|
|
151
|
-
- Respecte les en-têtes `Retry-After`
|
|
152
|
-
- Limitation de concurrence pour les requêtes en masse
|
|
153
|
-
- Cache TTL optionnel (extensible — utilisez Redis/fichier via l'interface `StatsCache`)
|
|
210
|
+
"La réunion aura lieu mardi à 14h00."
|
|
154
211
|
|
|
155
|
-
|
|
212
|
+
"Veuillez soumettre votre candidature avant la fin de la semaine."
|
|
156
213
|
|
|
157
|
-
|
|
214
|
+
"Pour plus d'informations, veuillez nous contacter." |
|
|
215
|
+
| `npm` | `express`, `@scope/pkg` | Oui (549 jours). | dernier jour, dernière semaine, dernier mois. |
|
|
216
|
+
| `pypi` | `requests` | Oui (180 jours). | dernier jour, dernière semaine, dernier mois, total. |
|
|
217
|
+
| `nuget` | `Newtonsoft.Json` | No | total |
|
|
218
|
+
| `vscode` | `publisher.extension` | No | total (installations), évaluation, tendances. |
|
|
219
|
+
| `docker` | `namespace/repo` | No | total (nombre de tirages), étoiles. |
|
|
220
|
+
|
|
221
|
+
## Fiabilité intégrée
|
|
222
|
+
|
|
223
|
+
- Nouvelle tentative automatique avec un délai exponentiel en cas d'erreurs 429/5xx.
|
|
224
|
+
- Respect des en-têtes "Retry-After".
|
|
225
|
+
- Limitation de la concurrence pour les requêtes groupées.
|
|
226
|
+
- Cache TTL optionnel (extensible – possibilité d'utiliser votre propre backend Redis ou fichier via l'interface "StatsCache").
|
|
227
|
+
|
|
228
|
+
## Serveur d'API REST
|
|
229
|
+
|
|
230
|
+
Fonctionnez en tant que microservice ou intégrez-le à votre propre serveur :
|
|
158
231
|
|
|
159
232
|
```bash
|
|
233
|
+
# CLI
|
|
160
234
|
registry-stats serve --port 3000
|
|
161
235
|
```
|
|
162
236
|
|
|
163
237
|
```
|
|
164
|
-
GET /stats/:package #
|
|
165
|
-
GET /stats/:registry/:package #
|
|
238
|
+
GET /stats/:package # all registries
|
|
239
|
+
GET /stats/:registry/:package # single registry
|
|
166
240
|
GET /compare/:package?registries=npm,pypi
|
|
167
241
|
GET /range/:registry/:package?start=YYYY-MM-DD&end=YYYY-MM-DD&format=json|csv|chart
|
|
168
242
|
```
|
|
169
243
|
|
|
244
|
+
Utilisation par programmation pour les serveurs personnalisés ou les environnements sans serveur :
|
|
245
|
+
|
|
170
246
|
```typescript
|
|
171
247
|
import { createHandler, serve } from '@mcptoolshop/registry-stats';
|
|
172
248
|
|
|
173
|
-
//
|
|
249
|
+
// Option 1: Quick start
|
|
174
250
|
serve({ port: 3000 });
|
|
175
251
|
|
|
176
|
-
//
|
|
252
|
+
// Option 2: Bring your own server
|
|
177
253
|
import { createServer } from 'node:http';
|
|
178
254
|
const handler = createHandler();
|
|
179
255
|
createServer(handler).listen(3000);
|
|
180
256
|
```
|
|
181
257
|
|
|
182
|
-
## Registres
|
|
258
|
+
## Registres personnalisés
|
|
183
259
|
|
|
184
260
|
```typescript
|
|
185
261
|
import { registerProvider, type RegistryProvider } from '@mcptoolshop/registry-stats';
|
|
@@ -202,6 +278,18 @@ registerProvider(cargo);
|
|
|
202
278
|
await stats('cargo', 'serde');
|
|
203
279
|
```
|
|
204
280
|
|
|
281
|
+
## Site web
|
|
282
|
+
|
|
283
|
+
Les pages de documentation et la page d'accueil se trouvent dans le répertoire `site/`.
|
|
284
|
+
|
|
285
|
+
- Développement : `npm run site:dev`
|
|
286
|
+
- Construction : `npm run site:build`
|
|
287
|
+
- Aperçu : `npm run site:preview`
|
|
288
|
+
|
|
205
289
|
## Licence
|
|
206
290
|
|
|
207
|
-
MIT
|
|
291
|
+
MIT.
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
Construit par <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a>.
|