@verdaccio/package-filter 13.0.4 → 13.1.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/build/_virtual/_rolldown/runtime.js +23 -0
- package/build/config/parser.d.ts +2 -0
- package/build/config/parser.js +56 -0
- package/build/config/parser.js.map +1 -0
- package/build/config/parser.mjs +54 -0
- package/build/config/parser.mjs.map +1 -0
- package/build/config/types.d.ts +39 -0
- package/build/filtering/matcher.d.ts +8 -0
- package/build/filtering/matcher.js +71 -0
- package/build/filtering/matcher.js.map +1 -0
- package/build/filtering/matcher.mjs +69 -0
- package/build/filtering/matcher.mjs.map +1 -0
- package/build/filtering/packageVersion.d.ts +20 -0
- package/build/filtering/packageVersion.js +129 -0
- package/build/filtering/packageVersion.js.map +1 -0
- package/build/filtering/packageVersion.mjs +127 -0
- package/build/filtering/packageVersion.mjs.map +1 -0
- package/build/filtering/publishDate.d.ts +6 -0
- package/build/filtering/publishDate.js +33 -0
- package/build/filtering/publishDate.js.map +1 -0
- package/build/filtering/publishDate.mjs +31 -0
- package/build/filtering/publishDate.mjs.map +1 -0
- package/build/filtering/types.d.ts +24 -0
- package/build/filtering/types.js +11 -0
- package/build/filtering/types.js.map +1 -0
- package/build/filtering/types.mjs +11 -0
- package/build/filtering/types.mjs.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.js +3 -490
- package/build/index.js.map +1 -1
- package/build/index.mjs +7 -0
- package/build/index.mjs.map +1 -0
- package/build/packageFilter.d.ts +10 -0
- package/build/packageFilter.js +86 -0
- package/build/packageFilter.js.map +1 -0
- package/build/packageFilter.mjs +84 -0
- package/build/packageFilter.mjs.map +1 -0
- package/build/utils/jsonUtils.d.ts +1 -0
- package/build/utils/jsonUtils.js +11 -0
- package/build/utils/jsonUtils.js.map +1 -0
- package/build/utils/jsonUtils.mjs +11 -0
- package/build/utils/jsonUtils.mjs.map +1 -0
- package/build/utils/manifestUtils.d.ts +36 -0
- package/build/utils/manifestUtils.js +129 -0
- package/build/utils/manifestUtils.js.map +1 -0
- package/build/utils/manifestUtils.mjs +121 -0
- package/build/utils/manifestUtils.mjs.map +1 -0
- package/package.json +26 -11
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const require_runtime = require("./_virtual/_rolldown/runtime.js");
|
|
2
|
+
const require_parser = require("./config/parser.js");
|
|
3
|
+
const require_packageVersion = require("./filtering/packageVersion.js");
|
|
4
|
+
const require_publishDate = require("./filtering/publishDate.js");
|
|
5
|
+
const require_jsonUtils = require("./utils/jsonUtils.js");
|
|
6
|
+
const require_manifestUtils = require("./utils/manifestUtils.js");
|
|
7
|
+
let debug = require("debug");
|
|
8
|
+
debug = require_runtime.__toESM(debug);
|
|
9
|
+
let _verdaccio_core = require("@verdaccio/core");
|
|
10
|
+
//#region src/packageFilter.ts
|
|
11
|
+
var debug$1 = (0, debug.default)("verdaccio:plugin:package-filter");
|
|
12
|
+
var PackageFilterPlugin = class extends _verdaccio_core.pluginUtils.Plugin {
|
|
13
|
+
config;
|
|
14
|
+
parsedConfig;
|
|
15
|
+
logger;
|
|
16
|
+
constructor(config, options) {
|
|
17
|
+
super(config, options);
|
|
18
|
+
this.config = config ?? {};
|
|
19
|
+
this.logger = options.logger;
|
|
20
|
+
this.parsedConfig = require_parser.parseConfig(this.config);
|
|
21
|
+
debug$1("plugin loaded: block rules: %d, allow rules: %d", this.parsedConfig.blockRules.size, this.parsedConfig.allowRules.size);
|
|
22
|
+
this.logger.debug({ config: JSON.stringify(this.parsedConfig, require_jsonUtils.jsonLogReplacer) }, "package-filter loaded with config: @{config}");
|
|
23
|
+
this.logger.trace({
|
|
24
|
+
blockRules: this.parsedConfig.blockRules.size,
|
|
25
|
+
allowRules: this.parsedConfig.allowRules.size
|
|
26
|
+
}, "package-filter plugin initialized: @{blockRules} block rules, @{allowRules} allow rules");
|
|
27
|
+
if (this.parsedConfig.dateThreshold) {
|
|
28
|
+
debug$1("date threshold: %s", this.parsedConfig.dateThreshold.toISOString());
|
|
29
|
+
this.logger.trace({ dateThreshold: this.parsedConfig.dateThreshold.toISOString() }, "package-filter date threshold: @{dateThreshold}");
|
|
30
|
+
}
|
|
31
|
+
if (this.parsedConfig.minAgeMs) {
|
|
32
|
+
const minAgeDays = this.parsedConfig.minAgeMs / (1440 * 60 * 1e3);
|
|
33
|
+
debug$1("min age: %d days", minAgeDays);
|
|
34
|
+
this.logger.trace({ minAgeDays }, "package-filter min age: @{minAgeDays} days");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async filter_metadata(manifest) {
|
|
38
|
+
const { dateThreshold, minAgeMs, blockRules, allowRules } = this.parsedConfig;
|
|
39
|
+
const versionCount = Object.keys(manifest.versions ?? {}).length;
|
|
40
|
+
debug$1("filtering manifest for %s (%d versions)", manifest.name, versionCount);
|
|
41
|
+
this.logger.trace({
|
|
42
|
+
name: manifest.name,
|
|
43
|
+
versionCount
|
|
44
|
+
}, "package-filter processing @{name} (@{versionCount} versions)");
|
|
45
|
+
let earliestDateThreshold = null;
|
|
46
|
+
if (minAgeMs) earliestDateThreshold = new Date(Date.now() - minAgeMs);
|
|
47
|
+
if (dateThreshold && (!earliestDateThreshold || dateThreshold < earliestDateThreshold)) earliestDateThreshold = dateThreshold;
|
|
48
|
+
if (blockRules.size === 0 && !earliestDateThreshold) {
|
|
49
|
+
debug$1("no filters configured, returning manifest untouched for %s", manifest.name);
|
|
50
|
+
return manifest;
|
|
51
|
+
}
|
|
52
|
+
let newManifest = require_manifestUtils.getManifestClone(manifest);
|
|
53
|
+
if (blockRules.size > 0) newManifest = require_packageVersion.filterBlockedVersions(newManifest, blockRules, allowRules, this.logger);
|
|
54
|
+
if (earliestDateThreshold) {
|
|
55
|
+
debug$1("applying date filter for %s, threshold: %s", manifest.name, earliestDateThreshold.toISOString());
|
|
56
|
+
this.logger.trace({
|
|
57
|
+
name: manifest.name,
|
|
58
|
+
threshold: earliestDateThreshold.toISOString()
|
|
59
|
+
}, "applying date filter for @{name}, cutoff: @{threshold}");
|
|
60
|
+
newManifest = require_publishDate.filterVersionsByPublishDate(newManifest, earliestDateThreshold, allowRules);
|
|
61
|
+
}
|
|
62
|
+
const filteredCount = Object.keys(newManifest.versions).length;
|
|
63
|
+
const removedCount = versionCount - filteredCount;
|
|
64
|
+
if (removedCount > 0 || newManifest.readme !== manifest.readme) {
|
|
65
|
+
require_manifestUtils.cleanupTags(newManifest);
|
|
66
|
+
require_manifestUtils.setupLatestTag(newManifest);
|
|
67
|
+
require_manifestUtils.cleanupTime(newManifest);
|
|
68
|
+
require_manifestUtils.setupCreatedAndModified(newManifest);
|
|
69
|
+
require_manifestUtils.cleanupDistFiles(newManifest);
|
|
70
|
+
}
|
|
71
|
+
if (removedCount > 0) {
|
|
72
|
+
debug$1("filtered %s: %d -> %d versions (%d removed)", manifest.name, versionCount, filteredCount, removedCount);
|
|
73
|
+
this.logger.trace({
|
|
74
|
+
name: manifest.name,
|
|
75
|
+
before: versionCount,
|
|
76
|
+
after: filteredCount,
|
|
77
|
+
removed: removedCount
|
|
78
|
+
}, "package-filter @{name}: @{before} -> @{after} versions (@{removed} removed)");
|
|
79
|
+
} else debug$1("no versions filtered for %s", manifest.name);
|
|
80
|
+
return newManifest;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
exports.PackageFilterPlugin = PackageFilterPlugin;
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=packageFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageFilter.js","names":[],"sources":["../src/packageFilter.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport { pluginUtils } from '@verdaccio/core';\nimport type { Logger, Manifest } from '@verdaccio/types';\n\nimport { parseConfig } from './config/parser';\nimport type { ParsedConfig, PluginConfig } from './config/types';\nimport { filterBlockedVersions } from './filtering/packageVersion';\nimport { filterVersionsByPublishDate } from './filtering/publishDate';\nimport { jsonLogReplacer } from './utils/jsonUtils';\nimport {\n cleanupDistFiles,\n cleanupTags,\n cleanupTime,\n getManifestClone,\n setupCreatedAndModified,\n setupLatestTag,\n} from './utils/manifestUtils';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter');\n\nexport class PackageFilterPlugin\n extends pluginUtils.Plugin<PluginConfig>\n implements pluginUtils.ManifestFilter<PluginConfig>\n{\n public readonly config: PluginConfig;\n private readonly parsedConfig: ParsedConfig;\n protected readonly logger: Logger;\n\n public constructor(config: PluginConfig, options: pluginUtils.PluginOptions) {\n super(config, options);\n this.config = config ?? {};\n this.logger = options.logger;\n this.parsedConfig = parseConfig(this.config);\n\n debug(\n 'plugin loaded: block rules: %d, allow rules: %d',\n this.parsedConfig.blockRules.size,\n this.parsedConfig.allowRules.size\n );\n this.logger.debug(\n { config: JSON.stringify(this.parsedConfig, jsonLogReplacer) },\n 'package-filter loaded with config: @{config}'\n );\n this.logger.trace(\n {\n blockRules: this.parsedConfig.blockRules.size,\n allowRules: this.parsedConfig.allowRules.size,\n },\n 'package-filter plugin initialized: @{blockRules} block rules, @{allowRules} allow rules'\n );\n if (this.parsedConfig.dateThreshold) {\n debug('date threshold: %s', this.parsedConfig.dateThreshold.toISOString());\n this.logger.trace(\n { dateThreshold: this.parsedConfig.dateThreshold.toISOString() },\n 'package-filter date threshold: @{dateThreshold}'\n );\n }\n if (this.parsedConfig.minAgeMs) {\n const minAgeDays = this.parsedConfig.minAgeMs / (24 * 60 * 60 * 1000);\n debug('min age: %d days', minAgeDays);\n this.logger.trace({ minAgeDays }, 'package-filter min age: @{minAgeDays} days');\n }\n }\n\n public async filter_metadata(manifest: Readonly<Manifest>): Promise<Manifest> {\n const { dateThreshold, minAgeMs, blockRules, allowRules } = this.parsedConfig;\n const versionCount = Object.keys(manifest.versions ?? {}).length;\n debug('filtering manifest for %s (%d versions)', manifest.name, versionCount);\n this.logger.trace(\n { name: manifest.name, versionCount },\n 'package-filter processing @{name} (@{versionCount} versions)'\n );\n\n let earliestDateThreshold: Date | null = null;\n if (minAgeMs) {\n earliestDateThreshold = new Date(Date.now() - minAgeMs);\n }\n\n if (dateThreshold && (!earliestDateThreshold || dateThreshold < earliestDateThreshold)) {\n earliestDateThreshold = dateThreshold;\n }\n\n // Fast path: when neither block rules nor a date threshold are configured there\n // is nothing this filter can change. Returning the manifest untouched avoids the\n // clone and the cleanup passes below. This matters most for `npm search`, which\n // invokes filter_metadata once per matched package (see issue #5837).\n if (blockRules.size === 0 && !earliestDateThreshold) {\n debug('no filters configured, returning manifest untouched for %s', manifest.name);\n return manifest as Manifest;\n }\n\n let newManifest = getManifestClone(manifest);\n if (blockRules.size > 0) {\n newManifest = filterBlockedVersions(newManifest, blockRules, allowRules, this.logger);\n }\n\n if (earliestDateThreshold) {\n debug(\n 'applying date filter for %s, threshold: %s',\n manifest.name,\n earliestDateThreshold.toISOString()\n );\n this.logger.trace(\n { name: manifest.name, threshold: earliestDateThreshold.toISOString() },\n 'applying date filter for @{name}, cutoff: @{threshold}'\n );\n newManifest = filterVersionsByPublishDate(newManifest, earliestDateThreshold, allowRules);\n }\n\n const filteredCount = Object.keys(newManifest.versions).length;\n const removedCount = versionCount - filteredCount;\n // The cleanup passes only repair inconsistencies introduced by filtering:\n // orphaned dist-tags/time/_distfiles entries and a `latest` tag pointing at a\n // removed version. When the filters left the manifest untouched (no version\n // removed or replaced) it is already consistent, so the passes are skipped.\n // `readme` changing is the signal that the (count-preserving) replace strategy\n // rewrote version content and the cleanup still needs to run.\n const wasModified = removedCount > 0 || newManifest.readme !== manifest.readme;\n if (wasModified) {\n cleanupTags(newManifest);\n setupLatestTag(newManifest);\n cleanupTime(newManifest);\n setupCreatedAndModified(newManifest);\n cleanupDistFiles(newManifest);\n }\n\n if (removedCount > 0) {\n debug(\n 'filtered %s: %d -> %d versions (%d removed)',\n manifest.name,\n versionCount,\n filteredCount,\n removedCount\n );\n this.logger.trace(\n { name: manifest.name, before: versionCount, after: filteredCount, removed: removedCount },\n 'package-filter @{name}: @{before} -> @{after} versions (@{removed} removed)'\n );\n } else {\n debug('no versions filtered for %s', manifest.name);\n }\n\n return newManifest;\n }\n}\n"],"mappings":";;;;;;;;;;AAmBA,IAAM,WAAA,GAAA,MAAA,SAAmB,iCAAiC;AAE1D,IAAa,sBAAb,cACU,gBAAA,YAAY,OAEtB;CACE;CACA;CACA;CAEA,YAAmB,QAAsB,SAAoC;EAC3E,MAAM,QAAQ,OAAO;EACrB,KAAK,SAAS,UAAU,CAAC;EACzB,KAAK,SAAS,QAAQ;EACtB,KAAK,eAAe,eAAA,YAAY,KAAK,MAAM;EAE3C,QACE,mDACA,KAAK,aAAa,WAAW,MAC7B,KAAK,aAAa,WAAW,IAC/B;EACA,KAAK,OAAO,MACV,EAAE,QAAQ,KAAK,UAAU,KAAK,cAAc,kBAAA,eAAe,EAAE,GAC7D,8CACF;EACA,KAAK,OAAO,MACV;GACE,YAAY,KAAK,aAAa,WAAW;GACzC,YAAY,KAAK,aAAa,WAAW;EAC3C,GACA,yFACF;EACA,IAAI,KAAK,aAAa,eAAe;GACnC,QAAM,sBAAsB,KAAK,aAAa,cAAc,YAAY,CAAC;GACzE,KAAK,OAAO,MACV,EAAE,eAAe,KAAK,aAAa,cAAc,YAAY,EAAE,GAC/D,iDACF;EACF;EACA,IAAI,KAAK,aAAa,UAAU;GAC9B,MAAM,aAAa,KAAK,aAAa,YAAY,OAAU,KAAK;GAChE,QAAM,oBAAoB,UAAU;GACpC,KAAK,OAAO,MAAM,EAAE,WAAW,GAAG,4CAA4C;EAChF;CACF;CAEA,MAAa,gBAAgB,UAAiD;EAC5E,MAAM,EAAE,eAAe,UAAU,YAAY,eAAe,KAAK;EACjE,MAAM,eAAe,OAAO,KAAK,SAAS,YAAY,CAAC,CAAC,EAAE;EAC1D,QAAM,2CAA2C,SAAS,MAAM,YAAY;EAC5E,KAAK,OAAO,MACV;GAAE,MAAM,SAAS;GAAM;EAAa,GACpC,8DACF;EAEA,IAAI,wBAAqC;EACzC,IAAI,UACF,wBAAwB,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ;EAGxD,IAAI,kBAAkB,CAAC,yBAAyB,gBAAgB,wBAC9D,wBAAwB;EAO1B,IAAI,WAAW,SAAS,KAAK,CAAC,uBAAuB;GACnD,QAAM,8DAA8D,SAAS,IAAI;GACjF,OAAO;EACT;EAEA,IAAI,cAAc,sBAAA,iBAAiB,QAAQ;EAC3C,IAAI,WAAW,OAAO,GACpB,cAAc,uBAAA,sBAAsB,aAAa,YAAY,YAAY,KAAK,MAAM;EAGtF,IAAI,uBAAuB;GACzB,QACE,8CACA,SAAS,MACT,sBAAsB,YAAY,CACpC;GACA,KAAK,OAAO,MACV;IAAE,MAAM,SAAS;IAAM,WAAW,sBAAsB,YAAY;GAAE,GACtE,wDACF;GACA,cAAc,oBAAA,4BAA4B,aAAa,uBAAuB,UAAU;EAC1F;EAEA,MAAM,gBAAgB,OAAO,KAAK,YAAY,QAAQ,EAAE;EACxD,MAAM,eAAe,eAAe;EAQpC,IADoB,eAAe,KAAK,YAAY,WAAW,SAAS,QACvD;GACf,sBAAA,YAAY,WAAW;GACvB,sBAAA,eAAe,WAAW;GAC1B,sBAAA,YAAY,WAAW;GACvB,sBAAA,wBAAwB,WAAW;GACnC,sBAAA,iBAAiB,WAAW;EAC9B;EAEA,IAAI,eAAe,GAAG;GACpB,QACE,+CACA,SAAS,MACT,cACA,eACA,YACF;GACA,KAAK,OAAO,MACV;IAAE,MAAM,SAAS;IAAM,QAAQ;IAAc,OAAO;IAAe,SAAS;GAAa,GACzF,6EACF;EACF,OACE,QAAM,+BAA+B,SAAS,IAAI;EAGpD,OAAO;CACT;AACF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { parseConfig } from "./config/parser.mjs";
|
|
2
|
+
import { filterBlockedVersions } from "./filtering/packageVersion.mjs";
|
|
3
|
+
import { filterVersionsByPublishDate } from "./filtering/publishDate.mjs";
|
|
4
|
+
import { jsonLogReplacer } from "./utils/jsonUtils.mjs";
|
|
5
|
+
import { cleanupDistFiles, cleanupTags, cleanupTime, getManifestClone, setupCreatedAndModified, setupLatestTag } from "./utils/manifestUtils.mjs";
|
|
6
|
+
import buildDebug from "debug";
|
|
7
|
+
import { pluginUtils } from "@verdaccio/core";
|
|
8
|
+
//#region src/packageFilter.ts
|
|
9
|
+
var debug = buildDebug("verdaccio:plugin:package-filter");
|
|
10
|
+
var PackageFilterPlugin = class extends pluginUtils.Plugin {
|
|
11
|
+
config;
|
|
12
|
+
parsedConfig;
|
|
13
|
+
logger;
|
|
14
|
+
constructor(config, options) {
|
|
15
|
+
super(config, options);
|
|
16
|
+
this.config = config ?? {};
|
|
17
|
+
this.logger = options.logger;
|
|
18
|
+
this.parsedConfig = parseConfig(this.config);
|
|
19
|
+
debug("plugin loaded: block rules: %d, allow rules: %d", this.parsedConfig.blockRules.size, this.parsedConfig.allowRules.size);
|
|
20
|
+
this.logger.debug({ config: JSON.stringify(this.parsedConfig, jsonLogReplacer) }, "package-filter loaded with config: @{config}");
|
|
21
|
+
this.logger.trace({
|
|
22
|
+
blockRules: this.parsedConfig.blockRules.size,
|
|
23
|
+
allowRules: this.parsedConfig.allowRules.size
|
|
24
|
+
}, "package-filter plugin initialized: @{blockRules} block rules, @{allowRules} allow rules");
|
|
25
|
+
if (this.parsedConfig.dateThreshold) {
|
|
26
|
+
debug("date threshold: %s", this.parsedConfig.dateThreshold.toISOString());
|
|
27
|
+
this.logger.trace({ dateThreshold: this.parsedConfig.dateThreshold.toISOString() }, "package-filter date threshold: @{dateThreshold}");
|
|
28
|
+
}
|
|
29
|
+
if (this.parsedConfig.minAgeMs) {
|
|
30
|
+
const minAgeDays = this.parsedConfig.minAgeMs / (1440 * 60 * 1e3);
|
|
31
|
+
debug("min age: %d days", minAgeDays);
|
|
32
|
+
this.logger.trace({ minAgeDays }, "package-filter min age: @{minAgeDays} days");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async filter_metadata(manifest) {
|
|
36
|
+
const { dateThreshold, minAgeMs, blockRules, allowRules } = this.parsedConfig;
|
|
37
|
+
const versionCount = Object.keys(manifest.versions ?? {}).length;
|
|
38
|
+
debug("filtering manifest for %s (%d versions)", manifest.name, versionCount);
|
|
39
|
+
this.logger.trace({
|
|
40
|
+
name: manifest.name,
|
|
41
|
+
versionCount
|
|
42
|
+
}, "package-filter processing @{name} (@{versionCount} versions)");
|
|
43
|
+
let earliestDateThreshold = null;
|
|
44
|
+
if (minAgeMs) earliestDateThreshold = new Date(Date.now() - minAgeMs);
|
|
45
|
+
if (dateThreshold && (!earliestDateThreshold || dateThreshold < earliestDateThreshold)) earliestDateThreshold = dateThreshold;
|
|
46
|
+
if (blockRules.size === 0 && !earliestDateThreshold) {
|
|
47
|
+
debug("no filters configured, returning manifest untouched for %s", manifest.name);
|
|
48
|
+
return manifest;
|
|
49
|
+
}
|
|
50
|
+
let newManifest = getManifestClone(manifest);
|
|
51
|
+
if (blockRules.size > 0) newManifest = filterBlockedVersions(newManifest, blockRules, allowRules, this.logger);
|
|
52
|
+
if (earliestDateThreshold) {
|
|
53
|
+
debug("applying date filter for %s, threshold: %s", manifest.name, earliestDateThreshold.toISOString());
|
|
54
|
+
this.logger.trace({
|
|
55
|
+
name: manifest.name,
|
|
56
|
+
threshold: earliestDateThreshold.toISOString()
|
|
57
|
+
}, "applying date filter for @{name}, cutoff: @{threshold}");
|
|
58
|
+
newManifest = filterVersionsByPublishDate(newManifest, earliestDateThreshold, allowRules);
|
|
59
|
+
}
|
|
60
|
+
const filteredCount = Object.keys(newManifest.versions).length;
|
|
61
|
+
const removedCount = versionCount - filteredCount;
|
|
62
|
+
if (removedCount > 0 || newManifest.readme !== manifest.readme) {
|
|
63
|
+
cleanupTags(newManifest);
|
|
64
|
+
setupLatestTag(newManifest);
|
|
65
|
+
cleanupTime(newManifest);
|
|
66
|
+
setupCreatedAndModified(newManifest);
|
|
67
|
+
cleanupDistFiles(newManifest);
|
|
68
|
+
}
|
|
69
|
+
if (removedCount > 0) {
|
|
70
|
+
debug("filtered %s: %d -> %d versions (%d removed)", manifest.name, versionCount, filteredCount, removedCount);
|
|
71
|
+
this.logger.trace({
|
|
72
|
+
name: manifest.name,
|
|
73
|
+
before: versionCount,
|
|
74
|
+
after: filteredCount,
|
|
75
|
+
removed: removedCount
|
|
76
|
+
}, "package-filter @{name}: @{before} -> @{after} versions (@{removed} removed)");
|
|
77
|
+
} else debug("no versions filtered for %s", manifest.name);
|
|
78
|
+
return newManifest;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
//#endregion
|
|
82
|
+
export { PackageFilterPlugin };
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=packageFilter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageFilter.mjs","names":[],"sources":["../src/packageFilter.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport { pluginUtils } from '@verdaccio/core';\nimport type { Logger, Manifest } from '@verdaccio/types';\n\nimport { parseConfig } from './config/parser';\nimport type { ParsedConfig, PluginConfig } from './config/types';\nimport { filterBlockedVersions } from './filtering/packageVersion';\nimport { filterVersionsByPublishDate } from './filtering/publishDate';\nimport { jsonLogReplacer } from './utils/jsonUtils';\nimport {\n cleanupDistFiles,\n cleanupTags,\n cleanupTime,\n getManifestClone,\n setupCreatedAndModified,\n setupLatestTag,\n} from './utils/manifestUtils';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter');\n\nexport class PackageFilterPlugin\n extends pluginUtils.Plugin<PluginConfig>\n implements pluginUtils.ManifestFilter<PluginConfig>\n{\n public readonly config: PluginConfig;\n private readonly parsedConfig: ParsedConfig;\n protected readonly logger: Logger;\n\n public constructor(config: PluginConfig, options: pluginUtils.PluginOptions) {\n super(config, options);\n this.config = config ?? {};\n this.logger = options.logger;\n this.parsedConfig = parseConfig(this.config);\n\n debug(\n 'plugin loaded: block rules: %d, allow rules: %d',\n this.parsedConfig.blockRules.size,\n this.parsedConfig.allowRules.size\n );\n this.logger.debug(\n { config: JSON.stringify(this.parsedConfig, jsonLogReplacer) },\n 'package-filter loaded with config: @{config}'\n );\n this.logger.trace(\n {\n blockRules: this.parsedConfig.blockRules.size,\n allowRules: this.parsedConfig.allowRules.size,\n },\n 'package-filter plugin initialized: @{blockRules} block rules, @{allowRules} allow rules'\n );\n if (this.parsedConfig.dateThreshold) {\n debug('date threshold: %s', this.parsedConfig.dateThreshold.toISOString());\n this.logger.trace(\n { dateThreshold: this.parsedConfig.dateThreshold.toISOString() },\n 'package-filter date threshold: @{dateThreshold}'\n );\n }\n if (this.parsedConfig.minAgeMs) {\n const minAgeDays = this.parsedConfig.minAgeMs / (24 * 60 * 60 * 1000);\n debug('min age: %d days', minAgeDays);\n this.logger.trace({ minAgeDays }, 'package-filter min age: @{minAgeDays} days');\n }\n }\n\n public async filter_metadata(manifest: Readonly<Manifest>): Promise<Manifest> {\n const { dateThreshold, minAgeMs, blockRules, allowRules } = this.parsedConfig;\n const versionCount = Object.keys(manifest.versions ?? {}).length;\n debug('filtering manifest for %s (%d versions)', manifest.name, versionCount);\n this.logger.trace(\n { name: manifest.name, versionCount },\n 'package-filter processing @{name} (@{versionCount} versions)'\n );\n\n let earliestDateThreshold: Date | null = null;\n if (minAgeMs) {\n earliestDateThreshold = new Date(Date.now() - minAgeMs);\n }\n\n if (dateThreshold && (!earliestDateThreshold || dateThreshold < earliestDateThreshold)) {\n earliestDateThreshold = dateThreshold;\n }\n\n // Fast path: when neither block rules nor a date threshold are configured there\n // is nothing this filter can change. Returning the manifest untouched avoids the\n // clone and the cleanup passes below. This matters most for `npm search`, which\n // invokes filter_metadata once per matched package (see issue #5837).\n if (blockRules.size === 0 && !earliestDateThreshold) {\n debug('no filters configured, returning manifest untouched for %s', manifest.name);\n return manifest as Manifest;\n }\n\n let newManifest = getManifestClone(manifest);\n if (blockRules.size > 0) {\n newManifest = filterBlockedVersions(newManifest, blockRules, allowRules, this.logger);\n }\n\n if (earliestDateThreshold) {\n debug(\n 'applying date filter for %s, threshold: %s',\n manifest.name,\n earliestDateThreshold.toISOString()\n );\n this.logger.trace(\n { name: manifest.name, threshold: earliestDateThreshold.toISOString() },\n 'applying date filter for @{name}, cutoff: @{threshold}'\n );\n newManifest = filterVersionsByPublishDate(newManifest, earliestDateThreshold, allowRules);\n }\n\n const filteredCount = Object.keys(newManifest.versions).length;\n const removedCount = versionCount - filteredCount;\n // The cleanup passes only repair inconsistencies introduced by filtering:\n // orphaned dist-tags/time/_distfiles entries and a `latest` tag pointing at a\n // removed version. When the filters left the manifest untouched (no version\n // removed or replaced) it is already consistent, so the passes are skipped.\n // `readme` changing is the signal that the (count-preserving) replace strategy\n // rewrote version content and the cleanup still needs to run.\n const wasModified = removedCount > 0 || newManifest.readme !== manifest.readme;\n if (wasModified) {\n cleanupTags(newManifest);\n setupLatestTag(newManifest);\n cleanupTime(newManifest);\n setupCreatedAndModified(newManifest);\n cleanupDistFiles(newManifest);\n }\n\n if (removedCount > 0) {\n debug(\n 'filtered %s: %d -> %d versions (%d removed)',\n manifest.name,\n versionCount,\n filteredCount,\n removedCount\n );\n this.logger.trace(\n { name: manifest.name, before: versionCount, after: filteredCount, removed: removedCount },\n 'package-filter @{name}: @{before} -> @{after} versions (@{removed} removed)'\n );\n } else {\n debug('no versions filtered for %s', manifest.name);\n }\n\n return newManifest;\n }\n}\n"],"mappings":";;;;;;;;AAmBA,IAAM,QAAQ,WAAW,iCAAiC;AAE1D,IAAa,sBAAb,cACU,YAAY,OAEtB;CACE;CACA;CACA;CAEA,YAAmB,QAAsB,SAAoC;EAC3E,MAAM,QAAQ,OAAO;EACrB,KAAK,SAAS,UAAU,CAAC;EACzB,KAAK,SAAS,QAAQ;EACtB,KAAK,eAAe,YAAY,KAAK,MAAM;EAE3C,MACE,mDACA,KAAK,aAAa,WAAW,MAC7B,KAAK,aAAa,WAAW,IAC/B;EACA,KAAK,OAAO,MACV,EAAE,QAAQ,KAAK,UAAU,KAAK,cAAc,eAAe,EAAE,GAC7D,8CACF;EACA,KAAK,OAAO,MACV;GACE,YAAY,KAAK,aAAa,WAAW;GACzC,YAAY,KAAK,aAAa,WAAW;EAC3C,GACA,yFACF;EACA,IAAI,KAAK,aAAa,eAAe;GACnC,MAAM,sBAAsB,KAAK,aAAa,cAAc,YAAY,CAAC;GACzE,KAAK,OAAO,MACV,EAAE,eAAe,KAAK,aAAa,cAAc,YAAY,EAAE,GAC/D,iDACF;EACF;EACA,IAAI,KAAK,aAAa,UAAU;GAC9B,MAAM,aAAa,KAAK,aAAa,YAAY,OAAU,KAAK;GAChE,MAAM,oBAAoB,UAAU;GACpC,KAAK,OAAO,MAAM,EAAE,WAAW,GAAG,4CAA4C;EAChF;CACF;CAEA,MAAa,gBAAgB,UAAiD;EAC5E,MAAM,EAAE,eAAe,UAAU,YAAY,eAAe,KAAK;EACjE,MAAM,eAAe,OAAO,KAAK,SAAS,YAAY,CAAC,CAAC,EAAE;EAC1D,MAAM,2CAA2C,SAAS,MAAM,YAAY;EAC5E,KAAK,OAAO,MACV;GAAE,MAAM,SAAS;GAAM;EAAa,GACpC,8DACF;EAEA,IAAI,wBAAqC;EACzC,IAAI,UACF,wBAAwB,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ;EAGxD,IAAI,kBAAkB,CAAC,yBAAyB,gBAAgB,wBAC9D,wBAAwB;EAO1B,IAAI,WAAW,SAAS,KAAK,CAAC,uBAAuB;GACnD,MAAM,8DAA8D,SAAS,IAAI;GACjF,OAAO;EACT;EAEA,IAAI,cAAc,iBAAiB,QAAQ;EAC3C,IAAI,WAAW,OAAO,GACpB,cAAc,sBAAsB,aAAa,YAAY,YAAY,KAAK,MAAM;EAGtF,IAAI,uBAAuB;GACzB,MACE,8CACA,SAAS,MACT,sBAAsB,YAAY,CACpC;GACA,KAAK,OAAO,MACV;IAAE,MAAM,SAAS;IAAM,WAAW,sBAAsB,YAAY;GAAE,GACtE,wDACF;GACA,cAAc,4BAA4B,aAAa,uBAAuB,UAAU;EAC1F;EAEA,MAAM,gBAAgB,OAAO,KAAK,YAAY,QAAQ,EAAE;EACxD,MAAM,eAAe,eAAe;EAQpC,IADoB,eAAe,KAAK,YAAY,WAAW,SAAS,QACvD;GACf,YAAY,WAAW;GACvB,eAAe,WAAW;GAC1B,YAAY,WAAW;GACvB,wBAAwB,WAAW;GACnC,iBAAiB,WAAW;EAC9B;EAEA,IAAI,eAAe,GAAG;GACpB,MACE,+CACA,SAAS,MACT,cACA,eACA,YACF;GACA,KAAK,OAAO,MACV;IAAE,MAAM,SAAS;IAAM,QAAQ;IAAc,OAAO;IAAe,SAAS;GAAa,GACzF,6EACF;EACF,OACE,MAAM,+BAA+B,SAAS,IAAI;EAGpD,OAAO;CACT;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function jsonLogReplacer(_key: string, value: unknown): any;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
let semver = require("semver");
|
|
2
|
+
//#region src/utils/jsonUtils.ts
|
|
3
|
+
function jsonLogReplacer(_key, value) {
|
|
4
|
+
if (value instanceof Map) return Object.fromEntries(value);
|
|
5
|
+
if (value instanceof semver.Range) return value.range;
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
exports.jsonLogReplacer = jsonLogReplacer;
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=jsonUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonUtils.js","names":[],"sources":["../../src/utils/jsonUtils.ts"],"sourcesContent":["import { Range } from 'semver';\n\nexport function jsonLogReplacer(_key: string, value: unknown) {\n if (value instanceof Map) {\n return Object.fromEntries(value);\n }\n\n if (value instanceof Range) {\n return value.range;\n }\n\n return value;\n}\n"],"mappings":";;AAEA,SAAgB,gBAAgB,MAAc,OAAgB;CAC5D,IAAI,iBAAiB,KACnB,OAAO,OAAO,YAAY,KAAK;CAGjC,IAAI,iBAAiB,OAAA,OACnB,OAAO,MAAM;CAGf,OAAO;AACT"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Range } from "semver";
|
|
2
|
+
//#region src/utils/jsonUtils.ts
|
|
3
|
+
function jsonLogReplacer(_key, value) {
|
|
4
|
+
if (value instanceof Map) return Object.fromEntries(value);
|
|
5
|
+
if (value instanceof Range) return value.range;
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { jsonLogReplacer };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=jsonUtils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonUtils.mjs","names":[],"sources":["../../src/utils/jsonUtils.ts"],"sourcesContent":["import { Range } from 'semver';\n\nexport function jsonLogReplacer(_key: string, value: unknown) {\n if (value instanceof Map) {\n return Object.fromEntries(value);\n }\n\n if (value instanceof Range) {\n return value.range;\n }\n\n return value;\n}\n"],"mappings":";;AAEA,SAAgB,gBAAgB,MAAc,OAAgB;CAC5D,IAAI,iBAAiB,KACnB,OAAO,OAAO,YAAY,KAAK;CAGjC,IAAI,iBAAiB,OACnB,OAAO,MAAM;CAGf,OAAO;AACT"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Manifest } from '@verdaccio/types';
|
|
2
|
+
/**
|
|
3
|
+
* Delete `dist-tags` entries corresponding to missing versions.
|
|
4
|
+
*/
|
|
5
|
+
export declare function cleanupTags(manifest: Manifest): void;
|
|
6
|
+
/**
|
|
7
|
+
* Delete `time` entries corresponding to missing versions.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cleanupTime(manifest: Manifest): void;
|
|
10
|
+
/**
|
|
11
|
+
* Get the latest version from a list of versions,
|
|
12
|
+
* ordered by time of their publication stored in the manifest.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getLatestVersion(manifest: Manifest, versions: string[]): string | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Set the latest tag if dist-tags/latest is missing.
|
|
17
|
+
* The last stable version available is used when possible.
|
|
18
|
+
* Otherwise, it uses the latest version not found in dist-tags.
|
|
19
|
+
*/
|
|
20
|
+
export declare function setupLatestTag(manifest: Manifest): void;
|
|
21
|
+
/**
|
|
22
|
+
* Set the created and modified times.
|
|
23
|
+
*/
|
|
24
|
+
export declare function setupCreatedAndModified(manifest: Manifest): void;
|
|
25
|
+
/**
|
|
26
|
+
* Remove `_distfiles` entries which are not used by any version.
|
|
27
|
+
*/
|
|
28
|
+
export declare function cleanupDistFiles(manifest: Manifest): void;
|
|
29
|
+
/**
|
|
30
|
+
* Creates a copy of a manifest suitable for safe, localized mutation.
|
|
31
|
+
*
|
|
32
|
+
* The returned object is shallow-cloned, except for `versions`, `dist-tags`,
|
|
33
|
+
* `time`, and `_distfiles`, which are cloned as independent maps so they can be
|
|
34
|
+
* filtered or modified without affecting the original manifest.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getManifestClone(manifest: Readonly<Manifest>): Manifest;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.js");
|
|
2
|
+
let debug = require("debug");
|
|
3
|
+
debug = require_runtime.__toESM(debug);
|
|
4
|
+
let _verdaccio_core = require("@verdaccio/core");
|
|
5
|
+
let semver = require("semver");
|
|
6
|
+
semver = require_runtime.__toESM(semver);
|
|
7
|
+
//#region src/utils/manifestUtils.ts
|
|
8
|
+
var debug$1 = (0, debug.default)("verdaccio:plugin:package-filter:manifest");
|
|
9
|
+
/**
|
|
10
|
+
* Delete `dist-tags` entries corresponding to missing versions.
|
|
11
|
+
*/
|
|
12
|
+
function cleanupTags(manifest) {
|
|
13
|
+
const distTags = manifest[_verdaccio_core.DIST_TAGS];
|
|
14
|
+
Object.entries(distTags).forEach(([tag, tagVersion]) => {
|
|
15
|
+
if (!manifest.versions[tagVersion]) {
|
|
16
|
+
debug$1("removing orphaned dist-tag %s -> %s from %s", tag, tagVersion, manifest.name);
|
|
17
|
+
delete distTags[tag];
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Delete `time` entries corresponding to missing versions.
|
|
23
|
+
*/
|
|
24
|
+
function cleanupTime(manifest) {
|
|
25
|
+
const time = manifest.time;
|
|
26
|
+
if (!time) return;
|
|
27
|
+
Object.keys(time).forEach((version) => {
|
|
28
|
+
if (!manifest.versions[version]) delete time[version];
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the latest version from a list of versions,
|
|
33
|
+
* ordered by time of their publication stored in the manifest.
|
|
34
|
+
*/
|
|
35
|
+
function getLatestVersion(manifest, versions) {
|
|
36
|
+
const time = manifest.time;
|
|
37
|
+
if (!time) return versions.sort(semver.default.rcompare)[0];
|
|
38
|
+
const timedVersions = versions.map((v) => ({
|
|
39
|
+
version: v,
|
|
40
|
+
time: time[v]
|
|
41
|
+
})).filter((v) => v.time);
|
|
42
|
+
if (timedVersions.length === 0) return;
|
|
43
|
+
return timedVersions.sort((a, b) => new Date(b.time).getTime() - new Date(a.time).getTime())[0].version;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Set the latest tag if dist-tags/latest is missing.
|
|
47
|
+
* The last stable version available is used when possible.
|
|
48
|
+
* Otherwise, it uses the latest version not found in dist-tags.
|
|
49
|
+
*/
|
|
50
|
+
function setupLatestTag(manifest) {
|
|
51
|
+
const distTags = manifest[_verdaccio_core.DIST_TAGS];
|
|
52
|
+
if (distTags.latest) return;
|
|
53
|
+
const versions = Object.keys(manifest.versions);
|
|
54
|
+
if (versions.length === 0) return;
|
|
55
|
+
const distTagsVersions = Object.values(distTags);
|
|
56
|
+
const untaggedVersions = versions.filter((v) => semver.default.valid(v) && !distTagsVersions.includes(v));
|
|
57
|
+
if (untaggedVersions.length === 0) return;
|
|
58
|
+
const latestStableVersion = getLatestVersion(manifest, untaggedVersions.filter((v) => !semver.default.prerelease(v)));
|
|
59
|
+
if (latestStableVersion) {
|
|
60
|
+
debug$1("reassigned latest tag to stable version %s for %s", latestStableVersion, manifest.name);
|
|
61
|
+
distTags.latest = latestStableVersion;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const latestVersion = getLatestVersion(manifest, untaggedVersions);
|
|
65
|
+
if (!latestVersion) return;
|
|
66
|
+
debug$1("reassigned latest tag to pre-release version %s for %s", latestVersion, manifest.name);
|
|
67
|
+
distTags.latest = latestVersion;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set the created and modified times.
|
|
71
|
+
*/
|
|
72
|
+
function setupCreatedAndModified(manifest) {
|
|
73
|
+
const time = manifest.time;
|
|
74
|
+
if (!time) return;
|
|
75
|
+
const times = Object.values(time);
|
|
76
|
+
if (times.length === 0) return;
|
|
77
|
+
let earliest = times[0];
|
|
78
|
+
let latest = times[0];
|
|
79
|
+
let earliestMs = new Date(earliest).getTime();
|
|
80
|
+
let latestMs = earliestMs;
|
|
81
|
+
for (let i = 1; i < times.length; i++) {
|
|
82
|
+
const currentMs = new Date(times[i]).getTime();
|
|
83
|
+
if (currentMs < earliestMs) {
|
|
84
|
+
earliestMs = currentMs;
|
|
85
|
+
earliest = times[i];
|
|
86
|
+
}
|
|
87
|
+
if (currentMs > latestMs) {
|
|
88
|
+
latestMs = currentMs;
|
|
89
|
+
latest = times[i];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
time.created = earliest;
|
|
93
|
+
time.modified = latest;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Remove `_distfiles` entries which are not used by any version.
|
|
97
|
+
*/
|
|
98
|
+
function cleanupDistFiles(manifest) {
|
|
99
|
+
const distFiles = manifest._distfiles;
|
|
100
|
+
const activeTarballs = new Set(Object.values(manifest.versions).map((v) => v.dist?.tarball).filter((tarball) => typeof tarball === "string"));
|
|
101
|
+
Object.keys(distFiles).forEach((key) => {
|
|
102
|
+
if (!activeTarballs.has(distFiles[key].url)) delete distFiles[key];
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Creates a copy of a manifest suitable for safe, localized mutation.
|
|
107
|
+
*
|
|
108
|
+
* The returned object is shallow-cloned, except for `versions`, `dist-tags`,
|
|
109
|
+
* `time`, and `_distfiles`, which are cloned as independent maps so they can be
|
|
110
|
+
* filtered or modified without affecting the original manifest.
|
|
111
|
+
*/
|
|
112
|
+
function getManifestClone(manifest) {
|
|
113
|
+
return {
|
|
114
|
+
...manifest,
|
|
115
|
+
versions: { ...manifest.versions },
|
|
116
|
+
[_verdaccio_core.DIST_TAGS]: { ...manifest[_verdaccio_core.DIST_TAGS] },
|
|
117
|
+
time: { ...manifest.time },
|
|
118
|
+
_distfiles: { ...manifest._distfiles }
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
exports.cleanupDistFiles = cleanupDistFiles;
|
|
123
|
+
exports.cleanupTags = cleanupTags;
|
|
124
|
+
exports.cleanupTime = cleanupTime;
|
|
125
|
+
exports.getManifestClone = getManifestClone;
|
|
126
|
+
exports.setupCreatedAndModified = setupCreatedAndModified;
|
|
127
|
+
exports.setupLatestTag = setupLatestTag;
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=manifestUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestUtils.js","names":[],"sources":["../../src/utils/manifestUtils.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport semver from 'semver';\n\nimport { DIST_TAGS } from '@verdaccio/core';\nimport type { Manifest } from '@verdaccio/types';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter:manifest');\n\n/**\n * Delete `dist-tags` entries corresponding to missing versions.\n */\nexport function cleanupTags(manifest: Manifest): void {\n const distTags = manifest[DIST_TAGS];\n Object.entries(distTags).forEach(([tag, tagVersion]) => {\n if (!manifest.versions[tagVersion]) {\n debug('removing orphaned dist-tag %s -> %s from %s', tag, tagVersion, manifest.name);\n delete distTags[tag];\n }\n });\n}\n\n/**\n * Delete `time` entries corresponding to missing versions.\n */\nexport function cleanupTime(manifest: Manifest): void {\n const time = manifest.time;\n if (!time) {\n return;\n }\n\n Object.keys(time).forEach((version) => {\n if (!manifest.versions[version]) {\n delete time[version];\n }\n });\n}\n\n/**\n * Get the latest version from a list of versions,\n * ordered by time of their publication stored in the manifest.\n */\nexport function getLatestVersion(manifest: Manifest, versions: string[]): string | undefined {\n const time = manifest.time;\n if (!time) {\n // No time information, it's the best we can do\n const sortedVersions = versions.sort(semver.rcompare);\n return sortedVersions[0];\n }\n\n const timedVersions = versions\n .map((v) => ({\n version: v,\n time: time[v],\n }))\n .filter((v) => v.time);\n\n if (timedVersions.length === 0) {\n return undefined;\n }\n\n const timeOrderedVersions = timedVersions.sort(\n (a, b) => new Date(b.time).getTime() - new Date(a.time).getTime()\n );\n return timeOrderedVersions[0].version;\n}\n\n/**\n * Set the latest tag if dist-tags/latest is missing.\n * The last stable version available is used when possible.\n * Otherwise, it uses the latest version not found in dist-tags.\n */\nexport function setupLatestTag(manifest: Manifest): void {\n const distTags = manifest[DIST_TAGS];\n if (distTags.latest) {\n // Tag 'latest' must only be fixed when latest version was blocked\n return;\n }\n\n const versions = Object.keys(manifest.versions);\n if (versions.length === 0) {\n return;\n }\n\n const distTagsVersions = Object.values(distTags);\n const untaggedVersions = versions.filter((v) => semver.valid(v) && !distTagsVersions.includes(v));\n if (untaggedVersions.length === 0) {\n return;\n }\n\n // Try stable versions first (no \"-next\" or \"-beta\", etc.)\n const stableVersions = untaggedVersions.filter((v) => !semver.prerelease(v));\n const latestStableVersion = getLatestVersion(manifest, stableVersions);\n if (latestStableVersion) {\n debug('reassigned latest tag to stable version %s for %s', latestStableVersion, manifest.name);\n distTags.latest = latestStableVersion;\n return;\n }\n\n // Fallback to all untagged versions\n const latestVersion = getLatestVersion(manifest, untaggedVersions);\n if (!latestVersion) {\n return;\n }\n\n debug('reassigned latest tag to pre-release version %s for %s', latestVersion, manifest.name);\n distTags.latest = latestVersion;\n}\n\n/**\n * Set the created and modified times.\n */\nexport function setupCreatedAndModified(manifest: Manifest): void {\n const time = manifest.time;\n if (!time) {\n return;\n }\n\n const times = Object.values(time);\n if (times.length === 0) {\n return;\n }\n\n // Single O(n) pass for the earliest/latest publication time instead of an\n // O(n log n) sort — the result is identical but cheaper on large manifests.\n let earliest = times[0];\n let latest = times[0];\n let earliestMs = new Date(earliest).getTime();\n let latestMs = earliestMs;\n for (let i = 1; i < times.length; i++) {\n const currentMs = new Date(times[i]).getTime();\n if (currentMs < earliestMs) {\n earliestMs = currentMs;\n earliest = times[i];\n }\n if (currentMs > latestMs) {\n latestMs = currentMs;\n latest = times[i];\n }\n }\n time.created = earliest;\n time.modified = latest;\n}\n\n/**\n * Remove `_distfiles` entries which are not used by any version.\n */\nexport function cleanupDistFiles(manifest: Manifest): void {\n const distFiles = manifest._distfiles;\n // Build a Set of active tarball URLs in one pass — O(n) instead of O(n²)\n const activeTarballs = new Set(\n Object.values(manifest.versions)\n .map((v) => v.dist?.tarball)\n .filter((tarball): tarball is string => typeof tarball === 'string')\n );\n Object.keys(distFiles).forEach((key) => {\n if (!activeTarballs.has(distFiles[key].url)) {\n delete distFiles[key];\n }\n });\n}\n\n/**\n * Creates a copy of a manifest suitable for safe, localized mutation.\n *\n * The returned object is shallow-cloned, except for `versions`, `dist-tags`,\n * `time`, and `_distfiles`, which are cloned as independent maps so they can be\n * filtered or modified without affecting the original manifest.\n */\nexport function getManifestClone(manifest: Readonly<Manifest>): Manifest {\n return {\n ...manifest,\n versions: {\n ...manifest.versions,\n },\n [DIST_TAGS]: {\n ...manifest[DIST_TAGS],\n },\n time: {\n ...manifest.time,\n },\n _distfiles: {\n ...manifest._distfiles,\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import buildDebug from "debug";
|
|
2
|
+
import { DIST_TAGS } from "@verdaccio/core";
|
|
3
|
+
import semver from "semver";
|
|
4
|
+
//#region src/utils/manifestUtils.ts
|
|
5
|
+
var debug = buildDebug("verdaccio:plugin:package-filter:manifest");
|
|
6
|
+
/**
|
|
7
|
+
* Delete `dist-tags` entries corresponding to missing versions.
|
|
8
|
+
*/
|
|
9
|
+
function cleanupTags(manifest) {
|
|
10
|
+
const distTags = manifest[DIST_TAGS];
|
|
11
|
+
Object.entries(distTags).forEach(([tag, tagVersion]) => {
|
|
12
|
+
if (!manifest.versions[tagVersion]) {
|
|
13
|
+
debug("removing orphaned dist-tag %s -> %s from %s", tag, tagVersion, manifest.name);
|
|
14
|
+
delete distTags[tag];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Delete `time` entries corresponding to missing versions.
|
|
20
|
+
*/
|
|
21
|
+
function cleanupTime(manifest) {
|
|
22
|
+
const time = manifest.time;
|
|
23
|
+
if (!time) return;
|
|
24
|
+
Object.keys(time).forEach((version) => {
|
|
25
|
+
if (!manifest.versions[version]) delete time[version];
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the latest version from a list of versions,
|
|
30
|
+
* ordered by time of their publication stored in the manifest.
|
|
31
|
+
*/
|
|
32
|
+
function getLatestVersion(manifest, versions) {
|
|
33
|
+
const time = manifest.time;
|
|
34
|
+
if (!time) return versions.sort(semver.rcompare)[0];
|
|
35
|
+
const timedVersions = versions.map((v) => ({
|
|
36
|
+
version: v,
|
|
37
|
+
time: time[v]
|
|
38
|
+
})).filter((v) => v.time);
|
|
39
|
+
if (timedVersions.length === 0) return;
|
|
40
|
+
return timedVersions.sort((a, b) => new Date(b.time).getTime() - new Date(a.time).getTime())[0].version;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Set the latest tag if dist-tags/latest is missing.
|
|
44
|
+
* The last stable version available is used when possible.
|
|
45
|
+
* Otherwise, it uses the latest version not found in dist-tags.
|
|
46
|
+
*/
|
|
47
|
+
function setupLatestTag(manifest) {
|
|
48
|
+
const distTags = manifest[DIST_TAGS];
|
|
49
|
+
if (distTags.latest) return;
|
|
50
|
+
const versions = Object.keys(manifest.versions);
|
|
51
|
+
if (versions.length === 0) return;
|
|
52
|
+
const distTagsVersions = Object.values(distTags);
|
|
53
|
+
const untaggedVersions = versions.filter((v) => semver.valid(v) && !distTagsVersions.includes(v));
|
|
54
|
+
if (untaggedVersions.length === 0) return;
|
|
55
|
+
const latestStableVersion = getLatestVersion(manifest, untaggedVersions.filter((v) => !semver.prerelease(v)));
|
|
56
|
+
if (latestStableVersion) {
|
|
57
|
+
debug("reassigned latest tag to stable version %s for %s", latestStableVersion, manifest.name);
|
|
58
|
+
distTags.latest = latestStableVersion;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const latestVersion = getLatestVersion(manifest, untaggedVersions);
|
|
62
|
+
if (!latestVersion) return;
|
|
63
|
+
debug("reassigned latest tag to pre-release version %s for %s", latestVersion, manifest.name);
|
|
64
|
+
distTags.latest = latestVersion;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Set the created and modified times.
|
|
68
|
+
*/
|
|
69
|
+
function setupCreatedAndModified(manifest) {
|
|
70
|
+
const time = manifest.time;
|
|
71
|
+
if (!time) return;
|
|
72
|
+
const times = Object.values(time);
|
|
73
|
+
if (times.length === 0) return;
|
|
74
|
+
let earliest = times[0];
|
|
75
|
+
let latest = times[0];
|
|
76
|
+
let earliestMs = new Date(earliest).getTime();
|
|
77
|
+
let latestMs = earliestMs;
|
|
78
|
+
for (let i = 1; i < times.length; i++) {
|
|
79
|
+
const currentMs = new Date(times[i]).getTime();
|
|
80
|
+
if (currentMs < earliestMs) {
|
|
81
|
+
earliestMs = currentMs;
|
|
82
|
+
earliest = times[i];
|
|
83
|
+
}
|
|
84
|
+
if (currentMs > latestMs) {
|
|
85
|
+
latestMs = currentMs;
|
|
86
|
+
latest = times[i];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
time.created = earliest;
|
|
90
|
+
time.modified = latest;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Remove `_distfiles` entries which are not used by any version.
|
|
94
|
+
*/
|
|
95
|
+
function cleanupDistFiles(manifest) {
|
|
96
|
+
const distFiles = manifest._distfiles;
|
|
97
|
+
const activeTarballs = new Set(Object.values(manifest.versions).map((v) => v.dist?.tarball).filter((tarball) => typeof tarball === "string"));
|
|
98
|
+
Object.keys(distFiles).forEach((key) => {
|
|
99
|
+
if (!activeTarballs.has(distFiles[key].url)) delete distFiles[key];
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Creates a copy of a manifest suitable for safe, localized mutation.
|
|
104
|
+
*
|
|
105
|
+
* The returned object is shallow-cloned, except for `versions`, `dist-tags`,
|
|
106
|
+
* `time`, and `_distfiles`, which are cloned as independent maps so they can be
|
|
107
|
+
* filtered or modified without affecting the original manifest.
|
|
108
|
+
*/
|
|
109
|
+
function getManifestClone(manifest) {
|
|
110
|
+
return {
|
|
111
|
+
...manifest,
|
|
112
|
+
versions: { ...manifest.versions },
|
|
113
|
+
[DIST_TAGS]: { ...manifest[DIST_TAGS] },
|
|
114
|
+
time: { ...manifest.time },
|
|
115
|
+
_distfiles: { ...manifest._distfiles }
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { cleanupDistFiles, cleanupTags, cleanupTime, getManifestClone, setupCreatedAndModified, setupLatestTag };
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=manifestUtils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestUtils.mjs","names":[],"sources":["../../src/utils/manifestUtils.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport semver from 'semver';\n\nimport { DIST_TAGS } from '@verdaccio/core';\nimport type { Manifest } from '@verdaccio/types';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter:manifest');\n\n/**\n * Delete `dist-tags` entries corresponding to missing versions.\n */\nexport function cleanupTags(manifest: Manifest): void {\n const distTags = manifest[DIST_TAGS];\n Object.entries(distTags).forEach(([tag, tagVersion]) => {\n if (!manifest.versions[tagVersion]) {\n debug('removing orphaned dist-tag %s -> %s from %s', tag, tagVersion, manifest.name);\n delete distTags[tag];\n }\n });\n}\n\n/**\n * Delete `time` entries corresponding to missing versions.\n */\nexport function cleanupTime(manifest: Manifest): void {\n const time = manifest.time;\n if (!time) {\n return;\n }\n\n Object.keys(time).forEach((version) => {\n if (!manifest.versions[version]) {\n delete time[version];\n }\n });\n}\n\n/**\n * Get the latest version from a list of versions,\n * ordered by time of their publication stored in the manifest.\n */\nexport function getLatestVersion(manifest: Manifest, versions: string[]): string | undefined {\n const time = manifest.time;\n if (!time) {\n // No time information, it's the best we can do\n const sortedVersions = versions.sort(semver.rcompare);\n return sortedVersions[0];\n }\n\n const timedVersions = versions\n .map((v) => ({\n version: v,\n time: time[v],\n }))\n .filter((v) => v.time);\n\n if (timedVersions.length === 0) {\n return undefined;\n }\n\n const timeOrderedVersions = timedVersions.sort(\n (a, b) => new Date(b.time).getTime() - new Date(a.time).getTime()\n );\n return timeOrderedVersions[0].version;\n}\n\n/**\n * Set the latest tag if dist-tags/latest is missing.\n * The last stable version available is used when possible.\n * Otherwise, it uses the latest version not found in dist-tags.\n */\nexport function setupLatestTag(manifest: Manifest): void {\n const distTags = manifest[DIST_TAGS];\n if (distTags.latest) {\n // Tag 'latest' must only be fixed when latest version was blocked\n return;\n }\n\n const versions = Object.keys(manifest.versions);\n if (versions.length === 0) {\n return;\n }\n\n const distTagsVersions = Object.values(distTags);\n const untaggedVersions = versions.filter((v) => semver.valid(v) && !distTagsVersions.includes(v));\n if (untaggedVersions.length === 0) {\n return;\n }\n\n // Try stable versions first (no \"-next\" or \"-beta\", etc.)\n const stableVersions = untaggedVersions.filter((v) => !semver.prerelease(v));\n const latestStableVersion = getLatestVersion(manifest, stableVersions);\n if (latestStableVersion) {\n debug('reassigned latest tag to stable version %s for %s', latestStableVersion, manifest.name);\n distTags.latest = latestStableVersion;\n return;\n }\n\n // Fallback to all untagged versions\n const latestVersion = getLatestVersion(manifest, untaggedVersions);\n if (!latestVersion) {\n return;\n }\n\n debug('reassigned latest tag to pre-release version %s for %s', latestVersion, manifest.name);\n distTags.latest = latestVersion;\n}\n\n/**\n * Set the created and modified times.\n */\nexport function setupCreatedAndModified(manifest: Manifest): void {\n const time = manifest.time;\n if (!time) {\n return;\n }\n\n const times = Object.values(time);\n if (times.length === 0) {\n return;\n }\n\n // Single O(n) pass for the earliest/latest publication time instead of an\n // O(n log n) sort — the result is identical but cheaper on large manifests.\n let earliest = times[0];\n let latest = times[0];\n let earliestMs = new Date(earliest).getTime();\n let latestMs = earliestMs;\n for (let i = 1; i < times.length; i++) {\n const currentMs = new Date(times[i]).getTime();\n if (currentMs < earliestMs) {\n earliestMs = currentMs;\n earliest = times[i];\n }\n if (currentMs > latestMs) {\n latestMs = currentMs;\n latest = times[i];\n }\n }\n time.created = earliest;\n time.modified = latest;\n}\n\n/**\n * Remove `_distfiles` entries which are not used by any version.\n */\nexport function cleanupDistFiles(manifest: Manifest): void {\n const distFiles = manifest._distfiles;\n // Build a Set of active tarball URLs in one pass — O(n) instead of O(n²)\n const activeTarballs = new Set(\n Object.values(manifest.versions)\n .map((v) => v.dist?.tarball)\n .filter((tarball): tarball is string => typeof tarball === 'string')\n );\n Object.keys(distFiles).forEach((key) => {\n if (!activeTarballs.has(distFiles[key].url)) {\n delete distFiles[key];\n }\n });\n}\n\n/**\n * Creates a copy of a manifest suitable for safe, localized mutation.\n *\n * The returned object is shallow-cloned, except for `versions`, `dist-tags`,\n * `time`, and `_distfiles`, which are cloned as independent maps so they can be\n * filtered or modified without affecting the original manifest.\n */\nexport function getManifestClone(manifest: Readonly<Manifest>): Manifest {\n return {\n ...manifest,\n versions: {\n ...manifest.versions,\n },\n [DIST_TAGS]: {\n ...manifest[DIST_TAGS],\n },\n time: {\n ...manifest.time,\n },\n _distfiles: {\n ...manifest._distfiles,\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/package-filter",
|
|
3
|
-
"version": "13.0
|
|
3
|
+
"version": "13.1.0",
|
|
4
4
|
"description": "Package filter plugin for Verdaccio that allows blocking packages by name, scope, version or date",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"enterprise",
|
|
@@ -33,28 +33,43 @@
|
|
|
33
33
|
"type": "opencollective",
|
|
34
34
|
"url": "https://opencollective.com/verdaccio"
|
|
35
35
|
},
|
|
36
|
-
"main": "build/index.js",
|
|
37
|
-
"
|
|
36
|
+
"main": "./build/index.js",
|
|
37
|
+
"module": "./build/index.mjs",
|
|
38
|
+
"types": "./build/index.d.ts",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"import": {
|
|
42
|
+
"types": "./build/index.d.ts",
|
|
43
|
+
"default": "./build/index.mjs"
|
|
44
|
+
},
|
|
45
|
+
"require": {
|
|
46
|
+
"types": "./build/index.d.ts",
|
|
47
|
+
"default": "./build/index.js"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"./build/*": "./build/*"
|
|
51
|
+
},
|
|
38
52
|
"dependencies": {
|
|
39
|
-
"@verdaccio/core": "8.
|
|
53
|
+
"@verdaccio/core": "8.2.0",
|
|
40
54
|
"debug": "4.4.3",
|
|
41
55
|
"semver": "7.7.4"
|
|
42
56
|
},
|
|
43
57
|
"devDependencies": {
|
|
44
58
|
"@types/debug": "4.1.12",
|
|
45
|
-
"@verdaccio/config": "8.
|
|
46
|
-
"@verdaccio/logger": "8.0
|
|
47
|
-
"@verdaccio/types": "13.0.
|
|
59
|
+
"@verdaccio/config": "8.2.0",
|
|
60
|
+
"@verdaccio/logger": "8.1.0",
|
|
61
|
+
"@verdaccio/types": "13.0.5",
|
|
48
62
|
"vite": "8.0.16",
|
|
49
63
|
"vitest": "4.1.2"
|
|
50
64
|
},
|
|
51
65
|
"engines": {
|
|
52
|
-
"node": ">=
|
|
66
|
+
"node": ">=22"
|
|
53
67
|
},
|
|
54
68
|
"scripts": {
|
|
55
69
|
"clean": "rimraf ./build",
|
|
56
|
-
"build": "vite build --
|
|
57
|
-
"watch": "vite build --watch
|
|
58
|
-
"test": "vitest run"
|
|
70
|
+
"build": "vite build && tsc --emitDeclarationOnly -p tsconfig.build.json",
|
|
71
|
+
"watch": "vite build --watch",
|
|
72
|
+
"test": "vitest run",
|
|
73
|
+
"type-check": "tsc --noEmit -p tsconfig.build.json"
|
|
59
74
|
}
|
|
60
75
|
}
|