@uxf/scripts 11.122.5 → 11.123.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
@@ -31,10 +31,8 @@ Requires **Node.js >= 24** (`engines.node`). No peer dependencies. Runtime depen
31
31
  | `uxf-audit` | Print a JSON report of Node / Yarn / Next / React and installed `@uxf/*` versions. |
32
32
  | `uxf-claude-sync` | Download global guidelines from a URL into a `CLAUDE.md` file. |
33
33
  | `uxf-i18n-namespaces-gen` | Generate an `i18n-pages.json` mapping routes to the translation namespaces they use. |
34
- | `uxf-unused` | Find (and optionally delete) unused files in a Next.js project. |
35
34
  | `uxf-sitemap-check` | Crawl a sitemap and check all URLs for HTTP errors, duplicates, and missing pages. |
36
35
  | `uxf-sitemap-meta-export` | Crawl a sitemap and export page meta tags (title, description, OG) to `export.csv`. |
37
- | `uxf-lunch` | Post today's lunch menu to a Slack channel. |
38
36
 
39
37
  Every command accepts `-h` / `--help`.
40
38
 
@@ -221,24 +219,6 @@ Options:
221
219
 
222
220
  Namespaces found on `/_app` are merged into the global `*` entry.
223
221
 
224
- ### uxf-unused
225
-
226
- Finds files in a Next.js project that are not reachable from the pages import graph, prints them, and (with `--removeFiles`) deletes them. Use `--debug` to dump intermediate JSON files (`uxf-unused-*.json`) into the working directory.
227
-
228
- ```
229
- Usage:
230
- uxf-unused [options]
231
-
232
- Options:
233
- -p, --pagesDirectory Glob of page entry points
234
- [default: "src/pages/**/*.(ts|tsx)"]
235
- -f, --allFilesDirectory Glob of all candidate files
236
- [default: "src/**/*.(ts|tsx)"]
237
- -r, --removeFiles Delete the unused files [boolean] [default: false]
238
- -d, --debug Write intermediate JSON files [boolean] [default: false]
239
- -h, --help Show help
240
- ```
241
-
242
222
  ### uxf-sitemap-check
243
223
 
244
224
  Crawls a sitemap and requests every URL, reporting HTTP errors, duplicate sitemap entries, and (optionally) indexable pages missing from the sitemap. Can also follow nested page links and images. Sends a summary to Google Chat when errors are found and exits with code 1.
@@ -286,28 +266,11 @@ Options:
286
266
  -h, --help Show help [boolean]
287
267
  ```
288
268
 
289
- ### uxf-lunch
290
-
291
- Fetches the daily menu (Hotel Radnice) and posts it as a formatted message to a Slack channel.
292
-
293
- ```
294
- Usage:
295
- uxf-lunch [options]
296
-
297
- Environment variables:
298
- SLACK_TOKEN - required
299
-
300
- Options:
301
- --slack-channel Slack channel (required) [string]
302
- -h, --help Show help
303
- ```
304
-
305
269
  ## Gotchas
306
270
 
307
271
  - **CLI-only, no importable API.** `main` references a `index.js` that is not shipped; use the `bin` commands.
308
272
  - **CI-oriented defaults.** `uxf-release`, `uxf-push-notifier`, and `uxf-sitemap-meta-export` expect GitLab CI / environment variables and mostly make sense inside a pipeline.
309
273
  - **`uxf-sitemap-check --check-missing`** only works together with `--with-nested`; used alone it exits with code 1.
310
- - **`uxf-unused --removeFiles` deletes files** on disk — run without it (or with `--debug`) first to review the list.
311
274
  - **`uxf-merge-requests-notifier`** exists in the source tree but is **not** exposed as a `bin` command; it is run internally via the package's `run:mr-notifier` npm script and is not installed for consumers.
312
275
 
313
276
  ## Links
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/scripts",
3
- "version": "11.122.5",
3
+ "version": "11.123.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -8,18 +8,15 @@
8
8
  "uxf-claude-sync": "bin/uxf-claude-sync.js",
9
9
  "uxf-dependencies-check": "bin/uxf-dependencies-check.js",
10
10
  "uxf-i18n-namespaces-gen": "bin/uxf-i18n-namespaces-gen.js",
11
- "uxf-lunch": "bin/uxf-lunch.js",
12
11
  "uxf-push-notifier": "bin/uxf-push-notifier.js",
13
12
  "uxf-release": "bin/uxf-release.js",
14
13
  "uxf-sitemap-check": "bin/uxf-sitemap-check.js",
15
- "uxf-sitemap-meta-export": "bin/uxf-sitemap-meta-export.js",
16
- "uxf-unused": "bin/uxf-unused.js"
14
+ "uxf-sitemap-meta-export": "bin/uxf-sitemap-meta-export.js"
17
15
  },
18
16
  "scripts": {
19
17
  "build": "tsc -P tsconfig.build.json && chmod +x ./bin/*",
20
18
  "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
- "test": "./node_modules/.bin/eslint ./bin",
22
- "typecheck": "tsc --noEmit -p tsconfig.json"
19
+ "typecheck": "tsc --noEmit"
23
20
  },
24
21
  "publishConfig": {
25
22
  "access": "public"
@@ -33,23 +30,23 @@
33
30
  "node": ">=24"
34
31
  },
35
32
  "dependencies": {
36
- "axios": "^1.13.4",
33
+ "axios": "^1.19.0",
37
34
  "cheerio": "1.2.0",
38
- "dayjs": "^1.11.19",
35
+ "dayjs": "^1.11.21",
39
36
  "fast-glob": "3.3.3",
40
- "got": "14.6.6",
37
+ "got": "15.1.0",
41
38
  "madge": "8.0.0",
42
39
  "robots-txt-parser": "2.0.3",
43
- "semver": "^7.7.3",
44
- "yaml": "2.8.2",
45
- "yargs": "18.0.0"
40
+ "semver": "^7.8.5",
41
+ "yaml": "2.9.0",
42
+ "yargs": "18.1.0"
46
43
  },
47
44
  "devDependencies": {
48
45
  "@types/node": "24",
49
- "@types/react": "18.3.27",
46
+ "@types/react": "18.3.31",
50
47
  "@types/react-dom": "18.3.7",
51
48
  "@types/semver": "^7.7.1",
52
- "@uxf/core": "11.114.0",
53
- "@uxf/ui": "11.122.5"
49
+ "@uxf/core": "11.123.0",
50
+ "@uxf/ui": "11.123.0"
54
51
  }
55
52
  }
package/bin/uxf-lunch.js DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env node
2
- require("../src/uxf-lunch/cli")()
3
- .then((exitCode) => {
4
- process.exitCode = exitCode;
5
- })
6
- .catch(() => {
7
- process.exitCode = 1;
8
- });
package/bin/uxf-unused.js DELETED
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
- require("../src/uxf-unused/cli")()
3
- .then((exitCode) => {
4
- process.exitCode = exitCode;
5
- })
6
- .catch((e) => {
7
- console.error(e);
8
- process.exitCode = 1;
9
- });
@@ -1,60 +0,0 @@
1
- const fg = require("fast-glob");
2
- const madge = require("madge");
3
- const path = require("path");
4
- const fs = require("fs");
5
-
6
- function getTSConfig() {
7
- const tsConfigPath = path.resolve(process.cwd(), "tsconfig.json");
8
-
9
- if (fs.existsSync(tsConfigPath)) {
10
- console.log("TS config loaded: " + tsConfigPath);
11
- return tsConfigPath;
12
- }
13
-
14
- console.log("TS config not found.");
15
- return undefined;
16
- }
17
-
18
- function getTree(subtree, tree, destination, viewedFiles = []) {
19
- if (!subtree || subtree.length === 0) {
20
- return;
21
- }
22
-
23
- for (let child of subtree) {
24
- if (viewedFiles.includes(child)) {
25
- continue;
26
- }
27
-
28
- const nextSubtree = tree[child];
29
-
30
- viewedFiles.push(child);
31
-
32
- if (nextSubtree) {
33
- destination.push(nextSubtree);
34
- }
35
-
36
- if (nextSubtree && nextSubtree.length > 0) {
37
- getTree(nextSubtree, tree, destination, viewedFiles);
38
- }
39
- }
40
- }
41
-
42
- module.exports = function loadPageImports(directory, fileExtensions = ["ts", "tsx"]) {
43
- const pages = fg.sync(directory).map(path.normalize);
44
-
45
- return madge(process.cwd(), { tsConfig: getTSConfig(), fileExtensions }).then((res) => {
46
- const tree = res.obj();
47
-
48
- return pages.reduce((previousValue, currentValue) => {
49
- const filesOnPath = [];
50
- getTree([currentValue], tree, filesOnPath);
51
-
52
- const uniqueImports = Array.from(new Set(filesOnPath.flat(Number.POSITIVE_INFINITY)));
53
- uniqueImports.sort();
54
-
55
- previousValue[currentValue] = uniqueImports;
56
-
57
- return previousValue;
58
- }, {});
59
- });
60
- };
@@ -1,44 +0,0 @@
1
- const { argv, env } = require("process");
2
-
3
- module.exports = async () => {
4
- const cli = require("yargs")()
5
- .command("$0", "UXF release helper", (yargs) => {
6
- yargs.demandCommand(0, 0).usage(`UXF lunch
7
- Usage:
8
- uxf-lunch [options]
9
-
10
- Environment variables:
11
- SLACK_TOKEN - required`);
12
- })
13
- .option("slack-channel", {
14
- describe: "Slack channel",
15
- type: "string",
16
- group: "Options",
17
- })
18
- .option("h", { alias: "help", group: "Options" })
19
- .strict(false)
20
- .exitProcess(false);
21
-
22
- try {
23
- const { help, ...options } = cli.parse(argv.slice(2));
24
-
25
- if (Boolean(help)) {
26
- return 0;
27
- }
28
-
29
- if (!env.SLACK_TOKEN) {
30
- console.log("Slack token must be set. Use environment variable SLACK_TOKEN.");
31
- return 1;
32
- }
33
-
34
- if (!options["slack-channel"]) {
35
- console.log("Slack channel must be set. Use parameter --slack-channel");
36
- return 1;
37
- }
38
-
39
- await require("./index")(options["slack-channel"]);
40
- } catch (e) {
41
- console.error(e);
42
- return 1;
43
- }
44
- };
@@ -1,50 +0,0 @@
1
- const { get } = require("axios");
2
- const Slack = require("../Slack");
3
-
4
- const numbers = [":keycap_star:", ":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:"];
5
- const paymentsUrl = "https://gitlab.uxf.cz/Vejvoda/obedy/-/wikis/%C4%8C%C3%ADsla-%C3%BA%C4%8Dt%C5%AF";
6
-
7
- module.exports = async (slackChannel) => {
8
- const { data } = await get("https://hotel.servispc-liberec.cz/server/api/data-jidelak");
9
-
10
- const menu = data.ListekPolozky.filter(({ druh }) => druh === "1").map((v) => ({
11
- ...v,
12
- cena: Number.parseInt(v.cena),
13
- }));
14
-
15
- const blocks = [
16
- {
17
- type: "section",
18
- text: {
19
- type: "mrkdwn",
20
- text: "*Hotel Radnice*",
21
- },
22
- },
23
- ];
24
-
25
- menu.forEach((menuItem, index) => {
26
- const { polozka, cena } = menuItem;
27
- blocks.push({
28
- type: "section",
29
- text: {
30
- type: "mrkdwn",
31
- text: `${numbers[index]} ${polozka} - \`${cena}Kč\``,
32
- },
33
- });
34
- });
35
- blocks.push({
36
- type: "context",
37
- elements: [
38
- {
39
- type: "mrkdwn",
40
- text: `:eyes: Ceny neobsahují *10Kč* za krabičku (máme vlastní krabičky)\n:moneybag: QR kódy a čísla účtů <${paymentsUrl}|zde> - po zaplacení přidat :white_check_mark:`,
41
- },
42
- {
43
- type: "mrkdwn",
44
- text: ":bulb: Objednávky ideálně formou přidání reakce :keycap_star:, :one:, :two:, ... Ať objednávající nemusí sčítat :-)",
45
- },
46
- ],
47
- });
48
-
49
- await Slack.chatPostMessage(slackChannel, { blocks });
50
- };
@@ -1,30 +0,0 @@
1
- const { argv, env } = require("process");
2
-
3
- module.exports = async () => {
4
- const cli = require("yargs")()
5
- .command("$0", "UXF find and remove unused files NextJS project", (yargs) => {
6
- yargs.demandCommand(0, 0).usage(`
7
- Usage:
8
- uxf-unused [options]`);
9
- })
10
- .option("p", { alias: "pagesDirectory", default: "src/pages/**/*.(ts|tsx)" })
11
- .option("f", { alias: "allFilesDirectory", default: "src/**/*.(ts|tsx)" })
12
- .option("r", { alias: "removeFiles", boolean: true, default: false })
13
- .option("d", { alias: "debug", boolean: true, default: false })
14
- .option("h", { alias: "help" })
15
- .strict(false)
16
- .exitProcess(false);
17
-
18
- try {
19
- const { help, pagesDirectory, allFilesDirectory, removeFiles, debug } = cli.parse(argv.slice(2));
20
-
21
- if (Boolean(help)) {
22
- return 0;
23
- }
24
-
25
- await require("./index")(pagesDirectory, allFilesDirectory, removeFiles, debug);
26
- } catch (e) {
27
- console.error(e);
28
- return 1;
29
- }
30
- };
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env node
2
- const loadPageImports = require("../shared/load-page-imports");
3
- const fg = require("fast-glob");
4
- const path = require("path");
5
- const fs = require("fs");
6
-
7
- function unique(value, index, array) {
8
- return array.indexOf(value) === index;
9
- }
10
-
11
- async function main(pagesDirectory, allFilesDirectory, shouldRemoveFiles, isDebug = false) {
12
- const pageImports = await loadPageImports(pagesDirectory);
13
-
14
- if (isDebug) {
15
- fs.writeFileSync(
16
- path.resolve(process.cwd(), "uxf-unused-1-page-imports.json"),
17
- JSON.stringify(pageImports, null, " "),
18
- );
19
- }
20
-
21
- const pages = Object.keys(pageImports);
22
-
23
- const usedFiles = Object.values(pageImports).flat().filter(unique).map(path.normalize);
24
-
25
- if (isDebug) {
26
- fs.writeFileSync(
27
- path.resolve(process.cwd(), "uxf-unused-2-used-files.json"),
28
- JSON.stringify(usedFiles, null, " "),
29
- );
30
- }
31
-
32
- const allFiles = fg.sync(allFilesDirectory).map(path.normalize);
33
-
34
- if (isDebug) {
35
- fs.writeFileSync(
36
- path.resolve(process.cwd(), "uxf-unused-3-all-files.json"),
37
- JSON.stringify(allFiles, null, " "),
38
- );
39
- }
40
-
41
- const unusedFiles = allFiles.filter((e) => !usedFiles.includes(e) && !pages.includes(e));
42
- unusedFiles.sort();
43
-
44
- if (isDebug) {
45
- fs.writeFileSync(
46
- path.resolve(process.cwd(), "uxf-unused-4-unused-files.json"),
47
- JSON.stringify(unusedFiles, null, " "),
48
- );
49
- }
50
-
51
- unusedFiles.forEach((unusedFile) => {
52
- if (shouldRemoveFiles) {
53
- fs.rmSync(unusedFile);
54
- }
55
- console.log(unusedFile);
56
- });
57
- }
58
-
59
- module.exports = main;