verdaccio-stats 0.4.0 → 0.4.1

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.md CHANGED
@@ -60,6 +60,20 @@ middlewares:
60
60
 
61
61
  Note: SQLite is the default database type, but for performance reason, it is not recommended for production use. For production, consider using MySQL, PostgreSQL, MariaDB, or MSSQL.
62
62
 
63
+ You'll also need to ensure that the appropriate database driver is installed. For example, if you're using MySQL, you would need to install `mysql2`:
64
+
65
+ ```bash
66
+ npm install -g mysql2
67
+ ```
68
+
69
+ For other databases, install the corresponding driver:
70
+
71
+ - PostgreSQL: `pg` and `pg-hstore`
72
+ - MariaDB: `mariadb`
73
+ - MSSQL: `tedious`
74
+ - SQLite: `sqlite3` (not recommended for production)
75
+ - Oracle: `oracledb`
76
+
63
77
  ### Configuration Options
64
78
 
65
79
  | Option | Type | Default | Description |
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var node_module = require('node:module');
5
+ var ms = require('ms');
6
6
  var zod = require('zod');
7
7
  var path = require('node:path');
8
8
  var dayjs = require('dayjs');
@@ -12,14 +12,12 @@ var weekOfYear = require('dayjs/plugin/weekOfYear');
12
12
  var weekYear = require('dayjs/plugin/weekYear');
13
13
  var buildDebug = require('debug');
14
14
  var core = require('@verdaccio/core');
15
- var tslib = require('tslib');
16
15
  var sequelizeTypescript = require('sequelize-typescript');
17
16
  var sequelize = require('sequelize');
18
17
  var umzug = require('umzug');
19
18
 
20
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
21
19
  var name = "verdaccio-stats";
22
- var version = "0.4.0";
20
+ var version = "0.4.1";
23
21
 
24
22
  const plugin = {
25
23
  name,
@@ -148,8 +146,6 @@ async function interopDefault(m) {
148
146
  return resolved.default ?? resolved;
149
147
  }
150
148
 
151
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
152
- const ms = require$1("ms");
153
149
  const statsConfig = zod.z
154
150
  .object({
155
151
  dialect: zod.z
@@ -212,7 +208,7 @@ const statsConfig = zod.z
212
208
  const parsed = ms(flushInterval);
213
209
  if (typeof parsed !== "number" || !Number.isFinite(parsed) || parsed < 0) {
214
210
  ctx.addIssue({
215
- code: zod.z.ZodIssueCode.custom,
211
+ code: "custom",
216
212
  message: "Flush interval must be a valid duration string or a non-negative number (ms)",
217
213
  path: ["flush-interval"],
218
214
  });
@@ -221,7 +217,7 @@ const statsConfig = zod.z
221
217
  if (data.dialect === "sqlite") {
222
218
  if (typeof data.database !== "string" || !data.database) {
223
219
  ctx.addIssue({
224
- code: zod.z.ZodIssueCode.custom,
220
+ code: "custom",
225
221
  message: "SQLite storage path is required and must be a non-empty string",
226
222
  path: ["storage"],
227
223
  });
@@ -232,7 +228,7 @@ const statsConfig = zod.z
232
228
  for (const key of ["name", "username", "password", "host", "port"]) {
233
229
  if (!data.database[key]) {
234
230
  ctx.addIssue({
235
- code: zod.z.ZodIssueCode.custom,
231
+ code: "custom",
236
232
  message: `Database ${key} is required for non-SQLite dialects`,
237
233
  path: ["database", key],
238
234
  });
@@ -241,7 +237,7 @@ const statsConfig = zod.z
241
237
  }
242
238
  else {
243
239
  ctx.addIssue({
244
- code: zod.z.ZodIssueCode.custom,
240
+ code: "custom",
245
241
  message: "Database configuration is required for non-SQLite dialects",
246
242
  path: ["database"],
247
243
  });
@@ -258,8 +254,12 @@ class ParsedPluginConfig {
258
254
  this.config = statsConfig.parse(config);
259
255
  }
260
256
  catch (err) {
261
- const fieldErrors = err.flatten().fieldErrors;
262
- logger.error({ errors: fieldErrors }, "Invalid config for verdaccio stats plugin, @{errors}");
257
+ const flattened = zod.z.flattenError(err);
258
+ const errorMessages = [
259
+ ...flattened.formErrors,
260
+ ...Object.entries(flattened.fieldErrors).flatMap(([key, errs]) => (errs ?? []).map((e) => `[${key}] ${e}`)),
261
+ ];
262
+ logger.error({ errors: errorMessages.join("\n") }, "Invalid config for verdaccio stats plugin:\n@{errors}");
263
263
  process.exit(1);
264
264
  }
265
265
  }
@@ -419,48 +419,81 @@ class Stats {
419
419
  };
420
420
  }
421
421
 
422
+ /******************************************************************************
423
+ Copyright (c) Microsoft Corporation.
424
+
425
+ Permission to use, copy, modify, and/or distribute this software for any
426
+ purpose with or without fee is hereby granted.
427
+
428
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
429
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
430
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
431
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
432
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
433
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
434
+ PERFORMANCE OF THIS SOFTWARE.
435
+ ***************************************************************************** */
436
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
437
+
438
+
439
+ function __decorate(decorators, target, key, desc) {
440
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
441
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
442
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
443
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
444
+ }
445
+
446
+ function __metadata(metadataKey, metadataValue) {
447
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
448
+ }
449
+
450
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
451
+ var e = new Error(message);
452
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
453
+ };
454
+
422
455
  class StatsModel extends sequelizeTypescript.Model {
423
456
  }
424
- tslib.__decorate([
457
+ __decorate([
425
458
  sequelizeTypescript.Column({
426
459
  type: sequelizeTypescript.DataType.INTEGER,
427
460
  allowNull: false,
428
461
  defaultValue: 0,
429
462
  }),
430
- tslib.__metadata("design:type", Number)
463
+ __metadata("design:type", Number)
431
464
  ], StatsModel.prototype, "count", void 0);
432
- tslib.__decorate([
465
+ __decorate([
433
466
  sequelizeTypescript.ForeignKey(() => Package),
434
467
  sequelizeTypescript.Column({
435
468
  type: sequelizeTypescript.DataType.INTEGER,
436
469
  allowNull: false,
437
470
  }),
438
- tslib.__metadata("design:type", Number)
471
+ __metadata("design:type", Number)
439
472
  ], StatsModel.prototype, "packageId", void 0);
440
- tslib.__decorate([
473
+ __decorate([
441
474
  sequelizeTypescript.Column({
442
475
  type: sequelizeTypescript.DataType.STRING(20),
443
476
  allowNull: false,
444
477
  }),
445
- tslib.__metadata("design:type", String)
478
+ __metadata("design:type", String)
446
479
  ], StatsModel.prototype, "periodType", void 0);
447
- tslib.__decorate([
480
+ __decorate([
448
481
  sequelizeTypescript.Column({
449
482
  type: sequelizeTypescript.DataType.STRING(20),
450
483
  allowNull: false,
451
484
  }),
452
- tslib.__metadata("design:type", String)
485
+ __metadata("design:type", String)
453
486
  ], StatsModel.prototype, "periodValue", void 0);
454
- tslib.__decorate([
487
+ __decorate([
455
488
  sequelizeTypescript.BelongsTo(() => Package, {
456
489
  targetKey: "id",
457
490
  foreignKey: "packageId",
458
491
  }),
459
- tslib.__metadata("design:type", Object)
492
+ __metadata("design:type", Object)
460
493
  ], StatsModel.prototype, "package", void 0);
461
494
  let DownloadStats = class DownloadStats extends StatsModel {
462
495
  };
463
- DownloadStats = tslib.__decorate([
496
+ DownloadStats = __decorate([
464
497
  sequelizeTypescript.Table({
465
498
  tableName: "download_stats",
466
499
  timestamps: true,
@@ -475,7 +508,7 @@ DownloadStats = tslib.__decorate([
475
508
  ], DownloadStats);
476
509
  let ManifestViewStats = class ManifestViewStats extends StatsModel {
477
510
  };
478
- ManifestViewStats = tslib.__decorate([
511
+ ManifestViewStats = __decorate([
479
512
  sequelizeTypescript.Table({
480
513
  tableName: "manifest_view_stats",
481
514
  timestamps: true,
@@ -494,34 +527,34 @@ let Package = class Package extends sequelizeTypescript.Model {
494
527
  return `${this.getDataValue("name")}@${this.getDataValue("version")}`;
495
528
  }
496
529
  };
497
- tslib.__decorate([
530
+ __decorate([
498
531
  sequelizeTypescript.Column({
499
532
  type: sequelizeTypescript.DataType.STRING(100),
500
533
  allowNull: false,
501
534
  }),
502
- tslib.__metadata("design:type", String)
535
+ __metadata("design:type", String)
503
536
  ], Package.prototype, "name", void 0);
504
- tslib.__decorate([
537
+ __decorate([
505
538
  sequelizeTypescript.Column({
506
539
  type: sequelizeTypescript.DataType.STRING(50),
507
540
  allowNull: false,
508
541
  }),
509
- tslib.__metadata("design:type", String)
542
+ __metadata("design:type", String)
510
543
  ], Package.prototype, "version", void 0);
511
- tslib.__decorate([
544
+ __decorate([
512
545
  sequelizeTypescript.Column(sequelizeTypescript.DataType.VIRTUAL(sequelizeTypescript.DataType.STRING, ["name", "version"])),
513
- tslib.__metadata("design:type", Object),
514
- tslib.__metadata("design:paramtypes", [])
546
+ __metadata("design:type", Object),
547
+ __metadata("design:paramtypes", [])
515
548
  ], Package.prototype, "displayName", null);
516
- tslib.__decorate([
549
+ __decorate([
517
550
  sequelizeTypescript.HasMany(() => DownloadStats, { sourceKey: "id", foreignKey: "packageId" }),
518
- tslib.__metadata("design:type", Object)
551
+ __metadata("design:type", Object)
519
552
  ], Package.prototype, "downloadStats", void 0);
520
- tslib.__decorate([
553
+ __decorate([
521
554
  sequelizeTypescript.HasMany(() => ManifestViewStats, { sourceKey: "id", foreignKey: "packageId" }),
522
- tslib.__metadata("design:type", Object)
555
+ __metadata("design:type", Object)
523
556
  ], Package.prototype, "manifestViewStats", void 0);
524
- Package = tslib.__decorate([
557
+ Package = __decorate([
525
558
  sequelizeTypescript.Table({
526
559
  tableName: "packages",
527
560
  timestamps: true,
package/lib/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { createRequire } from 'node:module';
1
+ import ms from 'ms';
2
2
  import { z } from 'zod';
3
3
  import path from 'node:path';
4
4
  import dayjs, { extend } from 'dayjs';
@@ -8,13 +8,12 @@ import weekOfYear from 'dayjs/plugin/weekOfYear';
8
8
  import weekYear from 'dayjs/plugin/weekYear';
9
9
  import buildDebug from 'debug';
10
10
  import { tarballUtils } from '@verdaccio/core';
11
- import { __decorate, __metadata } from 'tslib';
12
11
  import { Column, DataType, ForeignKey, BelongsTo, Table, Model, HasMany, Sequelize } from 'sequelize-typescript';
13
12
  import { Op } from 'sequelize';
14
13
  import { Umzug, SequelizeStorage } from 'umzug';
15
14
 
16
15
  var name = "verdaccio-stats";
17
- var version = "0.4.0";
16
+ var version = "0.4.1";
18
17
 
19
18
  const plugin = {
20
19
  name,
@@ -143,8 +142,6 @@ async function interopDefault(m) {
143
142
  return resolved.default ?? resolved;
144
143
  }
145
144
 
146
- const require$1 = createRequire(import.meta.url);
147
- const ms = require$1("ms");
148
145
  const statsConfig = z
149
146
  .object({
150
147
  dialect: z
@@ -207,7 +204,7 @@ const statsConfig = z
207
204
  const parsed = ms(flushInterval);
208
205
  if (typeof parsed !== "number" || !Number.isFinite(parsed) || parsed < 0) {
209
206
  ctx.addIssue({
210
- code: z.ZodIssueCode.custom,
207
+ code: "custom",
211
208
  message: "Flush interval must be a valid duration string or a non-negative number (ms)",
212
209
  path: ["flush-interval"],
213
210
  });
@@ -216,7 +213,7 @@ const statsConfig = z
216
213
  if (data.dialect === "sqlite") {
217
214
  if (typeof data.database !== "string" || !data.database) {
218
215
  ctx.addIssue({
219
- code: z.ZodIssueCode.custom,
216
+ code: "custom",
220
217
  message: "SQLite storage path is required and must be a non-empty string",
221
218
  path: ["storage"],
222
219
  });
@@ -227,7 +224,7 @@ const statsConfig = z
227
224
  for (const key of ["name", "username", "password", "host", "port"]) {
228
225
  if (!data.database[key]) {
229
226
  ctx.addIssue({
230
- code: z.ZodIssueCode.custom,
227
+ code: "custom",
231
228
  message: `Database ${key} is required for non-SQLite dialects`,
232
229
  path: ["database", key],
233
230
  });
@@ -236,7 +233,7 @@ const statsConfig = z
236
233
  }
237
234
  else {
238
235
  ctx.addIssue({
239
- code: z.ZodIssueCode.custom,
236
+ code: "custom",
240
237
  message: "Database configuration is required for non-SQLite dialects",
241
238
  path: ["database"],
242
239
  });
@@ -253,8 +250,12 @@ class ParsedPluginConfig {
253
250
  this.config = statsConfig.parse(config);
254
251
  }
255
252
  catch (err) {
256
- const fieldErrors = err.flatten().fieldErrors;
257
- logger.error({ errors: fieldErrors }, "Invalid config for verdaccio stats plugin, @{errors}");
253
+ const flattened = z.flattenError(err);
254
+ const errorMessages = [
255
+ ...flattened.formErrors,
256
+ ...Object.entries(flattened.fieldErrors).flatMap(([key, errs]) => (errs ?? []).map((e) => `[${key}] ${e}`)),
257
+ ];
258
+ logger.error({ errors: errorMessages.join("\n") }, "Invalid config for verdaccio stats plugin:\n@{errors}");
258
259
  process.exit(1);
259
260
  }
260
261
  }
@@ -414,6 +415,39 @@ class Stats {
414
415
  };
415
416
  }
416
417
 
418
+ /******************************************************************************
419
+ Copyright (c) Microsoft Corporation.
420
+
421
+ Permission to use, copy, modify, and/or distribute this software for any
422
+ purpose with or without fee is hereby granted.
423
+
424
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
425
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
426
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
427
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
428
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
429
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
430
+ PERFORMANCE OF THIS SOFTWARE.
431
+ ***************************************************************************** */
432
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
433
+
434
+
435
+ function __decorate(decorators, target, key, desc) {
436
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
437
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
438
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
439
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
440
+ }
441
+
442
+ function __metadata(metadataKey, metadataValue) {
443
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
444
+ }
445
+
446
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
447
+ var e = new Error(message);
448
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
449
+ };
450
+
417
451
  class StatsModel extends Model {
418
452
  }
419
453
  __decorate([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "verdaccio-stats",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "The stats plugin for Verdaccio",
5
5
  "main": "./lib/index.js",
6
6
  "module": "./lib/index.mjs",
@@ -17,18 +17,19 @@
17
17
  "author": "Xingwang Liao<kuoruan@gmail.com>",
18
18
  "license": "MIT",
19
19
  "devDependencies": {
20
- "@eslint/js": "^9.39.2",
20
+ "@eslint/js": "^9.39.3",
21
21
  "@rollup/plugin-commonjs": "^29.0.0",
22
22
  "@rollup/plugin-json": "^6.1.0",
23
23
  "@rollup/plugin-node-resolve": "^16.0.3",
24
24
  "@rollup/plugin-replace": "^6.0.3",
25
25
  "@rollup/plugin-typescript": "^12.3.0",
26
+ "@tsconfig/node18": "^18.2.6",
26
27
  "@types/debug": "^4.1.12",
27
28
  "@types/express": "^4.17.25",
28
29
  "@types/ms": "^2.1.0",
29
30
  "@verdaccio/types": "13.0.0-next-8.10",
30
31
  "cross-env": "^10.1.0",
31
- "eslint": "^9.39.2",
32
+ "eslint": "^9.39.3",
32
33
  "eslint-config-prettier": "^10.1.8",
33
34
  "eslint-import-resolver-next": "^0.6.0",
34
35
  "eslint-plugin-import-x": "^4.16.1",
@@ -37,17 +38,17 @@
37
38
  "eslint-plugin-unicorn": "^63.0.0",
38
39
  "express": "^4.22.1",
39
40
  "globals": "^17.3.0",
40
- "pg": "^8.18.0",
41
+ "pg": "^8.19.0",
41
42
  "pg-hstore": "^2.3.4",
42
43
  "prettier": "^3.8.1",
43
- "rimraf": "^6.1.2",
44
- "rollup": "^4.57.1",
44
+ "rimraf": "^6.1.3",
45
+ "rollup": "^4.59.0",
45
46
  "rollup-plugin-node-externals": "^8.1.2",
46
47
  "sqlite3": "^5.1.7",
47
48
  "tslib": "^2.8.1",
48
49
  "typescript": "^5.9.3",
49
- "typescript-eslint": "^8.55.0",
50
- "verdaccio": "^6.2.5",
50
+ "typescript-eslint": "^8.56.1",
51
+ "verdaccio": "^6.2.9",
51
52
  "verdaccio-stats": "file:",
52
53
  "vitest": "^4.0.18"
53
54
  },
@@ -60,7 +61,7 @@
60
61
  "dependencies": {
61
62
  "@adminjs/express": "^6.1.1",
62
63
  "@adminjs/sequelize": "^4.1.1",
63
- "@verdaccio/core": "8.0.0-next-8.29",
64
+ "@verdaccio/core": "8.0.0-next-8.30",
64
65
  "adminjs": "^7.8.17",
65
66
  "dayjs": "^1.11.19",
66
67
  "debug": "^4.4.3",