@uxf/scripts 11.107.0 → 11.109.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/README.md CHANGED
@@ -63,6 +63,56 @@ notify-push:
63
63
  - uxf-push-notifier --google-chat-webhook-url=$GOOGLE_CHAT_WEBHOOK
64
64
  ```
65
65
 
66
+ ## uxf-dependencies-check
67
+
68
+ All-in-one dependency health check for projects using `@uxf/*` packages. Runs two checks:
69
+
70
+ 1. **Version conflict detection** — parses the lock file and reports dependencies of `@uxf/*` packages that resolve to multiple versions
71
+ 2. **Peer dependency check** — verifies that all `peerDependencies` of installed `@uxf/*` packages are present and version-matched
72
+
73
+ Supports **yarn**, **npm**, **pnpm**, and **bun**. The package manager is auto-detected from the lock file.
74
+
75
+ Requires `tsx` or another tool to execute typescript (typically already available in your project's `devDependencies`).
76
+
77
+ ```bash
78
+ Usage:
79
+ uxf-dependencies-check [options]
80
+
81
+ Options:
82
+ --fix Auto-install missing/mismatched peer dependencies
83
+ --dry-run Show what would be installed without changes
84
+ -e, --exclude Packages to ignore in conflict check [array]
85
+ -h, --help Show help [boolean]
86
+ ```
87
+
88
+ Build-time dependencies (`yargs`, `fast-glob`) are automatically ignored in the conflict check.
89
+
90
+ ### Examples
91
+
92
+ ```bash
93
+ # Run both checks (exits with code 1 if issues found)
94
+ npx tsx -dependencies-check
95
+
96
+ # Auto-install missing peer deps
97
+ npx tsx uxf-dependencies-check --fix
98
+
99
+ # Preview what would be installed
100
+ npx tsx uxf-dependencies-check --dry-run
101
+
102
+ # Ignore specific packages in conflict check
103
+ npx tsx uxf-dependencies-check --exclude lodash dayjs
104
+ ```
105
+
106
+ ### What it checks
107
+
108
+ - Parses the lock file (yarn.lock / package-lock.json / pnpm-lock.yaml / bun.lock) to detect version conflicts
109
+ - Scans all `@uxf/*` packages in your `dependencies` / `devDependencies`
110
+ - Reads each package's `peerDependencies` from `node_modules`
111
+ - Skips `@uxf/*`, `react`, `react-dom`, and `next` (you manage these yourself)
112
+ - Reports missing dependencies and version mismatches
113
+ - Distinguishes between prod and dev dependencies — peer deps required only by `devDependencies` are installed with `-D`
114
+ - With `--fix`, auto-installs missing peer deps using the detected package manager
115
+
66
116
  ## uxf-lunch
67
117
 
68
118
  ```bash
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env tsx
2
+ import cli from "../src/uxf-dependencies-check/cli";
3
+
4
+ cli()
5
+ .then((exitCode) => {
6
+ process.exitCode = exitCode;
7
+ })
8
+ .catch((e) => {
9
+ console.error(e); // eslint-disable-line no-console
10
+ process.exitCode = 1;
11
+ });
package/package.json CHANGED
@@ -1,25 +1,25 @@
1
1
  {
2
2
  "name": "@uxf/scripts",
3
- "version": "11.107.0",
3
+ "version": "11.109.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
7
7
  "uxf-audit": "bin/uxf-audit.js",
8
8
  "uxf-claude-sync": "bin/uxf-claude-sync.js",
9
+ "uxf-dependencies-check": "bin/uxf-dependencies-check.ts",
10
+ "uxf-i18n-namespaces-gen": "bin/uxf-i18n-namespaces-gen.js",
9
11
  "uxf-lunch": "bin/uxf-lunch.js",
10
- "uxf-dependencies-check": "bin/uxf-dependencies-check.js",
11
12
  "uxf-push-notifier": "bin/uxf-push-notifier.js",
12
13
  "uxf-release": "bin/uxf-release.js",
13
14
  "uxf-sitemap-check": "bin/uxf-sitemap-check.js",
14
15
  "uxf-sitemap-meta-export": "bin/uxf-sitemap-meta-export.js",
15
- "uxf-i18n-namespaces-gen": "bin/uxf-i18n-namespaces-gen.js",
16
16
  "uxf-unused": "bin/uxf-unused.js"
17
17
  },
18
18
  "scripts": {
19
19
  "build": "",
20
- "typecheck": "",
20
+ "run:mr-notifier": "GOOGLE_WEBHOOK_URL=<<TODO>> GITLAB_TOKEN=<<TODO>> CI_SERVER_URL=https://gitlab.uxf.cz node ./bin/uxf-merge-requests-notifier.js",
21
21
  "test": "./node_modules/.bin/eslint ./bin",
22
- "run:mr-notifier": "GOOGLE_WEBHOOK_URL=<<TODO>> GITLAB_TOKEN=<<TODO>> CI_SERVER_URL=https://gitlab.uxf.cz node ./bin/uxf-merge-requests-notifier.js"
22
+ "typecheck": "tsc --noEmit -p tsconfig.json"
23
23
  },
24
24
  "publishConfig": {
25
25
  "access": "public"
@@ -33,9 +33,9 @@
33
33
  "node": ">=24"
34
34
  },
35
35
  "dependencies": {
36
- "axios": "1.13.4",
36
+ "axios": "^1.13.4",
37
37
  "cheerio": "1.2.0",
38
- "dayjs": "1.11.19",
38
+ "dayjs": "^1.11.19",
39
39
  "fast-glob": "3.3.3",
40
40
  "got": "14.6.6",
41
41
  "madge": "8.0.0",
@@ -47,7 +47,7 @@
47
47
  "@types/node": "24",
48
48
  "@types/react": "18.3.27",
49
49
  "@types/react-dom": "18.3.7",
50
- "@uxf/core": "11.107.0",
51
- "@uxf/ui": "11.107.0"
50
+ "@uxf/core": "11.108.0",
51
+ "@uxf/ui": "11.108.0"
52
52
  }
53
53
  }
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env node
2
- require("../src/uxf-dependencies-check/cli")()
3
- .then((exitCode) => {
4
- process.exitCode = exitCode;
5
- })
6
- .catch(() => {
7
- process.exitCode = 1;
8
- });
@@ -1,32 +0,0 @@
1
- const { checkUxfDependencies } = require("./index");
2
- const { argv } = require("process");
3
-
4
- module.exports = async () => {
5
- const cli = require("yargs")()
6
- .command("$0", "UXF Dependencies Check", (yargs) => {
7
- yargs.demandCommand(0, 0).usage(`
8
- Usage:
9
- uxf-dependencies-check [options]`);
10
- })
11
- .option("e", {
12
- alias: "exclude",
13
- array: true,
14
- default: [],
15
- describe: "Seznam balíčků, které budou ignorovány",
16
- })
17
- .strict(false)
18
- .exitProcess(false);
19
-
20
- try {
21
- const { help, exclude } = cli.parse(argv.slice(2));
22
-
23
- if (Boolean(help)) {
24
- return 0;
25
- }
26
-
27
- await checkUxfDependencies(new Set(exclude));
28
- } catch (e) {
29
- console.error(e);
30
- return 1;
31
- }
32
- };
@@ -1,106 +0,0 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
-
4
- const yarnLockPath = path.resolve(process.cwd(), "yarn.lock");
5
- const packageJsonPath = path.resolve(process.cwd(), "package.json");
6
-
7
- async function parseLockFile() {
8
- const YAML = await import("yaml");
9
-
10
- const content = fs.readFileSync(yarnLockPath, "utf8");
11
- return YAML.parse(content);
12
- }
13
-
14
- function parsePackageJson() {
15
- const content = fs.readFileSync(packageJsonPath, "utf8");
16
- return JSON.parse(content);
17
- }
18
-
19
- function extractPackageName(key) {
20
- const match = key.match(/^(@[^/]+\/[^@]+|[^@]+)@/);
21
- return match ? match[1] : null;
22
- }
23
-
24
- function findUxfPackagesInDependencies(lockData, packageJson) {
25
- const declaredDependencies = new Set(Object.keys(packageJson.dependencies || {}));
26
-
27
- const uxfPackages = [];
28
-
29
- for (const key of Object.keys(lockData)) {
30
- const name = extractPackageName(key);
31
- if (name?.startsWith("@uxf/") && declaredDependencies.has(name)) {
32
- uxfPackages.push(key);
33
- }
34
- }
35
-
36
- return uxfPackages;
37
- }
38
-
39
- function collectDirectDependencies(packageKeys, lockData) {
40
- const found = {};
41
-
42
- for (const key of packageKeys) {
43
- const entry = lockData[key];
44
- if (!entry) continue;
45
-
46
- const dependencies = entry.dependencies || {};
47
-
48
- for (const depName in dependencies) {
49
- const matchingKeys = Object.keys(lockData).filter((lockKey) => extractPackageName(lockKey) === depName);
50
-
51
- for (const matchKey of matchingKeys) {
52
- const depEntry = lockData[matchKey];
53
- if (!depEntry || !depEntry.version) continue;
54
-
55
- if (!found[depName]) {
56
- found[depName] = new Set();
57
- }
58
-
59
- found[depName].add(depEntry.version);
60
- }
61
- }
62
- }
63
-
64
- return found;
65
- }
66
-
67
- function checkMultipleVersions(dependencyMap, excludedPackages = new Set()) {
68
- const conflicts = [];
69
-
70
- for (const [name, versions] of Object.entries(dependencyMap)) {
71
- if (excludedPackages.has(name)) continue;
72
- if (versions.size > 1) {
73
- conflicts.push({ name, versions: Array.from(versions) });
74
- }
75
- }
76
-
77
- return conflicts;
78
- }
79
-
80
- async function checkUxfDependencies(excludedPackages = new Set()) {
81
- const lockData = await parseLockFile();
82
- const packageJson = parsePackageJson();
83
-
84
- const uxfPackages = findUxfPackagesInDependencies(lockData, packageJson);
85
- const dependencies = collectDirectDependencies(uxfPackages, lockData);
86
-
87
- const conflicts = checkMultipleVersions(dependencies, excludedPackages);
88
-
89
- if (conflicts.length > 0) {
90
- console.log("Následující balíčky mají více verzí v závislostech UXF balíčků:");
91
- for (const { name, versions } of conflicts) {
92
- console.log(`- ${name}: ${versions.join(", ")}`);
93
- }
94
- process.exit(1);
95
- } else {
96
- console.log("Všechny závislosti UXF balíčků mají jednotnou verzi.");
97
- process.exit(0);
98
- }
99
- }
100
-
101
- module.exports = {
102
- findUxfPackagesInDependencies,
103
- collectDirectDependencies,
104
- checkMultipleVersions,
105
- checkUxfDependencies,
106
- };
@@ -1,111 +0,0 @@
1
- const { findUxfPackagesInDependencies, collectDirectDependencies, checkMultipleVersions } = require("./index"); // Adjust the path if needed
2
-
3
- describe("findUxfPackagesInDependencies", () => {
4
- const lockData = {
5
- "@uxf/button@^1.0.0": {},
6
- "@uxf/form@^2.1.0": {},
7
- "react@^17.0.0": {},
8
- "lodash@^4.17.0": {},
9
- "classnames@^2.3.1": {},
10
- };
11
-
12
- const packageJson = {
13
- dependencies: {
14
- "@uxf/button": "^1.0.0",
15
- "@uxf/form": "^2.1.0",
16
- react: "^17.0.0",
17
- },
18
- };
19
-
20
- it("returns @uxf/* packages that are in package.json dependencies", () => {
21
- const result = findUxfPackagesInDependencies(lockData, packageJson);
22
- expect(result).toEqual(["@uxf/button@^1.0.0", "@uxf/form@^2.1.0"]);
23
- });
24
- });
25
-
26
- describe("collectDirectDependencies", () => {
27
- const lockData = {
28
- "@uxf/button@^1.0.0": {
29
- dependencies: {
30
- react: "^17.0.0",
31
- lodash: "^4.17.0",
32
- },
33
- },
34
- "@uxf/form@^2.1.0": {
35
- dependencies: {
36
- react: "^17.0.1", // different version range
37
- classnames: "^2.3.1",
38
- },
39
- },
40
- "react@^17.0.0": {
41
- version: "17.0.2",
42
- },
43
- "react@^17.0.1": {
44
- version: "17.0.1",
45
- },
46
- "lodash@^4.17.0": {
47
- version: "4.17.21",
48
- },
49
- "classnames@^2.3.1": {
50
- version: "2.3.1",
51
- },
52
- };
53
-
54
- const packageKeys = ["@uxf/button@^1.0.0", "@uxf/form@^2.1.0"];
55
-
56
- it("collects direct dependencies of multiple UXF packages with shared and unique deps", () => {
57
- const result = collectDirectDependencies(packageKeys, lockData);
58
-
59
- expect(result).toEqual({
60
- react: new Set(["17.0.2", "17.0.1"]),
61
- lodash: new Set(["4.17.21"]),
62
- classnames: new Set(["2.3.1"]),
63
- });
64
- });
65
-
66
- it("handles empty dependencies gracefully", () => {
67
- const lockData = {
68
- "@uxf/empty@1.0.0": {},
69
- };
70
-
71
- const result = collectDirectDependencies(["@uxf/empty@1.0.0"], lockData);
72
- expect(result).toEqual({});
73
- });
74
- });
75
-
76
- describe("checkMultipleVersions", () => {
77
- it("returns empty array when all packages have a single version", () => {
78
- const deps = {
79
- react: new Set(["17.0.2"]),
80
- lodash: new Set(["4.17.21"]),
81
- };
82
- expect(checkMultipleVersions(deps)).toEqual([]);
83
- });
84
-
85
- it("returns conflicts when a package has multiple versions", () => {
86
- const deps = {
87
- react: new Set(["17.0.2", "18.0.0"]),
88
- lodash: new Set(["4.17.21"]),
89
- };
90
- const conflicts = checkMultipleVersions(deps);
91
- expect(conflicts).toHaveLength(1);
92
- expect(conflicts[0].name).toBe("react");
93
- expect(conflicts[0].versions).toEqual(expect.arrayContaining(["17.0.2", "18.0.0"]));
94
- });
95
-
96
- it("excludes packages that are in the excludedPackages set", () => {
97
- const deps = {
98
- react: new Set(["17.0.2", "18.0.0"]),
99
- };
100
- const result = checkMultipleVersions(deps, new Set(["react"]));
101
- expect(result).toEqual([]);
102
- });
103
-
104
- it("returns multiple conflicts when several packages have version mismatches", () => {
105
- const deps = {
106
- react: new Set(["17.0.2", "18.0.0"]),
107
- lodash: new Set(["4.17.0", "4.17.21"]),
108
- };
109
- expect(checkMultipleVersions(deps)).toHaveLength(2);
110
- });
111
- });