@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.
Files changed (48) hide show
  1. package/build/_virtual/_rolldown/runtime.js +23 -0
  2. package/build/config/parser.d.ts +2 -0
  3. package/build/config/parser.js +56 -0
  4. package/build/config/parser.js.map +1 -0
  5. package/build/config/parser.mjs +54 -0
  6. package/build/config/parser.mjs.map +1 -0
  7. package/build/config/types.d.ts +39 -0
  8. package/build/filtering/matcher.d.ts +8 -0
  9. package/build/filtering/matcher.js +71 -0
  10. package/build/filtering/matcher.js.map +1 -0
  11. package/build/filtering/matcher.mjs +69 -0
  12. package/build/filtering/matcher.mjs.map +1 -0
  13. package/build/filtering/packageVersion.d.ts +20 -0
  14. package/build/filtering/packageVersion.js +129 -0
  15. package/build/filtering/packageVersion.js.map +1 -0
  16. package/build/filtering/packageVersion.mjs +127 -0
  17. package/build/filtering/packageVersion.mjs.map +1 -0
  18. package/build/filtering/publishDate.d.ts +6 -0
  19. package/build/filtering/publishDate.js +33 -0
  20. package/build/filtering/publishDate.js.map +1 -0
  21. package/build/filtering/publishDate.mjs +31 -0
  22. package/build/filtering/publishDate.mjs.map +1 -0
  23. package/build/filtering/types.d.ts +24 -0
  24. package/build/filtering/types.js +11 -0
  25. package/build/filtering/types.js.map +1 -0
  26. package/build/filtering/types.mjs +11 -0
  27. package/build/filtering/types.mjs.map +1 -0
  28. package/build/index.d.ts +3 -0
  29. package/build/index.js +3 -490
  30. package/build/index.js.map +1 -1
  31. package/build/index.mjs +7 -0
  32. package/build/index.mjs.map +1 -0
  33. package/build/packageFilter.d.ts +10 -0
  34. package/build/packageFilter.js +86 -0
  35. package/build/packageFilter.js.map +1 -0
  36. package/build/packageFilter.mjs +84 -0
  37. package/build/packageFilter.mjs.map +1 -0
  38. package/build/utils/jsonUtils.d.ts +1 -0
  39. package/build/utils/jsonUtils.js +11 -0
  40. package/build/utils/jsonUtils.js.map +1 -0
  41. package/build/utils/jsonUtils.mjs +11 -0
  42. package/build/utils/jsonUtils.mjs.map +1 -0
  43. package/build/utils/manifestUtils.d.ts +36 -0
  44. package/build/utils/manifestUtils.js +129 -0
  45. package/build/utils/manifestUtils.js.map +1 -0
  46. package/build/utils/manifestUtils.mjs +121 -0
  47. package/build/utils/manifestUtils.mjs.map +1 -0
  48. package/package.json +26 -11
@@ -0,0 +1,23 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ exports.__toESM = __toESM;
@@ -0,0 +1,2 @@
1
+ import type { ParsedConfig, PluginConfig } from './types';
2
+ export declare function parseConfig(config: PluginConfig): ParsedConfig;
@@ -0,0 +1,56 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
+ let debug = require("debug");
3
+ debug = require_runtime.__toESM(debug);
4
+ let semver = require("semver");
5
+ //#region src/config/parser.ts
6
+ var debug$1 = (0, debug.default)("verdaccio:plugin:package-filter:config");
7
+ function parseConfigRules(configRules) {
8
+ const ruleMap = /* @__PURE__ */ new Map();
9
+ for (const rule of configRules) {
10
+ if ("scope" in rule && typeof rule.scope === "string") {
11
+ if (!rule.scope.startsWith("@")) throw new TypeError(`Scope value must start with @, found: ${rule.scope}`);
12
+ ruleMap.set(rule.scope, "scope");
13
+ continue;
14
+ }
15
+ if ("package" in rule && !("versions" in rule)) {
16
+ ruleMap.set(rule.package, "package");
17
+ continue;
18
+ }
19
+ if ("package" in rule && "versions" in rule) {
20
+ const previousConfig = ruleMap.get(rule.package) || { versions: [] };
21
+ if (typeof previousConfig === "string") throw new Error(`Package ${rule.package} is already specified by another strict rule ${previousConfig}`);
22
+ const range = new semver.Range(rule.versions);
23
+ ruleMap.set(rule.package, {
24
+ versions: [...previousConfig.versions, range],
25
+ strategy: rule.strategy ?? "block"
26
+ });
27
+ continue;
28
+ }
29
+ throw new TypeError(`Could not parse rule ${JSON.stringify(rule, null, 4)}`);
30
+ }
31
+ return ruleMap;
32
+ }
33
+ function parseConfig(config) {
34
+ debug$1("parsing config: %o", config);
35
+ const blockMap = parseConfigRules(config.block ?? []);
36
+ const allowMap = parseConfigRules(config.allow ?? []);
37
+ debug$1("parsed %d block rules, %d allow rules", blockMap.size, allowMap.size);
38
+ const dateThreshold = config.dateThreshold ? new Date(config.dateThreshold) : null;
39
+ if (dateThreshold && isNaN(dateThreshold.getTime())) throw new TypeError(`Invalid date ${config.dateThreshold} was provided for dateThreshold`);
40
+ const minAgeDays = config.minAgeDays ? Number(config.minAgeDays) : null;
41
+ let minAgeMs = null;
42
+ if (minAgeDays !== null) {
43
+ if (isNaN(minAgeDays) || minAgeDays < 0) throw new TypeError(`Invalid number ${config.minAgeDays} was provided for minAgeDays`);
44
+ minAgeMs = minAgeDays * 24 * 60 * 60 * 1e3;
45
+ }
46
+ return {
47
+ dateThreshold,
48
+ minAgeMs,
49
+ blockRules: blockMap,
50
+ allowRules: allowMap
51
+ };
52
+ }
53
+ //#endregion
54
+ exports.parseConfig = parseConfig;
55
+
56
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","names":[],"sources":["../../src/config/parser.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Range } from 'semver';\n\nimport type { ConfigRule, ParsedConfig, ParsedRule, PluginConfig } from './types';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter:config');\n\nfunction parseConfigRules(configRules: ConfigRule[]): Map<string, ParsedRule> {\n const ruleMap = new Map<string, ParsedRule>();\n for (const rule of configRules) {\n if ('scope' in rule && typeof rule.scope === 'string') {\n if (!rule.scope.startsWith('@')) {\n throw new TypeError(`Scope value must start with @, found: ${rule.scope}`);\n }\n\n ruleMap.set(rule.scope, 'scope');\n continue;\n }\n\n if ('package' in rule && !('versions' in rule)) {\n ruleMap.set(rule.package, 'package');\n continue;\n }\n\n if ('package' in rule && 'versions' in rule) {\n const previousConfig = ruleMap.get(rule.package) || { versions: [] };\n\n if (typeof previousConfig === 'string') {\n throw new Error(\n `Package ${rule.package} is already specified by another strict rule ${previousConfig}`\n );\n }\n\n // Merge version ranges of the rules for the same package\n const range = new Range(rule.versions);\n ruleMap.set(rule.package, {\n versions: [...previousConfig.versions, range],\n strategy: rule.strategy ?? 'block',\n });\n\n continue;\n }\n\n throw new TypeError(`Could not parse rule ${JSON.stringify(rule, null, 4)}`);\n }\n\n return ruleMap;\n}\n\nexport function parseConfig(config: PluginConfig): ParsedConfig {\n debug('parsing config: %o', config);\n const blockMap = parseConfigRules(config.block ?? []);\n const allowMap = parseConfigRules(config.allow ?? []);\n debug('parsed %d block rules, %d allow rules', blockMap.size, allowMap.size);\n const dateThreshold = config.dateThreshold ? new Date(config.dateThreshold) : null;\n if (dateThreshold && isNaN(dateThreshold.getTime())) {\n throw new TypeError(`Invalid date ${config.dateThreshold} was provided for dateThreshold`);\n }\n\n const minAgeDays = config.minAgeDays ? Number(config.minAgeDays) : null;\n let minAgeMs: number | null = null;\n if (minAgeDays !== null) {\n if (isNaN(minAgeDays) || minAgeDays < 0) {\n throw new TypeError(`Invalid number ${config.minAgeDays} was provided for minAgeDays`);\n }\n\n minAgeMs = minAgeDays * 24 * 60 * 60 * 1000;\n }\n\n return {\n dateThreshold,\n minAgeMs,\n blockRules: blockMap,\n allowRules: allowMap,\n };\n}\n"],"mappings":";;;;;AAKA,IAAM,WAAA,GAAA,MAAA,SAAmB,wCAAwC;AAEjE,SAAS,iBAAiB,aAAoD;CAC5E,MAAM,0BAAU,IAAI,IAAwB;CAC5C,KAAK,MAAM,QAAQ,aAAa;EAC9B,IAAI,WAAW,QAAQ,OAAO,KAAK,UAAU,UAAU;GACrD,IAAI,CAAC,KAAK,MAAM,WAAW,GAAG,GAC5B,MAAM,IAAI,UAAU,yCAAyC,KAAK,OAAO;GAG3E,QAAQ,IAAI,KAAK,OAAO,OAAO;GAC/B;EACF;EAEA,IAAI,aAAa,QAAQ,EAAE,cAAc,OAAO;GAC9C,QAAQ,IAAI,KAAK,SAAS,SAAS;GACnC;EACF;EAEA,IAAI,aAAa,QAAQ,cAAc,MAAM;GAC3C,MAAM,iBAAiB,QAAQ,IAAI,KAAK,OAAO,KAAK,EAAE,UAAU,CAAC,EAAE;GAEnE,IAAI,OAAO,mBAAmB,UAC5B,MAAM,IAAI,MACR,WAAW,KAAK,QAAQ,+CAA+C,gBACzE;GAIF,MAAM,QAAQ,IAAI,OAAA,MAAM,KAAK,QAAQ;GACrC,QAAQ,IAAI,KAAK,SAAS;IACxB,UAAU,CAAC,GAAG,eAAe,UAAU,KAAK;IAC5C,UAAU,KAAK,YAAY;GAC7B,CAAC;GAED;EACF;EAEA,MAAM,IAAI,UAAU,wBAAwB,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG;CAC7E;CAEA,OAAO;AACT;AAEA,SAAgB,YAAY,QAAoC;CAC9D,QAAM,sBAAsB,MAAM;CAClC,MAAM,WAAW,iBAAiB,OAAO,SAAS,CAAC,CAAC;CACpD,MAAM,WAAW,iBAAiB,OAAO,SAAS,CAAC,CAAC;CACpD,QAAM,yCAAyC,SAAS,MAAM,SAAS,IAAI;CAC3E,MAAM,gBAAgB,OAAO,gBAAgB,IAAI,KAAK,OAAO,aAAa,IAAI;CAC9E,IAAI,iBAAiB,MAAM,cAAc,QAAQ,CAAC,GAChD,MAAM,IAAI,UAAU,gBAAgB,OAAO,cAAc,gCAAgC;CAG3F,MAAM,aAAa,OAAO,aAAa,OAAO,OAAO,UAAU,IAAI;CACnE,IAAI,WAA0B;CAC9B,IAAI,eAAe,MAAM;EACvB,IAAI,MAAM,UAAU,KAAK,aAAa,GACpC,MAAM,IAAI,UAAU,kBAAkB,OAAO,WAAW,6BAA6B;EAGvF,WAAW,aAAa,KAAK,KAAK,KAAK;CACzC;CAEA,OAAO;EACL;EACA;EACA,YAAY;EACZ,YAAY;CACd;AACF"}
@@ -0,0 +1,54 @@
1
+ import buildDebug from "debug";
2
+ import { Range } from "semver";
3
+ //#region src/config/parser.ts
4
+ var debug = buildDebug("verdaccio:plugin:package-filter:config");
5
+ function parseConfigRules(configRules) {
6
+ const ruleMap = /* @__PURE__ */ new Map();
7
+ for (const rule of configRules) {
8
+ if ("scope" in rule && typeof rule.scope === "string") {
9
+ if (!rule.scope.startsWith("@")) throw new TypeError(`Scope value must start with @, found: ${rule.scope}`);
10
+ ruleMap.set(rule.scope, "scope");
11
+ continue;
12
+ }
13
+ if ("package" in rule && !("versions" in rule)) {
14
+ ruleMap.set(rule.package, "package");
15
+ continue;
16
+ }
17
+ if ("package" in rule && "versions" in rule) {
18
+ const previousConfig = ruleMap.get(rule.package) || { versions: [] };
19
+ if (typeof previousConfig === "string") throw new Error(`Package ${rule.package} is already specified by another strict rule ${previousConfig}`);
20
+ const range = new Range(rule.versions);
21
+ ruleMap.set(rule.package, {
22
+ versions: [...previousConfig.versions, range],
23
+ strategy: rule.strategy ?? "block"
24
+ });
25
+ continue;
26
+ }
27
+ throw new TypeError(`Could not parse rule ${JSON.stringify(rule, null, 4)}`);
28
+ }
29
+ return ruleMap;
30
+ }
31
+ function parseConfig(config) {
32
+ debug("parsing config: %o", config);
33
+ const blockMap = parseConfigRules(config.block ?? []);
34
+ const allowMap = parseConfigRules(config.allow ?? []);
35
+ debug("parsed %d block rules, %d allow rules", blockMap.size, allowMap.size);
36
+ const dateThreshold = config.dateThreshold ? new Date(config.dateThreshold) : null;
37
+ if (dateThreshold && isNaN(dateThreshold.getTime())) throw new TypeError(`Invalid date ${config.dateThreshold} was provided for dateThreshold`);
38
+ const minAgeDays = config.minAgeDays ? Number(config.minAgeDays) : null;
39
+ let minAgeMs = null;
40
+ if (minAgeDays !== null) {
41
+ if (isNaN(minAgeDays) || minAgeDays < 0) throw new TypeError(`Invalid number ${config.minAgeDays} was provided for minAgeDays`);
42
+ minAgeMs = minAgeDays * 24 * 60 * 60 * 1e3;
43
+ }
44
+ return {
45
+ dateThreshold,
46
+ minAgeMs,
47
+ blockRules: blockMap,
48
+ allowRules: allowMap
49
+ };
50
+ }
51
+ //#endregion
52
+ export { parseConfig };
53
+
54
+ //# sourceMappingURL=parser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.mjs","names":[],"sources":["../../src/config/parser.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Range } from 'semver';\n\nimport type { ConfigRule, ParsedConfig, ParsedRule, PluginConfig } from './types';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter:config');\n\nfunction parseConfigRules(configRules: ConfigRule[]): Map<string, ParsedRule> {\n const ruleMap = new Map<string, ParsedRule>();\n for (const rule of configRules) {\n if ('scope' in rule && typeof rule.scope === 'string') {\n if (!rule.scope.startsWith('@')) {\n throw new TypeError(`Scope value must start with @, found: ${rule.scope}`);\n }\n\n ruleMap.set(rule.scope, 'scope');\n continue;\n }\n\n if ('package' in rule && !('versions' in rule)) {\n ruleMap.set(rule.package, 'package');\n continue;\n }\n\n if ('package' in rule && 'versions' in rule) {\n const previousConfig = ruleMap.get(rule.package) || { versions: [] };\n\n if (typeof previousConfig === 'string') {\n throw new Error(\n `Package ${rule.package} is already specified by another strict rule ${previousConfig}`\n );\n }\n\n // Merge version ranges of the rules for the same package\n const range = new Range(rule.versions);\n ruleMap.set(rule.package, {\n versions: [...previousConfig.versions, range],\n strategy: rule.strategy ?? 'block',\n });\n\n continue;\n }\n\n throw new TypeError(`Could not parse rule ${JSON.stringify(rule, null, 4)}`);\n }\n\n return ruleMap;\n}\n\nexport function parseConfig(config: PluginConfig): ParsedConfig {\n debug('parsing config: %o', config);\n const blockMap = parseConfigRules(config.block ?? []);\n const allowMap = parseConfigRules(config.allow ?? []);\n debug('parsed %d block rules, %d allow rules', blockMap.size, allowMap.size);\n const dateThreshold = config.dateThreshold ? new Date(config.dateThreshold) : null;\n if (dateThreshold && isNaN(dateThreshold.getTime())) {\n throw new TypeError(`Invalid date ${config.dateThreshold} was provided for dateThreshold`);\n }\n\n const minAgeDays = config.minAgeDays ? Number(config.minAgeDays) : null;\n let minAgeMs: number | null = null;\n if (minAgeDays !== null) {\n if (isNaN(minAgeDays) || minAgeDays < 0) {\n throw new TypeError(`Invalid number ${config.minAgeDays} was provided for minAgeDays`);\n }\n\n minAgeMs = minAgeDays * 24 * 60 * 60 * 1000;\n }\n\n return {\n dateThreshold,\n minAgeMs,\n blockRules: blockMap,\n allowRules: allowMap,\n };\n}\n"],"mappings":";;;AAKA,IAAM,QAAQ,WAAW,wCAAwC;AAEjE,SAAS,iBAAiB,aAAoD;CAC5E,MAAM,0BAAU,IAAI,IAAwB;CAC5C,KAAK,MAAM,QAAQ,aAAa;EAC9B,IAAI,WAAW,QAAQ,OAAO,KAAK,UAAU,UAAU;GACrD,IAAI,CAAC,KAAK,MAAM,WAAW,GAAG,GAC5B,MAAM,IAAI,UAAU,yCAAyC,KAAK,OAAO;GAG3E,QAAQ,IAAI,KAAK,OAAO,OAAO;GAC/B;EACF;EAEA,IAAI,aAAa,QAAQ,EAAE,cAAc,OAAO;GAC9C,QAAQ,IAAI,KAAK,SAAS,SAAS;GACnC;EACF;EAEA,IAAI,aAAa,QAAQ,cAAc,MAAM;GAC3C,MAAM,iBAAiB,QAAQ,IAAI,KAAK,OAAO,KAAK,EAAE,UAAU,CAAC,EAAE;GAEnE,IAAI,OAAO,mBAAmB,UAC5B,MAAM,IAAI,MACR,WAAW,KAAK,QAAQ,+CAA+C,gBACzE;GAIF,MAAM,QAAQ,IAAI,MAAM,KAAK,QAAQ;GACrC,QAAQ,IAAI,KAAK,SAAS;IACxB,UAAU,CAAC,GAAG,eAAe,UAAU,KAAK;IAC5C,UAAU,KAAK,YAAY;GAC7B,CAAC;GAED;EACF;EAEA,MAAM,IAAI,UAAU,wBAAwB,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG;CAC7E;CAEA,OAAO;AACT;AAEA,SAAgB,YAAY,QAAoC;CAC9D,MAAM,sBAAsB,MAAM;CAClC,MAAM,WAAW,iBAAiB,OAAO,SAAS,CAAC,CAAC;CACpD,MAAM,WAAW,iBAAiB,OAAO,SAAS,CAAC,CAAC;CACpD,MAAM,yCAAyC,SAAS,MAAM,SAAS,IAAI;CAC3E,MAAM,gBAAgB,OAAO,gBAAgB,IAAI,KAAK,OAAO,aAAa,IAAI;CAC9E,IAAI,iBAAiB,MAAM,cAAc,QAAQ,CAAC,GAChD,MAAM,IAAI,UAAU,gBAAgB,OAAO,cAAc,gCAAgC;CAG3F,MAAM,aAAa,OAAO,aAAa,OAAO,OAAO,UAAU,IAAI;CACnE,IAAI,WAA0B;CAC9B,IAAI,eAAe,MAAM;EACvB,IAAI,MAAM,UAAU,KAAK,aAAa,GACpC,MAAM,IAAI,UAAU,kBAAkB,OAAO,WAAW,6BAA6B;EAGvF,WAAW,aAAa,KAAK,KAAK,KAAK;CACzC;CAEA,OAAO;EACL;EACA;EACA,YAAY;EACZ,YAAY;CACd;AACF"}
@@ -0,0 +1,39 @@
1
+ import type { Range } from 'semver';
2
+ export type BlockStrategy = 'block' | 'replace';
3
+ export type ConfigRule = {
4
+ scope: string;
5
+ } | {
6
+ package: string;
7
+ } | {
8
+ package: string;
9
+ versions: string;
10
+ strategy?: BlockStrategy;
11
+ };
12
+ export interface PluginConfig {
13
+ /**
14
+ * An absolute date cutoff (e.g. '2023-01-01'). Versions published after this
15
+ * date will be blocked. When both `dateThreshold` and `minAgeDays` are set,
16
+ * the earlier (more restrictive) date wins.
17
+ */
18
+ dateThreshold?: string | number;
19
+ /**
20
+ * A relative age cutoff in days. Versions published less than this many days
21
+ * ago will be blocked. When both `minAgeDays` and `dateThreshold` are set,
22
+ * the earlier (more restrictive) date wins.
23
+ */
24
+ minAgeDays?: number;
25
+ block?: ConfigRule[];
26
+ allow?: ConfigRule[];
27
+ }
28
+ export interface ParsedConfigRule {
29
+ versions: Range[];
30
+ strategy?: BlockStrategy;
31
+ }
32
+ export type PackageScopeLevel = 'scope' | 'package' | undefined;
33
+ export type ParsedRule = ParsedConfigRule | PackageScopeLevel;
34
+ export interface ParsedConfig {
35
+ dateThreshold: Date | null;
36
+ minAgeMs: number | null;
37
+ blockRules: Map<string, ParsedRule>;
38
+ allowRules: Map<string, ParsedRule>;
39
+ }
@@ -0,0 +1,8 @@
1
+ import type { Manifest } from '@verdaccio/types';
2
+ import type { ParsedRule } from '../config/types';
3
+ import type { MatchResult } from './types';
4
+ /**
5
+ * Try to find a rule that matches the package.
6
+ * If found, returns the rule and the matched package versions from the manifest.
7
+ */
8
+ export declare function matchRules(manifest: Manifest, rules: Map<string, ParsedRule>): MatchResult | undefined;
@@ -0,0 +1,71 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
+ const require_types = require("./types.js");
3
+ let debug = require("debug");
4
+ debug = require_runtime.__toESM(debug);
5
+ let semver = require("semver");
6
+ //#region src/filtering/matcher.ts
7
+ var debug$1 = (0, debug.default)("verdaccio:plugin:package-filter:filter");
8
+ /**
9
+ * Split a package name into name itself and scope.
10
+ */
11
+ function splitName(name) {
12
+ if (!name) return { name: "" };
13
+ const parts = name.split("/");
14
+ if (parts.length > 1) return {
15
+ scope: parts[0],
16
+ name: parts[1]
17
+ };
18
+ else return { name: parts[0] };
19
+ }
20
+ /**
21
+ * Try to find a rule that matches the package.
22
+ * If found, returns the rule and the matched package versions from the manifest.
23
+ */
24
+ function matchRules(manifest, rules) {
25
+ const { scope } = splitName(manifest.name);
26
+ if (scope) {
27
+ const rule = rules.get(scope);
28
+ if (rule === "scope") {
29
+ debug$1("scope match: %s matched rule for %s", manifest.name, scope);
30
+ return {
31
+ type: require_types.MatchType.SCOPE,
32
+ rule,
33
+ scope,
34
+ versions: Object.keys(manifest.versions)
35
+ };
36
+ }
37
+ }
38
+ const rule = rules.get(manifest.name);
39
+ if (!rule) return;
40
+ if (rule === "package") {
41
+ debug$1("package match: %s", manifest.name);
42
+ return {
43
+ type: require_types.MatchType.PACKAGE,
44
+ rule,
45
+ package: manifest.name,
46
+ versions: Object.keys(manifest.versions)
47
+ };
48
+ }
49
+ if (rule === "scope") throw new Error("Unexpected case - rule for package should never be \"scope\"");
50
+ const versionRanges = rule.versions;
51
+ if (versionRanges.length === 0) return;
52
+ const matchedVersions = [];
53
+ Object.keys(manifest.versions).forEach((version) => {
54
+ versionRanges.forEach((versionRange) => {
55
+ if ((0, semver.satisfies)(version, versionRange, {
56
+ includePrerelease: true,
57
+ loose: true
58
+ })) matchedVersions.push(version);
59
+ });
60
+ });
61
+ if (matchedVersions.length > 0) debug$1("version match: %s matched %d versions: %o", manifest.name, matchedVersions.length, matchedVersions);
62
+ return {
63
+ type: require_types.MatchType.VERSIONS,
64
+ rule,
65
+ versions: matchedVersions
66
+ };
67
+ }
68
+ //#endregion
69
+ exports.matchRules = matchRules;
70
+
71
+ //# sourceMappingURL=matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.js","names":[],"sources":["../../src/filtering/matcher.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { satisfies } from 'semver';\n\nimport type { Manifest } from '@verdaccio/types';\n\nimport type { ParsedRule } from '../config/types';\nimport type { MatchResult } from './types';\nimport { MatchType } from './types';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter:filter');\n\n/**\n * Split a package name into name itself and scope.\n */\nfunction splitName(name: string): { name: string; scope?: string } {\n if (!name) {\n return { name: '' };\n }\n\n const parts = name.split('/');\n\n if (parts.length > 1) {\n return {\n scope: parts[0],\n name: parts[1],\n };\n } else {\n return {\n name: parts[0],\n };\n }\n}\n\n/**\n * Try to find a rule that matches the package.\n * If found, returns the rule and the matched package versions from the manifest.\n */\nexport function matchRules(\n manifest: Manifest,\n rules: Map<string, ParsedRule>\n): MatchResult | undefined {\n const { scope } = splitName(manifest.name);\n if (scope) {\n const rule = rules.get(scope);\n if (rule === 'scope') {\n debug('scope match: %s matched rule for %s', manifest.name, scope);\n return {\n type: MatchType.SCOPE,\n rule,\n scope,\n versions: Object.keys(manifest.versions),\n };\n }\n }\n\n const rule = rules.get(manifest.name);\n if (!rule) {\n // No match\n return undefined;\n }\n\n if (rule === 'package') {\n debug('package match: %s', manifest.name);\n return {\n type: MatchType.PACKAGE,\n rule,\n package: manifest.name,\n versions: Object.keys(manifest.versions),\n };\n }\n\n if (rule === 'scope') {\n throw new Error('Unexpected case - rule for package should never be \"scope\"');\n }\n\n const versionRanges = rule.versions;\n if (versionRanges.length === 0) {\n // No match\n return undefined;\n }\n\n const matchedVersions: string[] = [];\n Object.keys(manifest.versions).forEach((version) => {\n versionRanges.forEach((versionRange) => {\n if (\n satisfies(version, versionRange, {\n includePrerelease: true,\n loose: true,\n })\n ) {\n matchedVersions.push(version);\n }\n });\n });\n\n if (matchedVersions.length > 0) {\n debug(\n 'version match: %s matched %d versions: %o',\n manifest.name,\n matchedVersions.length,\n matchedVersions\n );\n }\n\n return {\n type: MatchType.VERSIONS,\n rule,\n versions: matchedVersions,\n };\n}\n"],"mappings":";;;;;;AASA,IAAM,WAAA,GAAA,MAAA,SAAmB,wCAAwC;;;;AAKjE,SAAS,UAAU,MAAgD;CACjE,IAAI,CAAC,MACH,OAAO,EAAE,MAAM,GAAG;CAGpB,MAAM,QAAQ,KAAK,MAAM,GAAG;CAE5B,IAAI,MAAM,SAAS,GACjB,OAAO;EACL,OAAO,MAAM;EACb,MAAM,MAAM;CACd;MAEA,OAAO,EACL,MAAM,MAAM,GACd;AAEJ;;;;;AAMA,SAAgB,WACd,UACA,OACyB;CACzB,MAAM,EAAE,UAAU,UAAU,SAAS,IAAI;CACzC,IAAI,OAAO;EACT,MAAM,OAAO,MAAM,IAAI,KAAK;EAC5B,IAAI,SAAS,SAAS;GACpB,QAAM,uCAAuC,SAAS,MAAM,KAAK;GACjE,OAAO;IACL,MAAM,cAAA,UAAU;IAChB;IACA;IACA,UAAU,OAAO,KAAK,SAAS,QAAQ;GACzC;EACF;CACF;CAEA,MAAM,OAAO,MAAM,IAAI,SAAS,IAAI;CACpC,IAAI,CAAC,MAEH;CAGF,IAAI,SAAS,WAAW;EACtB,QAAM,qBAAqB,SAAS,IAAI;EACxC,OAAO;GACL,MAAM,cAAA,UAAU;GAChB;GACA,SAAS,SAAS;GAClB,UAAU,OAAO,KAAK,SAAS,QAAQ;EACzC;CACF;CAEA,IAAI,SAAS,SACX,MAAM,IAAI,MAAM,8DAA4D;CAG9E,MAAM,gBAAgB,KAAK;CAC3B,IAAI,cAAc,WAAW,GAE3B;CAGF,MAAM,kBAA4B,CAAC;CACnC,OAAO,KAAK,SAAS,QAAQ,EAAE,SAAS,YAAY;EAClD,cAAc,SAAS,iBAAiB;GACtC,KAAA,GAAA,OAAA,WACY,SAAS,cAAc;IAC/B,mBAAmB;IACnB,OAAO;GACT,CAAC,GAED,gBAAgB,KAAK,OAAO;EAEhC,CAAC;CACH,CAAC;CAED,IAAI,gBAAgB,SAAS,GAC3B,QACE,6CACA,SAAS,MACT,gBAAgB,QAChB,eACF;CAGF,OAAO;EACL,MAAM,cAAA,UAAU;EAChB;EACA,UAAU;CACZ;AACF"}
@@ -0,0 +1,69 @@
1
+ import { MatchType } from "./types.mjs";
2
+ import buildDebug from "debug";
3
+ import { satisfies } from "semver";
4
+ //#region src/filtering/matcher.ts
5
+ var debug = buildDebug("verdaccio:plugin:package-filter:filter");
6
+ /**
7
+ * Split a package name into name itself and scope.
8
+ */
9
+ function splitName(name) {
10
+ if (!name) return { name: "" };
11
+ const parts = name.split("/");
12
+ if (parts.length > 1) return {
13
+ scope: parts[0],
14
+ name: parts[1]
15
+ };
16
+ else return { name: parts[0] };
17
+ }
18
+ /**
19
+ * Try to find a rule that matches the package.
20
+ * If found, returns the rule and the matched package versions from the manifest.
21
+ */
22
+ function matchRules(manifest, rules) {
23
+ const { scope } = splitName(manifest.name);
24
+ if (scope) {
25
+ const rule = rules.get(scope);
26
+ if (rule === "scope") {
27
+ debug("scope match: %s matched rule for %s", manifest.name, scope);
28
+ return {
29
+ type: MatchType.SCOPE,
30
+ rule,
31
+ scope,
32
+ versions: Object.keys(manifest.versions)
33
+ };
34
+ }
35
+ }
36
+ const rule = rules.get(manifest.name);
37
+ if (!rule) return;
38
+ if (rule === "package") {
39
+ debug("package match: %s", manifest.name);
40
+ return {
41
+ type: MatchType.PACKAGE,
42
+ rule,
43
+ package: manifest.name,
44
+ versions: Object.keys(manifest.versions)
45
+ };
46
+ }
47
+ if (rule === "scope") throw new Error("Unexpected case - rule for package should never be \"scope\"");
48
+ const versionRanges = rule.versions;
49
+ if (versionRanges.length === 0) return;
50
+ const matchedVersions = [];
51
+ Object.keys(manifest.versions).forEach((version) => {
52
+ versionRanges.forEach((versionRange) => {
53
+ if (satisfies(version, versionRange, {
54
+ includePrerelease: true,
55
+ loose: true
56
+ })) matchedVersions.push(version);
57
+ });
58
+ });
59
+ if (matchedVersions.length > 0) debug("version match: %s matched %d versions: %o", manifest.name, matchedVersions.length, matchedVersions);
60
+ return {
61
+ type: MatchType.VERSIONS,
62
+ rule,
63
+ versions: matchedVersions
64
+ };
65
+ }
66
+ //#endregion
67
+ export { matchRules };
68
+
69
+ //# sourceMappingURL=matcher.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.mjs","names":[],"sources":["../../src/filtering/matcher.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { satisfies } from 'semver';\n\nimport type { Manifest } from '@verdaccio/types';\n\nimport type { ParsedRule } from '../config/types';\nimport type { MatchResult } from './types';\nimport { MatchType } from './types';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter:filter');\n\n/**\n * Split a package name into name itself and scope.\n */\nfunction splitName(name: string): { name: string; scope?: string } {\n if (!name) {\n return { name: '' };\n }\n\n const parts = name.split('/');\n\n if (parts.length > 1) {\n return {\n scope: parts[0],\n name: parts[1],\n };\n } else {\n return {\n name: parts[0],\n };\n }\n}\n\n/**\n * Try to find a rule that matches the package.\n * If found, returns the rule and the matched package versions from the manifest.\n */\nexport function matchRules(\n manifest: Manifest,\n rules: Map<string, ParsedRule>\n): MatchResult | undefined {\n const { scope } = splitName(manifest.name);\n if (scope) {\n const rule = rules.get(scope);\n if (rule === 'scope') {\n debug('scope match: %s matched rule for %s', manifest.name, scope);\n return {\n type: MatchType.SCOPE,\n rule,\n scope,\n versions: Object.keys(manifest.versions),\n };\n }\n }\n\n const rule = rules.get(manifest.name);\n if (!rule) {\n // No match\n return undefined;\n }\n\n if (rule === 'package') {\n debug('package match: %s', manifest.name);\n return {\n type: MatchType.PACKAGE,\n rule,\n package: manifest.name,\n versions: Object.keys(manifest.versions),\n };\n }\n\n if (rule === 'scope') {\n throw new Error('Unexpected case - rule for package should never be \"scope\"');\n }\n\n const versionRanges = rule.versions;\n if (versionRanges.length === 0) {\n // No match\n return undefined;\n }\n\n const matchedVersions: string[] = [];\n Object.keys(manifest.versions).forEach((version) => {\n versionRanges.forEach((versionRange) => {\n if (\n satisfies(version, versionRange, {\n includePrerelease: true,\n loose: true,\n })\n ) {\n matchedVersions.push(version);\n }\n });\n });\n\n if (matchedVersions.length > 0) {\n debug(\n 'version match: %s matched %d versions: %o',\n manifest.name,\n matchedVersions.length,\n matchedVersions\n );\n }\n\n return {\n type: MatchType.VERSIONS,\n rule,\n versions: matchedVersions,\n };\n}\n"],"mappings":";;;;AASA,IAAM,QAAQ,WAAW,wCAAwC;;;;AAKjE,SAAS,UAAU,MAAgD;CACjE,IAAI,CAAC,MACH,OAAO,EAAE,MAAM,GAAG;CAGpB,MAAM,QAAQ,KAAK,MAAM,GAAG;CAE5B,IAAI,MAAM,SAAS,GACjB,OAAO;EACL,OAAO,MAAM;EACb,MAAM,MAAM;CACd;MAEA,OAAO,EACL,MAAM,MAAM,GACd;AAEJ;;;;;AAMA,SAAgB,WACd,UACA,OACyB;CACzB,MAAM,EAAE,UAAU,UAAU,SAAS,IAAI;CACzC,IAAI,OAAO;EACT,MAAM,OAAO,MAAM,IAAI,KAAK;EAC5B,IAAI,SAAS,SAAS;GACpB,MAAM,uCAAuC,SAAS,MAAM,KAAK;GACjE,OAAO;IACL,MAAM,UAAU;IAChB;IACA;IACA,UAAU,OAAO,KAAK,SAAS,QAAQ;GACzC;EACF;CACF;CAEA,MAAM,OAAO,MAAM,IAAI,SAAS,IAAI;CACpC,IAAI,CAAC,MAEH;CAGF,IAAI,SAAS,WAAW;EACtB,MAAM,qBAAqB,SAAS,IAAI;EACxC,OAAO;GACL,MAAM,UAAU;GAChB;GACA,SAAS,SAAS;GAClB,UAAU,OAAO,KAAK,SAAS,QAAQ;EACzC;CACF;CAEA,IAAI,SAAS,SACX,MAAM,IAAI,MAAM,8DAA4D;CAG9E,MAAM,gBAAgB,KAAK;CAC3B,IAAI,cAAc,WAAW,GAE3B;CAGF,MAAM,kBAA4B,CAAC;CACnC,OAAO,KAAK,SAAS,QAAQ,EAAE,SAAS,YAAY;EAClD,cAAc,SAAS,iBAAiB;GACtC,IACE,UAAU,SAAS,cAAc;IAC/B,mBAAmB;IACnB,OAAO;GACT,CAAC,GAED,gBAAgB,KAAK,OAAO;EAEhC,CAAC;CACH,CAAC;CAED,IAAI,gBAAgB,SAAS,GAC3B,MACE,6CACA,SAAS,MACT,gBAAgB,QAChB,eACF;CAGF,OAAO;EACL,MAAM,UAAU;EAChB;EACA,UAAU;CACZ;AACF"}
@@ -0,0 +1,20 @@
1
+ import type { Logger, Manifest } from '@verdaccio/types';
2
+ import type { ParsedRule } from '../config/types';
3
+ /**
4
+ * Filter out all blocked package versions.
5
+ * If package or scope is blocked, then block all versions.
6
+ *
7
+ * TODO: consider adding a `prerelease` filter option to block/allow
8
+ * prerelease versions independently. Currently prereleases are matched by
9
+ * semver ranges with `includePrerelease: true`, but there's no dedicated toggle.
10
+ *
11
+ * Example config (not yet implemented):
12
+ * block:
13
+ * - package: 'foo'
14
+ * prerelease: true # block 1.0.0-beta.1, 2.0.0-rc.1, keep 1.0.0, 2.0.0
15
+ * - package: 'bar'
16
+ * prerelease: false # block 1.0.0, 2.0.0, keep 1.0.0-beta.1
17
+ *
18
+ * Today the only workaround is using awkward ranges like ">=1.0.0-0 <1.0.0".
19
+ */
20
+ export declare function filterBlockedVersions(manifest: Manifest, blockRules: Map<string, ParsedRule>, allowRules: Map<string, ParsedRule>, logger: Logger): Manifest;
@@ -0,0 +1,129 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
+ const require_types = require("./types.js");
3
+ const require_matcher = require("./matcher.js");
4
+ let debug = require("debug");
5
+ debug = require_runtime.__toESM(debug);
6
+ let semver = require("semver");
7
+ //#region src/filtering/packageVersion.ts
8
+ var debug$1 = (0, debug.default)("verdaccio:plugin:package-filter:filter");
9
+ /**
10
+ * Filter out all blocked package versions.
11
+ * If package or scope is blocked, then block all versions.
12
+ *
13
+ * TODO: consider adding a `prerelease` filter option to block/allow
14
+ * prerelease versions independently. Currently prereleases are matched by
15
+ * semver ranges with `includePrerelease: true`, but there's no dedicated toggle.
16
+ *
17
+ * Example config (not yet implemented):
18
+ * block:
19
+ * - package: 'foo'
20
+ * prerelease: true # block 1.0.0-beta.1, 2.0.0-rc.1, keep 1.0.0, 2.0.0
21
+ * - package: 'bar'
22
+ * prerelease: false # block 1.0.0, 2.0.0, keep 1.0.0-beta.1
23
+ *
24
+ * Today the only workaround is using awkward ranges like ">=1.0.0-0 <1.0.0".
25
+ */
26
+ function filterBlockedVersions(manifest, blockRules, allowRules, logger) {
27
+ const allowMatch = require_matcher.matchRules(manifest, allowRules);
28
+ if (allowMatch && (allowMatch.type === require_types.MatchType.SCOPE || allowMatch.type === require_types.MatchType.PACKAGE)) {
29
+ logger.trace({ name: manifest.name }, "package @{name} is allow-listed, skipping block rules");
30
+ return manifest;
31
+ }
32
+ const blockMatch = require_matcher.matchRules(manifest, blockRules);
33
+ if (!blockMatch) return manifest;
34
+ logger.trace({
35
+ name: manifest.name,
36
+ type: blockMatch.type
37
+ }, "block rule matched for @{name} (type: @{type})");
38
+ const whitelistedVersions = allowMatch ? allowMatch.versions : [];
39
+ let blockRule = {
40
+ versions: [new semver.Range("*")],
41
+ strategy: "block"
42
+ };
43
+ if (blockMatch.type === require_types.MatchType.SCOPE) {
44
+ if (whitelistedVersions.length === 0) {
45
+ debug$1("blocking all versions of %s (scope %s blocked)", manifest.name, blockMatch.scope);
46
+ logger.trace({
47
+ name: manifest.name,
48
+ scope: blockMatch.scope
49
+ }, "all versions of @{name} blocked (scope @{scope})");
50
+ return {
51
+ ...manifest,
52
+ versions: {},
53
+ readme: `All packages in scope ${blockMatch.scope} are blocked by rule`
54
+ };
55
+ }
56
+ } else if (blockMatch.type === require_types.MatchType.PACKAGE) {
57
+ if (whitelistedVersions.length === 0) {
58
+ debug$1("blocking all versions of %s (package blocked)", manifest.name);
59
+ logger.trace({ name: manifest.name }, "all versions of @{name} blocked (package rule)");
60
+ return {
61
+ ...manifest,
62
+ versions: {},
63
+ readme: `All package versions are blocked by rule`
64
+ };
65
+ }
66
+ } else blockRule = {
67
+ ...blockRule,
68
+ ...blockMatch.rule
69
+ };
70
+ const versionRanges = blockRule.versions;
71
+ if (blockRule.strategy === "block") {
72
+ const blockedVersions = blockMatch.versions.filter((v) => !whitelistedVersions.includes(v));
73
+ for (const version of blockedVersions) delete manifest.versions[version];
74
+ if (blockedVersions.length > 0) {
75
+ debug$1("blocked %d versions of %s: %o", blockedVersions.length, manifest.name, blockedVersions);
76
+ logger.trace({
77
+ name: manifest.name,
78
+ count: blockedVersions.length,
79
+ versions: blockedVersions.join(", ")
80
+ }, "@{count} versions of @{name} blocked: @{versions}");
81
+ manifest.readme = (manifest.readme || "") + `\nSome versions(${blockedVersions.length}) of package are blocked by rules: ${versionRanges.map((range) => range.raw)}`;
82
+ }
83
+ return manifest;
84
+ }
85
+ const nonBlockedVersions = { ...manifest.versions };
86
+ const newVersionsMapping = {};
87
+ versionRanges.forEach((versionRange) => {
88
+ const allVersions = Object.keys(nonBlockedVersions);
89
+ let lastNonBlockedVersion = null;
90
+ allVersions.forEach((version) => {
91
+ if (!whitelistedVersions.includes(version) && (0, semver.satisfies)(version, versionRange, {
92
+ includePrerelease: true,
93
+ loose: true
94
+ })) {
95
+ delete nonBlockedVersions[version];
96
+ newVersionsMapping[version] = lastNonBlockedVersion;
97
+ } else lastNonBlockedVersion = version;
98
+ });
99
+ });
100
+ debug$1("replacing versions for %s: %o", manifest.name, newVersionsMapping);
101
+ const removedVersions = Object.entries(newVersionsMapping).filter(([_, replace]) => replace === null);
102
+ const replacedVersions = Object.entries(newVersionsMapping).filter(([_, replace]) => replace !== null);
103
+ removedVersions.forEach(([version]) => {
104
+ debug$1("no version to replace %s in %s", version, manifest.name);
105
+ logger.trace({
106
+ name: manifest.name,
107
+ version
108
+ }, "version @{version} of @{name} removed (no replacement available)");
109
+ delete manifest.versions[version];
110
+ });
111
+ replacedVersions.forEach(([version, replaceVersion]) => {
112
+ logger.trace({
113
+ name: manifest.name,
114
+ version,
115
+ replaceVersion
116
+ }, "version @{version} of @{name} replaced with @{replaceVersion}");
117
+ manifest.versions[version] = {
118
+ ...manifest.versions[replaceVersion],
119
+ version
120
+ };
121
+ });
122
+ if (removedVersions.length > 0) manifest.readme += `\nSome versions of package could not be replaced and thus are fully blocked (${removedVersions.length}): ${removedVersions.map((a) => a[0])}`;
123
+ if (replacedVersions.length > 0) manifest.readme += `\nSome versions of package are replaced by other(${replacedVersions.length}): ${replacedVersions.map((a) => `${a[0]} => ${a[1]}`)}`;
124
+ return manifest;
125
+ }
126
+ //#endregion
127
+ exports.filterBlockedVersions = filterBlockedVersions;
128
+
129
+ //# sourceMappingURL=packageVersion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.js","names":[],"sources":["../../src/filtering/packageVersion.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Range, satisfies } from 'semver';\n\nimport type { Logger, Manifest } from '@verdaccio/types';\n\nimport type { ParsedConfigRule, ParsedRule } from '../config/types';\nimport { matchRules } from './matcher';\nimport { MatchType } from './types';\n\nconst debug = buildDebug('verdaccio:plugin:package-filter:filter');\n\n/**\n * Filter out all blocked package versions.\n * If package or scope is blocked, then block all versions.\n *\n * TODO: consider adding a `prerelease` filter option to block/allow\n * prerelease versions independently. Currently prereleases are matched by\n * semver ranges with `includePrerelease: true`, but there's no dedicated toggle.\n *\n * Example config (not yet implemented):\n * block:\n * - package: 'foo'\n * prerelease: true # block 1.0.0-beta.1, 2.0.0-rc.1, keep 1.0.0, 2.0.0\n * - package: 'bar'\n * prerelease: false # block 1.0.0, 2.0.0, keep 1.0.0-beta.1\n *\n * Today the only workaround is using awkward ranges like \">=1.0.0-0 <1.0.0\".\n */\nexport function filterBlockedVersions(\n manifest: Manifest,\n blockRules: Map<string, ParsedRule>,\n allowRules: Map<string, ParsedRule>,\n logger: Logger\n): Manifest {\n const allowMatch = matchRules(manifest, allowRules);\n if (\n allowMatch &&\n (allowMatch.type === MatchType.SCOPE || allowMatch.type === MatchType.PACKAGE)\n ) {\n // An entire scope or package is whitelisted\n logger.trace({ name: manifest.name }, 'package @{name} is allow-listed, skipping block rules');\n return manifest;\n }\n\n const blockMatch = matchRules(manifest, blockRules);\n if (!blockMatch) {\n // No rule is blocking this package\n return manifest;\n }\n\n logger.trace(\n { name: manifest.name, type: blockMatch.type },\n 'block rule matched for @{name} (type: @{type})'\n );\n\n const whitelistedVersions: string[] = allowMatch ? allowMatch.versions : [];\n let blockRule: ParsedConfigRule = {\n versions: [new Range('*')],\n strategy: 'block',\n };\n\n if (blockMatch.type === MatchType.SCOPE) {\n if (whitelistedVersions.length === 0) {\n debug('blocking all versions of %s (scope %s blocked)', manifest.name, blockMatch.scope);\n logger.trace(\n { name: manifest.name, scope: blockMatch.scope },\n 'all versions of @{name} blocked (scope @{scope})'\n );\n return {\n ...manifest,\n versions: {},\n readme: `All packages in scope ${blockMatch.scope} are blocked by rule`,\n };\n }\n } else if (blockMatch.type === MatchType.PACKAGE) {\n if (whitelistedVersions.length === 0) {\n debug('blocking all versions of %s (package blocked)', manifest.name);\n logger.trace({ name: manifest.name }, 'all versions of @{name} blocked (package rule)');\n return {\n ...manifest,\n versions: {},\n readme: `All package versions are blocked by rule`,\n };\n }\n } else {\n blockRule = { ...blockRule, ...blockMatch.rule };\n }\n\n const versionRanges = blockRule.versions;\n\n if (blockRule.strategy === 'block') {\n const blockedVersions = blockMatch.versions.filter((v) => !whitelistedVersions.includes(v));\n for (const version of blockedVersions) {\n delete manifest.versions[version];\n }\n\n if (blockedVersions.length > 0) {\n debug(\n 'blocked %d versions of %s: %o',\n blockedVersions.length,\n manifest.name,\n blockedVersions\n );\n logger.trace(\n {\n name: manifest.name,\n count: blockedVersions.length,\n versions: blockedVersions.join(', '),\n },\n '@{count} versions of @{name} blocked: @{versions}'\n );\n // Add debug info for devs\n manifest.readme =\n (manifest.readme || '') +\n `\\nSome versions(${blockedVersions.length}) of package are blocked by rules: ${versionRanges.map(\n (range) => range.raw\n )}`;\n }\n\n return manifest;\n }\n\n // Process block rule strategy 'replace'.\n // We assume that the order of versions is already sorted.\n const nonBlockedVersions = { ...manifest.versions };\n const newVersionsMapping: Record<string, string | null> = {};\n\n versionRanges.forEach((versionRange) => {\n const allVersions = Object.keys(nonBlockedVersions);\n\n let lastNonBlockedVersion: string | null = null;\n\n allVersions.forEach((version) => {\n if (\n !whitelistedVersions.includes(version) &&\n satisfies(version, versionRange, {\n includePrerelease: true,\n loose: true,\n })\n ) {\n delete nonBlockedVersions[version];\n newVersionsMapping[version] = lastNonBlockedVersion;\n } else {\n lastNonBlockedVersion = version;\n }\n });\n });\n\n debug('replacing versions for %s: %o', manifest.name, newVersionsMapping);\n\n const removedVersions = Object.entries(newVersionsMapping).filter(\n ([_, replace]) => replace === null\n ) as [string, null][];\n const replacedVersions = Object.entries(newVersionsMapping).filter(\n ([_, replace]) => replace !== null\n ) as [string, string][];\n\n removedVersions.forEach(([version]) => {\n debug('no version to replace %s in %s', version, manifest.name);\n logger.trace(\n { name: manifest.name, version },\n 'version @{version} of @{name} removed (no replacement available)'\n );\n delete manifest.versions[version];\n });\n\n replacedVersions.forEach(([version, replaceVersion]) => {\n logger.trace(\n { name: manifest.name, version, replaceVersion },\n 'version @{version} of @{name} replaced with @{replaceVersion}'\n );\n manifest.versions[version] = {\n ...manifest.versions[replaceVersion],\n version,\n };\n });\n\n if (removedVersions.length > 0) {\n manifest.readme +=\n `\\nSome versions of package could not be replaced and thus are fully blocked (${removedVersions.length}):` +\n ` ${removedVersions.map((a) => a[0])}`;\n }\n\n if (replacedVersions.length > 0) {\n manifest.readme +=\n `\\nSome versions of package are replaced by other(${replacedVersions.length}):` +\n ` ${replacedVersions.map((a) => `${a[0]} => ${a[1]}`)}`;\n }\n\n return manifest;\n}\n"],"mappings":"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"}