@mcptoolshop/registry-stats 0.3.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/LICENSE +21 -0
- package/README.es.md +206 -0
- package/README.fr.md +206 -0
- package/README.hi.md +206 -0
- package/README.it.md +206 -0
- package/README.ja.md +206 -0
- package/README.md +239 -0
- package/README.pt-BR.md +206 -0
- package/README.zh.md +206 -0
- package/assets/logo.png +0 -0
- package/dist/cli.js +880 -0
- package/dist/index.cjs +669 -0
- package/dist/index.d.cts +130 -0
- package/dist/index.d.ts +130 -0
- package/dist/index.js +633 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mcp-tool-shop
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.es.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="README.md">English</a> | <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <strong>Español</strong> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português</a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="assets/logo.png" alt="logo de registry-stats" width="280" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<h1 align="center">@mcptoolshop/registry-stats</h1>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
Un comando. Cinco registros. Todas tus estadísticas de descargas.
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="#instalación">Instalación</a> ·
|
|
17
|
+
<a href="#cli">CLI</a> ·
|
|
18
|
+
<a href="#archivo-de-configuración">Configuración</a> ·
|
|
19
|
+
<a href="#api-programática">API</a> ·
|
|
20
|
+
<a href="#servidor-rest-api">Servidor REST</a> ·
|
|
21
|
+
<a href="#licencia">Licencia</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
Si publicas en npm, PyPI, NuGet, VS Code Marketplace o Docker Hub, actualmente necesitas cinco APIs diferentes para responder "¿cuántas descargas tuve este mes?" Esta biblioteca te ofrece una interfaz unificada — como CLI o API programática.
|
|
27
|
+
|
|
28
|
+
Sin dependencias. Usa `fetch()` nativo. Node 18+.
|
|
29
|
+
|
|
30
|
+
## Instalación
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @mcptoolshop/registry-stats
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## CLI
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Consultar un solo registro
|
|
40
|
+
registry-stats express -r npm
|
|
41
|
+
|
|
42
|
+
# Consultar todos los registros a la vez
|
|
43
|
+
registry-stats express
|
|
44
|
+
|
|
45
|
+
# Serie temporal con desglose mensual + tendencia
|
|
46
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30
|
|
47
|
+
|
|
48
|
+
# Salida JSON
|
|
49
|
+
registry-stats express -r npm --json
|
|
50
|
+
|
|
51
|
+
# Otros registros
|
|
52
|
+
registry-stats requests -r pypi
|
|
53
|
+
registry-stats Newtonsoft.Json -r nuget
|
|
54
|
+
registry-stats esbenp.prettier-vscode -r vscode
|
|
55
|
+
registry-stats library/node -r docker
|
|
56
|
+
|
|
57
|
+
# Crear archivo de configuración
|
|
58
|
+
registry-stats --init
|
|
59
|
+
|
|
60
|
+
# Ejecutar con configuración — obtiene todos los paquetes rastreados
|
|
61
|
+
registry-stats
|
|
62
|
+
|
|
63
|
+
# Comparar entre registros
|
|
64
|
+
registry-stats express --compare
|
|
65
|
+
|
|
66
|
+
# Exportar como CSV o JSON para gráficos
|
|
67
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format csv
|
|
68
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format chart
|
|
69
|
+
|
|
70
|
+
# Iniciar servidor REST API
|
|
71
|
+
registry-stats serve --port 3000
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Archivo de Configuración
|
|
75
|
+
|
|
76
|
+
Crea un `registry-stats.config.json` en la raíz de tu proyecto (o ejecuta `registry-stats --init`):
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"registries": ["npm", "pypi", "nuget", "vscode", "docker"],
|
|
81
|
+
"packages": {
|
|
82
|
+
"mcpt": {
|
|
83
|
+
"npm": "mcpt",
|
|
84
|
+
"pypi": "mcpt"
|
|
85
|
+
},
|
|
86
|
+
"tool-compass": {
|
|
87
|
+
"npm": "@mcptoolshop/tool-compass",
|
|
88
|
+
"vscode": "mcp-tool-shop.tool-compass"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"cache": true,
|
|
92
|
+
"cacheTtlMs": 300000,
|
|
93
|
+
"concurrency": 5
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Ejecuta `registry-stats` sin argumentos para obtener estadísticas de todos los paquetes configurados. El CLI busca el archivo de configuración hacia arriba desde el directorio actual.
|
|
98
|
+
|
|
99
|
+
## API Programática
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { stats, calc, createCache } from '@mcptoolshop/registry-stats';
|
|
103
|
+
|
|
104
|
+
// Registro individual
|
|
105
|
+
const npm = await stats('npm', 'express');
|
|
106
|
+
const pypi = await stats('pypi', 'requests');
|
|
107
|
+
|
|
108
|
+
// Todos los registros (usa Promise.allSettled — nunca lanza error)
|
|
109
|
+
const all = await stats.all('express');
|
|
110
|
+
|
|
111
|
+
// Masivo — múltiples paquetes, concurrencia limitada (por defecto: 5)
|
|
112
|
+
const bulk = await stats.bulk('npm', ['express', 'koa', 'fastify']);
|
|
113
|
+
|
|
114
|
+
// Serie temporal (solo npm + pypi)
|
|
115
|
+
const daily = await stats.range('npm', 'express', '2025-01-01', '2025-06-30');
|
|
116
|
+
|
|
117
|
+
// Cálculos
|
|
118
|
+
calc.total(daily); // total de descargas
|
|
119
|
+
calc.avg(daily); // promedio diario
|
|
120
|
+
calc.trend(daily); // { direction: 'up', changePercent: 8.3 }
|
|
121
|
+
calc.movingAvg(daily, 7); // media móvil de 7 días
|
|
122
|
+
calc.popularity(daily); // puntuación 0-100 escala logarítmica
|
|
123
|
+
|
|
124
|
+
// Formatos de exportación
|
|
125
|
+
calc.toCSV(daily); // cadena CSV
|
|
126
|
+
calc.toChartData(daily, 'express'); // { labels: [...], datasets: [...] }
|
|
127
|
+
|
|
128
|
+
// Comparación — mismo paquete entre registros
|
|
129
|
+
const comparison = await stats.compare('express');
|
|
130
|
+
await stats.compare('express', ['npm', 'pypi']);
|
|
131
|
+
|
|
132
|
+
// Caché (TTL 5 min, en memoria)
|
|
133
|
+
const cache = createCache();
|
|
134
|
+
await stats('npm', 'express', { cache });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Soporte de Registros
|
|
138
|
+
|
|
139
|
+
| Registro | Formato de paquete | Serie temporal | Datos disponibles |
|
|
140
|
+
|----------|-------------------|----------------|-------------------|
|
|
141
|
+
| `npm` | `express`, `@scope/pkg` | Sí (549 días) | lastDay, lastWeek, lastMonth |
|
|
142
|
+
| `pypi` | `requests` | Sí (180 días) | lastDay, lastWeek, lastMonth, total |
|
|
143
|
+
| `nuget` | `Newtonsoft.Json` | No | total |
|
|
144
|
+
| `vscode` | `publisher.extension` | No | total (instalaciones), rating, trends |
|
|
145
|
+
| `docker` | `namespace/repo` | No | total (pulls), stars |
|
|
146
|
+
|
|
147
|
+
## Fiabilidad Integrada
|
|
148
|
+
|
|
149
|
+
- Reintento automático con retroceso exponencial en errores 429/5xx
|
|
150
|
+
- Respeta las cabeceras `Retry-After`
|
|
151
|
+
- Limitación de concurrencia para solicitudes masivas
|
|
152
|
+
- Caché TTL opcional (extensible — usa Redis/archivo via interfaz `StatsCache`)
|
|
153
|
+
|
|
154
|
+
## Servidor REST API
|
|
155
|
+
|
|
156
|
+
Ejecuta como microservicio o intégralo en tu propio servidor:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
registry-stats serve --port 3000
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
GET /stats/:package # todos los registros
|
|
164
|
+
GET /stats/:registry/:package # registro individual
|
|
165
|
+
GET /compare/:package?registries=npm,pypi
|
|
166
|
+
GET /range/:registry/:package?start=YYYY-MM-DD&end=YYYY-MM-DD&format=json|csv|chart
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { createHandler, serve } from '@mcptoolshop/registry-stats';
|
|
171
|
+
|
|
172
|
+
// Inicio rápido
|
|
173
|
+
serve({ port: 3000 });
|
|
174
|
+
|
|
175
|
+
// Servidor personalizado
|
|
176
|
+
import { createServer } from 'node:http';
|
|
177
|
+
const handler = createHandler();
|
|
178
|
+
createServer(handler).listen(3000);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Registros Personalizados
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { registerProvider, type RegistryProvider } from '@mcptoolshop/registry-stats';
|
|
185
|
+
|
|
186
|
+
const cargo: RegistryProvider = {
|
|
187
|
+
name: 'cargo',
|
|
188
|
+
async getStats(pkg) {
|
|
189
|
+
const res = await fetch(`https://crates.io/api/v1/crates/${pkg}`);
|
|
190
|
+
const json = await res.json();
|
|
191
|
+
return {
|
|
192
|
+
registry: 'cargo' as any,
|
|
193
|
+
package: pkg,
|
|
194
|
+
downloads: { total: json.crate.downloads },
|
|
195
|
+
fetchedAt: new Date().toISOString(),
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
registerProvider(cargo);
|
|
201
|
+
await stats('cargo', 'serde');
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Licencia
|
|
205
|
+
|
|
206
|
+
MIT
|
package/README.fr.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="README.md">English</a> | <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <strong>Français</strong> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português</a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="assets/logo.png" alt="logo registry-stats" width="280" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<h1 align="center">@mcptoolshop/registry-stats</h1>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
Une commande. Cinq registres. Toutes vos statistiques de téléchargement.
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="#installation">Installation</a> ·
|
|
17
|
+
<a href="#cli">CLI</a> ·
|
|
18
|
+
<a href="#fichier-de-configuration">Configuration</a> ·
|
|
19
|
+
<a href="#api-programmatique">API</a> ·
|
|
20
|
+
<a href="#serveur-rest-api">Serveur REST</a> ·
|
|
21
|
+
<a href="#licence">Licence</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
Si vous publiez sur npm, PyPI, NuGet, VS Code Marketplace ou Docker Hub, vous avez actuellement besoin de cinq API différentes pour répondre à « combien de téléchargements ce mois-ci ? » Cette bibliothèque offre une interface unifiée — en CLI ou API programmatique.
|
|
27
|
+
|
|
28
|
+
Zéro dépendance. Utilise `fetch()` natif. Node 18+.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @mcptoolshop/registry-stats
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## CLI
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Interroger un seul registre
|
|
40
|
+
registry-stats express -r npm
|
|
41
|
+
|
|
42
|
+
# Interroger tous les registres
|
|
43
|
+
registry-stats express
|
|
44
|
+
|
|
45
|
+
# Série temporelle avec ventilation mensuelle + tendance
|
|
46
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30
|
|
47
|
+
|
|
48
|
+
# Sortie JSON
|
|
49
|
+
registry-stats express -r npm --json
|
|
50
|
+
|
|
51
|
+
# Autres registres
|
|
52
|
+
registry-stats requests -r pypi
|
|
53
|
+
registry-stats Newtonsoft.Json -r nuget
|
|
54
|
+
registry-stats esbenp.prettier-vscode -r vscode
|
|
55
|
+
registry-stats library/node -r docker
|
|
56
|
+
|
|
57
|
+
# Créer un fichier de configuration
|
|
58
|
+
registry-stats --init
|
|
59
|
+
|
|
60
|
+
# Exécuter avec la configuration — récupère tous les paquets suivis
|
|
61
|
+
registry-stats
|
|
62
|
+
|
|
63
|
+
# Comparer entre registres
|
|
64
|
+
registry-stats express --compare
|
|
65
|
+
|
|
66
|
+
# Exporter en CSV ou JSON pour graphiques
|
|
67
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format csv
|
|
68
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format chart
|
|
69
|
+
|
|
70
|
+
# Démarrer un serveur REST API
|
|
71
|
+
registry-stats serve --port 3000
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Fichier de Configuration
|
|
75
|
+
|
|
76
|
+
Créez un `registry-stats.config.json` à la racine de votre projet (ou exécutez `registry-stats --init`) :
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"registries": ["npm", "pypi", "nuget", "vscode", "docker"],
|
|
81
|
+
"packages": {
|
|
82
|
+
"mcpt": {
|
|
83
|
+
"npm": "mcpt",
|
|
84
|
+
"pypi": "mcpt"
|
|
85
|
+
},
|
|
86
|
+
"tool-compass": {
|
|
87
|
+
"npm": "@mcptoolshop/tool-compass",
|
|
88
|
+
"vscode": "mcp-tool-shop.tool-compass"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"cache": true,
|
|
92
|
+
"cacheTtlMs": 300000,
|
|
93
|
+
"concurrency": 5
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Exécutez `registry-stats` sans arguments pour obtenir les statistiques de tous les paquets configurés. Le CLI remonte les répertoires depuis le dossier courant pour trouver le fichier de configuration.
|
|
98
|
+
|
|
99
|
+
## API Programmatique
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { stats, calc, createCache } from '@mcptoolshop/registry-stats';
|
|
103
|
+
|
|
104
|
+
// Registre unique
|
|
105
|
+
const npm = await stats('npm', 'express');
|
|
106
|
+
const pypi = await stats('pypi', 'requests');
|
|
107
|
+
|
|
108
|
+
// Tous les registres (utilise Promise.allSettled — ne lance jamais d'erreur)
|
|
109
|
+
const all = await stats.all('express');
|
|
110
|
+
|
|
111
|
+
// En masse — plusieurs paquets, concurrence limitée (par défaut : 5)
|
|
112
|
+
const bulk = await stats.bulk('npm', ['express', 'koa', 'fastify']);
|
|
113
|
+
|
|
114
|
+
// Série temporelle (npm + pypi uniquement)
|
|
115
|
+
const daily = await stats.range('npm', 'express', '2025-01-01', '2025-06-30');
|
|
116
|
+
|
|
117
|
+
// Calculs
|
|
118
|
+
calc.total(daily); // total des téléchargements
|
|
119
|
+
calc.avg(daily); // moyenne journalière
|
|
120
|
+
calc.trend(daily); // { direction: 'up', changePercent: 8.3 }
|
|
121
|
+
calc.movingAvg(daily, 7); // moyenne mobile sur 7 jours
|
|
122
|
+
calc.popularity(daily); // score 0-100 échelle logarithmique
|
|
123
|
+
|
|
124
|
+
// Formats d'exportation
|
|
125
|
+
calc.toCSV(daily); // chaîne CSV
|
|
126
|
+
calc.toChartData(daily, 'express'); // { labels: [...], datasets: [...] }
|
|
127
|
+
|
|
128
|
+
// Comparaison — même paquet entre registres
|
|
129
|
+
const comparison = await stats.compare('express');
|
|
130
|
+
await stats.compare('express', ['npm', 'pypi']);
|
|
131
|
+
|
|
132
|
+
// Cache (TTL 5 min, en mémoire)
|
|
133
|
+
const cache = createCache();
|
|
134
|
+
await stats('npm', 'express', { cache });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Support des Registres
|
|
138
|
+
|
|
139
|
+
| Registre | Format de paquet | Série temporelle | Données disponibles |
|
|
140
|
+
|----------|-----------------|-----------------|---------------------|
|
|
141
|
+
| `npm` | `express`, `@scope/pkg` | Oui (549 jours) | lastDay, lastWeek, lastMonth |
|
|
142
|
+
| `pypi` | `requests` | Oui (180 jours) | lastDay, lastWeek, lastMonth, total |
|
|
143
|
+
| `nuget` | `Newtonsoft.Json` | Non | total |
|
|
144
|
+
| `vscode` | `publisher.extension` | Non | total (installations), rating, trends |
|
|
145
|
+
| `docker` | `namespace/repo` | Non | total (pulls), stars |
|
|
146
|
+
|
|
147
|
+
## Fiabilité Intégrée
|
|
148
|
+
|
|
149
|
+
- Réessai automatique avec recul exponentiel sur erreurs 429/5xx
|
|
150
|
+
- Respecte les en-têtes `Retry-After`
|
|
151
|
+
- Limitation de concurrence pour les requêtes en masse
|
|
152
|
+
- Cache TTL optionnel (extensible — utilisez Redis/fichier via l'interface `StatsCache`)
|
|
153
|
+
|
|
154
|
+
## Serveur REST API
|
|
155
|
+
|
|
156
|
+
Exécutez comme microservice ou intégrez dans votre propre serveur :
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
registry-stats serve --port 3000
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
GET /stats/:package # tous les registres
|
|
164
|
+
GET /stats/:registry/:package # registre unique
|
|
165
|
+
GET /compare/:package?registries=npm,pypi
|
|
166
|
+
GET /range/:registry/:package?start=YYYY-MM-DD&end=YYYY-MM-DD&format=json|csv|chart
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { createHandler, serve } from '@mcptoolshop/registry-stats';
|
|
171
|
+
|
|
172
|
+
// Démarrage rapide
|
|
173
|
+
serve({ port: 3000 });
|
|
174
|
+
|
|
175
|
+
// Serveur personnalisé
|
|
176
|
+
import { createServer } from 'node:http';
|
|
177
|
+
const handler = createHandler();
|
|
178
|
+
createServer(handler).listen(3000);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Registres Personnalisés
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { registerProvider, type RegistryProvider } from '@mcptoolshop/registry-stats';
|
|
185
|
+
|
|
186
|
+
const cargo: RegistryProvider = {
|
|
187
|
+
name: 'cargo',
|
|
188
|
+
async getStats(pkg) {
|
|
189
|
+
const res = await fetch(`https://crates.io/api/v1/crates/${pkg}`);
|
|
190
|
+
const json = await res.json();
|
|
191
|
+
return {
|
|
192
|
+
registry: 'cargo' as any,
|
|
193
|
+
package: pkg,
|
|
194
|
+
downloads: { total: json.crate.downloads },
|
|
195
|
+
fetchedAt: new Date().toISOString(),
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
registerProvider(cargo);
|
|
201
|
+
await stats('cargo', 'serde');
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Licence
|
|
205
|
+
|
|
206
|
+
MIT
|
package/README.hi.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="README.md">English</a> | <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <strong>हिन्दी</strong> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português</a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="assets/logo.png" alt="registry-stats लोगो" width="280" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<h1 align="center">@mcptoolshop/registry-stats</h1>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
एक कमांड। पाँच रजिस्ट्री। आपके सभी डाउनलोड आँकड़े।
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="#इंस्टॉल">इंस्टॉल</a> ·
|
|
17
|
+
<a href="#cli">CLI</a> ·
|
|
18
|
+
<a href="#कॉन्फ़िग-फ़ाइल">कॉन्फ़िग</a> ·
|
|
19
|
+
<a href="#प्रोग्रामैटिक-api">API</a> ·
|
|
20
|
+
<a href="#rest-api-सर्वर">REST सर्वर</a> ·
|
|
21
|
+
<a href="#लाइसेंस">लाइसेंस</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
यदि आप npm, PyPI, NuGet, VS Code Marketplace, या Docker Hub पर पैकेज प्रकाशित करते हैं, तो "इस महीने मेरे कितने डाउनलोड हुए?" का जवाब देने के लिए आपको पाँच अलग-अलग API की आवश्यकता होती है। यह लाइब्रेरी सभी के लिए एक इंटरफ़ेस प्रदान करती है — CLI या प्रोग्रामैटिक API के रूप में।
|
|
27
|
+
|
|
28
|
+
शून्य निर्भरता। नेटिव `fetch()` का उपयोग। Node 18+.
|
|
29
|
+
|
|
30
|
+
## इंस्टॉल
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @mcptoolshop/registry-stats
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## CLI
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# एकल रजिस्ट्री क्वेरी
|
|
40
|
+
registry-stats express -r npm
|
|
41
|
+
|
|
42
|
+
# सभी रजिस्ट्री एक साथ क्वेरी
|
|
43
|
+
registry-stats express
|
|
44
|
+
|
|
45
|
+
# मासिक ब्रेकडाउन + ट्रेंड के साथ टाइम सीरीज़
|
|
46
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30
|
|
47
|
+
|
|
48
|
+
# JSON आउटपुट
|
|
49
|
+
registry-stats express -r npm --json
|
|
50
|
+
|
|
51
|
+
# अन्य रजिस्ट्री
|
|
52
|
+
registry-stats requests -r pypi
|
|
53
|
+
registry-stats Newtonsoft.Json -r nuget
|
|
54
|
+
registry-stats esbenp.prettier-vscode -r vscode
|
|
55
|
+
registry-stats library/node -r docker
|
|
56
|
+
|
|
57
|
+
# कॉन्फ़िग फ़ाइल बनाएँ
|
|
58
|
+
registry-stats --init
|
|
59
|
+
|
|
60
|
+
# कॉन्फ़िग से चलाएँ — सभी ट्रैक किए गए पैकेज प्राप्त करें
|
|
61
|
+
registry-stats
|
|
62
|
+
|
|
63
|
+
# रजिस्ट्री में तुलना करें
|
|
64
|
+
registry-stats express --compare
|
|
65
|
+
|
|
66
|
+
# CSV या चार्ट-फ्रेंडली JSON में एक्सपोर्ट
|
|
67
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format csv
|
|
68
|
+
registry-stats express -r npm --range 2025-01-01:2025-06-30 --format chart
|
|
69
|
+
|
|
70
|
+
# REST API सर्वर शुरू करें
|
|
71
|
+
registry-stats serve --port 3000
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## कॉन्फ़िग फ़ाइल
|
|
75
|
+
|
|
76
|
+
अपने प्रोजेक्ट रूट में `registry-stats.config.json` बनाएँ (या `registry-stats --init` चलाएँ):
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"registries": ["npm", "pypi", "nuget", "vscode", "docker"],
|
|
81
|
+
"packages": {
|
|
82
|
+
"mcpt": {
|
|
83
|
+
"npm": "mcpt",
|
|
84
|
+
"pypi": "mcpt"
|
|
85
|
+
},
|
|
86
|
+
"tool-compass": {
|
|
87
|
+
"npm": "@mcptoolshop/tool-compass",
|
|
88
|
+
"vscode": "mcp-tool-shop.tool-compass"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"cache": true,
|
|
92
|
+
"cacheTtlMs": 300000,
|
|
93
|
+
"concurrency": 5
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
बिना तर्क के `registry-stats` चलाएँ और सभी कॉन्फ़िगर किए गए पैकेजों के आँकड़े प्राप्त करें। CLI वर्तमान डायरेक्टरी से ऊपर की ओर कॉन्फ़िग फ़ाइल खोजता है।
|
|
98
|
+
|
|
99
|
+
## प्रोग्रामैटिक API
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { stats, calc, createCache } from '@mcptoolshop/registry-stats';
|
|
103
|
+
|
|
104
|
+
// एकल रजिस्ट्री
|
|
105
|
+
const npm = await stats('npm', 'express');
|
|
106
|
+
const pypi = await stats('pypi', 'requests');
|
|
107
|
+
|
|
108
|
+
// सभी रजिस्ट्री (Promise.allSettled का उपयोग — कभी एरर नहीं फेंकता)
|
|
109
|
+
const all = await stats.all('express');
|
|
110
|
+
|
|
111
|
+
// बल्क — कई पैकेज, सीमित कंकरेंसी (डिफ़ॉल्ट: 5)
|
|
112
|
+
const bulk = await stats.bulk('npm', ['express', 'koa', 'fastify']);
|
|
113
|
+
|
|
114
|
+
// टाइम सीरीज़ (केवल npm + pypi)
|
|
115
|
+
const daily = await stats.range('npm', 'express', '2025-01-01', '2025-06-30');
|
|
116
|
+
|
|
117
|
+
// गणनाएँ
|
|
118
|
+
calc.total(daily); // कुल डाउनलोड
|
|
119
|
+
calc.avg(daily); // दैनिक औसत
|
|
120
|
+
calc.trend(daily); // { direction: 'up', changePercent: 8.3 }
|
|
121
|
+
calc.movingAvg(daily, 7); // 7-दिन मूविंग एवरेज
|
|
122
|
+
calc.popularity(daily); // 0-100 लॉग-स्केल स्कोर
|
|
123
|
+
|
|
124
|
+
// एक्सपोर्ट फ़ॉर्मेट
|
|
125
|
+
calc.toCSV(daily); // CSV स्ट्रिंग
|
|
126
|
+
calc.toChartData(daily, 'express'); // { labels: [...], datasets: [...] }
|
|
127
|
+
|
|
128
|
+
// तुलना — रजिस्ट्री में एक ही पैकेज
|
|
129
|
+
const comparison = await stats.compare('express');
|
|
130
|
+
await stats.compare('express', ['npm', 'pypi']);
|
|
131
|
+
|
|
132
|
+
// कैश (5 मिनट TTL, इन-मेमोरी)
|
|
133
|
+
const cache = createCache();
|
|
134
|
+
await stats('npm', 'express', { cache });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## रजिस्ट्री सपोर्ट
|
|
138
|
+
|
|
139
|
+
| रजिस्ट्री | पैकेज फ़ॉर्मेट | टाइम सीरीज़ | उपलब्ध डेटा |
|
|
140
|
+
|-----------|---------------|------------|-------------|
|
|
141
|
+
| `npm` | `express`, `@scope/pkg` | हाँ (549 दिन) | lastDay, lastWeek, lastMonth |
|
|
142
|
+
| `pypi` | `requests` | हाँ (180 दिन) | lastDay, lastWeek, lastMonth, total |
|
|
143
|
+
| `nuget` | `Newtonsoft.Json` | नहीं | total |
|
|
144
|
+
| `vscode` | `publisher.extension` | नहीं | total (इंस्टॉल), rating, trends |
|
|
145
|
+
| `docker` | `namespace/repo` | नहीं | total (पुल), stars |
|
|
146
|
+
|
|
147
|
+
## अंतर्निर्मित विश्वसनीयता
|
|
148
|
+
|
|
149
|
+
- 429/5xx त्रुटियों पर एक्सपोनेंशियल बैकऑफ़ के साथ स्वचालित रीट्राई
|
|
150
|
+
- `Retry-After` हेडर का सम्मान
|
|
151
|
+
- बल्क अनुरोधों के लिए कंकरेंसी सीमा
|
|
152
|
+
- वैकल्पिक TTL कैश (प्लगेबल — `StatsCache` इंटरफ़ेस के माध्यम से Redis/फ़ाइल बैकएंड)
|
|
153
|
+
|
|
154
|
+
## REST API सर्वर
|
|
155
|
+
|
|
156
|
+
माइक्रोसर्विस के रूप में चलाएँ, या अपने सर्वर में एम्बेड करें:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
registry-stats serve --port 3000
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
GET /stats/:package # सभी रजिस्ट्री
|
|
164
|
+
GET /stats/:registry/:package # एकल रजिस्ट्री
|
|
165
|
+
GET /compare/:package?registries=npm,pypi
|
|
166
|
+
GET /range/:registry/:package?start=YYYY-MM-DD&end=YYYY-MM-DD&format=json|csv|chart
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { createHandler, serve } from '@mcptoolshop/registry-stats';
|
|
171
|
+
|
|
172
|
+
// क्विक स्टार्ट
|
|
173
|
+
serve({ port: 3000 });
|
|
174
|
+
|
|
175
|
+
// कस्टम सर्वर
|
|
176
|
+
import { createServer } from 'node:http';
|
|
177
|
+
const handler = createHandler();
|
|
178
|
+
createServer(handler).listen(3000);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## कस्टम रजिस्ट्री
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { registerProvider, type RegistryProvider } from '@mcptoolshop/registry-stats';
|
|
185
|
+
|
|
186
|
+
const cargo: RegistryProvider = {
|
|
187
|
+
name: 'cargo',
|
|
188
|
+
async getStats(pkg) {
|
|
189
|
+
const res = await fetch(`https://crates.io/api/v1/crates/${pkg}`);
|
|
190
|
+
const json = await res.json();
|
|
191
|
+
return {
|
|
192
|
+
registry: 'cargo' as any,
|
|
193
|
+
package: pkg,
|
|
194
|
+
downloads: { total: json.crate.downloads },
|
|
195
|
+
fetchedAt: new Date().toISOString(),
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
registerProvider(cargo);
|
|
201
|
+
await stats('cargo', 'serde');
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## लाइसेंस
|
|
205
|
+
|
|
206
|
+
MIT
|