@semba-ryuichiro/webpify 1.0.8 → 1.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/README.md +1 -0
- package/dist/cli/argument-parser/index.js +4 -0
- package/dist/cli/main/index.js +8 -4
- package/dist/cli/reporter/index.d.ts +2 -1
- package/dist/cli/reporter/index.js +19 -6
- package/dist/index.js +0 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +35 -37
package/README.md
CHANGED
|
@@ -60,6 +60,7 @@ webpify ./images -r
|
|
|
60
60
|
| `-r, --recursive` | 再帰的に処理 | false |
|
|
61
61
|
| `-f, --force` | 既存ファイルを上書き | false |
|
|
62
62
|
| `--list` | WebP ファイル一覧表示 | - |
|
|
63
|
+
| `--absolute` | 一覧表示時に絶対パスで表示 | false |
|
|
63
64
|
| `--quiet` | 統計情報を非表示 | false |
|
|
64
65
|
| `-v, --version` | バージョン表示 | - |
|
|
65
66
|
| `-h, --help` | ヘルプ表示 | - |
|
|
@@ -46,6 +46,7 @@ export function createArgumentParser() {
|
|
|
46
46
|
.option('-f, --force', '既存ファイルを上書き', false)
|
|
47
47
|
.option('--quiet', 'サイレントモード(出力なし)', false)
|
|
48
48
|
.option('--list', 'WebP ファイルをサイズ情報付きで一覧表示', false)
|
|
49
|
+
.option('--absolute', '--list オプション使用時に絶対パスで表示', false)
|
|
49
50
|
.configureOutput({
|
|
50
51
|
writeErr: (str) => process.stderr.write(str),
|
|
51
52
|
writeOut: (str) => process.stdout.write(str),
|
|
@@ -57,6 +58,7 @@ export function createArgumentParser() {
|
|
|
57
58
|
if (argv.length <= 2) {
|
|
58
59
|
program.outputHelp();
|
|
59
60
|
return {
|
|
61
|
+
absolutePath: false,
|
|
60
62
|
force: false,
|
|
61
63
|
input: '',
|
|
62
64
|
list: false,
|
|
@@ -75,6 +77,7 @@ export function createArgumentParser() {
|
|
|
75
77
|
const code = err.code;
|
|
76
78
|
if (code === 'commander.helpDisplayed' || code === 'commander.version') {
|
|
77
79
|
return {
|
|
80
|
+
absolutePath: false,
|
|
78
81
|
force: false,
|
|
79
82
|
input: '',
|
|
80
83
|
list: false,
|
|
@@ -89,6 +92,7 @@ export function createArgumentParser() {
|
|
|
89
92
|
const options = program.opts();
|
|
90
93
|
const args = program.args;
|
|
91
94
|
return {
|
|
95
|
+
absolutePath: options['absolute'],
|
|
92
96
|
force: options['force'],
|
|
93
97
|
input: args[0] || '',
|
|
94
98
|
list: options['list'],
|
package/dist/cli/main/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
/**
|
|
2
3
|
* サポートされる変換対象の拡張子
|
|
3
4
|
*/
|
|
@@ -16,7 +17,7 @@ export function createMain(deps) {
|
|
|
16
17
|
/**
|
|
17
18
|
* 一覧表示モードを実行する
|
|
18
19
|
*/
|
|
19
|
-
async function executeListMode(inputPath, recursive) {
|
|
20
|
+
async function executeListMode(inputPath, recursive, absolutePath) {
|
|
20
21
|
const files = await fileScanner.scan(inputPath, {
|
|
21
22
|
extensions: WEBP_EXTENSIONS,
|
|
22
23
|
recursive,
|
|
@@ -28,7 +29,9 @@ export function createMain(deps) {
|
|
|
28
29
|
size: info.size,
|
|
29
30
|
width: info.width,
|
|
30
31
|
}));
|
|
31
|
-
|
|
32
|
+
// absolutePath が false の場合は basePath を渡して相対パスを表示
|
|
33
|
+
const basePath = absolutePath ? undefined : path.resolve(inputPath);
|
|
34
|
+
reporter.reportImageList(items, basePath);
|
|
32
35
|
return 0;
|
|
33
36
|
}
|
|
34
37
|
/**
|
|
@@ -89,6 +92,7 @@ export function createMain(deps) {
|
|
|
89
92
|
if (!isDir) {
|
|
90
93
|
// 単一ファイルの場合も一覧表示
|
|
91
94
|
const info = await imageInspector.getInfo(options.input);
|
|
95
|
+
const basePath = options.absolutePath ? undefined : path.dirname(path.resolve(options.input));
|
|
92
96
|
reporter.reportImageList([
|
|
93
97
|
{
|
|
94
98
|
height: info.height,
|
|
@@ -96,10 +100,10 @@ export function createMain(deps) {
|
|
|
96
100
|
size: info.size,
|
|
97
101
|
width: info.width,
|
|
98
102
|
},
|
|
99
|
-
]);
|
|
103
|
+
], basePath);
|
|
100
104
|
return 0;
|
|
101
105
|
}
|
|
102
|
-
return executeListMode(options.input, options.recursive);
|
|
106
|
+
return executeListMode(options.input, options.recursive, options.absolutePath);
|
|
103
107
|
}
|
|
104
108
|
// ファイル or ディレクトリの判定
|
|
105
109
|
const isDirectory = await fileScanner.isDirectory(options.input);
|
|
@@ -24,8 +24,9 @@ export interface ReporterService {
|
|
|
24
24
|
/**
|
|
25
25
|
* WebP ファイル一覧を表示する
|
|
26
26
|
* @param items - 画像アイテムのリスト
|
|
27
|
+
* @param basePath - 相対パス計算の基準パス(省略時は絶対パスを表示)
|
|
27
28
|
*/
|
|
28
|
-
reportImageList(items: ImageListItem[]): void;
|
|
29
|
+
reportImageList(items: ImageListItem[], basePath?: string): void;
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
32
|
* Reporter のファクトリ関数
|
|
@@ -53,18 +53,31 @@ export function createReporter() {
|
|
|
53
53
|
const reduction = formatReduction(result.inputSize, result.outputSize);
|
|
54
54
|
process.stdout.write(`Converted: ${fileName} (${inputSizeStr} -> ${outputSizeStr}, ${reduction})\n`);
|
|
55
55
|
},
|
|
56
|
-
reportImageList(items) {
|
|
56
|
+
reportImageList(items, basePath) {
|
|
57
57
|
if (items.length === 0) {
|
|
58
58
|
process.stdout.write('WebP ファイルが見つかりません\n');
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
+
// 表示用パスを計算(basePath が指定されていれば相対パス、なければ絶対パス)
|
|
62
|
+
const displayPaths = items.map((item) => {
|
|
63
|
+
if (basePath) {
|
|
64
|
+
const relativePath = path.relative(basePath, item.path);
|
|
65
|
+
return relativePath || path.basename(item.path);
|
|
66
|
+
}
|
|
67
|
+
return item.path;
|
|
68
|
+
});
|
|
69
|
+
// 動的なカラム幅を計算(最小20、最大60文字)
|
|
70
|
+
const maxPathLength = Math.max(...displayPaths.map((p) => p.length));
|
|
71
|
+
const pathColumnWidth = Math.min(Math.max(maxPathLength + 2, 20), 60);
|
|
61
72
|
process.stdout.write('\n--- WebP File List ---\n');
|
|
62
|
-
process.stdout.write(`${'File'.padEnd(
|
|
63
|
-
process.stdout.write(`${'-'.repeat(
|
|
64
|
-
for (const item of items) {
|
|
65
|
-
const
|
|
73
|
+
process.stdout.write(`${'File'.padEnd(pathColumnWidth)} ${'Size'.padEnd(12)} ${'Width'.padEnd(8)} ${'Height'.padEnd(8)}\n`);
|
|
74
|
+
process.stdout.write(`${'-'.repeat(pathColumnWidth + 30)}\n`);
|
|
75
|
+
for (const [index, item] of items.entries()) {
|
|
76
|
+
const displayPath = displayPaths[index] ?? '';
|
|
66
77
|
const sizeStr = formatSize(item.size);
|
|
67
|
-
|
|
78
|
+
// 長いパスは省略表示
|
|
79
|
+
const truncatedPath = displayPath.length > pathColumnWidth - 2 ? `...${displayPath.slice(-(pathColumnWidth - 5))}` : displayPath;
|
|
80
|
+
process.stdout.write(`${truncatedPath.padEnd(pathColumnWidth)} ${sizeStr.padEnd(12)} ${String(item.width).padEnd(8)} ${String(item.height).padEnd(8)}\n`);
|
|
68
81
|
}
|
|
69
82
|
},
|
|
70
83
|
reportProgress(current, total, fileName) {
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -7,39 +7,39 @@
|
|
|
7
7
|
"url": "https://github.com/semba-yui/webpify/issues"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"commander": "
|
|
11
|
-
"sharp": "
|
|
10
|
+
"commander": "14.0.2",
|
|
11
|
+
"sharp": "0.34.5"
|
|
12
12
|
},
|
|
13
13
|
"description": "CLI tool to convert images to WebP format",
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@biomejs/biome": "
|
|
16
|
-
"@commitlint/cli": "
|
|
17
|
-
"@commitlint/config-conventional": "
|
|
18
|
-
"@fast-check/vitest": "
|
|
19
|
-
"@secretlint/secretlint-rule-preset-recommend": "
|
|
20
|
-
"@stryker-mutator/core": "
|
|
21
|
-
"@stryker-mutator/typescript-checker": "
|
|
22
|
-
"@stryker-mutator/vitest-runner": "
|
|
23
|
-
"@types/node": "
|
|
24
|
-
"@vitest/coverage-v8": "
|
|
25
|
-
"dependency-cruiser": "
|
|
26
|
-
"fast-check": "
|
|
27
|
-
"lefthook": "
|
|
28
|
-
"remark": "
|
|
29
|
-
"remark-cli": "
|
|
30
|
-
"remark-frontmatter": "
|
|
31
|
-
"remark-gfm": "
|
|
32
|
-
"remark-lint": "
|
|
33
|
-
"remark-preset-lint-consistent": "
|
|
34
|
-
"remark-preset-lint-recommended": "
|
|
35
|
-
"remark-toc": "
|
|
36
|
-
"secretlint": "
|
|
37
|
-
"ts-node": "
|
|
38
|
-
"typedoc": "
|
|
39
|
-
"typedoc-plugin-merge-modules": "
|
|
40
|
-
"typedoc-theme-hierarchy": "
|
|
41
|
-
"typescript": "
|
|
42
|
-
"vitest": "
|
|
15
|
+
"@biomejs/biome": "2.3.10",
|
|
16
|
+
"@commitlint/cli": "20.2.0",
|
|
17
|
+
"@commitlint/config-conventional": "20.2.0",
|
|
18
|
+
"@fast-check/vitest": "0.2.4",
|
|
19
|
+
"@secretlint/secretlint-rule-preset-recommend": "11.2.5",
|
|
20
|
+
"@stryker-mutator/core": "9.4.0",
|
|
21
|
+
"@stryker-mutator/typescript-checker": "9.4.0",
|
|
22
|
+
"@stryker-mutator/vitest-runner": "9.4.0",
|
|
23
|
+
"@types/node": "25.0.3",
|
|
24
|
+
"@vitest/coverage-v8": "4.0.16",
|
|
25
|
+
"dependency-cruiser": "17.2.0",
|
|
26
|
+
"fast-check": "4.5.3",
|
|
27
|
+
"lefthook": "2.0.13",
|
|
28
|
+
"remark": "15.0.1",
|
|
29
|
+
"remark-cli": "12.0.1",
|
|
30
|
+
"remark-frontmatter": "5.0.0",
|
|
31
|
+
"remark-gfm": "4.0.1",
|
|
32
|
+
"remark-lint": "10.0.1",
|
|
33
|
+
"remark-preset-lint-consistent": "6.0.1",
|
|
34
|
+
"remark-preset-lint-recommended": "7.0.1",
|
|
35
|
+
"remark-toc": "9.0.0",
|
|
36
|
+
"secretlint": "11.2.5",
|
|
37
|
+
"ts-node": "10.9.2",
|
|
38
|
+
"typedoc": "0.28.15",
|
|
39
|
+
"typedoc-plugin-merge-modules": "7.0.0",
|
|
40
|
+
"typedoc-theme-hierarchy": "6.0.0",
|
|
41
|
+
"typescript": "5.9.3",
|
|
42
|
+
"vitest": "4.0.16"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=22.0.0"
|
|
@@ -70,7 +70,6 @@
|
|
|
70
70
|
"license": "MIT",
|
|
71
71
|
"main": "./dist/index.js",
|
|
72
72
|
"name": "@semba-ryuichiro/webpify",
|
|
73
|
-
"packageManager": "pnpm@10.26.2",
|
|
74
73
|
"publishConfig": {
|
|
75
74
|
"access": "public",
|
|
76
75
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -79,6 +78,9 @@
|
|
|
79
78
|
"type": "git",
|
|
80
79
|
"url": "git+https://github.com/semba-yui/webpify.git"
|
|
81
80
|
},
|
|
81
|
+
"type": "module",
|
|
82
|
+
"types": "./dist/index.d.ts",
|
|
83
|
+
"version": "1.1.0",
|
|
82
84
|
"scripts": {
|
|
83
85
|
"build": "tsc",
|
|
84
86
|
"deps": "dependency-cruiser src --config .dependency-cruiser.cjs",
|
|
@@ -94,15 +96,11 @@
|
|
|
94
96
|
"lint:secret": "secretlint \"**/*\"",
|
|
95
97
|
"lint:yaml": "yamllint .",
|
|
96
98
|
"lint:zizmor": "zizmor .github/workflows/",
|
|
97
|
-
"prepublishOnly": "pnpm run lint && pnpm run test && pnpm run build",
|
|
98
99
|
"test": "vitest run",
|
|
99
100
|
"test:coverage": "vitest run --coverage",
|
|
100
101
|
"test:mutation": "stryker run",
|
|
101
102
|
"test:mutation:dry": "stryker run --dryRunOnly",
|
|
102
103
|
"test:watch": "vitest",
|
|
103
104
|
"typecheck": "tsc --noEmit"
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
"types": "./dist/index.d.ts",
|
|
107
|
-
"version": "1.0.8"
|
|
108
|
-
}
|
|
105
|
+
}
|
|
106
|
+
}
|