@macrulez/devtoolz 0.3.3 → 0.4.1

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 (85) hide show
  1. package/README.md +79 -3
  2. package/dist/cli.js +3 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/image-batch/backup.d.ts +22 -0
  5. package/dist/commands/image-batch/backup.js +55 -0
  6. package/dist/commands/image-batch/backup.js.map +1 -0
  7. package/dist/commands/image-batch/cache.d.ts +15 -0
  8. package/dist/commands/image-batch/cache.js +38 -0
  9. package/dist/commands/image-batch/cache.js.map +1 -0
  10. package/dist/commands/image-batch/cli.d.ts +15 -0
  11. package/dist/commands/image-batch/cli.js +307 -0
  12. package/dist/commands/image-batch/cli.js.map +1 -0
  13. package/dist/commands/image-batch/codecs.d.ts +38 -0
  14. package/dist/commands/image-batch/codecs.js +366 -0
  15. package/dist/commands/image-batch/codecs.js.map +1 -0
  16. package/dist/commands/image-batch/config.d.ts +120 -0
  17. package/dist/commands/image-batch/config.js +679 -0
  18. package/dist/commands/image-batch/config.js.map +1 -0
  19. package/dist/commands/image-batch/errors.d.ts +5 -0
  20. package/dist/commands/image-batch/errors.js +8 -0
  21. package/dist/commands/image-batch/errors.js.map +1 -0
  22. package/dist/commands/image-batch/geometry.d.ts +26 -0
  23. package/dist/commands/image-batch/geometry.js +90 -0
  24. package/dist/commands/image-batch/geometry.js.map +1 -0
  25. package/dist/commands/image-batch/inputs.d.ts +22 -0
  26. package/dist/commands/image-batch/inputs.js +87 -0
  27. package/dist/commands/image-batch/inputs.js.map +1 -0
  28. package/dist/commands/image-batch/manage-cli.d.ts +2 -0
  29. package/dist/commands/image-batch/manage-cli.js +276 -0
  30. package/dist/commands/image-batch/manage-cli.js.map +1 -0
  31. package/dist/commands/image-batch/manage.d.ts +51 -0
  32. package/dist/commands/image-batch/manage.js +1041 -0
  33. package/dist/commands/image-batch/manage.js.map +1 -0
  34. package/dist/commands/image-batch/overwrite.d.ts +14 -0
  35. package/dist/commands/image-batch/overwrite.js +31 -0
  36. package/dist/commands/image-batch/overwrite.js.map +1 -0
  37. package/dist/commands/image-batch/plan.d.ts +86 -0
  38. package/dist/commands/image-batch/plan.js +396 -0
  39. package/dist/commands/image-batch/plan.js.map +1 -0
  40. package/dist/commands/image-batch/process.d.ts +8 -0
  41. package/dist/commands/image-batch/process.js +97 -0
  42. package/dist/commands/image-batch/process.js.map +1 -0
  43. package/dist/commands/image-batch/report.d.ts +6 -0
  44. package/dist/commands/image-batch/report.js +251 -0
  45. package/dist/commands/image-batch/report.js.map +1 -0
  46. package/dist/commands/image-batch/restore.d.ts +29 -0
  47. package/dist/commands/image-batch/restore.js +125 -0
  48. package/dist/commands/image-batch/restore.js.map +1 -0
  49. package/dist/commands/image-batch/run.d.ts +123 -0
  50. package/dist/commands/image-batch/run.js +649 -0
  51. package/dist/commands/image-batch/run.js.map +1 -0
  52. package/dist/commands/image-batch/sharpen-ask.d.ts +6 -0
  53. package/dist/commands/image-batch/sharpen-ask.js +53 -0
  54. package/dist/commands/image-batch/sharpen-ask.js.map +1 -0
  55. package/dist/commands/image-batch/sharpen-manage.d.ts +26 -0
  56. package/dist/commands/image-batch/sharpen-manage.js +238 -0
  57. package/dist/commands/image-batch/sharpen-manage.js.map +1 -0
  58. package/dist/commands/image-batch/sharpen-presets.d.ts +24 -0
  59. package/dist/commands/image-batch/sharpen-presets.js +145 -0
  60. package/dist/commands/image-batch/sharpen-presets.js.map +1 -0
  61. package/dist/commands/image-batch/sharpen.d.ts +46 -0
  62. package/dist/commands/image-batch/sharpen.js +159 -0
  63. package/dist/commands/image-batch/sharpen.js.map +1 -0
  64. package/dist/commands/image-batch/template.d.ts +45 -0
  65. package/dist/commands/image-batch/template.js +142 -0
  66. package/dist/commands/image-batch/template.js.map +1 -0
  67. package/dist/commands/image-hash/sharp-loader.d.ts +2 -0
  68. package/dist/commands/image-hash/sharp-loader.js +7 -5
  69. package/dist/commands/image-hash/sharp-loader.js.map +1 -1
  70. package/dist/format/bytes.d.ts +2 -0
  71. package/dist/format/bytes.js +17 -0
  72. package/dist/format/bytes.js.map +1 -0
  73. package/dist/index.d.ts +5 -0
  74. package/dist/index.js +3 -0
  75. package/dist/index.js.map +1 -1
  76. package/dist/utils/closest.d.ts +2 -0
  77. package/dist/utils/closest.js +35 -0
  78. package/dist/utils/closest.js.map +1 -0
  79. package/dist/utils/glob.d.ts +4 -0
  80. package/dist/utils/glob.js +86 -0
  81. package/dist/utils/glob.js.map +1 -0
  82. package/dist/utils/tty.d.ts +60 -0
  83. package/dist/utils/tty.js +390 -0
  84. package/dist/utils/tty.js.map +1 -0
  85. package/package.json +1 -1
@@ -0,0 +1,46 @@
1
+ import type { Command } from 'commander';
2
+ export declare const SHARPEN_TARGETS: readonly ["screen", "matte", "glossy"];
3
+ export declare const SHARPEN_AMOUNTS: readonly ["low", "standard", "high"];
4
+ export declare const SHARPEN_FINE_KEYS: readonly ["radius", "flat", "jagged", "threshold"];
5
+ export type SharpenTarget = (typeof SHARPEN_TARGETS)[number];
6
+ export type SharpenAmount = (typeof SHARPEN_AMOUNTS)[number];
7
+ export type SharpenFineKey = (typeof SHARPEN_FINE_KEYS)[number];
8
+ export interface SharpenFields {
9
+ for?: SharpenTarget;
10
+ amount?: SharpenAmount;
11
+ radius?: number;
12
+ flat?: number;
13
+ jagged?: number;
14
+ threshold?: number;
15
+ }
16
+ export interface SharpenLayer extends SharpenFields {
17
+ preset?: string;
18
+ }
19
+ export interface SharpenSpec extends SharpenFields {
20
+ for: SharpenTarget;
21
+ amount: SharpenAmount;
22
+ }
23
+ export interface SharpenParams {
24
+ sigma: number;
25
+ m1: number;
26
+ m2: number;
27
+ x1?: number;
28
+ }
29
+ export declare const SHARPEN_RANGES: Record<SharpenFineKey, readonly [number, number]>;
30
+ export declare function completeSharpen(fields: SharpenFields): SharpenSpec;
31
+ export declare function sharpenParams(spec: SharpenSpec): SharpenParams;
32
+ export declare function describeSharpen(fields: SharpenLayer): string;
33
+ export declare function parseSharpenFields(object: Record<string, unknown>, at: string, allowPreset: boolean): SharpenLayer;
34
+ export declare function parseSharpenLayer(value: unknown, at: string): SharpenLayer;
35
+ export declare function expandSharpen(layer: SharpenLayer, presets: Record<string, SharpenFields> | undefined, at: string): SharpenFields;
36
+ export interface SharpenFlagOptions {
37
+ sharpen?: string;
38
+ sharpenFor?: string;
39
+ sharpenAmount?: string;
40
+ sharpenRadius?: string;
41
+ sharpenFlat?: string;
42
+ sharpenJagged?: string;
43
+ sharpenThreshold?: string;
44
+ }
45
+ export declare function parseSharpenFlags(options: SharpenFlagOptions): SharpenLayer | undefined;
46
+ export declare function addSharpenFlags(command: Command, withPreset?: boolean): Command;
@@ -0,0 +1,159 @@
1
+ import { ImageBatchUsageError } from './errors.js';
2
+ export const SHARPEN_TARGETS = ['screen', 'matte', 'glossy'];
3
+ export const SHARPEN_AMOUNTS = ['low', 'standard', 'high'];
4
+ export const SHARPEN_FINE_KEYS = ['radius', 'flat', 'jagged', 'threshold'];
5
+ export const SHARPEN_RANGES = {
6
+ radius: [0.000001, 10],
7
+ flat: [0, 1_000_000],
8
+ jagged: [0, 1_000_000],
9
+ threshold: [0, 1_000_000],
10
+ };
11
+ const RADIUS = { screen: 0.6, matte: 1, glossy: 1.4 };
12
+ const STRENGTH = {
13
+ low: { m1: 0.5, m2: 1.5 },
14
+ standard: { m1: 1, m2: 3 },
15
+ high: { m1: 1.8, m2: 5 },
16
+ };
17
+ const LAYER_KEYS = ['preset', 'for', 'amount', ...SHARPEN_FINE_KEYS];
18
+ const FIELD_KEYS = LAYER_KEYS.filter((key) => key !== 'preset');
19
+ export function completeSharpen(fields) {
20
+ return { ...fields, for: fields.for ?? 'screen', amount: fields.amount ?? 'standard' };
21
+ }
22
+ export function sharpenParams(spec) {
23
+ const strength = STRENGTH[spec.amount];
24
+ return {
25
+ sigma: spec.radius ?? RADIUS[spec.for],
26
+ m1: spec.flat ?? strength.m1,
27
+ m2: spec.jagged ?? strength.m2,
28
+ ...(spec.threshold !== undefined ? { x1: spec.threshold } : {}),
29
+ };
30
+ }
31
+ export function describeSharpen(fields) {
32
+ const parts = [];
33
+ if (fields.preset !== undefined)
34
+ parts.push(fields.preset);
35
+ if (fields.for !== undefined)
36
+ parts.push(`for ${fields.for}`);
37
+ if (fields.amount !== undefined)
38
+ parts.push(fields.amount);
39
+ for (const key of SHARPEN_FINE_KEYS) {
40
+ if (fields[key] !== undefined)
41
+ parts.push(`${key} ${fields[key]}`);
42
+ }
43
+ return parts.join(', ');
44
+ }
45
+ function rangeText(key) {
46
+ const [min, max] = SHARPEN_RANGES[key];
47
+ return `${min} to ${max}`;
48
+ }
49
+ function checkFine(key, value, where) {
50
+ const [min, max] = SHARPEN_RANGES[key];
51
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < min || value > max) {
52
+ throw new ImageBatchUsageError(`${where}: expected a number from ${rangeText(key)}`);
53
+ }
54
+ return value;
55
+ }
56
+ export function parseSharpenFields(object, at, allowPreset) {
57
+ const allowed = allowPreset ? LAYER_KEYS : FIELD_KEYS;
58
+ for (const key of Object.keys(object)) {
59
+ if (!allowed.includes(key)) {
60
+ throw new ImageBatchUsageError(`${at}: unknown key "${key}" — expected ${allowed.join(', ')}`);
61
+ }
62
+ }
63
+ const layer = {};
64
+ if (object.preset !== undefined) {
65
+ if (typeof object.preset !== 'string' || object.preset === '') {
66
+ throw new ImageBatchUsageError(`${at}.preset: expected the name of a sharpen preset`);
67
+ }
68
+ layer.preset = object.preset;
69
+ }
70
+ if (object.for !== undefined) {
71
+ if (!SHARPEN_TARGETS.includes(object.for)) {
72
+ throw new ImageBatchUsageError(`${at}.for: expected one of ${SHARPEN_TARGETS.join(', ')}`);
73
+ }
74
+ layer.for = object.for;
75
+ }
76
+ if (object.amount !== undefined) {
77
+ if (!SHARPEN_AMOUNTS.includes(object.amount)) {
78
+ throw new ImageBatchUsageError(`${at}.amount: expected one of ${SHARPEN_AMOUNTS.join(', ')}`);
79
+ }
80
+ layer.amount = object.amount;
81
+ }
82
+ for (const key of SHARPEN_FINE_KEYS) {
83
+ if (object[key] !== undefined)
84
+ layer[key] = checkFine(key, object[key], `${at}.${key}`);
85
+ }
86
+ if (Object.keys(layer).length === 0) {
87
+ throw new ImageBatchUsageError(`${at}: expected at least one of ${allowed.join(', ')}`);
88
+ }
89
+ return layer;
90
+ }
91
+ export function parseSharpenLayer(value, at) {
92
+ if (typeof value === 'string') {
93
+ return parseSharpenFields({ preset: value }, at, true);
94
+ }
95
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
96
+ throw new ImageBatchUsageError(`${at}: expected a preset name or an object with ${LAYER_KEYS.join(', ')}`);
97
+ }
98
+ return parseSharpenFields(value, at, true);
99
+ }
100
+ export function expandSharpen(layer, presets, at) {
101
+ const { preset, ...own } = layer;
102
+ if (preset === undefined)
103
+ return own;
104
+ const base = presets?.[preset];
105
+ if (!base) {
106
+ throw new ImageBatchUsageError(`${at}: the sharpen preset "${preset}" is not loaded — see \`devtoolz image-batch sharpen list\``);
107
+ }
108
+ return { ...base, ...own };
109
+ }
110
+ const FLAG_FINE = [
111
+ ['radius', 'sharpenRadius'],
112
+ ['flat', 'sharpenFlat'],
113
+ ['jagged', 'sharpenJagged'],
114
+ ['threshold', 'sharpenThreshold'],
115
+ ];
116
+ export function parseSharpenFlags(options) {
117
+ const raw = {};
118
+ if (options.sharpen !== undefined)
119
+ raw.preset = options.sharpen;
120
+ if (options.sharpenFor !== undefined)
121
+ raw.for = options.sharpenFor;
122
+ if (options.sharpenAmount !== undefined)
123
+ raw.amount = options.sharpenAmount;
124
+ for (const [key, flag] of FLAG_FINE) {
125
+ const text = options[flag];
126
+ if (text === undefined)
127
+ continue;
128
+ const number = Number(text);
129
+ if (text.trim() === '' || !Number.isFinite(number)) {
130
+ throw new ImageBatchUsageError(`--sharpen-${key} must be a number from ${rangeText(key)}`);
131
+ }
132
+ raw[key] = number;
133
+ }
134
+ if (Object.keys(raw).length === 0)
135
+ return undefined;
136
+ try {
137
+ return parseSharpenFields(raw, 'sharpen', true);
138
+ }
139
+ catch (error) {
140
+ const message = error instanceof Error ? error.message : String(error);
141
+ throw new ImageBatchUsageError(message
142
+ .replace(/^sharpen\.for/, '--sharpen-for')
143
+ .replace(/^sharpen\.amount/, '--sharpen-amount')
144
+ .replace(/^sharpen\.(radius|flat|jagged|threshold)/, '--sharpen-$1'));
145
+ }
146
+ }
147
+ export function addSharpenFlags(command, withPreset = true) {
148
+ if (withPreset) {
149
+ command.option('--sharpen <preset>', 'sharpen with a saved preset (see the sharpen command)');
150
+ }
151
+ return command
152
+ .option('--sharpen-for <target>', 'sharpen the result for: screen, matte or glossy')
153
+ .option('--sharpen-amount <amount>', 'sharpening amount: low, standard or high')
154
+ .option('--sharpen-radius <sigma>', 'sharpening radius (sigma), 0.000001 to 10')
155
+ .option('--sharpen-flat <n>', 'sharpening strength on flat areas, 0 to 1000000')
156
+ .option('--sharpen-jagged <n>', 'sharpening strength on sharp edges, 0 to 1000000')
157
+ .option('--sharpen-threshold <n>', 'edge threshold that separates flat from jagged, 0 to 1000000');
158
+ }
159
+ //# sourceMappingURL=sharpen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharpen.js","sourceRoot":"","sources":["../../../src/commands/image-batch/sharpen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ export declare const TEMPLATE_VARIABLES: readonly ["name", "ext", "format", "dir", "width", "height", "size", "long", "short", "mp", "percent", "scale", "index", "hash", "date", "orig"];
2
+ export type TemplateVariable = (typeof TEMPLATE_VARIABLES)[number];
3
+ export type TemplateToken = {
4
+ type: 'text';
5
+ text: string;
6
+ } | {
7
+ type: 'var';
8
+ name: TemplateVariable;
9
+ param?: number;
10
+ };
11
+ export interface TemplateValues {
12
+ name: string;
13
+ ext: string;
14
+ format: string;
15
+ dir: string;
16
+ width: number;
17
+ height: number;
18
+ size: string;
19
+ long: number;
20
+ short: number;
21
+ mp: string;
22
+ percent: string;
23
+ scale: string;
24
+ index: number;
25
+ hash: string;
26
+ date: string;
27
+ orig: string;
28
+ }
29
+ export interface DefaultTemplateShape {
30
+ widths?: boolean;
31
+ heights?: boolean;
32
+ size?: boolean;
33
+ longEdge?: boolean;
34
+ shortEdge?: boolean;
35
+ megapixels?: boolean;
36
+ percent?: boolean;
37
+ scale?: boolean;
38
+ }
39
+ export declare function defaultTemplate(shape: DefaultTemplateShape): string;
40
+ export declare function parseTemplate(text: string, where: string): TemplateToken[];
41
+ export declare function templateUses(tokens: TemplateToken[], name: TemplateVariable): boolean;
42
+ export declare function templateUsesAny(tokens: TemplateToken[], names: TemplateVariable[]): boolean;
43
+ export declare function normalizeRelativePath(path: string, where: string): string;
44
+ export declare function expandTemplate(tokens: TemplateToken[], values: TemplateValues, where: string): string;
45
+ export declare function formatDate(date: Date): string;
@@ -0,0 +1,142 @@
1
+ import { didYouMean } from '../../utils/closest.js';
2
+ import { ImageBatchUsageError } from './errors.js';
3
+ export const TEMPLATE_VARIABLES = [
4
+ 'name',
5
+ 'ext',
6
+ 'format',
7
+ 'dir',
8
+ 'width',
9
+ 'height',
10
+ 'size',
11
+ 'long',
12
+ 'short',
13
+ 'mp',
14
+ 'percent',
15
+ 'scale',
16
+ 'index',
17
+ 'hash',
18
+ 'date',
19
+ 'orig',
20
+ ];
21
+ const PARAMETERIZED = ['index', 'hash'];
22
+ const DEFAULT_HASH_LENGTH = 8;
23
+ const MAX_HASH_LENGTH = 40;
24
+ const MAX_INDEX_PADDING = 12;
25
+ const FORBIDDEN_SEGMENT_CHARS = /[<>:"|?*]/;
26
+ export function defaultTemplate(shape) {
27
+ if (shape.widths)
28
+ return '{dir}/{name}-{width}w.{format}';
29
+ if (shape.heights)
30
+ return '{dir}/{name}-{height}h.{format}';
31
+ if (shape.size)
32
+ return '{dir}/{name}-{size}.{format}';
33
+ if (shape.longEdge)
34
+ return '{dir}/{name}-{long}l.{format}';
35
+ if (shape.shortEdge)
36
+ return '{dir}/{name}-{short}s.{format}';
37
+ if (shape.megapixels)
38
+ return '{dir}/{name}-{mp}mp.{format}';
39
+ if (shape.percent)
40
+ return '{dir}/{name}-{percent}pct.{format}';
41
+ if (shape.scale)
42
+ return '{dir}/{name}@{scale}x.{format}';
43
+ return '{dir}/{name}.{format}';
44
+ }
45
+ export function parseTemplate(text, where) {
46
+ if (text.trim() === '') {
47
+ throw new ImageBatchUsageError(`${where}: the name template is empty`);
48
+ }
49
+ if (/^([\\/]|[A-Za-z]:)/.test(text)) {
50
+ throw new ImageBatchUsageError(`${where}: the name template "${text}" is an absolute path — templates are always relative to the output folder`);
51
+ }
52
+ const tokens = [];
53
+ const pattern = /\{([a-zA-Z]+)(?::(\d+))?\}/g;
54
+ let last = 0;
55
+ let match;
56
+ while ((match = pattern.exec(text)) !== null) {
57
+ if (match.index > last)
58
+ tokens.push({ type: 'text', text: text.slice(last, match.index) });
59
+ const name = match[1];
60
+ if (!TEMPLATE_VARIABLES.includes(name)) {
61
+ throw new ImageBatchUsageError(`${where}: unknown variable {${name}} in "${text}".${didYouMean(name, TEMPLATE_VARIABLES)} Available: ${TEMPLATE_VARIABLES.map((v) => `{${v}}`).join(' ')}`);
62
+ }
63
+ const variable = name;
64
+ if (match[2] !== undefined) {
65
+ if (!PARAMETERIZED.includes(variable)) {
66
+ throw new ImageBatchUsageError(`${where}: {${variable}} takes no parameter (only ${PARAMETERIZED.map((v) => `{${v}:N}`).join(' and ')} do)`);
67
+ }
68
+ const param = Number(match[2]);
69
+ const limit = variable === 'hash' ? MAX_HASH_LENGTH : MAX_INDEX_PADDING;
70
+ if (param < 1 || param > limit) {
71
+ throw new ImageBatchUsageError(`${where}: {${variable}:${param}} must be 1–${limit}`);
72
+ }
73
+ tokens.push({ type: 'var', name: variable, param });
74
+ }
75
+ else {
76
+ tokens.push({ type: 'var', name: variable });
77
+ }
78
+ last = match.index + match[0].length;
79
+ }
80
+ if (last < text.length)
81
+ tokens.push({ type: 'text', text: text.slice(last) });
82
+ const literal = tokens
83
+ .filter((t) => t.type === 'text')
84
+ .map((t) => t.text)
85
+ .join('');
86
+ if (/[{}]/.test(literal)) {
87
+ throw new ImageBatchUsageError(`${where}: unbalanced "{" or "}" in the name template "${text}" — write variables as {name}`);
88
+ }
89
+ const shape = tokens.map((t) => (t.type === 'text' ? t.text : 'x')).join('');
90
+ if (shape.split(/[\\/]/).includes('..')) {
91
+ throw new ImageBatchUsageError(`${where}: the name template "${text}" must not contain ".." — results stay inside the output folder`);
92
+ }
93
+ return tokens;
94
+ }
95
+ export function templateUses(tokens, name) {
96
+ return tokens.some((token) => token.type === 'var' && token.name === name);
97
+ }
98
+ export function templateUsesAny(tokens, names) {
99
+ return names.some((name) => templateUses(tokens, name));
100
+ }
101
+ export function normalizeRelativePath(path, where) {
102
+ const segments = [];
103
+ for (const segment of path.split(/[\\/]/)) {
104
+ if (segment === '' || segment === '.')
105
+ continue;
106
+ if (segment === '..') {
107
+ throw new ImageBatchUsageError(`${where}: "${path}" escapes the output folder`);
108
+ }
109
+ if (FORBIDDEN_SEGMENT_CHARS.test(segment) || [...segment].some((ch) => ch.charCodeAt(0) < 32)) {
110
+ throw new ImageBatchUsageError(`${where}: "${segment}" contains a character that is not allowed in a file name`);
111
+ }
112
+ segments.push(segment);
113
+ }
114
+ if (segments.length === 0) {
115
+ throw new ImageBatchUsageError(`${where}: the name template produced an empty path`);
116
+ }
117
+ return segments.join('/');
118
+ }
119
+ export function expandTemplate(tokens, values, where) {
120
+ const pieces = tokens.map((token) => {
121
+ if (token.type === 'text')
122
+ return token.text;
123
+ switch (token.name) {
124
+ case 'index':
125
+ return String(values.index).padStart(token.param ?? 1, '0');
126
+ case 'hash':
127
+ return values.hash.slice(0, token.param ?? DEFAULT_HASH_LENGTH);
128
+ case 'width':
129
+ return String(values.width);
130
+ case 'height':
131
+ return String(values.height);
132
+ default:
133
+ return String(values[token.name]);
134
+ }
135
+ });
136
+ return normalizeRelativePath(pieces.join(''), where);
137
+ }
138
+ export function formatDate(date) {
139
+ const pad = (n) => String(n).padStart(2, '0');
140
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
141
+ }
142
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/commands/image-batch/template.ts"],"names":[],"mappings":"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"}
@@ -56,4 +56,6 @@ export declare function defaultSharpLoaderDeps(): SharpLoaderDeps;
56
56
  export declare function loadSharp(options: {
57
57
  assumeYes?: boolean;
58
58
  cwd?: string;
59
+ command?: string;
60
+ createError?: (message: string) => Error;
59
61
  }, deps?: SharpLoaderDeps): Promise<SharpFactory>;
@@ -56,23 +56,25 @@ export async function loadSharp(options, deps = defaultSharpLoaderDeps()) {
56
56
  deps.resolveManaged();
57
57
  if (existing)
58
58
  return existing;
59
+ const command = options.command ?? 'image-hash';
60
+ const fail = (message) => options.createError ? options.createError(message) : new ImageHashUsageError(message);
59
61
  const manualHint = `Install it yourself with: npm install ${SHARP_SPEC}`;
60
62
  if (!options.assumeYes) {
61
63
  if (!deps.interactive) {
62
- throw new ImageHashUsageError(`image-hash needs the "sharp" image library, and it is not installed. ` +
64
+ throw fail(`${command} needs the "sharp" image library, and it is not installed. ` +
63
65
  `Run with --yes to let devtoolz install it into ${MANAGED_DEPS_DIR}. ${manualHint}`);
64
66
  }
65
- const agreed = await deps.confirm(`image-hash needs the "sharp" image library (native, ~30 MB). Install it into ${MANAGED_DEPS_DIR}?`);
67
+ const agreed = await deps.confirm(`${command} needs the "sharp" image library (native, ~30 MB). Install it into ${MANAGED_DEPS_DIR}?`);
66
68
  if (!agreed) {
67
- throw new ImageHashUsageError(`"sharp" was not installed, nothing to do. ${manualHint}`);
69
+ throw fail(`"sharp" was not installed, nothing to do. ${manualHint}`);
68
70
  }
69
71
  }
70
72
  if (!deps.install()) {
71
- throw new ImageHashUsageError(`Installing "sharp" failed. ${manualHint}`);
73
+ throw fail(`Installing "sharp" failed. ${manualHint}`);
72
74
  }
73
75
  const installed = deps.resolveManaged();
74
76
  if (!installed) {
75
- throw new ImageHashUsageError(`"sharp" was installed but could not be loaded on this platform. ${manualHint}`);
77
+ throw fail(`"sharp" was installed but could not be loaded on this platform. ${manualHint}`);
76
78
  }
77
79
  return installed;
78
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sharp-loader.js","sourceRoot":"","sources":["../../../src/commands/image-hash/sharp-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sharp-loader.js","sourceRoot":"","sources":["../../../src/commands/image-hash/sharp-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function formatBytes(bytes: number): string;
2
+ export declare function formatPercent(part: number, whole: number): string;
@@ -0,0 +1,17 @@
1
+ const UNITS = ['B', 'KB', 'MB', 'GB'];
2
+ export function formatBytes(bytes) {
3
+ let value = bytes;
4
+ let unit = 0;
5
+ while (value >= 1024 && unit < UNITS.length - 1) {
6
+ value /= 1024;
7
+ unit += 1;
8
+ }
9
+ const digits = unit === 0 || value >= 100 ? 0 : value >= 10 ? 1 : 2;
10
+ return `${value.toFixed(digits)} ${UNITS[unit]}`;
11
+ }
12
+ export function formatPercent(part, whole) {
13
+ if (whole <= 0)
14
+ return '0%';
15
+ return `${Math.round((part / whole) * 100)}%`;
16
+ }
17
+ //# sourceMappingURL=bytes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/format/bytes.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAErC,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,GAAG,KAAK,CAAA;IACjB,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,OAAO,KAAK,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,KAAK,IAAI,IAAI,CAAA;QACb,IAAI,IAAI,CAAC,CAAA;IACX,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnE,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAa;IACvD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3B,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,CAAA;AAC/C,CAAC"}
package/dist/index.d.ts CHANGED
@@ -98,3 +98,8 @@ export { runImageHash } from './commands/image-hash/run.js';
98
98
  export type { ImageHashRunOptions, ImageHashReport, ImageHashError, ImageHashProgress, OutdatedOutput, } from './commands/image-hash/run.js';
99
99
  export { renderImageHashReport } from './commands/image-hash/report.js';
100
100
  export type { Components, HashEntry, HashType, OutputFormat } from './commands/image-hash/core.js';
101
+ export { runImageBatch } from './commands/image-batch/run.js';
102
+ export type { BatchJobResult, BatchOverrides, ImageBatchOptions, ImageBatchReport, } from './commands/image-batch/run.js';
103
+ export { renderImageBatchReport } from './commands/image-batch/report.js';
104
+ export { parseConfig } from './commands/image-batch/config.js';
105
+ export type { BatchConfig } from './commands/image-batch/config.js';
package/dist/index.js CHANGED
@@ -60,4 +60,7 @@ export { renderFullCheckReport } from './commands/full-check/report.js';
60
60
  export { walk } from './utils/walk.js';
61
61
  export { runImageHash } from './commands/image-hash/run.js';
62
62
  export { renderImageHashReport } from './commands/image-hash/report.js';
63
+ export { runImageBatch } from './commands/image-batch/run.js';
64
+ export { renderImageBatchReport } from './commands/image-batch/report.js';
65
+ export { parseConfig } from './commands/image-batch/config.js';
63
66
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function closest(word: string, candidates: readonly string[]): string | undefined;
2
+ export declare function didYouMean(word: string, candidates: readonly string[]): string;
@@ -0,0 +1,35 @@
1
+ function distance(a, b) {
2
+ const previous = Array.from({ length: b.length + 1 }, (_, i) => i);
3
+ for (let i = 1; i <= a.length; i++) {
4
+ let diagonal = previous[0];
5
+ previous[0] = i;
6
+ for (let j = 1; j <= b.length; j++) {
7
+ const above = previous[j];
8
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
9
+ previous[j] = Math.min(above + 1, previous[j - 1] + 1, diagonal + cost);
10
+ diagonal = above;
11
+ }
12
+ }
13
+ return previous[b.length];
14
+ }
15
+ export function closest(word, candidates) {
16
+ const lower = word.toLowerCase();
17
+ let best;
18
+ let bestDistance = Infinity;
19
+ for (const candidate of candidates) {
20
+ const d = distance(lower, candidate.toLowerCase());
21
+ if (d < bestDistance) {
22
+ best = candidate;
23
+ bestDistance = d;
24
+ }
25
+ }
26
+ if (best === undefined)
27
+ return undefined;
28
+ const limit = Math.max(2, Math.floor(best.length / 3));
29
+ return bestDistance <= limit ? best : undefined;
30
+ }
31
+ export function didYouMean(word, candidates) {
32
+ const match = closest(word, candidates);
33
+ return match === undefined ? '' : ` Did you mean "${match}"?`;
34
+ }
35
+ //# sourceMappingURL=closest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"closest.js","sourceRoot":"","sources":["../../src/utils/closest.ts"],"names":[],"mappings":"AAAA,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAW,CAAA;QACpC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAW,CAAA;YACnC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1C,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAY,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAA;YACnF,QAAQ,GAAG,KAAK,CAAA;QAClB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAW,CAAA;AACrC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,UAA6B;IACjE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IAChC,IAAI,IAAwB,CAAA;IAC5B,IAAI,YAAY,GAAG,QAAQ,CAAA;IAC3B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;QAClD,IAAI,CAAC,GAAG,YAAY,EAAE,CAAC;YACrB,IAAI,GAAG,SAAS,CAAA;YAChB,YAAY,GAAG,CAAC,CAAA;QAClB,CAAC;IACH,CAAC;IACD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;IACtD,OAAO,YAAY,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,UAA6B;IACpE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACvC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,KAAK,IAAI,CAAA;AAC/D,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function hasGlobChars(text: string): boolean;
2
+ export declare function globToRegExp(pattern: string): RegExp;
3
+ export declare function matchGlob(pattern: string, path: string): boolean;
4
+ export declare function literalPrefix(pattern: string): string;