@macrulez/devtoolz 0.4.0 → 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.
@@ -0,0 +1,238 @@
1
+ import { existsSync, renameSync, rmSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { createStyle } from '../../format/style.js';
4
+ import { renderTable } from '../../format/table.js';
5
+ import { askText, isInteractive, promptChoice, singleSelect, } from '../../utils/tty.js';
6
+ import { CONFIG_DIR_SEGMENTS } from './config.js';
7
+ import { ImageBatchUsageError } from './errors.js';
8
+ import { validName, writeJson } from './manage.js';
9
+ import { askSharpenFields } from './sharpen-ask.js';
10
+ import { SHARPEN_FINE_KEYS, completeSharpen, describeSharpen, parseSharpenFields, sharpenParams, } from './sharpen.js';
11
+ import { SHARPEN_DIR_NAME, discoverSharpenPresets, findSharpenPreset, globalSharpenDir, readSharpenPreset, } from './sharpen-presets.js';
12
+ export function sharpenDir(scope, env) {
13
+ return scope === 'global'
14
+ ? globalSharpenDir(env.globalDir)
15
+ : join(env.cwd, ...CONFIG_DIR_SEGMENTS, SHARPEN_DIR_NAME);
16
+ }
17
+ export function listSharpenRows(env) {
18
+ const discovered = discoverSharpenPresets({
19
+ cwd: env.cwd,
20
+ ...(env.globalDir !== undefined ? { globalDir: env.globalDir } : {}),
21
+ });
22
+ return discovered.map((location) => {
23
+ try {
24
+ const preset = readSharpenPreset(location);
25
+ return {
26
+ location,
27
+ fields: preset.fields,
28
+ ...(preset.description !== undefined ? { description: preset.description } : {}),
29
+ };
30
+ }
31
+ catch (error) {
32
+ return { location, error: error instanceof Error ? error.message : String(error) };
33
+ }
34
+ });
35
+ }
36
+ export function renderSharpenTable(rows, style) {
37
+ const s = createStyle(style);
38
+ const columns = [
39
+ { header: 'Name', style: s.name },
40
+ { header: 'Scope', style: s.accent },
41
+ { header: 'Settings', style: s.value },
42
+ { header: 'Path', shrink: true, style: s.path },
43
+ ];
44
+ return renderTable(columns, rows.map((row) => [
45
+ row.location.name,
46
+ row.location.scope,
47
+ row.error ? 'error' : describeSharpen(row.fields ?? {}),
48
+ row.location.path,
49
+ ]), style);
50
+ }
51
+ export function describeSharpenPreset(row, style) {
52
+ const s = createStyle(style);
53
+ const lines = [
54
+ `${s.heading(row.location.name)} ${s.muted(`(${row.location.scope})`)}${row.description ? s.muted(` — ${row.description}`) : ''}`,
55
+ ` ${s.muted('file')} ${s.path(row.location.path)}`,
56
+ ];
57
+ if (row.error || !row.fields) {
58
+ lines.push(` ${s.error(row.error ?? 'unreadable')}`);
59
+ return lines;
60
+ }
61
+ const spec = completeSharpen(row.fields);
62
+ lines.push(` ${s.muted('for')} ${s.value(spec.for)} ${s.muted('amount')} ${s.value(spec.amount)}`);
63
+ for (const key of SHARPEN_FINE_KEYS) {
64
+ if (row.fields[key] !== undefined) {
65
+ lines.push(` ${s.muted(key)} ${s.value(String(row.fields[key]))}`);
66
+ }
67
+ }
68
+ const params = sharpenParams(spec);
69
+ lines.push(` ${s.muted('sharp')} sigma ${params.sigma}, flat ${params.m1}, jagged ${params.m2}${params.x1 !== undefined ? `, threshold ${params.x1}` : ''}`);
70
+ return lines;
71
+ }
72
+ export function sharpenLocationFor(env, name) {
73
+ return findSharpenPreset(name, discoverSharpenPresets({
74
+ cwd: env.cwd,
75
+ ...(env.globalDir !== undefined ? { globalDir: env.globalDir } : {}),
76
+ }));
77
+ }
78
+ export function showSharpenPreset(env, name) {
79
+ const location = sharpenLocationFor(env, name);
80
+ const row = { location };
81
+ try {
82
+ const preset = readSharpenPreset(location);
83
+ row.fields = preset.fields;
84
+ if (preset.description !== undefined)
85
+ row.description = preset.description;
86
+ }
87
+ catch (error) {
88
+ row.error = error instanceof Error ? error.message : String(error);
89
+ }
90
+ env.log(describeSharpenPreset(row, env.style).join('\n'));
91
+ }
92
+ export function removeSharpenPreset(location, force) {
93
+ if (location.scope === 'built-in') {
94
+ throw new ImageBatchUsageError(`${location.name} is a built-in preset and cannot be deleted — copy it to this project with the sharpen command to change it`);
95
+ }
96
+ if (force) {
97
+ rmSync(location.path, { force: true });
98
+ return location.path;
99
+ }
100
+ const backup = `${location.path}.bak`;
101
+ if (existsSync(backup))
102
+ rmSync(backup, { force: true });
103
+ renameSync(location.path, backup);
104
+ return backup;
105
+ }
106
+ function writePreset(env, name, scope, fields, description, force) {
107
+ const path = join(sharpenDir(scope, env), `${name}.json`);
108
+ if (existsSync(path) && !force) {
109
+ throw new ImageBatchUsageError(`${path} already exists — pick another name or pass --force`);
110
+ }
111
+ writeJson(path, { ...(description ? { description } : {}), ...fields });
112
+ return path;
113
+ }
114
+ export async function runSharpenNew(env, options) {
115
+ const s = createStyle(env.style);
116
+ const interactive = isInteractive(env.io);
117
+ let name = options.name;
118
+ if (name === undefined) {
119
+ if (!interactive) {
120
+ throw new ImageBatchUsageError('sharpen new needs --name <name> when it is not run in a terminal');
121
+ }
122
+ const answer = await askText(env.io, 'Name of the sharpen preset:', s, 'web-crisp');
123
+ if (answer === null)
124
+ throw new ImageBatchUsageError('cancelled');
125
+ name = answer;
126
+ }
127
+ const clean = validName(name);
128
+ let scope = options.global ? 'global' : 'project';
129
+ if (interactive && options.global === undefined) {
130
+ const picked = await singleSelect(env.io, [
131
+ {
132
+ label: 'This project',
133
+ hint: '.devtoolz/image-batch/sharpen/',
134
+ value: 'project',
135
+ },
136
+ {
137
+ label: 'All projects',
138
+ hint: '~/.devtoolz/image-batch/sharpen/',
139
+ value: 'global',
140
+ },
141
+ ], { title: 'Where should the preset live?', help: 'enter pick · q cancel' }, s);
142
+ if (picked === null)
143
+ throw new ImageBatchUsageError('cancelled');
144
+ scope = picked;
145
+ }
146
+ let fields = options.fields;
147
+ if (fields === undefined) {
148
+ if (!interactive) {
149
+ throw new ImageBatchUsageError('sharpen new needs at least one of --sharpen-for, --sharpen-amount, --sharpen-radius, --sharpen-flat, --sharpen-jagged, --sharpen-threshold when it is not run in a terminal');
150
+ }
151
+ const asked = await askSharpenFields(env, s);
152
+ if (asked === null)
153
+ throw new ImageBatchUsageError('cancelled');
154
+ fields = asked;
155
+ }
156
+ parseSharpenFields({ ...fields }, clean, false);
157
+ const path = writePreset(env, clean, scope, fields, options.description, options.force ?? false);
158
+ env.log(`${s.success('Created')} ${s.path(path)}`);
159
+ env.log(s.hint(`(use it with: devtoolz image-batch <folder> -o <out> --sharpen ${clean} — or "sharpen": "${clean}" in a config)`));
160
+ return path;
161
+ }
162
+ export async function manageSharpenPresets(env) {
163
+ const s = createStyle(env.style);
164
+ if (!isInteractive(env.io)) {
165
+ const rows = listSharpenRows(env);
166
+ env.log(rows.length === 0
167
+ ? s.warn('No sharpen presets found — create one with `devtoolz image-batch sharpen new`.')
168
+ : renderSharpenTable(rows, env.style).join('\n'));
169
+ return;
170
+ }
171
+ for (;;) {
172
+ const rows = listSharpenRows(env);
173
+ const items = [
174
+ ...rows.map((row) => ({
175
+ label: row.location.name,
176
+ hint: row.error
177
+ ? `unreadable — ${row.error.slice(0, 50)}`
178
+ : `${row.location.scope} · ${describeSharpen(row.fields ?? {})}`,
179
+ value: row,
180
+ })),
181
+ { label: '+ new preset', hint: 'wizard', value: 'new' },
182
+ ];
183
+ const picked = await singleSelect(env.io, items, { title: 'Sharpen presets', help: 'enter open · / filter · q quit', filterable: true }, s);
184
+ if (picked === null)
185
+ return;
186
+ try {
187
+ if (picked === 'new') {
188
+ await runSharpenNew(env, {});
189
+ continue;
190
+ }
191
+ const location = picked.location;
192
+ const action = await singleSelect(env.io, [
193
+ { label: 'Show', hint: 'the settings and what sharp receives', value: 'show' },
194
+ ...(location.scope === 'built-in'
195
+ ? []
196
+ : [{ label: 'Edit', hint: 'the same questions as for a new preset', value: 'edit' }]),
197
+ {
198
+ label: location.scope === 'project' ? 'Copy to global' : 'Copy to this project',
199
+ hint: location.scope === 'built-in' ? 'to change it as your own' : '',
200
+ value: 'copy',
201
+ },
202
+ ...(location.scope === 'built-in' ? [] : [{ label: 'Delete', value: 'delete' }]),
203
+ { label: '— back —', value: 'back' },
204
+ ], { title: `${location.name} ${location.scope}`, help: 'enter pick · q back' }, s);
205
+ if (action === 'show') {
206
+ env.log(describeSharpenPreset(picked, env.style).join('\n'));
207
+ }
208
+ else if (action === 'edit') {
209
+ const fields = await askSharpenFields(env, s, picked.fields ?? {});
210
+ if (fields !== null) {
211
+ writeJson(location.path, {
212
+ ...(picked.description ? { description: picked.description } : {}),
213
+ ...fields,
214
+ });
215
+ env.log(`${s.success('Saved')} ${s.path(location.path)}`);
216
+ }
217
+ }
218
+ else if (action === 'copy' && picked.fields) {
219
+ const target = location.scope === 'project' ? 'global' : 'project';
220
+ const path = writePreset(env, location.name, target, picked.fields, picked.description, false);
221
+ env.log(`${s.success('Copied to')} ${s.path(path)}`);
222
+ }
223
+ else if (action === 'delete') {
224
+ const answer = await promptChoice(env.io, `Delete ${location.name}? A .bak copy stays.`, [
225
+ { key: 'y', label: 'yes' },
226
+ { key: 'n', label: 'no' },
227
+ ], s, 'n');
228
+ if (answer === 'y') {
229
+ env.log(`${s.success('Deleted')} ${s.path(removeSharpenPreset(location, false))}`);
230
+ }
231
+ }
232
+ }
233
+ catch (error) {
234
+ env.log(s.error(error instanceof Error ? error.message : String(error)));
235
+ }
236
+ }
237
+ }
238
+ //# sourceMappingURL=sharpen-manage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharpen-manage.js","sourceRoot":"","sources":["../../../src/commands/image-batch/sharpen-manage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type BatchConfig } from './config.js';
2
+ import { type SharpenFields, type SharpenLayer } from './sharpen.js';
3
+ export declare const SHARPEN_DIR_NAME = "sharpen";
4
+ export interface SharpenPresetLocation {
5
+ name: string;
6
+ path: string;
7
+ scope: 'project' | 'global' | 'built-in';
8
+ }
9
+ export interface SharpenPreset {
10
+ description?: string;
11
+ fields: SharpenFields;
12
+ }
13
+ export interface SharpenDiscoverOptions {
14
+ cwd: string;
15
+ globalDir?: string;
16
+ }
17
+ export declare const BUILT_IN_SHARPEN_PRESETS: Record<string, SharpenPreset>;
18
+ export declare function globalSharpenDir(globalDir?: string): string;
19
+ export declare function discoverSharpenPresets(options: SharpenDiscoverOptions): SharpenPresetLocation[];
20
+ export declare function readSharpenPreset(location: SharpenPresetLocation): SharpenPreset;
21
+ export declare function findSharpenPreset(name: string, discovered: SharpenPresetLocation[]): SharpenPresetLocation;
22
+ export declare function attachSharpenPresets(config: BatchConfig, options: SharpenDiscoverOptions & {
23
+ extra?: (SharpenLayer | undefined)[];
24
+ }): BatchConfig;
@@ -0,0 +1,145 @@
1
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { basename, dirname, extname, join, resolve } from 'node:path';
4
+ import { didYouMean } from '../../utils/closest.js';
5
+ import { CONFIG_DIR_SEGMENTS, globalConfigDir } from './config.js';
6
+ import { ImageBatchUsageError } from './errors.js';
7
+ import { parseSharpenFields } from './sharpen.js';
8
+ export const SHARPEN_DIR_NAME = 'sharpen';
9
+ export const BUILT_IN_SHARPEN_PRESETS = {
10
+ 'web-light': {
11
+ description: 'A light touch for web photos',
12
+ fields: { for: 'screen', amount: 'low' },
13
+ },
14
+ 'web-crisp': {
15
+ description: 'Everyday sharpening for the web',
16
+ fields: { for: 'screen', amount: 'standard' },
17
+ },
18
+ 'web-detail': {
19
+ description: 'Fine detail for large web photos',
20
+ fields: { for: 'screen', amount: 'high', radius: 0.8 },
21
+ },
22
+ thumbnail: {
23
+ description: 'Small previews: a fine radius, gentle on flat areas',
24
+ fields: { for: 'screen', amount: 'standard', radius: 0.4, flat: 0.6, jagged: 2.5 },
25
+ },
26
+ 'print-matte': {
27
+ description: 'Matte paper',
28
+ fields: { for: 'matte', amount: 'standard' },
29
+ },
30
+ 'print-glossy': {
31
+ description: 'Glossy paper',
32
+ fields: { for: 'glossy', amount: 'standard' },
33
+ },
34
+ };
35
+ export function globalSharpenDir(globalDir) {
36
+ return join(globalDir ?? globalConfigDir(homedir()), SHARPEN_DIR_NAME);
37
+ }
38
+ function listPresets(dir, scope) {
39
+ const stat = statSync(dir, { throwIfNoEntry: false });
40
+ if (!stat?.isDirectory())
41
+ return [];
42
+ return readdirSync(dir, { withFileTypes: true })
43
+ .filter((entry) => entry.isFile() && extname(entry.name).toLowerCase() === '.json')
44
+ .sort((a, b) => a.name.localeCompare(b.name))
45
+ .map((entry) => ({
46
+ name: basename(entry.name, extname(entry.name)),
47
+ path: join(dir, entry.name),
48
+ scope,
49
+ }));
50
+ }
51
+ export function discoverSharpenPresets(options) {
52
+ const found = [];
53
+ const seen = new Set();
54
+ const globalDir = resolve(globalSharpenDir(options.globalDir));
55
+ const homeGlobalDir = resolve(globalSharpenDir());
56
+ let dir = resolve(options.cwd);
57
+ for (;;) {
58
+ const candidate = join(dir, ...CONFIG_DIR_SEGMENTS, SHARPEN_DIR_NAME);
59
+ const resolved = resolve(candidate);
60
+ if (resolved !== globalDir && resolved !== homeGlobalDir && !seen.has(candidate)) {
61
+ seen.add(candidate);
62
+ found.push(...listPresets(candidate, 'project'));
63
+ }
64
+ if (existsSync(join(dir, '.git')))
65
+ break;
66
+ const parent = dirname(dir);
67
+ if (parent === dir)
68
+ break;
69
+ dir = parent;
70
+ }
71
+ found.push(...listPresets(globalDir, 'global'));
72
+ const own = new Set(found.map((location) => location.name));
73
+ for (const name of Object.keys(BUILT_IN_SHARPEN_PRESETS)) {
74
+ if (!own.has(name))
75
+ found.push({ name, path: `(built-in ${name})`, scope: 'built-in' });
76
+ }
77
+ return found;
78
+ }
79
+ export function readSharpenPreset(location) {
80
+ if (location.scope === 'built-in') {
81
+ const preset = BUILT_IN_SHARPEN_PRESETS[location.name];
82
+ if (!preset)
83
+ throw new ImageBatchUsageError(`${location.name} is not a built-in preset`);
84
+ return preset;
85
+ }
86
+ let parsed;
87
+ try {
88
+ parsed = JSON.parse(readFileSync(location.path, 'utf8'));
89
+ }
90
+ catch (error) {
91
+ throw new ImageBatchUsageError(`${location.path}: not valid JSON — ${error instanceof Error ? error.message : String(error)}`);
92
+ }
93
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
94
+ throw new ImageBatchUsageError(`${location.path}: expected a JSON object`);
95
+ }
96
+ const { description, ...rest } = parsed;
97
+ if (description !== undefined && typeof description !== 'string') {
98
+ throw new ImageBatchUsageError(`${location.path}.description: expected a string`);
99
+ }
100
+ const fields = parseSharpenFields(rest, location.path, false);
101
+ return { ...(description !== undefined ? { description } : {}), fields };
102
+ }
103
+ export function findSharpenPreset(name, discovered) {
104
+ const matches = discovered.filter((location) => location.name === name);
105
+ const chosen = matches.find((match) => match.scope === 'project') ?? matches[0];
106
+ if (!chosen) {
107
+ const names = [...new Set(discovered.map((location) => location.name))];
108
+ throw new ImageBatchUsageError(`no sharpen preset named "${name}".${didYouMean(name, names)} ${names.length > 0
109
+ ? `Available: ${names.join(', ')}.`
110
+ : 'None found — create one with `devtoolz image-batch sharpen new`.'}`);
111
+ }
112
+ return chosen;
113
+ }
114
+ function layersOf(config, extra) {
115
+ const recipes = [
116
+ config.defaults,
117
+ ...Object.values(config.presets),
118
+ ...config.outputs,
119
+ ...config.match.flatMap((rule) => rule.outputs),
120
+ ];
121
+ const layers = [];
122
+ for (const recipe of recipes)
123
+ if (recipe.sharpen)
124
+ layers.push(recipe.sharpen);
125
+ for (const layer of extra)
126
+ if (layer)
127
+ layers.push(layer);
128
+ return layers;
129
+ }
130
+ export function attachSharpenPresets(config, options) {
131
+ const names = [
132
+ ...new Set(layersOf(config, options.extra ?? [])
133
+ .map((layer) => layer.preset)
134
+ .filter((name) => name !== undefined)),
135
+ ];
136
+ if (names.length === 0)
137
+ return config;
138
+ const discovered = discoverSharpenPresets(options);
139
+ const presets = {};
140
+ for (const name of names) {
141
+ presets[name] = readSharpenPreset(findSharpenPreset(name, discovered)).fields;
142
+ }
143
+ return { ...config, sharpenPresets: presets };
144
+ }
145
+ //# sourceMappingURL=sharpen-presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharpen-presets.js","sourceRoot":"","sources":["../../../src/commands/image-batch/sharpen-presets.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,22 @@
1
+ import type { Command } from 'commander';
1
2
  export declare const SHARPEN_TARGETS: readonly ["screen", "matte", "glossy"];
2
3
  export declare const SHARPEN_AMOUNTS: readonly ["low", "standard", "high"];
4
+ export declare const SHARPEN_FINE_KEYS: readonly ["radius", "flat", "jagged", "threshold"];
3
5
  export type SharpenTarget = (typeof SHARPEN_TARGETS)[number];
4
6
  export type SharpenAmount = (typeof SHARPEN_AMOUNTS)[number];
5
- export interface SharpenSpec {
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 {
6
20
  for: SharpenTarget;
7
21
  amount: SharpenAmount;
8
22
  }
@@ -10,7 +24,23 @@ export interface SharpenParams {
10
24
  sigma: number;
11
25
  m1: number;
12
26
  m2: number;
27
+ x1?: number;
13
28
  }
29
+ export declare const SHARPEN_RANGES: Record<SharpenFineKey, readonly [number, number]>;
30
+ export declare function completeSharpen(fields: SharpenFields): SharpenSpec;
14
31
  export declare function sharpenParams(spec: SharpenSpec): SharpenParams;
15
- export declare function completeSharpen(partial: Partial<SharpenSpec>): SharpenSpec;
16
- export declare function parseSharpenFlags(target: string | undefined, amount: string | undefined): Partial<SharpenSpec> | undefined;
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;