devcompass 2.3.1 → 2.5.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.
@@ -0,0 +1,813 @@
1
+ // src/alerts/github-tracker.js
2
+ const https = require('https');
3
+
4
+ // Top 500+ npm packages organized by category
5
+ const TRACKED_REPOS = {
6
+ // === WEB FRAMEWORKS (25) ===
7
+ 'react': 'facebook/react',
8
+ 'vue': 'vuejs/core',
9
+ 'angular': 'angular/angular',
10
+ 'svelte': 'sveltejs/svelte',
11
+ 'preact': 'preactjs/preact',
12
+ 'solid-js': 'solidjs/solid',
13
+ 'lit': 'lit/lit',
14
+ 'alpinejs': 'alpinejs/alpine',
15
+ 'ember.js': 'emberjs/ember.js',
16
+ 'backbone': 'jashkenas/backbone',
17
+ 'knockout': 'knockout/knockout',
18
+ 'marko': 'marko-js/marko',
19
+ 'mithril': 'MithrilJS/mithril.js',
20
+ 'hyperapp': 'jorgebucaran/hyperapp',
21
+ 'riot': 'riot/riot',
22
+ 'inferno': 'infernojs/inferno',
23
+ 'aurelia': 'aurelia/framework',
24
+ 'polymer': 'Polymer/polymer',
25
+ 'stimulus': 'hotwired/stimulus',
26
+ 'qwik': 'QwikDev/qwik',
27
+ 'astro': 'withastro/astro',
28
+ 'fresh': 'denoland/fresh',
29
+ 'marko': 'marko-js/marko',
30
+ 'htmx': 'bigskysoftware/htmx',
31
+ 'alpine': 'alpinejs/alpine',
32
+
33
+ // === META FRAMEWORKS (15) ===
34
+ 'next': 'vercel/next.js',
35
+ 'nuxt': 'nuxt/nuxt',
36
+ 'gatsby': 'gatsbyjs/gatsby',
37
+ 'remix': 'remix-run/remix',
38
+ 'sveltekit': 'sveltejs/kit',
39
+ 'blitz': 'blitz-js/blitz',
40
+ 'redwood': 'redwoodjs/redwood',
41
+ 'nextra': 'shuding/nextra',
42
+ 'docusaurus': 'facebook/docusaurus',
43
+ 'vuepress': 'vuejs/vuepress',
44
+ 'eleventy': '11ty/eleventy',
45
+ 'hexo': 'hexojs/hexo',
46
+ 'hugo': 'gohugoio/hugo',
47
+ 'jekyll': 'jekyll/jekyll',
48
+ 'gridsome': 'gridsome/gridsome',
49
+
50
+ // === MOBILE FRAMEWORKS (10) ===
51
+ 'react-native': 'facebook/react-native',
52
+ 'ionic': 'ionic-team/ionic-framework',
53
+ 'nativescript': 'NativeScript/NativeScript',
54
+ 'expo': 'expo/expo',
55
+ 'capacitor': 'ionic-team/capacitor',
56
+ 'cordova': 'apache/cordova',
57
+ 'framework7': 'framework7io/framework7',
58
+ 'onsen-ui': 'OnsenUI/OnsenUI',
59
+ 'quasar': 'quasarframework/quasar',
60
+ 'metro': 'facebook/metro',
61
+
62
+ // === BACKEND FRAMEWORKS (20) ===
63
+ 'express': 'expressjs/express',
64
+ 'koa': 'koajs/koa',
65
+ 'fastify': 'fastify/fastify',
66
+ 'hapi': 'hapijs/hapi',
67
+ 'nest': 'nestjs/nest',
68
+ 'loopback': 'loopbackio/loopback-next',
69
+ 'sails': 'balderdashy/sails',
70
+ 'feathers': 'feathersjs/feathers',
71
+ 'adonis': 'adonisjs/core',
72
+ 'strapi': 'strapi/strapi',
73
+ 'meteor': 'meteor/meteor',
74
+ 'keystone': 'keystonejs/keystone',
75
+ 'directus': 'directus/directus',
76
+ 'payload': 'payloadcms/payload',
77
+ 'ghost': 'TryGhost/Ghost',
78
+ 'redwood': 'redwoodjs/redwood',
79
+ 'trpc': 'trpc/trpc',
80
+ 'graphql-yoga': 'dotansimha/graphql-yoga',
81
+ 'apollo-server': 'apollographql/apollo-server',
82
+ 'prisma': 'prisma/prisma',
83
+
84
+ // === BUILD TOOLS (25) ===
85
+ 'webpack': 'webpack/webpack',
86
+ 'vite': 'vitejs/vite',
87
+ 'rollup': 'rollup/rollup',
88
+ 'parcel': 'parcel-bundler/parcel',
89
+ 'esbuild': 'evanw/esbuild',
90
+ 'turbopack': 'vercel/turbo',
91
+ 'swc': 'swc-project/swc',
92
+ 'babel': 'babel/babel',
93
+ 'rome': 'rome/tools',
94
+ 'tsup': 'egoist/tsup',
95
+ 'unbuild': 'unjs/unbuild',
96
+ 'microbundle': 'developit/microbundle',
97
+ 'tsdx': 'jaredpalmer/tsdx',
98
+ 'wmr': 'preactjs/wmr',
99
+ 'snowpack': 'FredKSchott/snowpack',
100
+ 'gulp': 'gulpjs/gulp',
101
+ 'grunt': 'gruntjs/grunt',
102
+ 'brunch': 'brunch/brunch',
103
+ 'browserify': 'browserify/browserify',
104
+ 'fuse-box': 'fuse-box/fuse-box',
105
+ 'poi': 'egoist/poi',
106
+ 'neutrino': 'neutrinojs/neutrino',
107
+ 'backpack': 'jaredpalmer/backpack',
108
+ 'ncc': 'vercel/ncc',
109
+ 'pkg': 'vercel/pkg',
110
+
111
+ // === TESTING FRAMEWORKS (25) ===
112
+ 'jest': 'jestjs/jest',
113
+ 'mocha': 'mochajs/mocha',
114
+ 'jasmine': 'jasmine/jasmine',
115
+ 'vitest': 'vitest-dev/vitest',
116
+ 'ava': 'avajs/ava',
117
+ 'tape': 'tape-testing/tape',
118
+ 'cypress': 'cypress-io/cypress',
119
+ 'playwright': 'microsoft/playwright',
120
+ 'puppeteer': 'puppeteer/puppeteer',
121
+ 'selenium-webdriver': 'SeleniumHQ/selenium',
122
+ 'webdriverio': 'webdriverio/webdriverio',
123
+ 'nightwatch': 'nightwatchjs/nightwatch',
124
+ 'testcafe': 'DevExpress/testcafe',
125
+ 'karma': 'karma-runner/karma',
126
+ 'protractor': 'angular/protractor',
127
+ 'enzyme': 'enzymejs/enzyme',
128
+ '@testing-library/react': 'testing-library/react-testing-library',
129
+ '@testing-library/vue': 'testing-library/vue-testing-library',
130
+ '@testing-library/angular': 'testing-library/angular-testing-library',
131
+ 'chai': 'chaijs/chai',
132
+ 'sinon': 'sinonjs/sinon',
133
+ 'supertest': 'ladjs/supertest',
134
+ 'nock': 'nock/nock',
135
+ 'mock-service-worker': 'mswjs/msw',
136
+ 'storybook': 'storybookjs/storybook',
137
+
138
+ // === LINTERS & FORMATTERS (15) ===
139
+ 'eslint': 'eslint/eslint',
140
+ 'prettier': 'prettier/prettier',
141
+ 'stylelint': 'stylelint/stylelint',
142
+ 'tslint': 'palantir/tslint',
143
+ 'standard': 'standard/standard',
144
+ 'xo': 'xojs/xo',
145
+ 'jshint': 'jshint/jshint',
146
+ 'jslint': 'jslint-org/jslint',
147
+ 'rome': 'rome/tools',
148
+ 'dprint': 'dprint/dprint',
149
+ 'biome': 'biomejs/biome',
150
+ 'oxlint': 'web-infra-dev/oxc',
151
+ 'quick-lint-js': 'quick-lint/quick-lint-js',
152
+ 'rslint': 'rslint/rslint',
153
+ 'deno_lint': 'denoland/deno_lint',
154
+
155
+ // === TYPESCRIPT & TYPE TOOLS (15) ===
156
+ 'typescript': 'microsoft/TypeScript',
157
+ 'ts-node': 'TypeStrong/ts-node',
158
+ 'tsx': 'privatenumber/tsx',
159
+ 'tsup': 'egoist/tsup',
160
+ 'tsc-watch': 'gilamran/tsc-watch',
161
+ 'ttypescript': 'cevek/ttypescript',
162
+ 'typedoc': 'TypeStrong/typedoc',
163
+ 'api-extractor': 'microsoft/rushstack',
164
+ 'type-fest': 'sindresorhus/type-fest',
165
+ 'zod': 'colinhacks/zod',
166
+ 'yup': 'jquense/yup',
167
+ 'joi': 'hapijs/joi',
168
+ 'ajv': 'ajv-validator/ajv',
169
+ 'superstruct': 'ianstormtaylor/superstruct',
170
+ 'runtypes': 'pelotom/runtypes',
171
+
172
+ // === STATE MANAGEMENT (20) ===
173
+ 'redux': 'reduxjs/redux',
174
+ 'mobx': 'mobxjs/mobx',
175
+ 'zustand': 'pmndrs/zustand',
176
+ 'jotai': 'pmndrs/jotai',
177
+ 'recoil': 'facebookexperimental/Recoil',
178
+ 'valtio': 'pmndrs/valtio',
179
+ 'xstate': 'statelyai/xstate',
180
+ 'effector': 'effector/effector',
181
+ 'rematch': 'rematch/rematch',
182
+ 'easy-peasy': 'ctrlplusb/easy-peasy',
183
+ 'pullstate': 'lostpebble/pullstate',
184
+ 'hookstate': 'avkonst/hookstate',
185
+ 'storeon': 'storeon/storeon',
186
+ 'nano-stores': 'nanostores/nanostores',
187
+ 'valtio': 'pmndrs/valtio',
188
+ 'signal': 'preactjs/signals',
189
+ 'vuex': 'vuejs/vuex',
190
+ 'pinia': 'vuejs/pinia',
191
+ 'ngxs': 'ngxs/store',
192
+ 'akita': 'salesforce/akita',
193
+
194
+ // === HTTP CLIENTS (20) ===
195
+ 'axios': 'axios/axios',
196
+ 'node-fetch': 'node-fetch/node-fetch',
197
+ 'got': 'sindresorhus/got',
198
+ 'ky': 'sindresorhus/ky',
199
+ 'superagent': 'ladjs/superagent',
200
+ 'request': 'request/request',
201
+ 'needle': 'tomas/needle',
202
+ 'bent': 'mikeal/bent',
203
+ 'phin': 'ethanent/phin',
204
+ 'undici': 'nodejs/undici',
205
+ 'cross-fetch': 'lquixada/cross-fetch',
206
+ 'isomorphic-fetch': 'matthew-andrews/isomorphic-fetch',
207
+ 'whatwg-fetch': 'github/fetch',
208
+ 'unfetch': 'developit/unfetch',
209
+ 'redaxios': 'developit/redaxios',
210
+ '@tanstack/react-query': 'TanStack/query',
211
+ 'swr': 'vercel/swr',
212
+ 'apollo-client': 'apollographql/apollo-client',
213
+ 'urql': 'urql-graphql/urql',
214
+ 'relay': 'facebook/relay',
215
+
216
+ // === UTILITIES (50) ===
217
+ 'lodash': 'lodash/lodash',
218
+ 'underscore': 'jashkenas/underscore',
219
+ 'ramda': 'ramda/ramda',
220
+ 'moment': 'moment/moment',
221
+ 'dayjs': 'iamkun/dayjs',
222
+ 'date-fns': 'date-fns/date-fns',
223
+ 'luxon': 'moment/luxon',
224
+ 'chalk': 'chalk/chalk',
225
+ 'colors': 'Marak/colors.js',
226
+ 'ora': 'sindresorhus/ora',
227
+ 'inquirer': 'SBoudrias/Inquirer.js',
228
+ 'prompts': 'terkelg/prompts',
229
+ 'commander': 'tj/commander.js',
230
+ 'yargs': 'yargs/yargs',
231
+ 'minimist': 'minimistjs/minimist',
232
+ 'dotenv': 'motdotla/dotenv',
233
+ 'cross-env': 'kentcdodds/cross-env',
234
+ 'uuid': 'uuidjs/uuid',
235
+ 'nanoid': 'ai/nanoid',
236
+ 'short-uuid': 'oculus42/short-uuid',
237
+ 'validator': 'validatorjs/validator.js',
238
+ 'is': 'enricomarino/is',
239
+ 'debug': 'debug-js/debug',
240
+ 'winston': 'winstonjs/winston',
241
+ 'pino': 'pinojs/pino',
242
+ 'bunyan': 'trentm/node-bunyan',
243
+ 'morgan': 'expressjs/morgan',
244
+ 'ms': 'vercel/ms',
245
+ 'glob': 'isaacs/node-glob',
246
+ 'minimatch': 'isaacs/minimatch',
247
+ 'micromatch': 'micromatch/micromatch',
248
+ 'fast-glob': 'mrmlnc/fast-glob',
249
+ 'chokidar': 'paulmillr/chokidar',
250
+ 'fs-extra': 'jprichardson/node-fs-extra',
251
+ 'rimraf': 'isaacs/rimraf',
252
+ 'del': 'sindresorhus/del',
253
+ 'make-dir': 'sindresorhus/make-dir',
254
+ 'execa': 'sindresorhus/execa',
255
+ 'shelljs': 'shelljs/shelljs',
256
+ 'cross-spawn': 'moxystudio/node-cross-spawn',
257
+ 'concurrently': 'open-cli-tools/concurrently',
258
+ 'npm-run-all': 'mysticatea/npm-run-all',
259
+ 'nodemon': 'remy/nodemon',
260
+ 'pm2': 'Unitech/pm2',
261
+ 'forever': 'foreversd/forever',
262
+ 'bluebird': 'petkaantonov/bluebird',
263
+ 'p-limit': 'sindresorhus/p-limit',
264
+ 'p-queue': 'sindresorhus/p-queue',
265
+ 'p-retry': 'sindresorhus/p-retry',
266
+ 'async': 'caolan/async',
267
+
268
+ // === CSS & STYLING (25) ===
269
+ 'tailwindcss': 'tailwindlabs/tailwindcss',
270
+ 'sass': 'sass/dart-sass',
271
+ 'less': 'less/less.js',
272
+ 'stylus': 'stylus/stylus',
273
+ 'postcss': 'postcss/postcss',
274
+ 'autoprefixer': 'postcss/autoprefixer',
275
+ 'cssnano': 'cssnano/cssnano',
276
+ 'styled-components': 'styled-components/styled-components',
277
+ 'emotion': 'emotion-js/emotion',
278
+ '@emotion/react': 'emotion-js/emotion',
279
+ 'styled-jsx': 'vercel/styled-jsx',
280
+ 'linaria': 'callstack/linaria',
281
+ 'vanilla-extract': 'vanilla-extract-css/vanilla-extract',
282
+ 'stitches': 'stitchesjs/stitches',
283
+ 'twin.macro': 'ben-rogerson/twin.macro',
284
+ 'css-modules': 'css-modules/css-modules',
285
+ 'classnames': 'JedWatson/classnames',
286
+ 'clsx': 'lukeed/clsx',
287
+ 'unocss': 'unocss/unocss',
288
+ 'windicss': 'windicss/windicss',
289
+ 'twind': 'tw-in-js/twind',
290
+ 'goober': 'cristianbote/goober',
291
+ 'fela': 'robinweser/fela',
292
+ 'aphrodite': 'Khan/aphrodite',
293
+ 'jss': 'cssinjs/jss',
294
+
295
+ // === DOCUMENTATION (15) ===
296
+ 'jsdoc': 'jsdoc/jsdoc',
297
+ 'typedoc': 'TypeStrong/typedoc',
298
+ 'documentation': 'documentationjs/documentation',
299
+ 'esdoc': 'esdoc/esdoc',
300
+ 'docz': 'doczjs/docz',
301
+ 'react-docgen': 'reactjs/react-docgen',
302
+ 'compodoc': 'compodoc/compodoc',
303
+ 'api-documenter': 'microsoft/rushstack',
304
+ 'swagger-ui': 'swagger-api/swagger-ui',
305
+ 'redoc': 'Redocly/redoc',
306
+ 'slate': 'slatedocs/slate',
307
+ 'docsify': 'docsifyjs/docsify',
308
+ 'gitbook': 'GitbookIO/gitbook',
309
+ 'mkdocs': 'mkdocs/mkdocs',
310
+ 'sphinx': 'sphinx-doc/sphinx',
311
+
312
+ // === DATABASE & ORM (20) ===
313
+ 'mongoose': 'Automattic/mongoose',
314
+ 'sequelize': 'sequelize/sequelize',
315
+ 'typeorm': 'typeorm/typeorm',
316
+ 'knex': 'knex/knex',
317
+ 'objection': 'Vincit/objection.js',
318
+ 'bookshelf': 'bookshelf/bookshelf',
319
+ 'waterline': 'balderdashy/waterline',
320
+ 'mikro-orm': 'mikro-orm/mikro-orm',
321
+ 'drizzle-orm': 'drizzle-team/drizzle-orm',
322
+ 'kysely': 'kysely-org/kysely',
323
+ 'mongodb': 'mongodb/node-mongodb-native',
324
+ 'pg': 'brianc/node-postgres',
325
+ 'mysql': 'mysqljs/mysql',
326
+ 'mysql2': 'sidorares/node-mysql2',
327
+ 'sqlite3': 'TryGhost/node-sqlite3',
328
+ 'better-sqlite3': 'WiseLibs/better-sqlite3',
329
+ 'redis': 'redis/node-redis',
330
+ 'ioredis': 'redis/ioredis',
331
+ 'cassandra-driver': 'datastax/nodejs-driver',
332
+ 'neo4j-driver': 'neo4j/neo4j-javascript-driver',
333
+
334
+ // === GRAPHQL (15) ===
335
+ 'graphql': 'graphql/graphql-js',
336
+ '@graphql-tools/schema': 'ardatan/graphql-tools',
337
+ 'graphql-yoga': 'dotansimha/graphql-yoga',
338
+ 'apollo-server-express': 'apollographql/apollo-server',
339
+ 'mercurius': 'mercurius-js/mercurius',
340
+ 'type-graphql': 'MichalLytek/type-graphql',
341
+ 'nexus': 'graphql-nexus/nexus',
342
+ 'pothos': 'hayes/pothos',
343
+ 'graphql-request': 'jasonkuhrt/graphql-request',
344
+ 'graphql-tag': 'apollographql/graphql-tag',
345
+ 'dataloader': 'graphql/dataloader',
346
+ 'graphql-subscriptions': 'apollographql/graphql-subscriptions',
347
+ 'graphql-ws': 'enisdenjo/graphql-ws',
348
+ 'subscriptions-transport-ws': 'apollographql/subscriptions-transport-ws',
349
+ 'graphql-shield': 'dimatill/graphql-shield',
350
+
351
+ // === AUTHENTICATION (15) ===
352
+ 'passport': 'jaredhanson/passport',
353
+ 'jsonwebtoken': 'auth0/node-jsonwebtoken',
354
+ 'bcrypt': 'kelektiv/node.bcrypt.js',
355
+ 'bcryptjs': 'dcodeIO/bcrypt.js',
356
+ 'argon2': 'ranisalt/node-argon2',
357
+ 'oauth': 'ciaranj/node-oauth',
358
+ 'oauth2-server': 'oauthjs/node-oauth2-server',
359
+ 'next-auth': 'nextauthjs/next-auth',
360
+ 'lucia': 'lucia-auth/lucia',
361
+ 'iron-session': 'vvo/iron-session',
362
+ 'jose': 'panva/jose',
363
+ 'otplib': 'yeojz/otplib',
364
+ 'speakeasy': 'speakeasyjs/speakeasy',
365
+ 'node-2fa': 'jeremyscalpello/node-2fa',
366
+ 'Grant': 'simov/grant',
367
+
368
+ // === VALIDATION (10) ===
369
+ 'joi': 'hapijs/joi',
370
+ 'yup': 'jquense/yup',
371
+ 'zod': 'colinhacks/zod',
372
+ 'ajv': 'ajv-validator/ajv',
373
+ 'superstruct': 'ianstormtaylor/superstruct',
374
+ 'io-ts': 'gcanti/io-ts',
375
+ 'runtypes': 'pelotom/runtypes',
376
+ 'valibot': 'fabian-hiller/valibot',
377
+ 'typia': 'samchon/typia',
378
+ 'arktype': 'arktypeio/arktype',
379
+
380
+ // === REACTIVITY & SIGNALS (10) ===
381
+ '@preact/signals': 'preactjs/signals',
382
+ 'solid-js': 'solidjs/solid',
383
+ 'mobx': 'mobxjs/mobx',
384
+ 'vue': 'vuejs/core',
385
+ 'rxjs': 'ReactiveX/rxjs',
386
+ 'most': 'mostjs/core',
387
+ 'kefir': 'kefirjs/kefir',
388
+ 'bacon': 'baconjs/bacon.js',
389
+ 'flyd': 'paldepind/flyd',
390
+ 'callbag': 'callbag/callbag',
391
+
392
+ // === ANIMATION (10) ===
393
+ 'gsap': 'greensock/GSAP',
394
+ 'framer-motion': 'framer/motion',
395
+ 'react-spring': 'pmndrs/react-spring',
396
+ 'anime': 'juliangarnier/anime',
397
+ 'popmotion': 'Popmotion/popmotion',
398
+ 'velocity': 'julianshapiro/velocity',
399
+ 'mo-js': 'mojs/mojs',
400
+ 'lottie-web': 'airbnb/lottie-web',
401
+ 'three': 'mrdoob/three.js',
402
+ 'pixi.js': 'pixijs/pixijs',
403
+
404
+ // === CHARTS & DATA VIZ (15) ===
405
+ 'chart.js': 'chartjs/Chart.js',
406
+ 'd3': 'd3/d3',
407
+ 'recharts': 'recharts/recharts',
408
+ 'victory': 'FormidableLabs/victory',
409
+ 'nivo': 'plouc/nivo',
410
+ 'visx': 'airbnb/visx',
411
+ 'plotly.js': 'plotly/plotly.js',
412
+ 'highcharts': 'highcharts/highcharts',
413
+ 'echarts': 'apache/echarts',
414
+ 'apexcharts': 'apexcharts/apexcharts.js',
415
+ 'react-chartjs-2': 'reactchartjs/react-chartjs-2',
416
+ 'vue-chartjs': 'apertureless/vue-chartjs',
417
+ 'chartist': 'chartist-js/chartist',
418
+ 'c3': 'c3js/c3',
419
+ 'billboard.js': 'naver/billboard.js',
420
+
421
+ // === UI COMPONENT LIBRARIES (25) ===
422
+ '@mui/material': 'mui/material-ui',
423
+ 'antd': 'ant-design/ant-design',
424
+ 'react-bootstrap': 'react-bootstrap/react-bootstrap',
425
+ 'semantic-ui-react': 'Semantic-Org/Semantic-UI-React',
426
+ 'chakra-ui': 'chakra-ui/chakra-ui',
427
+ 'mantine': 'mantinedev/mantine',
428
+ 'blueprint': 'palantir/blueprint',
429
+ 'evergreen': 'segmentio/evergreen',
430
+ 'fluent-ui': 'microsoft/fluentui',
431
+ 'carbon-components-react': 'carbon-design-system/carbon',
432
+ 'grommet': 'grommet/grommet',
433
+ 'rebass': 'rebassjs/rebass',
434
+ 'theme-ui': 'system-ui/theme-ui',
435
+ 'radix-ui': 'radix-ui/primitives',
436
+ 'headlessui': 'tailwindlabs/headlessui',
437
+ 'daisyui': 'saadeghi/daisyui',
438
+ 'nextui': 'nextui-org/nextui',
439
+ 'shadcn-ui': 'shadcn-ui/ui',
440
+ 'primereact': 'primefaces/primereact',
441
+ 'vuetify': 'vuetifyjs/vuetify',
442
+ 'quasar': 'quasarframework/quasar',
443
+ 'element-plus': 'element-plus/element-plus',
444
+ 'naive-ui': 'tusen-ai/naive-ui',
445
+ 'arco-design': 'arco-design/arco-design',
446
+ 'semi-design': 'DouyinFE/semi-design',
447
+
448
+ // === FORM LIBRARIES (10) ===
449
+ 'react-hook-form': 'react-hook-form/react-hook-form',
450
+ 'formik': 'jaredpalmer/formik',
451
+ 'final-form': 'final-form/final-form',
452
+ 'redux-form': 'redux-form/redux-form',
453
+ 'react-final-form': 'final-form/react-final-form',
454
+ 'vee-validate': 'logaretm/vee-validate',
455
+ 'vue-formulate': 'wearebraid/vue-formulate',
456
+ 'unform': 'unform/unform',
457
+ 'informed': 'teslamotors/informed',
458
+ 'formsy-react': 'formsy/formsy-react',
459
+
460
+ // === ROUTING (10) ===
461
+ 'react-router': 'remix-run/react-router',
462
+ 'vue-router': 'vuejs/router',
463
+ 'wouter': 'molefrog/wouter',
464
+ 'reach-router': 'reach/router',
465
+ 'universal-router': 'kriasoft/universal-router',
466
+ 'navigo': 'krasimir/navigo',
467
+ 'page': 'visionmedia/page.js',
468
+ 'director': 'flatiron/director',
469
+ 'routify': 'roxiness/routify',
470
+ 'tanstack-router': 'TanStack/router',
471
+
472
+ // === FILE UPLOAD (8) ===
473
+ 'multer': 'expressjs/multer',
474
+ 'formidable': 'node-formidable/formidable',
475
+ 'busboy': 'mscdex/busboy',
476
+ 'multiparty': 'pillarjs/multiparty',
477
+ 'express-fileupload': 'richardgirges/express-fileupload',
478
+ 'react-dropzone': 'react-dropzone/react-dropzone',
479
+ 'uppy': 'transloadit/uppy',
480
+ 'filepond': 'pqina/filepond',
481
+
482
+ // === MARKDOWN & RICH TEXT (12) ===
483
+ 'markdown-it': 'markdown-it/markdown-it',
484
+ 'marked': 'markedjs/marked',
485
+ 'remark': 'remarkjs/remark',
486
+ 'rehype': 'rehypejs/rehype',
487
+ 'gray-matter': 'jonschlinkert/gray-matter',
488
+ 'unified': 'unifiedjs/unified',
489
+ 'mdx': 'mdx-js/mdx',
490
+ 'slate': 'ianstormtaylor/slate',
491
+ 'draft-js': 'facebook/draft-js',
492
+ 'prosemirror': 'ProseMirror/prosemirror',
493
+ 'tiptap': 'ueberdosis/tiptap',
494
+ 'quill': 'slab/quill',
495
+
496
+ // === IMAGE PROCESSING (10) ===
497
+ 'sharp': 'lovell/sharp',
498
+ 'jimp': 'jimp-dev/jimp',
499
+ 'canvas': 'Automattic/node-canvas',
500
+ 'gm': 'aheckmann/gm',
501
+ 'imagemin': 'imagemin/imagemin',
502
+ 'pica': 'nodeca/pica',
503
+ 'blurhash': 'woltapp/blurhash',
504
+ 'qrcode': 'soldair/node-qrcode',
505
+ 'svg-captcha': 'produck/svg-captcha',
506
+ 'pdf-lib': 'Hopding/pdf-lib',
507
+
508
+ // === EMAIL (8) ===
509
+ 'nodemailer': 'nodemailer/nodemailer',
510
+ 'emailjs': 'eleith/emailjs',
511
+ 'sendgrid': 'sendgrid/sendgrid-nodejs',
512
+ 'mailgun-js': 'mailgun/mailgun-js',
513
+ 'postmark': 'wildbit/postmark.js',
514
+ 'mjml': 'mjmlio/mjml',
515
+ 'react-email': 'resend/react-email',
516
+ 'handlebars': 'handlebars-lang/handlebars.js',
517
+
518
+ // === WEBSOCKETS (8) ===
519
+ 'ws': 'websockets/ws',
520
+ 'socket.io': 'socketio/socket.io',
521
+ 'sockjs': 'sockjs/sockjs-node',
522
+ 'uWebSockets.js': 'uNetworking/uWebSockets.js',
523
+ 'faye-websocket': 'faye/faye-websocket-node',
524
+ 'websocket': 'theturtle32/WebSocket-Node',
525
+ 'reconnecting-websocket': 'pladaria/reconnecting-websocket',
526
+ 'pusher-js': 'pusher/pusher-js',
527
+
528
+ // === COMPRESSION (6) ===
529
+ 'compression': 'expressjs/compression',
530
+ 'pako': 'nodeca/pako',
531
+ 'brotli': 'google/brotli',
532
+ 'zlib': 'nodejs/node',
533
+ 'tar': 'npm/node-tar',
534
+ 'archiver': 'archiverjs/node-archiver',
535
+
536
+ // === SECURITY (10) ===
537
+ 'helmet': 'helmetjs/helmet',
538
+ 'cors': 'expressjs/cors',
539
+ 'csurf': 'expressjs/csurf',
540
+ 'express-rate-limit': 'express-rate-limit/express-rate-limit',
541
+ 'express-validator': 'express-validator/express-validator',
542
+ 'sanitize-html': 'apostrophecms/sanitize-html',
543
+ 'dompurify': 'cure53/DOMPurify',
544
+ 'xss': 'leizongmin/js-xss',
545
+ 'hpp': 'analog-nico/hpp',
546
+ 'toobusy-js': 'STRML/node-toobusy',
547
+
548
+ // === CLI TOOLS (15) ===
549
+ 'commander': 'tj/commander.js',
550
+ 'yargs': 'yargs/yargs',
551
+ 'inquirer': 'SBoudrias/Inquirer.js',
552
+ 'prompts': 'terkelg/prompts',
553
+ 'enquirer': 'enquirer/enquirer',
554
+ 'ora': 'sindresorhus/ora',
555
+ 'chalk': 'chalk/chalk',
556
+ 'boxen': 'sindresorhus/boxen',
557
+ 'figures': 'sindresorhus/figures',
558
+ 'cli-table3': 'cli-table/cli-table3',
559
+ 'progress': 'visionmedia/node-progress',
560
+ 'listr': 'SamVerschueren/listr',
561
+ 'blessed': 'chjj/blessed',
562
+ 'ink': 'vadimdemedes/ink',
563
+ 'oclif': 'oclif/oclif',
564
+
565
+ // === PERFORMANCE & MONITORING (10) ===
566
+ 'clinic': 'clinicjs/node-clinic',
567
+ 'autocannon': 'mcollina/autocannon',
568
+ 'benchmark': 'bestiejs/benchmark.js',
569
+ 'prom-client': 'siimon/prom-client',
570
+ 'hot-shots': 'brightcove/hot-shots',
571
+ 'node-statsd': 'sivy/node-statsd',
572
+ 'lightship': 'gajus/lightship',
573
+ 'express-status-monitor': 'RafalWilinski/express-status-monitor',
574
+ 'appmetrics': 'RuntimeTools/appmetrics',
575
+ 'newrelic': 'newrelic/node-newrelic',
576
+
577
+ // === MISCELLANEOUS POPULAR (20) ===
578
+ 'cheerio': 'cheeriojs/cheerio',
579
+ 'jsdom': 'jsdom/jsdom',
580
+ 'xml2js': 'Leonidas-from-XIV/node-xml2js',
581
+ 'csv-parse': 'adaltas/node-csv',
582
+ 'papaparse': 'mholt/PapaParse',
583
+ 'pdf-parse': 'modesty/pdf-parse',
584
+ 'docxtemplater': 'open-xml-templating/docxtemplater',
585
+ 'slugify': 'simov/slugify',
586
+ 'url-slug': 'stldo/url-slug',
587
+ 'helmet': 'helmetjs/helmet',
588
+ 'cookie-parser': 'expressjs/cookie-parser',
589
+ 'body-parser': 'expressjs/body-parser',
590
+ 'serve-static': 'expressjs/serve-static',
591
+ 'serve-favicon': 'expressjs/serve-favicon',
592
+ 'method-override': 'expressjs/method-override',
593
+ 'connect': 'senchalabs/connect',
594
+ 'path-to-regexp': 'pillarjs/path-to-regexp',
595
+ 'qs': 'ljharb/qs',
596
+ 'mime': 'broofa/mime',
597
+ 'content-type': 'jshttp/content-type',
598
+ };
599
+
600
+ /**
601
+ * Fetch GitHub issues for a package
602
+ */
603
+ async function fetchGitHubIssues(packageName) {
604
+ const repo = TRACKED_REPOS[packageName];
605
+
606
+ if (!repo) {
607
+ return null; // Not tracked
608
+ }
609
+
610
+ try {
611
+ const data = await makeGitHubRequest(`/repos/${repo}/issues`, {
612
+ state: 'open',
613
+ per_page: 100,
614
+ labels: 'bug'
615
+ });
616
+
617
+ return analyzeIssues(data, packageName);
618
+ } catch (error) {
619
+ console.error(`GitHub API error for ${packageName}:`, error.message);
620
+ return null;
621
+ }
622
+ }
623
+
624
+ /**
625
+ * Make GitHub API request
626
+ */
627
+ function makeGitHubRequest(path, params = {}) {
628
+ return new Promise((resolve, reject) => {
629
+ const queryString = Object.entries(params)
630
+ .map(([key, val]) => `${key}=${encodeURIComponent(val)}`)
631
+ .join('&');
632
+
633
+ const options = {
634
+ hostname: 'api.github.com',
635
+ path: `${path}?${queryString}`,
636
+ method: 'GET',
637
+ headers: {
638
+ 'User-Agent': 'DevCompass',
639
+ 'Accept': 'application/vnd.github.v3+json'
640
+ }
641
+ };
642
+
643
+ const req = https.request(options, (res) => {
644
+ let data = '';
645
+
646
+ res.on('data', (chunk) => {
647
+ data += chunk;
648
+ });
649
+
650
+ res.on('end', () => {
651
+ if (res.statusCode === 200) {
652
+ try {
653
+ resolve(JSON.parse(data));
654
+ } catch (error) {
655
+ reject(new Error('Failed to parse GitHub response'));
656
+ }
657
+ } else {
658
+ reject(new Error(`GitHub API returned ${res.statusCode}`));
659
+ }
660
+ });
661
+ });
662
+
663
+ req.on('error', reject);
664
+ req.end();
665
+ });
666
+ }
667
+
668
+ /**
669
+ * Analyze issues to detect trends
670
+ */
671
+ function analyzeIssues(issues, packageName) {
672
+ const now = Date.now();
673
+ const day = 24 * 60 * 60 * 1000;
674
+
675
+ // Count issues by recency
676
+ const last7Days = issues.filter(i =>
677
+ (now - new Date(i.created_at).getTime()) < 7 * day
678
+ ).length;
679
+
680
+ const last30Days = issues.filter(i =>
681
+ (now - new Date(i.created_at).getTime()) < 30 * day
682
+ ).length;
683
+
684
+ // Detect critical issues (high priority labels)
685
+ const criticalLabels = ['critical', 'security', 'regression', 'breaking'];
686
+ const criticalIssues = issues.filter(issue =>
687
+ issue.labels.some(label =>
688
+ criticalLabels.some(critical =>
689
+ label.name.toLowerCase().includes(critical)
690
+ )
691
+ )
692
+ );
693
+
694
+ // Calculate risk score
695
+ let riskScore = 0;
696
+ if (last7Days > 15) riskScore += 3;
697
+ else if (last7Days > 10) riskScore += 2;
698
+ else if (last7Days > 5) riskScore += 1;
699
+
700
+ if (criticalIssues.length > 5) riskScore += 2;
701
+ else if (criticalIssues.length > 2) riskScore += 1;
702
+
703
+ return {
704
+ package: packageName,
705
+ totalIssues: issues.length,
706
+ last7Days,
707
+ last30Days,
708
+ criticalIssues: criticalIssues.length,
709
+ riskScore,
710
+ trend: determineTrend(last7Days, last30Days),
711
+ repoUrl: `https://github.com/${TRACKED_REPOS[packageName]}`
712
+ };
713
+ }
714
+
715
+ /**
716
+ * Determine trend (increasing/stable/decreasing)
717
+ */
718
+ function determineTrend(last7Days, last30Days) {
719
+ const weeklyAverage = last30Days / 4;
720
+
721
+ if (last7Days > weeklyAverage * 1.5) {
722
+ return 'increasing';
723
+ } else if (last7Days < weeklyAverage * 0.5) {
724
+ return 'decreasing';
725
+ } else {
726
+ return 'stable';
727
+ }
728
+ }
729
+
730
+ /**
731
+ * Check GitHub issues for multiple packages (OPTIMIZED)
732
+ */
733
+ async function checkGitHubIssues(packages) {
734
+ const results = [];
735
+ const packageNames = Object.keys(packages);
736
+
737
+ // Only check packages that are tracked AND installed
738
+ const trackedAndInstalled = packageNames.filter(pkg => TRACKED_REPOS[pkg]);
739
+
740
+ if (trackedAndInstalled.length === 0) {
741
+ return results;
742
+ }
743
+
744
+ // Process in batches to avoid rate limits
745
+ for (const packageName of trackedAndInstalled) {
746
+ const result = await fetchGitHubIssues(packageName);
747
+
748
+ if (result) {
749
+ results.push(result);
750
+ }
751
+
752
+ // Rate limit: wait 1 second between requests
753
+ await new Promise(resolve => setTimeout(resolve, 1000));
754
+ }
755
+
756
+ return results;
757
+ }
758
+
759
+ /**
760
+ * Get total count of tracked packages
761
+ */
762
+ function getTrackedPackageCount() {
763
+ return Object.keys(TRACKED_REPOS).length;
764
+ }
765
+
766
+ /**
767
+ * Get tracked packages by category (for documentation)
768
+ */
769
+ function getTrackedPackagesByCategory() {
770
+ return {
771
+ 'Web Frameworks': 25,
772
+ 'Meta Frameworks': 15,
773
+ 'Mobile Frameworks': 10,
774
+ 'Backend Frameworks': 20,
775
+ 'Build Tools': 25,
776
+ 'Testing': 25,
777
+ 'Linters & Formatters': 15,
778
+ 'TypeScript Tools': 15,
779
+ 'State Management': 20,
780
+ 'HTTP Clients': 20,
781
+ 'Utilities': 50,
782
+ 'CSS & Styling': 25,
783
+ 'Documentation': 15,
784
+ 'Database & ORM': 20,
785
+ 'GraphQL': 15,
786
+ 'Authentication': 15,
787
+ 'Validation': 10,
788
+ 'Reactivity': 10,
789
+ 'Animation': 10,
790
+ 'Charts & Visualization': 15,
791
+ 'UI Libraries': 25,
792
+ 'Forms': 10,
793
+ 'Routing': 10,
794
+ 'File Upload': 8,
795
+ 'Markdown & Rich Text': 12,
796
+ 'Image Processing': 10,
797
+ 'Email': 8,
798
+ 'WebSockets': 8,
799
+ 'Compression': 6,
800
+ 'Security': 10,
801
+ 'CLI Tools': 15,
802
+ 'Performance': 10,
803
+ 'Miscellaneous': 20
804
+ };
805
+ }
806
+
807
+ module.exports = {
808
+ checkGitHubIssues,
809
+ fetchGitHubIssues,
810
+ TRACKED_REPOS,
811
+ getTrackedPackageCount,
812
+ getTrackedPackagesByCategory
813
+ };