@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.
Files changed (3) hide show
  1. package/dist/cli.js +196 -77
  2. package/dist/cli.mjs +231 -81
  3. 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((resolve2, reject) => {
207
+ return new Promise((resolve3, reject) => {
208
208
  writer.on("finish", () => {
209
- resolve2(fullPath);
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
- var possibleEnvPaths = [
251
- path2.resolve(process.cwd(), ".env"),
252
- // Current working directory
253
- path2.resolve(__dirname, ".env"),
254
- // Same directory as the CLI script (dist/)
255
- path2.resolve(__dirname, "..", ".env")
256
- // Parent directory (root of project)
257
- ];
258
- for (const envPath of possibleEnvPaths) {
259
- if (fs2.existsSync(envPath)) {
260
- dotenv.config({ path: envPath });
261
- console.log(`Loaded environment from: ${envPath}`);
262
- break;
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 availableProviders = Object.entries(providers).filter(([_, key]) => key).map(([name]) => name);
277
- if (availableProviders.length === 0) {
278
- console.error("Error: No API keys found in environment variables.");
279
- console.error("Please set at least one of: UNSPLASH_KEY, PEXELS_KEY, PIXABAY_KEY");
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 = availableProviders[Math.floor(Math.random() * availableProviders.length)];
283
- console.log(`Using random provider: ${providerName}`);
433
+ providerName = selectedProvider;
434
+ displayInfo(`Using random provider: ${import_chalk3.default.bold(providerName)}`);
284
435
  }
285
- let provider;
286
- const apiKey = providers[providerName];
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
- switch (providerName) {
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
- if (options.query) fetchOptions.query = options.query;
310
- if (options.width) fetchOptions.width = options.width;
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 = typeof options.download === "string" ? options.download : "./downloads";
324
- console.log(`
325
- Downloading to ${path2.resolve(downloadPath)}...`);
326
- const downloadOptions = {
327
- overwrite: options.overwrite,
328
- keepOriginalName: options.keepOriginalName
329
- };
330
- if (options.filename) {
331
- downloadOptions.filename = options.filename;
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
- console.error(`
339
- Error: ${error.message}`);
458
+ displayError(error.message);
340
459
  } else {
341
- console.error("\nAn unexpected error occurred");
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((resolve, reject) => {
217
+ return new Promise((resolve3, reject) => {
218
218
  writer.on("finish", () => {
219
- resolve(fullPath);
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
- var possibleEnvPaths = [
279
- path2.resolve(process.cwd(), ".env"),
280
- // Current working directory
281
- path2.resolve(__dirname, ".env"),
282
- // Same directory as the CLI script (dist/)
283
- path2.resolve(__dirname, "..", ".env")
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 availableProviders = Object.entries(providers).filter(([_, key]) => key).map(([name]) => name);
305
- if (availableProviders.length === 0) {
306
- console.error("Error: No API keys found in environment variables.");
307
- console.error("Please set at least one of: UNSPLASH_KEY, PEXELS_KEY, PIXABAY_KEY");
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 = availableProviders[Math.floor(Math.random() * availableProviders.length)];
311
- console.log(`Using random provider: ${providerName}`);
492
+ providerName = selectedProvider;
493
+ displayInfo(`Using random provider: ${chalk3.bold(providerName)}`);
312
494
  }
313
- let provider;
314
- const apiKey = providers[providerName];
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
- switch (providerName) {
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
- if (options.query) fetchOptions.query = options.query;
338
- if (options.width) fetchOptions.width = options.width;
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 = typeof options.download === "string" ? options.download : "./downloads";
352
- console.log(`
353
- Downloading to ${path2.resolve(downloadPath)}...`);
354
- const downloadOptions = {
355
- overwrite: options.overwrite,
356
- keepOriginalName: options.keepOriginalName
357
- };
358
- if (options.filename) {
359
- downloadOptions.filename = options.filename;
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
- console.error(`
367
- Error: ${error.message}`);
517
+ displayError(error.message);
368
518
  } else {
369
- console.error("\nAn unexpected error occurred");
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.0",
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": {