@nghiavuive/random-image 1.2.0 → 1.2.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.
- package/dist/cli.js +196 -77
- package/dist/cli.mjs +231 -81
- package/package.json +4 -1
package/dist/cli.js
CHANGED
|
@@ -204,9 +204,9 @@ var RandomImage = class {
|
|
|
204
204
|
});
|
|
205
205
|
const writer = fs.createWriteStream(fullPath);
|
|
206
206
|
response.data.pipe(writer);
|
|
207
|
-
return new Promise((
|
|
207
|
+
return new Promise((resolve3, reject) => {
|
|
208
208
|
writer.on("finish", () => {
|
|
209
|
-
|
|
209
|
+
resolve3(fullPath);
|
|
210
210
|
});
|
|
211
211
|
writer.on("error", (err) => {
|
|
212
212
|
fs.unlink(fullPath, () => {
|
|
@@ -244,101 +244,220 @@ var RandomImage = class {
|
|
|
244
244
|
};
|
|
245
245
|
|
|
246
246
|
// src/cli.ts
|
|
247
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
248
|
+
|
|
249
|
+
// src/cli/env-loader.ts
|
|
247
250
|
var path2 = __toESM(require("path"));
|
|
248
251
|
var dotenv = __toESM(require("dotenv"));
|
|
249
252
|
var fs2 = __toESM(require("fs"));
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
253
|
+
function loadEnvironment() {
|
|
254
|
+
const possibleEnvPaths = [
|
|
255
|
+
path2.resolve(process.cwd(), ".env"),
|
|
256
|
+
// Current working directory
|
|
257
|
+
path2.resolve(__dirname, ".env"),
|
|
258
|
+
// Same directory as the CLI script (dist/)
|
|
259
|
+
path2.resolve(__dirname, "..", ".env")
|
|
260
|
+
// Parent directory (root of project)
|
|
261
|
+
];
|
|
262
|
+
for (const envPath of possibleEnvPaths) {
|
|
263
|
+
if (fs2.existsSync(envPath)) {
|
|
264
|
+
dotenv.config({ path: envPath });
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function getApiKeys() {
|
|
270
|
+
return {
|
|
271
|
+
unsplash: process.env.UNSPLASH_KEY,
|
|
272
|
+
pexels: process.env.PEXELS_KEY,
|
|
273
|
+
pixabay: process.env.PIXABAY_KEY
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// src/cli/display.ts
|
|
278
|
+
var import_chalk = __toESM(require("chalk"));
|
|
279
|
+
var import_boxen = __toESM(require("boxen"));
|
|
280
|
+
function displayError(message) {
|
|
281
|
+
console.error(import_chalk.default.red(`
|
|
282
|
+
\u274C ${message}`));
|
|
283
|
+
}
|
|
284
|
+
function displayInfo(message) {
|
|
285
|
+
console.log(import_chalk.default.blue(`
|
|
286
|
+
\u2139\uFE0F ${message}`));
|
|
287
|
+
}
|
|
288
|
+
function displayImageInfo(image, providerName) {
|
|
289
|
+
const content = [
|
|
290
|
+
`${import_chalk.default.bold("\u{1F3A8} Provider:")} ${import_chalk.default.cyan(providerName)}`,
|
|
291
|
+
`${import_chalk.default.bold("\u{1F4D0} Size:")} ${import_chalk.default.yellow(`${image.width}x${image.height}`)}`,
|
|
292
|
+
`${import_chalk.default.bold("\u{1F464} Author:")} ${import_chalk.default.magenta(image.author)}`,
|
|
293
|
+
image.authorUrl ? `${import_chalk.default.bold("\u{1F517} Author URL:")} ${import_chalk.default.gray(image.authorUrl)}` : "",
|
|
294
|
+
`${import_chalk.default.bold("\u{1F310} Original:")} ${import_chalk.default.gray(image.originalUrl)}`,
|
|
295
|
+
`${import_chalk.default.bold("\u{1F4F7} Image URL:")} ${import_chalk.default.gray(image.url)}`
|
|
296
|
+
].filter(Boolean).join("\n");
|
|
297
|
+
console.log("\n" + (0, import_boxen.default)(content, {
|
|
298
|
+
padding: 1,
|
|
299
|
+
margin: 1,
|
|
300
|
+
borderStyle: "round",
|
|
301
|
+
borderColor: "green",
|
|
302
|
+
title: "\u{1F5BC}\uFE0F Image Details",
|
|
303
|
+
titleAlignment: "center"
|
|
304
|
+
}));
|
|
305
|
+
}
|
|
306
|
+
function displayDownloadSuccess(filePath) {
|
|
307
|
+
const content = `${import_chalk.default.bold("\u{1F4C1} Saved to:")} ${import_chalk.default.cyan(filePath)}`;
|
|
308
|
+
console.log("\n" + (0, import_boxen.default)(content, {
|
|
309
|
+
padding: 1,
|
|
310
|
+
margin: 1,
|
|
311
|
+
borderStyle: "round",
|
|
312
|
+
borderColor: "blue",
|
|
313
|
+
title: "\u{1F4BE} Download Complete",
|
|
314
|
+
titleAlignment: "center"
|
|
315
|
+
}));
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/cli/provider-manager.ts
|
|
319
|
+
function selectRandomProvider(providers) {
|
|
320
|
+
const availableProviders = Object.entries(providers).filter(([_, key]) => key).map(([name]) => name);
|
|
321
|
+
if (availableProviders.length === 0) {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
return availableProviders[Math.floor(Math.random() * availableProviders.length)];
|
|
325
|
+
}
|
|
326
|
+
function createProvider(providerName, apiKey) {
|
|
327
|
+
switch (providerName) {
|
|
328
|
+
case "unsplash":
|
|
329
|
+
return new UnsplashProvider(apiKey);
|
|
330
|
+
case "pexels":
|
|
331
|
+
return new PexelsProvider(apiKey);
|
|
332
|
+
case "pixabay":
|
|
333
|
+
return new PixabayProvider(apiKey);
|
|
334
|
+
default:
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function getProviderInstance(providerName, providers) {
|
|
339
|
+
const name = providerName.toLowerCase();
|
|
340
|
+
const apiKey = providers[name];
|
|
341
|
+
if (!apiKey) {
|
|
342
|
+
displayError(`API key for ${providerName} not found.`);
|
|
343
|
+
console.log(`Please set ${providerName.toUpperCase()}_KEY environment variable.
|
|
344
|
+
`);
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
const provider = createProvider(name, apiKey);
|
|
348
|
+
if (!provider) {
|
|
349
|
+
displayError(`Unknown provider "${providerName}"`);
|
|
350
|
+
console.log("Available providers: unsplash, pexels, pixabay, random\n");
|
|
351
|
+
return null;
|
|
263
352
|
}
|
|
353
|
+
return { provider, name };
|
|
264
354
|
}
|
|
355
|
+
|
|
356
|
+
// src/cli/options-builder.ts
|
|
357
|
+
function buildFetchOptions(options) {
|
|
358
|
+
const fetchOptions = {};
|
|
359
|
+
if (options.query) fetchOptions.query = options.query;
|
|
360
|
+
if (options.width) fetchOptions.width = options.width;
|
|
361
|
+
if (options.height) fetchOptions.height = options.height;
|
|
362
|
+
if (options.quality) fetchOptions.quality = options.quality;
|
|
363
|
+
if (options.orientation) fetchOptions.orientation = options.orientation;
|
|
364
|
+
return fetchOptions;
|
|
365
|
+
}
|
|
366
|
+
function buildDownloadOptions(options) {
|
|
367
|
+
const downloadOptions = {
|
|
368
|
+
overwrite: options.overwrite,
|
|
369
|
+
keepOriginalName: options.keepOriginalName
|
|
370
|
+
};
|
|
371
|
+
if (options.filename) {
|
|
372
|
+
downloadOptions.filename = options.filename;
|
|
373
|
+
}
|
|
374
|
+
return downloadOptions;
|
|
375
|
+
}
|
|
376
|
+
function getDownloadPath(options) {
|
|
377
|
+
return typeof options.download === "string" ? options.download : "./downloads";
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/cli/actions.ts
|
|
381
|
+
var import_ora = __toESM(require("ora"));
|
|
382
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
383
|
+
var path3 = __toESM(require("path"));
|
|
384
|
+
async function fetchImage(fetcher, providerName, fetchOptions) {
|
|
385
|
+
const spinner = (0, import_ora.default)({
|
|
386
|
+
text: import_chalk2.default.cyan("\u{1F50D} Searching for the perfect image..."),
|
|
387
|
+
spinner: "dots"
|
|
388
|
+
}).start();
|
|
389
|
+
try {
|
|
390
|
+
const image = await fetcher.getRandom(fetchOptions);
|
|
391
|
+
spinner.succeed(import_chalk2.default.green("\u2728 Image found!"));
|
|
392
|
+
return image;
|
|
393
|
+
} catch (error) {
|
|
394
|
+
spinner.fail(import_chalk2.default.red("Failed to fetch image"));
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
async function downloadImage(fetcher, image, downloadPath, downloadOptions) {
|
|
399
|
+
const resolvedPath = path3.resolve(downloadPath);
|
|
400
|
+
displayInfo(`Downloading to: ${import_chalk2.default.cyan(resolvedPath)}`);
|
|
401
|
+
const spinner = (0, import_ora.default)({
|
|
402
|
+
text: import_chalk2.default.cyan("\u{1F4BE} Downloading image..."),
|
|
403
|
+
spinner: "dots"
|
|
404
|
+
}).start();
|
|
405
|
+
try {
|
|
406
|
+
const filePath = await fetcher.download(image, downloadPath, downloadOptions);
|
|
407
|
+
spinner.succeed(import_chalk2.default.green("\u{1F4E6} Download complete!"));
|
|
408
|
+
return filePath;
|
|
409
|
+
} catch (error) {
|
|
410
|
+
spinner.fail(import_chalk2.default.red("Download failed"));
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// src/cli.ts
|
|
416
|
+
loadEnvironment();
|
|
265
417
|
var program = new import_commander.Command();
|
|
266
|
-
program.name("random-image").description("CLI tool to fetch random images from various providers").version("1.2.0");
|
|
267
|
-
program.command("fetch").description("Fetch a random image from image providers").option("-q, --query <search>", "Search query for the image").option("-w, --width <number>", "Width of the image", parseInt).option("-h, --height <number>", "Height of the image", parseInt).option("--quality <number>", "Quality of the image (0-100)", parseInt).option("--orientation <type>", "Image orientation (landscape or portrait)").option("-p, --provider <name>", "Provider to use (unsplash, pexels, pixabay, or random)", "random").option("-d, --download [path]", "Download the image to specified directory (default: ./downloads)").option("--filename <name>", "Custom filename for downloaded image").option("--overwrite", "Overwrite existing files", false).option("--no-keep-original-name", "Generate random UUID filename instead of keeping original").action(async (options) => {
|
|
418
|
+
program.name("random-image").description("\u{1F3A8} CLI tool to fetch random images from various providers").version("1.2.0");
|
|
419
|
+
program.command("fetch").description("\u{1F5BC}\uFE0F Fetch a random image from image providers").option("-q, --query <search>", "Search query for the image").option("-w, --width <number>", "Width of the image", parseInt).option("-h, --height <number>", "Height of the image", parseInt).option("--quality <number>", "Quality of the image (0-100)", parseInt).option("--orientation <type>", "Image orientation (landscape or portrait)").option("-p, --provider <name>", "Provider to use (unsplash, pexels, pixabay, or random)", "random").option("-d, --download [path]", "Download the image to specified directory (default: ./downloads)").option("--filename <name>", "Custom filename for downloaded image").option("--overwrite", "Overwrite existing files", false).option("--no-keep-original-name", "Generate random UUID filename instead of keeping original").action(async (options) => {
|
|
268
420
|
try {
|
|
269
|
-
const providers =
|
|
270
|
-
unsplash: process.env.UNSPLASH_KEY,
|
|
271
|
-
pexels: process.env.PEXELS_KEY,
|
|
272
|
-
pixabay: process.env.PIXABAY_KEY
|
|
273
|
-
};
|
|
421
|
+
const providers = getApiKeys();
|
|
274
422
|
let providerName = options.provider.toLowerCase();
|
|
275
423
|
if (providerName === "random") {
|
|
276
|
-
const
|
|
277
|
-
if (
|
|
278
|
-
|
|
279
|
-
console.
|
|
424
|
+
const selectedProvider = selectRandomProvider(providers);
|
|
425
|
+
if (!selectedProvider) {
|
|
426
|
+
displayError("No API keys found in environment variables.");
|
|
427
|
+
console.log(import_chalk3.default.yellow("\n\u{1F4A1} Please set at least one of:"));
|
|
428
|
+
console.log(import_chalk3.default.cyan(" \u2022 UNSPLASH_KEY"));
|
|
429
|
+
console.log(import_chalk3.default.cyan(" \u2022 PEXELS_KEY"));
|
|
430
|
+
console.log(import_chalk3.default.cyan(" \u2022 PIXABAY_KEY\n"));
|
|
280
431
|
process.exit(1);
|
|
281
432
|
}
|
|
282
|
-
providerName =
|
|
283
|
-
|
|
433
|
+
providerName = selectedProvider;
|
|
434
|
+
displayInfo(`Using random provider: ${import_chalk3.default.bold(providerName)}`);
|
|
284
435
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (!apiKey) {
|
|
288
|
-
console.error(`Error: API key for ${providerName} not found.`);
|
|
289
|
-
console.error(`Please set ${providerName.toUpperCase()}_KEY environment variable.`);
|
|
436
|
+
const result = getProviderInstance(providerName, providers);
|
|
437
|
+
if (!result) {
|
|
290
438
|
process.exit(1);
|
|
291
439
|
}
|
|
292
|
-
|
|
293
|
-
case "unsplash":
|
|
294
|
-
provider = new UnsplashProvider(apiKey);
|
|
295
|
-
break;
|
|
296
|
-
case "pexels":
|
|
297
|
-
provider = new PexelsProvider(apiKey);
|
|
298
|
-
break;
|
|
299
|
-
case "pixabay":
|
|
300
|
-
provider = new PixabayProvider(apiKey);
|
|
301
|
-
break;
|
|
302
|
-
default:
|
|
303
|
-
console.error(`Error: Unknown provider "${providerName}"`);
|
|
304
|
-
console.error("Available providers: unsplash, pexels, pixabay, random");
|
|
305
|
-
process.exit(1);
|
|
306
|
-
}
|
|
440
|
+
const { provider, name } = result;
|
|
307
441
|
const fetcher = new RandomImage(provider);
|
|
308
|
-
const fetchOptions =
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (options.height) fetchOptions.height = options.height;
|
|
312
|
-
if (options.quality) fetchOptions.quality = options.quality;
|
|
313
|
-
if (options.orientation) fetchOptions.orientation = options.orientation;
|
|
314
|
-
console.log("Fetching random image...");
|
|
315
|
-
const image = await fetcher.getRandom(fetchOptions);
|
|
316
|
-
console.log("\n\u2713 Image fetched successfully!");
|
|
317
|
-
console.log(` URL: ${image.url}`);
|
|
318
|
-
console.log(` Size: ${image.width}x${image.height}`);
|
|
319
|
-
console.log(` Author: ${image.author}`);
|
|
320
|
-
if (image.authorUrl) console.log(` Author URL: ${image.authorUrl}`);
|
|
321
|
-
console.log(` Original: ${image.originalUrl}`);
|
|
442
|
+
const fetchOptions = buildFetchOptions(options);
|
|
443
|
+
const image = await fetchImage(fetcher, name, fetchOptions);
|
|
444
|
+
displayImageInfo(image, name);
|
|
322
445
|
if (options.download !== void 0) {
|
|
323
|
-
const downloadPath =
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}
|
|
333
|
-
const filePath = await fetcher.download(image, downloadPath, downloadOptions);
|
|
334
|
-
console.log(`\u2713 Downloaded: ${filePath}`);
|
|
446
|
+
const downloadPath = getDownloadPath(options);
|
|
447
|
+
const downloadOptions = buildDownloadOptions(options);
|
|
448
|
+
const filePath = await downloadImage(
|
|
449
|
+
fetcher,
|
|
450
|
+
image,
|
|
451
|
+
downloadPath,
|
|
452
|
+
downloadOptions
|
|
453
|
+
);
|
|
454
|
+
displayDownloadSuccess(filePath);
|
|
335
455
|
}
|
|
336
456
|
} catch (error) {
|
|
337
457
|
if (error instanceof Error) {
|
|
338
|
-
|
|
339
|
-
Error: ${error.message}`);
|
|
458
|
+
displayError(error.message);
|
|
340
459
|
} else {
|
|
341
|
-
|
|
460
|
+
displayError("An unexpected error occurred");
|
|
342
461
|
}
|
|
343
462
|
process.exit(1);
|
|
344
463
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -214,9 +214,9 @@ var init_image_fetcher = __esm({
|
|
|
214
214
|
});
|
|
215
215
|
const writer = fs.createWriteStream(fullPath);
|
|
216
216
|
response.data.pipe(writer);
|
|
217
|
-
return new Promise((
|
|
217
|
+
return new Promise((resolve3, reject) => {
|
|
218
218
|
writer.on("finish", () => {
|
|
219
|
-
|
|
219
|
+
resolve3(fullPath);
|
|
220
220
|
});
|
|
221
221
|
writer.on("error", (err) => {
|
|
222
222
|
fs.unlink(fullPath, () => {
|
|
@@ -267,106 +267,256 @@ var init_index = __esm({
|
|
|
267
267
|
}
|
|
268
268
|
});
|
|
269
269
|
|
|
270
|
-
// src/cli.ts
|
|
271
|
-
import { Command } from "commander";
|
|
270
|
+
// src/cli/env-loader.ts
|
|
272
271
|
import * as path2 from "path";
|
|
273
272
|
import * as dotenv from "dotenv";
|
|
274
273
|
import * as fs2 from "fs";
|
|
274
|
+
function loadEnvironment() {
|
|
275
|
+
const possibleEnvPaths = [
|
|
276
|
+
path2.resolve(process.cwd(), ".env"),
|
|
277
|
+
// Current working directory
|
|
278
|
+
path2.resolve(__dirname, ".env"),
|
|
279
|
+
// Same directory as the CLI script (dist/)
|
|
280
|
+
path2.resolve(__dirname, "..", ".env")
|
|
281
|
+
// Parent directory (root of project)
|
|
282
|
+
];
|
|
283
|
+
for (const envPath of possibleEnvPaths) {
|
|
284
|
+
if (fs2.existsSync(envPath)) {
|
|
285
|
+
dotenv.config({ path: envPath });
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function getApiKeys() {
|
|
291
|
+
return {
|
|
292
|
+
unsplash: process.env.UNSPLASH_KEY,
|
|
293
|
+
pexels: process.env.PEXELS_KEY,
|
|
294
|
+
pixabay: process.env.PIXABAY_KEY
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
var init_env_loader = __esm({
|
|
298
|
+
"src/cli/env-loader.ts"() {
|
|
299
|
+
"use strict";
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// src/cli/display.ts
|
|
304
|
+
import chalk from "chalk";
|
|
305
|
+
import boxen from "boxen";
|
|
306
|
+
function displayError(message) {
|
|
307
|
+
console.error(chalk.red(`
|
|
308
|
+
\u274C ${message}`));
|
|
309
|
+
}
|
|
310
|
+
function displayInfo(message) {
|
|
311
|
+
console.log(chalk.blue(`
|
|
312
|
+
\u2139\uFE0F ${message}`));
|
|
313
|
+
}
|
|
314
|
+
function displayImageInfo(image, providerName) {
|
|
315
|
+
const content = [
|
|
316
|
+
`${chalk.bold("\u{1F3A8} Provider:")} ${chalk.cyan(providerName)}`,
|
|
317
|
+
`${chalk.bold("\u{1F4D0} Size:")} ${chalk.yellow(`${image.width}x${image.height}`)}`,
|
|
318
|
+
`${chalk.bold("\u{1F464} Author:")} ${chalk.magenta(image.author)}`,
|
|
319
|
+
image.authorUrl ? `${chalk.bold("\u{1F517} Author URL:")} ${chalk.gray(image.authorUrl)}` : "",
|
|
320
|
+
`${chalk.bold("\u{1F310} Original:")} ${chalk.gray(image.originalUrl)}`,
|
|
321
|
+
`${chalk.bold("\u{1F4F7} Image URL:")} ${chalk.gray(image.url)}`
|
|
322
|
+
].filter(Boolean).join("\n");
|
|
323
|
+
console.log("\n" + boxen(content, {
|
|
324
|
+
padding: 1,
|
|
325
|
+
margin: 1,
|
|
326
|
+
borderStyle: "round",
|
|
327
|
+
borderColor: "green",
|
|
328
|
+
title: "\u{1F5BC}\uFE0F Image Details",
|
|
329
|
+
titleAlignment: "center"
|
|
330
|
+
}));
|
|
331
|
+
}
|
|
332
|
+
function displayDownloadSuccess(filePath) {
|
|
333
|
+
const content = `${chalk.bold("\u{1F4C1} Saved to:")} ${chalk.cyan(filePath)}`;
|
|
334
|
+
console.log("\n" + boxen(content, {
|
|
335
|
+
padding: 1,
|
|
336
|
+
margin: 1,
|
|
337
|
+
borderStyle: "round",
|
|
338
|
+
borderColor: "blue",
|
|
339
|
+
title: "\u{1F4BE} Download Complete",
|
|
340
|
+
titleAlignment: "center"
|
|
341
|
+
}));
|
|
342
|
+
}
|
|
343
|
+
var init_display = __esm({
|
|
344
|
+
"src/cli/display.ts"() {
|
|
345
|
+
"use strict";
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// src/cli/provider-manager.ts
|
|
350
|
+
function selectRandomProvider(providers) {
|
|
351
|
+
const availableProviders = Object.entries(providers).filter(([_, key]) => key).map(([name]) => name);
|
|
352
|
+
if (availableProviders.length === 0) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
return availableProviders[Math.floor(Math.random() * availableProviders.length)];
|
|
356
|
+
}
|
|
357
|
+
function createProvider(providerName, apiKey) {
|
|
358
|
+
switch (providerName) {
|
|
359
|
+
case "unsplash":
|
|
360
|
+
return new UnsplashProvider(apiKey);
|
|
361
|
+
case "pexels":
|
|
362
|
+
return new PexelsProvider(apiKey);
|
|
363
|
+
case "pixabay":
|
|
364
|
+
return new PixabayProvider(apiKey);
|
|
365
|
+
default:
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function getProviderInstance(providerName, providers) {
|
|
370
|
+
const name = providerName.toLowerCase();
|
|
371
|
+
const apiKey = providers[name];
|
|
372
|
+
if (!apiKey) {
|
|
373
|
+
displayError(`API key for ${providerName} not found.`);
|
|
374
|
+
console.log(`Please set ${providerName.toUpperCase()}_KEY environment variable.
|
|
375
|
+
`);
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
const provider = createProvider(name, apiKey);
|
|
379
|
+
if (!provider) {
|
|
380
|
+
displayError(`Unknown provider "${providerName}"`);
|
|
381
|
+
console.log("Available providers: unsplash, pexels, pixabay, random\n");
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
return { provider, name };
|
|
385
|
+
}
|
|
386
|
+
var init_provider_manager = __esm({
|
|
387
|
+
"src/cli/provider-manager.ts"() {
|
|
388
|
+
"use strict";
|
|
389
|
+
init_index();
|
|
390
|
+
init_display();
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// src/cli/options-builder.ts
|
|
395
|
+
function buildFetchOptions(options) {
|
|
396
|
+
const fetchOptions = {};
|
|
397
|
+
if (options.query) fetchOptions.query = options.query;
|
|
398
|
+
if (options.width) fetchOptions.width = options.width;
|
|
399
|
+
if (options.height) fetchOptions.height = options.height;
|
|
400
|
+
if (options.quality) fetchOptions.quality = options.quality;
|
|
401
|
+
if (options.orientation) fetchOptions.orientation = options.orientation;
|
|
402
|
+
return fetchOptions;
|
|
403
|
+
}
|
|
404
|
+
function buildDownloadOptions(options) {
|
|
405
|
+
const downloadOptions = {
|
|
406
|
+
overwrite: options.overwrite,
|
|
407
|
+
keepOriginalName: options.keepOriginalName
|
|
408
|
+
};
|
|
409
|
+
if (options.filename) {
|
|
410
|
+
downloadOptions.filename = options.filename;
|
|
411
|
+
}
|
|
412
|
+
return downloadOptions;
|
|
413
|
+
}
|
|
414
|
+
function getDownloadPath(options) {
|
|
415
|
+
return typeof options.download === "string" ? options.download : "./downloads";
|
|
416
|
+
}
|
|
417
|
+
var init_options_builder = __esm({
|
|
418
|
+
"src/cli/options-builder.ts"() {
|
|
419
|
+
"use strict";
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
// src/cli/actions.ts
|
|
424
|
+
import ora from "ora";
|
|
425
|
+
import chalk2 from "chalk";
|
|
426
|
+
import * as path3 from "path";
|
|
427
|
+
async function fetchImage(fetcher, providerName, fetchOptions) {
|
|
428
|
+
const spinner = ora({
|
|
429
|
+
text: chalk2.cyan("\u{1F50D} Searching for the perfect image..."),
|
|
430
|
+
spinner: "dots"
|
|
431
|
+
}).start();
|
|
432
|
+
try {
|
|
433
|
+
const image = await fetcher.getRandom(fetchOptions);
|
|
434
|
+
spinner.succeed(chalk2.green("\u2728 Image found!"));
|
|
435
|
+
return image;
|
|
436
|
+
} catch (error) {
|
|
437
|
+
spinner.fail(chalk2.red("Failed to fetch image"));
|
|
438
|
+
throw error;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async function downloadImage(fetcher, image, downloadPath, downloadOptions) {
|
|
442
|
+
const resolvedPath = path3.resolve(downloadPath);
|
|
443
|
+
displayInfo(`Downloading to: ${chalk2.cyan(resolvedPath)}`);
|
|
444
|
+
const spinner = ora({
|
|
445
|
+
text: chalk2.cyan("\u{1F4BE} Downloading image..."),
|
|
446
|
+
spinner: "dots"
|
|
447
|
+
}).start();
|
|
448
|
+
try {
|
|
449
|
+
const filePath = await fetcher.download(image, downloadPath, downloadOptions);
|
|
450
|
+
spinner.succeed(chalk2.green("\u{1F4E6} Download complete!"));
|
|
451
|
+
return filePath;
|
|
452
|
+
} catch (error) {
|
|
453
|
+
spinner.fail(chalk2.red("Download failed"));
|
|
454
|
+
throw error;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
var init_actions = __esm({
|
|
458
|
+
"src/cli/actions.ts"() {
|
|
459
|
+
"use strict";
|
|
460
|
+
init_display();
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// src/cli.ts
|
|
465
|
+
import { Command } from "commander";
|
|
466
|
+
import chalk3 from "chalk";
|
|
275
467
|
var require_cli = __commonJS({
|
|
276
468
|
"src/cli.ts"() {
|
|
277
469
|
init_index();
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
// Parent directory (root of project)
|
|
285
|
-
];
|
|
286
|
-
for (const envPath of possibleEnvPaths) {
|
|
287
|
-
if (fs2.existsSync(envPath)) {
|
|
288
|
-
dotenv.config({ path: envPath });
|
|
289
|
-
console.log(`Loaded environment from: ${envPath}`);
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
470
|
+
init_env_loader();
|
|
471
|
+
init_display();
|
|
472
|
+
init_provider_manager();
|
|
473
|
+
init_options_builder();
|
|
474
|
+
init_actions();
|
|
475
|
+
loadEnvironment();
|
|
293
476
|
var program = new Command();
|
|
294
|
-
program.name("random-image").description("CLI tool to fetch random images from various providers").version("1.2.0");
|
|
295
|
-
program.command("fetch").description("Fetch a random image from image providers").option("-q, --query <search>", "Search query for the image").option("-w, --width <number>", "Width of the image", parseInt).option("-h, --height <number>", "Height of the image", parseInt).option("--quality <number>", "Quality of the image (0-100)", parseInt).option("--orientation <type>", "Image orientation (landscape or portrait)").option("-p, --provider <name>", "Provider to use (unsplash, pexels, pixabay, or random)", "random").option("-d, --download [path]", "Download the image to specified directory (default: ./downloads)").option("--filename <name>", "Custom filename for downloaded image").option("--overwrite", "Overwrite existing files", false).option("--no-keep-original-name", "Generate random UUID filename instead of keeping original").action(async (options) => {
|
|
477
|
+
program.name("random-image").description("\u{1F3A8} CLI tool to fetch random images from various providers").version("1.2.0");
|
|
478
|
+
program.command("fetch").description("\u{1F5BC}\uFE0F Fetch a random image from image providers").option("-q, --query <search>", "Search query for the image").option("-w, --width <number>", "Width of the image", parseInt).option("-h, --height <number>", "Height of the image", parseInt).option("--quality <number>", "Quality of the image (0-100)", parseInt).option("--orientation <type>", "Image orientation (landscape or portrait)").option("-p, --provider <name>", "Provider to use (unsplash, pexels, pixabay, or random)", "random").option("-d, --download [path]", "Download the image to specified directory (default: ./downloads)").option("--filename <name>", "Custom filename for downloaded image").option("--overwrite", "Overwrite existing files", false).option("--no-keep-original-name", "Generate random UUID filename instead of keeping original").action(async (options) => {
|
|
296
479
|
try {
|
|
297
|
-
const providers =
|
|
298
|
-
unsplash: process.env.UNSPLASH_KEY,
|
|
299
|
-
pexels: process.env.PEXELS_KEY,
|
|
300
|
-
pixabay: process.env.PIXABAY_KEY
|
|
301
|
-
};
|
|
480
|
+
const providers = getApiKeys();
|
|
302
481
|
let providerName = options.provider.toLowerCase();
|
|
303
482
|
if (providerName === "random") {
|
|
304
|
-
const
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
-
console.
|
|
483
|
+
const selectedProvider = selectRandomProvider(providers);
|
|
484
|
+
if (!selectedProvider) {
|
|
485
|
+
displayError("No API keys found in environment variables.");
|
|
486
|
+
console.log(chalk3.yellow("\n\u{1F4A1} Please set at least one of:"));
|
|
487
|
+
console.log(chalk3.cyan(" \u2022 UNSPLASH_KEY"));
|
|
488
|
+
console.log(chalk3.cyan(" \u2022 PEXELS_KEY"));
|
|
489
|
+
console.log(chalk3.cyan(" \u2022 PIXABAY_KEY\n"));
|
|
308
490
|
process.exit(1);
|
|
309
491
|
}
|
|
310
|
-
providerName =
|
|
311
|
-
|
|
492
|
+
providerName = selectedProvider;
|
|
493
|
+
displayInfo(`Using random provider: ${chalk3.bold(providerName)}`);
|
|
312
494
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (!apiKey) {
|
|
316
|
-
console.error(`Error: API key for ${providerName} not found.`);
|
|
317
|
-
console.error(`Please set ${providerName.toUpperCase()}_KEY environment variable.`);
|
|
495
|
+
const result = getProviderInstance(providerName, providers);
|
|
496
|
+
if (!result) {
|
|
318
497
|
process.exit(1);
|
|
319
498
|
}
|
|
320
|
-
|
|
321
|
-
case "unsplash":
|
|
322
|
-
provider = new UnsplashProvider(apiKey);
|
|
323
|
-
break;
|
|
324
|
-
case "pexels":
|
|
325
|
-
provider = new PexelsProvider(apiKey);
|
|
326
|
-
break;
|
|
327
|
-
case "pixabay":
|
|
328
|
-
provider = new PixabayProvider(apiKey);
|
|
329
|
-
break;
|
|
330
|
-
default:
|
|
331
|
-
console.error(`Error: Unknown provider "${providerName}"`);
|
|
332
|
-
console.error("Available providers: unsplash, pexels, pixabay, random");
|
|
333
|
-
process.exit(1);
|
|
334
|
-
}
|
|
499
|
+
const { provider, name } = result;
|
|
335
500
|
const fetcher = new RandomImage(provider);
|
|
336
|
-
const fetchOptions =
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (options.height) fetchOptions.height = options.height;
|
|
340
|
-
if (options.quality) fetchOptions.quality = options.quality;
|
|
341
|
-
if (options.orientation) fetchOptions.orientation = options.orientation;
|
|
342
|
-
console.log("Fetching random image...");
|
|
343
|
-
const image = await fetcher.getRandom(fetchOptions);
|
|
344
|
-
console.log("\n\u2713 Image fetched successfully!");
|
|
345
|
-
console.log(` URL: ${image.url}`);
|
|
346
|
-
console.log(` Size: ${image.width}x${image.height}`);
|
|
347
|
-
console.log(` Author: ${image.author}`);
|
|
348
|
-
if (image.authorUrl) console.log(` Author URL: ${image.authorUrl}`);
|
|
349
|
-
console.log(` Original: ${image.originalUrl}`);
|
|
501
|
+
const fetchOptions = buildFetchOptions(options);
|
|
502
|
+
const image = await fetchImage(fetcher, name, fetchOptions);
|
|
503
|
+
displayImageInfo(image, name);
|
|
350
504
|
if (options.download !== void 0) {
|
|
351
|
-
const downloadPath =
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
const filePath = await fetcher.download(image, downloadPath, downloadOptions);
|
|
362
|
-
console.log(`\u2713 Downloaded: ${filePath}`);
|
|
505
|
+
const downloadPath = getDownloadPath(options);
|
|
506
|
+
const downloadOptions = buildDownloadOptions(options);
|
|
507
|
+
const filePath = await downloadImage(
|
|
508
|
+
fetcher,
|
|
509
|
+
image,
|
|
510
|
+
downloadPath,
|
|
511
|
+
downloadOptions
|
|
512
|
+
);
|
|
513
|
+
displayDownloadSuccess(filePath);
|
|
363
514
|
}
|
|
364
515
|
} catch (error) {
|
|
365
516
|
if (error instanceof Error) {
|
|
366
|
-
|
|
367
|
-
Error: ${error.message}`);
|
|
517
|
+
displayError(error.message);
|
|
368
518
|
} else {
|
|
369
|
-
|
|
519
|
+
displayError("An unexpected error occurred");
|
|
370
520
|
}
|
|
371
521
|
process.exit(1);
|
|
372
522
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nghiavuive/random-image",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Fetch random images from Unsplash, Pexels, and Pixabay with CLI support",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -38,8 +38,11 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"axios": "^1.13.4",
|
|
41
|
+
"boxen": "^8.0.1",
|
|
42
|
+
"chalk": "^5.6.2",
|
|
41
43
|
"commander": "^12.1.0",
|
|
42
44
|
"dotenv": "^17.2.3",
|
|
45
|
+
"ora": "^9.1.0",
|
|
43
46
|
"uuid": "^13.0.0"
|
|
44
47
|
},
|
|
45
48
|
"bin": {
|