@teamflojo/floimg 0.1.0 ā 0.3.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/QUICK_START.md +199 -0
- package/dist/cli/commands/chart.d.ts +20 -0
- package/dist/cli/commands/chart.d.ts.map +1 -0
- package/dist/cli/commands/chart.js +126 -0
- package/dist/cli/commands/chart.js.map +1 -0
- package/dist/cli/commands/config.js +11 -11
- package/dist/cli/commands/convert.d.ts +18 -0
- package/dist/cli/commands/convert.d.ts.map +1 -0
- package/dist/cli/commands/convert.js +122 -0
- package/dist/cli/commands/convert.js.map +1 -0
- package/dist/cli/commands/generate.js +1 -1
- package/dist/cli/commands/mcp.js +9 -9
- package/dist/cli/commands/plugins.js +14 -14
- package/dist/cli/commands/qr.d.ts +20 -0
- package/dist/cli/commands/qr.d.ts.map +1 -0
- package/dist/cli/commands/qr.js +82 -0
- package/dist/cli/commands/qr.js.map +1 -0
- package/dist/cli/commands/resize.d.ts +18 -0
- package/dist/cli/commands/resize.d.ts.map +1 -0
- package/dist/cli/commands/resize.js +100 -0
- package/dist/cli/commands/resize.js.map +1 -0
- package/dist/cli/index.js +20 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/interactive.d.ts +10 -0
- package/dist/cli/interactive.d.ts.map +1 -0
- package/dist/cli/interactive.js +115 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli/utils/plugin-loader.d.ts +32 -0
- package/dist/cli/utils/plugin-loader.d.ts.map +1 -0
- package/dist/cli/utils/plugin-loader.js +150 -0
- package/dist/cli/utils/plugin-loader.js.map +1 -0
- package/dist/core/client.d.ts +23 -2
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +98 -4
- package/dist/core/client.js.map +1 -1
- package/dist/core/logger.d.ts +1 -1
- package/dist/core/logger.js +5 -5
- package/dist/core/pipeline-runner.d.ts +1 -1
- package/dist/core/pipeline-runner.js +1 -1
- package/dist/core/types.d.ts +189 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +27 -1
- package/dist/core/types.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +165 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/providers/ai/index.d.ts +4 -0
- package/dist/providers/ai/index.d.ts.map +1 -1
- package/dist/providers/ai/index.js +5 -0
- package/dist/providers/ai/index.js.map +1 -1
- package/dist/providers/ai/openai.d.ts +78 -1
- package/dist/providers/ai/openai.d.ts.map +1 -1
- package/dist/providers/ai/openai.js +234 -0
- package/dist/providers/ai/openai.js.map +1 -1
- package/package.json +10 -9
- package/LICENSE +0 -21
package/QUICK_START.md
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
|
|
3
|
+
Get started with floimg in seconds using `npx` - no installation required.
|
|
4
|
+
|
|
5
|
+
## Try It Now
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Generate a QR code
|
|
9
|
+
npx @teamflojo/floimg qr "https://floimg.com" -o qr.png
|
|
10
|
+
|
|
11
|
+
# Create a chart
|
|
12
|
+
npx @teamflojo/floimg chart bar --labels "Q1,Q2,Q3" --values "10,20,30" -o chart.png
|
|
13
|
+
|
|
14
|
+
# Resize an image
|
|
15
|
+
npx @teamflojo/floimg resize photo.jpg 800x600 -o thumbnail.jpg
|
|
16
|
+
|
|
17
|
+
# Convert format (PNG to WebP)
|
|
18
|
+
npx @teamflojo/floimg convert image.png -o image.webp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## How Plugin Auto-Install Works
|
|
22
|
+
|
|
23
|
+
floimg is modular. The core package is lightweight, and plugins are installed on-demand.
|
|
24
|
+
|
|
25
|
+
When you run a command that requires a plugin (like `qr` or `chart`), floimg will:
|
|
26
|
+
|
|
27
|
+
1. Check if the required plugin is installed
|
|
28
|
+
2. If not, prompt you to install it
|
|
29
|
+
3. Install and run your command
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
$ npx @teamflojo/floimg qr "https://example.com"
|
|
33
|
+
|
|
34
|
+
š The 'qr' command requires @teamflojo/floimg-qr
|
|
35
|
+
QR Code Generator
|
|
36
|
+
|
|
37
|
+
Install it now? (y/n): y
|
|
38
|
+
š¦ Installing @teamflojo/floimg-qr...
|
|
39
|
+
ā
Installed!
|
|
40
|
+
|
|
41
|
+
ā
QR code saved to: qr.png
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**After the first run**, the plugin is cached and subsequent runs are fast.
|
|
45
|
+
|
|
46
|
+
## Interactive Mode
|
|
47
|
+
|
|
48
|
+
Run floimg with no arguments to see an interactive menu:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx @teamflojo/floimg
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This shows all available commands and examples.
|
|
55
|
+
|
|
56
|
+
## Command Reference
|
|
57
|
+
|
|
58
|
+
### QR Code
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
floimg qr <text> [options]
|
|
62
|
+
|
|
63
|
+
Options:
|
|
64
|
+
-o, --out <path> Output file (default: qr.png)
|
|
65
|
+
-s, --size <pixels> Size in pixels (default: 300)
|
|
66
|
+
-f, --format <format> png or svg (default: png)
|
|
67
|
+
-e, --error-correction L, M, Q, or H (default: M)
|
|
68
|
+
--dark <color> Dark color hex (default: #000000)
|
|
69
|
+
--light <color> Light color hex (default: #ffffff)
|
|
70
|
+
|
|
71
|
+
Examples:
|
|
72
|
+
floimg qr "https://floimg.com" -o qr.png
|
|
73
|
+
floimg qr "Hello World" --size 400 --format svg -o hello.svg
|
|
74
|
+
floimg qr "https://example.com" --error-correction H --dark "#1a1a2e"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Chart
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
floimg chart <type> [options]
|
|
81
|
+
|
|
82
|
+
Types: bar, line, pie, doughnut, radar, polarArea, scatter
|
|
83
|
+
|
|
84
|
+
Options:
|
|
85
|
+
-o, --out <path> Output file (default: chart.png)
|
|
86
|
+
-l, --labels <items> Comma-separated labels
|
|
87
|
+
-v, --values <items> Comma-separated values
|
|
88
|
+
-d, --data <file> JSON file with Chart.js config
|
|
89
|
+
--title <text> Chart title
|
|
90
|
+
-w, --width <pixels> Width (default: 500)
|
|
91
|
+
-h, --height <pixels> Height (default: 300)
|
|
92
|
+
-f, --format <format> png, svg, or webp (default: png)
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
floimg chart bar --labels "A,B,C" --values "10,20,30" -o chart.png
|
|
96
|
+
floimg chart pie --labels "Yes,No" --values "70,30" --title "Survey Results"
|
|
97
|
+
floimg chart line --data sales.json -o sales-chart.png
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Resize
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
floimg resize <input> <size> [options]
|
|
104
|
+
|
|
105
|
+
Size formats: WIDTHxHEIGHT (e.g., 800x600) or WIDTH (e.g., 800)
|
|
106
|
+
|
|
107
|
+
Options:
|
|
108
|
+
-o, --out <path> Output file (default: input-resized.ext)
|
|
109
|
+
--fit <mode> cover, contain, fill, inside, outside
|
|
110
|
+
--position <pos> center, top, bottom, left, right, etc.
|
|
111
|
+
--background <color> Background color for contain mode
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
floimg resize photo.jpg 800x600 -o thumbnail.jpg
|
|
115
|
+
floimg resize hero.png 1200 -o hero-resized.png
|
|
116
|
+
floimg resize logo.png 200x200 --fit contain --background "#ffffff"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Convert
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
floimg convert <input> [options]
|
|
123
|
+
|
|
124
|
+
Options:
|
|
125
|
+
-o, --out <path> Output file (format inferred from extension)
|
|
126
|
+
-t, --to <format> Target format: png, jpg, webp, avif, svg
|
|
127
|
+
-q, --quality <number> Quality for lossy formats (1-100)
|
|
128
|
+
|
|
129
|
+
Examples:
|
|
130
|
+
floimg convert photo.png -o photo.webp
|
|
131
|
+
floimg convert image.jpg --to avif -o optimized.avif
|
|
132
|
+
floimg convert screenshot.png -o screenshot.jpg --quality 85
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Performance Tips
|
|
136
|
+
|
|
137
|
+
### First Run
|
|
138
|
+
|
|
139
|
+
The first run with npx will:
|
|
140
|
+
- Download the @teamflojo/floimg package
|
|
141
|
+
- Compile native dependencies (sharp, canvas)
|
|
142
|
+
- This takes ~10-15 seconds
|
|
143
|
+
|
|
144
|
+
### Subsequent Runs
|
|
145
|
+
|
|
146
|
+
After the first run:
|
|
147
|
+
- npx caches the package in `~/.npm/_npx/`
|
|
148
|
+
- Runs take ~2-3 seconds
|
|
149
|
+
- This is normal and matches tools like prettier, eslint
|
|
150
|
+
|
|
151
|
+
### For Frequent Use
|
|
152
|
+
|
|
153
|
+
If you use floimg often, install it globally for faster startup:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npm install -g @teamflojo/floimg
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Then just run `floimg` directly (no npx needed).
|
|
160
|
+
|
|
161
|
+
## Troubleshooting
|
|
162
|
+
|
|
163
|
+
### "Cannot find module" errors
|
|
164
|
+
|
|
165
|
+
This usually means native dependencies failed to compile. Try:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Clear npx cache and retry
|
|
169
|
+
rm -rf ~/.npm/_npx
|
|
170
|
+
npx @teamflojo/floimg doctor
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Plugin not installing
|
|
174
|
+
|
|
175
|
+
If auto-install fails in CI/scripts (non-interactive mode):
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# Pre-install plugins explicitly
|
|
179
|
+
npm install @teamflojo/floimg-qr @teamflojo/floimg-quickchart
|
|
180
|
+
|
|
181
|
+
# Then run commands
|
|
182
|
+
npx @teamflojo/floimg qr "text" --no-auto-install
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Permission errors
|
|
186
|
+
|
|
187
|
+
If you get EACCES errors:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Fix npm permissions
|
|
191
|
+
sudo chown -R $(whoami) ~/.npm
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Next Steps
|
|
195
|
+
|
|
196
|
+
- **[Full CLI Reference](https://floimg.com/docs/cli)** - All commands and options
|
|
197
|
+
- **[Library API](https://floimg.com/docs/api)** - Use floimg in your code
|
|
198
|
+
- **[MCP Integration](https://floimg.com/docs/mcp)** - Use with Claude/AI agents
|
|
199
|
+
- **[Plugin Development](https://floimg.com/docs/plugins)** - Create custom generators
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* Shorthand command for generating charts
|
|
4
|
+
*
|
|
5
|
+
* This command auto-installs @teamflojo/floimg-quickchart if not present.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```bash
|
|
9
|
+
* # Bar chart with inline data
|
|
10
|
+
* floimg chart bar --labels "Q1,Q2,Q3,Q4" --values "10,20,30,40" -o chart.png
|
|
11
|
+
*
|
|
12
|
+
* # Chart from JSON file
|
|
13
|
+
* floimg chart line --data sales.json -o sales-chart.png
|
|
14
|
+
*
|
|
15
|
+
* # Pie chart with title
|
|
16
|
+
* floimg chart pie --labels "A,B,C" --values "30,50,20" --title "Distribution"
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare const chartCommand: Command;
|
|
20
|
+
//# sourceMappingURL=chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/chart.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,SAqHrB,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { readFile, writeFile } from "fs/promises";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import createClient from "../../index.js";
|
|
4
|
+
import { loadConfig } from "../../config/loader.js";
|
|
5
|
+
import { loadPlugin, showNpxTip } from "../utils/plugin-loader.js";
|
|
6
|
+
/**
|
|
7
|
+
* Shorthand command for generating charts
|
|
8
|
+
*
|
|
9
|
+
* This command auto-installs @teamflojo/floimg-quickchart if not present.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```bash
|
|
13
|
+
* # Bar chart with inline data
|
|
14
|
+
* floimg chart bar --labels "Q1,Q2,Q3,Q4" --values "10,20,30,40" -o chart.png
|
|
15
|
+
*
|
|
16
|
+
* # Chart from JSON file
|
|
17
|
+
* floimg chart line --data sales.json -o sales-chart.png
|
|
18
|
+
*
|
|
19
|
+
* # Pie chart with title
|
|
20
|
+
* floimg chart pie --labels "A,B,C" --values "30,50,20" --title "Distribution"
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const chartCommand = new Command("chart")
|
|
24
|
+
.description("Generate a chart (auto-installs @teamflojo/floimg-quickchart if needed)")
|
|
25
|
+
.argument("<type>", "Chart type: bar, line, pie, doughnut, radar, polarArea, scatter")
|
|
26
|
+
.option("-o, --out <path>", "Output file path (default: chart.png)", "chart.png")
|
|
27
|
+
.option("-d, --data <file>", "JSON file with Chart.js data configuration")
|
|
28
|
+
.option("-l, --labels <items>", "Comma-separated labels (e.g., 'Q1,Q2,Q3,Q4')")
|
|
29
|
+
.option("-v, --values <items>", "Comma-separated values (e.g., '10,20,30,40')")
|
|
30
|
+
.option("--title <text>", "Chart title")
|
|
31
|
+
.option("-w, --width <pixels>", "Width in pixels", "500")
|
|
32
|
+
.option("-h, --height <pixels>", "Height in pixels", "300")
|
|
33
|
+
.option("--background <color>", "Background color", "transparent")
|
|
34
|
+
.option("-f, --format <format>", "Output format: png, svg, webp", "png")
|
|
35
|
+
.option("--no-auto-install", "Don't prompt to install missing plugins")
|
|
36
|
+
.option("--config <path>", "Path to config file")
|
|
37
|
+
.action(async (type, options) => {
|
|
38
|
+
try {
|
|
39
|
+
const config = await loadConfig(options.config);
|
|
40
|
+
const client = createClient(config);
|
|
41
|
+
// Load the QuickChart plugin (auto-installs if needed)
|
|
42
|
+
const quickchartPlugin = await loadPlugin("quickchart", options.autoInstall !== false);
|
|
43
|
+
if (!quickchartPlugin) {
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
client.registerGenerator(quickchartPlugin.default());
|
|
47
|
+
// Build chart data
|
|
48
|
+
let chartData;
|
|
49
|
+
if (options.data) {
|
|
50
|
+
// Load from JSON file
|
|
51
|
+
const fileContent = await readFile(options.data, "utf-8");
|
|
52
|
+
chartData = JSON.parse(fileContent);
|
|
53
|
+
}
|
|
54
|
+
else if (options.labels && options.values) {
|
|
55
|
+
// Build from command line options
|
|
56
|
+
const labels = options.labels.split(",").map((s) => s.trim());
|
|
57
|
+
const values = options.values.split(",").map((s) => parseFloat(s.trim()));
|
|
58
|
+
chartData = {
|
|
59
|
+
labels,
|
|
60
|
+
datasets: [
|
|
61
|
+
{
|
|
62
|
+
label: options.title || "Data",
|
|
63
|
+
data: values,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.error("Error: Provide --data <file> or both --labels and --values");
|
|
70
|
+
console.error("");
|
|
71
|
+
console.error("Examples:");
|
|
72
|
+
console.error(' floimg chart bar --labels "A,B,C" --values "10,20,30" -o chart.png');
|
|
73
|
+
console.error(" floimg chart line --data sales.json -o chart.png");
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
// Build chart options
|
|
77
|
+
const chartOptions = {};
|
|
78
|
+
if (options.title) {
|
|
79
|
+
chartOptions.plugins = {
|
|
80
|
+
title: {
|
|
81
|
+
display: true,
|
|
82
|
+
text: options.title,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const blob = await client.generate({
|
|
87
|
+
generator: "quickchart",
|
|
88
|
+
params: {
|
|
89
|
+
type,
|
|
90
|
+
data: chartData,
|
|
91
|
+
options: chartOptions,
|
|
92
|
+
width: parseInt(options.width, 10),
|
|
93
|
+
height: parseInt(options.height, 10),
|
|
94
|
+
backgroundColor: options.background,
|
|
95
|
+
format: options.format,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
// Determine output path with correct extension
|
|
99
|
+
let outPath = options.out;
|
|
100
|
+
const extMap = {
|
|
101
|
+
png: ".png",
|
|
102
|
+
svg: ".svg",
|
|
103
|
+
webp: ".webp",
|
|
104
|
+
};
|
|
105
|
+
if (outPath === "chart.png" && options.format !== "png") {
|
|
106
|
+
outPath = `chart${extMap[options.format] || ".png"}`;
|
|
107
|
+
}
|
|
108
|
+
if (outPath.includes("://")) {
|
|
109
|
+
// Cloud storage
|
|
110
|
+
const result = await client.save(blob, outPath);
|
|
111
|
+
console.log(`ā
Chart saved to: ${result.location}`);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Local file
|
|
115
|
+
await writeFile(outPath, blob.bytes);
|
|
116
|
+
console.log(`ā
Chart saved to: ${outPath}`);
|
|
117
|
+
}
|
|
118
|
+
// Show tip for npx users
|
|
119
|
+
showNpxTip();
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error("Error generating chart:", error instanceof Error ? error.message : error);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=chart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.js","sourceRoot":"","sources":["../../../src/cli/commands/chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,yEAAyE,CAAC;KACtF,QAAQ,CAAC,QAAQ,EAAE,iEAAiE,CAAC;KACrF,MAAM,CAAC,kBAAkB,EAAE,uCAAuC,EAAE,WAAW,CAAC;KAChF,MAAM,CAAC,mBAAmB,EAAE,4CAA4C,CAAC;KACzE,MAAM,CAAC,sBAAsB,EAAE,8CAA8C,CAAC;KAC9E,MAAM,CAAC,sBAAsB,EAAE,8CAA8C,CAAC;KAC9E,MAAM,CAAC,gBAAgB,EAAE,aAAa,CAAC;KACvC,MAAM,CAAC,sBAAsB,EAAE,iBAAiB,EAAE,KAAK,CAAC;KACxD,MAAM,CAAC,uBAAuB,EAAE,kBAAkB,EAAE,KAAK,CAAC;KAC1D,MAAM,CAAC,sBAAsB,EAAE,kBAAkB,EAAE,aAAa,CAAC;KACjE,MAAM,CAAC,uBAAuB,EAAE,+BAA+B,EAAE,KAAK,CAAC;KACvE,MAAM,CAAC,mBAAmB,EAAE,yCAAyC,CAAC;KACtE,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;IAC9B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAEpC,uDAAuD;QACvD,MAAM,gBAAgB,GAAG,MAAM,UAAU,CACvC,YAAY,EACZ,OAAO,CAAC,WAAW,KAAK,KAAK,CAC9B,CAAC;QAEF,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,CAAC,iBAAiB,CACtB,gBAAgB,CAAC,OAAO,EAAoD,CAC7E,CAAC;QAEF,mBAAmB;QACnB,IAAI,SAAkC,CAAC;QAEvC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,sBAAsB;YACtB,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC1D,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAC5C,kCAAkC;YAClC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACtE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAElF,SAAS,GAAG;gBACV,MAAM;gBACN,QAAQ,EAAE;oBACR;wBACE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM;wBAC9B,IAAI,EAAE,MAAM;qBACb;iBACF;aACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;YAC5E,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;YACtF,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,sBAAsB;QACtB,MAAM,YAAY,GAA4B,EAAE,CAAC;QACjD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,YAAY,CAAC,OAAO,GAAG;gBACrB,KAAK,EAAE;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,OAAO,CAAC,KAAK;iBACpB;aACF,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;YACjC,SAAS,EAAE,YAAY;YACvB,MAAM,EAAE;gBACN,IAAI;gBACJ,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,YAAY;gBACrB,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;gBAClC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACpC,eAAe,EAAE,OAAO,CAAC,UAAU;gBACnC,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB;SACF,CAAC,CAAC;QAEH,+CAA+C;QAC/C,IAAI,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;QAC1B,MAAM,MAAM,GAA2B;YACrC,GAAG,EAAE,MAAM;YACX,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,OAAO;SACd,CAAC;QACF,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YACxD,OAAO,GAAG,QAAQ,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvD,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,gBAAgB;YAChB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,aAAa;YACb,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,yBAAyB;QACzB,UAAU,EAAE,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,yBAAyB,EACzB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAC/C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { saveGlobalConfig, loadConfig } from "../../config/loader.js";
|
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { homedir } from "os";
|
|
5
5
|
export const configCommand = new Command("config")
|
|
6
|
-
.description("Manage
|
|
6
|
+
.description("Manage floimg configuration")
|
|
7
7
|
.addCommand(new Command("set")
|
|
8
8
|
.description("Set a configuration value")
|
|
9
9
|
.argument("<key>", "Configuration key (e.g., s3.bucket, s3.region)")
|
|
@@ -54,7 +54,7 @@ export const configCommand = new Command("config")
|
|
|
54
54
|
}
|
|
55
55
|
await saveGlobalConfig(config);
|
|
56
56
|
console.log(`ā Configuration saved: ${key} = ${value.includes('key') || value.includes('secret') ? '***' : value}`);
|
|
57
|
-
console.log(` Location: ${join(homedir(), ".
|
|
57
|
+
console.log(` Location: ${join(homedir(), ".floimg", "config.json")}`);
|
|
58
58
|
}
|
|
59
59
|
catch (error) {
|
|
60
60
|
console.error("Error saving configuration:", error instanceof Error ? error.message : error);
|
|
@@ -96,9 +96,9 @@ export const configCommand = new Command("config")
|
|
|
96
96
|
}
|
|
97
97
|
}))
|
|
98
98
|
.addCommand(new Command("init")
|
|
99
|
-
.description("Initialize
|
|
99
|
+
.description("Initialize floimg configuration interactively")
|
|
100
100
|
.action(async () => {
|
|
101
|
-
console.log("
|
|
101
|
+
console.log("floimg configuration setup");
|
|
102
102
|
console.log("=========================\n");
|
|
103
103
|
const readline = await import('readline');
|
|
104
104
|
const rl = readline.createInterface({
|
|
@@ -140,10 +140,10 @@ export const configCommand = new Command("config")
|
|
|
140
140
|
return;
|
|
141
141
|
}
|
|
142
142
|
await saveGlobalConfig(config);
|
|
143
|
-
console.log("\nā Configuration saved to:", join(homedir(), ".
|
|
144
|
-
console.log("\nYou can now use
|
|
143
|
+
console.log("\nā Configuration saved to:", join(homedir(), ".floimg", "config.json"));
|
|
144
|
+
console.log("\nYou can now use floimg without setting environment variables!");
|
|
145
145
|
console.log("\nTry it:");
|
|
146
|
-
console.log("
|
|
146
|
+
console.log(" floimg generate --provider svg --params '{\"type\":\"gradient\"}' --out test.svg");
|
|
147
147
|
rl.close();
|
|
148
148
|
}
|
|
149
149
|
catch (error) {
|
|
@@ -156,10 +156,10 @@ export const configCommand = new Command("config")
|
|
|
156
156
|
.description("Show configuration file location")
|
|
157
157
|
.action(() => {
|
|
158
158
|
console.log("Configuration file locations (in order of priority):");
|
|
159
|
-
console.log(" 1. ./
|
|
160
|
-
console.log(" 2. ./.
|
|
161
|
-
console.log(" 3. ~/.
|
|
159
|
+
console.log(" 1. ./floimg.config.ts (current directory)");
|
|
160
|
+
console.log(" 2. ./.floimgrc.json (current directory)");
|
|
161
|
+
console.log(" 3. ~/.floimg/config.json (global)");
|
|
162
162
|
console.log(" 4. Environment variables");
|
|
163
|
-
console.log("\nGlobal config location:", join(homedir(), ".
|
|
163
|
+
console.log("\nGlobal config location:", join(homedir(), ".floimg", "config.json"));
|
|
164
164
|
}));
|
|
165
165
|
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* Shorthand command for converting image formats
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```bash
|
|
7
|
+
* # Convert to WebP (format inferred from output extension)
|
|
8
|
+
* floimg convert input.png -o output.webp
|
|
9
|
+
*
|
|
10
|
+
* # Explicit format specification
|
|
11
|
+
* floimg convert input.png --to webp -o output.webp
|
|
12
|
+
*
|
|
13
|
+
* # With quality setting
|
|
14
|
+
* floimg convert input.png -o output.jpg --quality 85
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare const convertCommand: Command;
|
|
18
|
+
//# sourceMappingURL=convert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/convert.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,SA2FvB,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { readFile, writeFile } from "fs/promises";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import createClient from "../../index.js";
|
|
4
|
+
import { loadConfig } from "../../config/loader.js";
|
|
5
|
+
/**
|
|
6
|
+
* Detect MIME type from file extension
|
|
7
|
+
*/
|
|
8
|
+
function detectMime(filepath) {
|
|
9
|
+
const ext = filepath.split(".").pop()?.toLowerCase();
|
|
10
|
+
const mimeMap = {
|
|
11
|
+
png: "image/png",
|
|
12
|
+
jpg: "image/jpeg",
|
|
13
|
+
jpeg: "image/jpeg",
|
|
14
|
+
webp: "image/webp",
|
|
15
|
+
avif: "image/avif",
|
|
16
|
+
svg: "image/svg+xml",
|
|
17
|
+
};
|
|
18
|
+
return mimeMap[ext || ""] || "image/png";
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get format from output path extension
|
|
22
|
+
*/
|
|
23
|
+
function getFormatFromPath(filepath) {
|
|
24
|
+
return detectMime(filepath);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Shorthand command for converting image formats
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```bash
|
|
31
|
+
* # Convert to WebP (format inferred from output extension)
|
|
32
|
+
* floimg convert input.png -o output.webp
|
|
33
|
+
*
|
|
34
|
+
* # Explicit format specification
|
|
35
|
+
* floimg convert input.png --to webp -o output.webp
|
|
36
|
+
*
|
|
37
|
+
* # With quality setting
|
|
38
|
+
* floimg convert input.png -o output.jpg --quality 85
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export const convertCommand = new Command("convert")
|
|
42
|
+
.description("Convert image format (shorthand for transform --op convert)")
|
|
43
|
+
.argument("<input>", "Input image file")
|
|
44
|
+
.option("-o, --out <path>", "Output file path (format inferred from extension)")
|
|
45
|
+
.option("-t, --to <format>", "Target format: png, jpg, jpeg, webp, avif, svg")
|
|
46
|
+
.option("-q, --quality <number>", "Quality for lossy formats (1-100)", "80")
|
|
47
|
+
.option("--config <path>", "Path to config file")
|
|
48
|
+
.action(async (input, options) => {
|
|
49
|
+
try {
|
|
50
|
+
const config = await loadConfig(options.config);
|
|
51
|
+
const client = createClient(config);
|
|
52
|
+
// Read input file
|
|
53
|
+
const inputBytes = await readFile(input);
|
|
54
|
+
const inputMime = detectMime(input);
|
|
55
|
+
const inputBlob = {
|
|
56
|
+
bytes: inputBytes,
|
|
57
|
+
mime: inputMime,
|
|
58
|
+
};
|
|
59
|
+
// Determine target format
|
|
60
|
+
let targetFormat;
|
|
61
|
+
if (options.to) {
|
|
62
|
+
// Explicit format specified
|
|
63
|
+
const formatMap = {
|
|
64
|
+
png: "image/png",
|
|
65
|
+
jpg: "image/jpeg",
|
|
66
|
+
jpeg: "image/jpeg",
|
|
67
|
+
webp: "image/webp",
|
|
68
|
+
avif: "image/avif",
|
|
69
|
+
svg: "image/svg+xml",
|
|
70
|
+
};
|
|
71
|
+
targetFormat = formatMap[options.to.toLowerCase()] || "image/png";
|
|
72
|
+
}
|
|
73
|
+
else if (options.out) {
|
|
74
|
+
// Infer from output extension
|
|
75
|
+
const inferred = getFormatFromPath(options.out);
|
|
76
|
+
if (!inferred) {
|
|
77
|
+
console.error("Error: Could not infer format from output path.");
|
|
78
|
+
console.error("Use --to to specify format explicitly.");
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
targetFormat = inferred;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.error("Error: Must specify --out or --to.");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
const result = await client.transform({
|
|
88
|
+
blob: inputBlob,
|
|
89
|
+
op: "convert",
|
|
90
|
+
to: targetFormat,
|
|
91
|
+
params: {
|
|
92
|
+
quality: parseInt(options.quality, 10),
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
// Determine output path
|
|
96
|
+
const extMap = {
|
|
97
|
+
"image/png": "png",
|
|
98
|
+
"image/jpeg": "jpg",
|
|
99
|
+
"image/webp": "webp",
|
|
100
|
+
"image/avif": "avif",
|
|
101
|
+
"image/svg+xml": "svg",
|
|
102
|
+
};
|
|
103
|
+
const newExt = extMap[targetFormat] || "png";
|
|
104
|
+
const outPath = options.out || input.replace(/\.[^.]+$/, `.${newExt}`);
|
|
105
|
+
if (outPath.includes("://")) {
|
|
106
|
+
// Cloud storage
|
|
107
|
+
const saveResult = await client.save(result, outPath);
|
|
108
|
+
console.log(`Converted image saved to: ${saveResult.location}`);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// Local file
|
|
112
|
+
await writeFile(outPath, result.bytes);
|
|
113
|
+
console.log(`Converted image saved to: ${outPath}`);
|
|
114
|
+
}
|
|
115
|
+
console.log(`Format: ${inputMime} ā ${result.mime}`);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error("Error converting image:", error instanceof Error ? error.message : error);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../../src/cli/commands/convert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD;;GAEG;AACH,SAAS,UAAU,CAAC,QAAgB;IAClC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,CAAC;IACrD,MAAM,OAAO,GAA6B;QACxC,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,YAAY;QACjB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,YAAY;QAClB,GAAG,EAAE,eAAe;KACrB,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,WAAW,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,QAAgB;IACzC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;KACjD,WAAW,CAAC,6DAA6D,CAAC;KAC1E,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;KACvC,MAAM,CAAC,kBAAkB,EAAE,mDAAmD,CAAC;KAC/E,MAAM,CACL,mBAAmB,EACnB,gDAAgD,CACjD;KACA,MAAM,CAAC,wBAAwB,EAAE,mCAAmC,EAAE,IAAI,CAAC;KAC3E,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAEpC,kBAAkB;QAClB,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAEpC,MAAM,SAAS,GAAG;YAChB,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,SAAS;SAChB,CAAC;QAEF,0BAA0B;QAC1B,IAAI,YAAsB,CAAC;QAE3B,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,4BAA4B;YAC5B,MAAM,SAAS,GAA6B;gBAC1C,GAAG,EAAE,WAAW;gBAChB,GAAG,EAAE,YAAY;gBACjB,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,YAAY;gBAClB,GAAG,EAAE,eAAe;aACrB,CAAC;YACF,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,WAAW,CAAC;QACpE,CAAC;aAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YACvB,8BAA8B;YAC9B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACjE,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;gBACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,YAAY,GAAG,QAAQ,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC;YACpC,IAAI,EAAE,SAAS;YACf,EAAE,EAAE,SAAS;YACb,EAAE,EAAE,YAAY;YAChB,MAAM,EAAE;gBACN,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;aACvC;SACF,CAAC,CAAC;QAEH,wBAAwB;QACxB,MAAM,MAAM,GAA2B;YACrC,WAAW,EAAE,KAAK;YAClB,YAAY,EAAE,KAAK;YACnB,YAAY,EAAE,MAAM;YACpB,YAAY,EAAE,MAAM;YACpB,eAAe,EAAE,KAAK;SACvB,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC;QAC7C,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,MAAM,EAAE,CAAC,CAAC;QAEzD,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,gBAAgB;YAChB,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,6BAA6B,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,aAAa;YACb,MAAM,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,WAAW,SAAS,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,yBAAyB,EACzB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAC/C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -20,7 +20,7 @@ export const generateCommand = new Command("generate")
|
|
|
20
20
|
if (options.out) {
|
|
21
21
|
// Check if destination is cloud storage (s3://, r2://, etc.) or local file
|
|
22
22
|
if (options.out.includes('://')) {
|
|
23
|
-
// Use
|
|
23
|
+
// Use floimg's save provider (supports S3, etc.)
|
|
24
24
|
const result = await client.save(blob, options.out);
|
|
25
25
|
console.log(`Generated image saved to cloud storage!`);
|
|
26
26
|
console.log(`Provider: ${result.provider}`);
|
package/dist/cli/commands/mcp.js
CHANGED
|
@@ -9,21 +9,21 @@ mcpCommand
|
|
|
9
9
|
.option("--global", "Install to global Claude Code config")
|
|
10
10
|
.option("--output <path>", "Output path for MCP config snippet")
|
|
11
11
|
.action(async (options) => {
|
|
12
|
-
console.log("
|
|
12
|
+
console.log("floimg MCP Setup");
|
|
13
13
|
console.log("================\n");
|
|
14
14
|
// Get the path to the built MCP server
|
|
15
|
-
// When
|
|
15
|
+
// When floimg is installed globally, use require.resolve to find it
|
|
16
16
|
let serverPath;
|
|
17
17
|
try {
|
|
18
|
-
serverPath = require.resolve("
|
|
18
|
+
serverPath = require.resolve("floimg/dist/mcp/server.js");
|
|
19
19
|
}
|
|
20
20
|
catch {
|
|
21
21
|
// Fallback to local path if not found via require.resolve
|
|
22
|
-
serverPath = resolve(join(process.cwd(), "node_modules/
|
|
22
|
+
serverPath = resolve(join(process.cwd(), "node_modules/floimg/dist/mcp/server.js"));
|
|
23
23
|
}
|
|
24
24
|
const mcpConfig = {
|
|
25
25
|
mcpServers: {
|
|
26
|
-
|
|
26
|
+
floimg: {
|
|
27
27
|
command: "node",
|
|
28
28
|
args: [serverPath],
|
|
29
29
|
env: {
|
|
@@ -58,24 +58,24 @@ mcpCommand
|
|
|
58
58
|
console.log(" 3. Restart Claude Code");
|
|
59
59
|
console.log(" 4. Try: 'Create a QR code for https://example.com'");
|
|
60
60
|
console.log("\nš Documentation:");
|
|
61
|
-
console.log(" https://github.com/bcooke/
|
|
61
|
+
console.log(" https://github.com/bcooke/floimg/blob/main/packages/floimg/docs/guides/MCP_SERVER.md");
|
|
62
62
|
});
|
|
63
63
|
mcpCommand
|
|
64
64
|
.command("test")
|
|
65
65
|
.description("Test MCP server with inspector (opens browser)")
|
|
66
66
|
.action(async () => {
|
|
67
67
|
console.log("Starting MCP Inspector...\n");
|
|
68
|
-
console.log("This will open a web interface to test
|
|
68
|
+
console.log("This will open a web interface to test floimg's MCP tools.");
|
|
69
69
|
console.log("Press Ctrl+C to stop.\n");
|
|
70
70
|
const { spawn } = await import("child_process");
|
|
71
71
|
// Get the path to the built MCP server
|
|
72
72
|
let serverPath;
|
|
73
73
|
try {
|
|
74
|
-
serverPath = require.resolve("
|
|
74
|
+
serverPath = require.resolve("floimg/dist/mcp/server.js");
|
|
75
75
|
}
|
|
76
76
|
catch {
|
|
77
77
|
// Fallback to local path if not found via require.resolve
|
|
78
|
-
serverPath = resolve(join(process.cwd(), "node_modules/
|
|
78
|
+
serverPath = resolve(join(process.cwd(), "node_modules/floimg/dist/mcp/server.js"));
|
|
79
79
|
}
|
|
80
80
|
const inspector = spawn("npx", ["@modelcontextprotocol/inspector", "node", serverPath], {
|
|
81
81
|
stdio: "inherit",
|