algolia-codegen 0.1.2 → 0.1.4

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.cjs CHANGED
@@ -42,7 +42,7 @@ async function loadTypeScriptConfig(resolvedPath) {
42
42
  const result = esbuild.transformSync(source, {
43
43
  loader: "ts",
44
44
  format: "esm",
45
- target: "node18",
45
+ target: "node20",
46
46
  sourcefile: resolvedPath
47
47
  });
48
48
  if (!result.code) {
@@ -56,10 +56,8 @@ async function loadTypeScriptConfig(resolvedPath) {
56
56
  // src/utils/validations/generator-config.ts
57
57
  function validateGeneratorConfig(config, path) {
58
58
  if (typeof config !== "object" || config === null || Array.isArray(config)) {
59
- throw new Error(
60
- `Invalid generator config: must be an object
61
- Path: ${path}`
62
- );
59
+ throw new Error(`Invalid generator config: must be an object
60
+ Path: ${path}`);
63
61
  }
64
62
  const cfg = config;
65
63
  const requiredFields = [
@@ -101,10 +99,8 @@ Received: ${typeof cfg.postfix}`
101
99
  // src/utils/validations/url-schema.ts
102
100
  function validateUrlSchema(urlSchema, path) {
103
101
  if (typeof urlSchema !== "object" || urlSchema === null || Array.isArray(urlSchema)) {
104
- throw new Error(
105
- `Invalid generates entry: must be an object
106
- Path: ${path}`
107
- );
102
+ throw new Error(`Invalid generates entry: must be an object
103
+ Path: ${path}`);
108
104
  }
109
105
  const schema = urlSchema;
110
106
  for (const [filePath, generatorConfig] of Object.entries(schema)) {
@@ -121,10 +117,8 @@ Path: ${path}[${filePath}]`
121
117
  // src/utils/validations/config.ts
122
118
  function validateConfig(config, configPath) {
123
119
  if (typeof config !== "object" || config === null || Array.isArray(config)) {
124
- throw new Error(
125
- `Invalid config: must be an object
126
- Config file: ${configPath}`
127
- );
120
+ throw new Error(`Invalid config: must be an object
121
+ Config file: ${configPath}`);
128
122
  }
129
123
  const cfg = config;
130
124
  if (!("overwrite" in cfg)) {
@@ -205,10 +199,8 @@ Make sure esbuild is installed as a dependency.`
205
199
  configModule = await import(configUrl);
206
200
  } catch (importError) {
207
201
  const errorMessage = importError instanceof Error ? importError.message : String(importError);
208
- throw new Error(
209
- `Failed to import config file: ${resolvedPath}
210
- Error: ${errorMessage}`
211
- );
202
+ throw new Error(`Failed to import config file: ${resolvedPath}
203
+ Error: ${errorMessage}`);
212
204
  }
213
205
  }
214
206
  if (!configModule.default) {
@@ -337,7 +329,7 @@ var TypeGenerator = class {
337
329
  return `${this.prefix}Hit${this.postfix}`;
338
330
  }
339
331
  const lastPart = path[path.length - 1];
340
- const parts = lastPart.replace(/[\[\]]/g, "").split(/[-_\s]+/).filter(Boolean);
332
+ const parts = lastPart.replace(/[[\]]/g, "").split(/[-_\s]+/).filter(Boolean);
341
333
  const pascalCase = parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
342
334
  if (path.length > 1) {
343
335
  const parent = path[path.length - 2];
@@ -489,30 +481,34 @@ function generateTypeScriptTypes(sampleHit, config) {
489
481
  }
490
482
 
491
483
  // src/utils/fetch-algolia-data.ts
492
- async function fetchAlgoliaData(filePath, generatorConfig, overwrite) {
493
- console.log(`
494
- Processing file: ${filePath}`);
484
+ async function fetchAlgoliaData(filePath, generatorConfig, overwrite, logger) {
485
+ logger.info(`Processing file: ${filePath}`);
495
486
  const resolvedPath = (0, import_path2.resolve)(process.cwd(), filePath);
487
+ logger.verbose(`Resolved path: ${resolvedPath}`);
496
488
  if ((0, import_fs3.existsSync)(resolvedPath) && !overwrite) {
497
489
  throw new Error(
498
490
  `File already exists: ${resolvedPath}
499
491
  Set overwrite: true in config to allow overwriting existing files.`
500
492
  );
501
493
  }
502
- console.log(`Connecting to Algolia...`);
503
- console.log(`App ID: ${generatorConfig.appId}`);
494
+ const connectSpinner = logger.spinner("Connecting to Algolia...");
495
+ connectSpinner.start();
504
496
  let client;
505
497
  try {
506
- client = (0, import_algoliasearch.algoliasearch)(
507
- generatorConfig.appId,
508
- generatorConfig.searchKey
509
- );
498
+ logger.verbose(`App ID: ${generatorConfig.appId}`);
499
+ logger.verbose(`Index: ${generatorConfig.indexName}`);
500
+ client = (0, import_algoliasearch.algoliasearch)(generatorConfig.appId, generatorConfig.searchKey);
501
+ connectSpinner.succeed("Connected to Algolia");
510
502
  } catch (error) {
503
+ connectSpinner.fail("Failed to connect to Algolia");
511
504
  throw new Error(
512
505
  `Failed to initialize Algolia client: ${error instanceof Error ? error.message : String(error)}`
513
506
  );
514
507
  }
515
- console.log(`Fetching sample record from index: ${generatorConfig.indexName}`);
508
+ const fetchSpinner = logger.spinner(
509
+ `Fetching sample record from index: ${generatorConfig.indexName}`
510
+ );
511
+ fetchSpinner.start();
516
512
  let results;
517
513
  try {
518
514
  results = await client.search([
@@ -524,7 +520,9 @@ Set overwrite: true in config to allow overwriting existing files.`
524
520
  }
525
521
  }
526
522
  ]);
523
+ fetchSpinner.succeed("Sample record fetched successfully");
527
524
  } catch (error) {
525
+ fetchSpinner.fail("Failed to fetch data from Algolia");
528
526
  let errorMessage;
529
527
  if (error instanceof Error) {
530
528
  errorMessage = error.message;
@@ -556,52 +554,183 @@ Set overwrite: true in config to allow overwriting existing files.`
556
554
  throw new Error(`No hits found in Algolia index: ${generatorConfig.indexName}`);
557
555
  }
558
556
  const sampleHit = result.hits[0];
559
- console.log("Sample record fetched successfully");
560
- console.log(`ObjectID: ${sampleHit.objectID || "N/A"}`);
557
+ logger.verbose(`ObjectID: ${sampleHit.objectID || "N/A"}`);
558
+ const generateSpinner = logger.spinner("Generating TypeScript types...");
559
+ generateSpinner.start();
561
560
  const fileContent = generateTypeScriptTypes(sampleHit, generatorConfig);
561
+ generateSpinner.succeed("TypeScript types generated");
562
562
  const dir = (0, import_path2.dirname)(resolvedPath);
563
563
  if (!(0, import_fs3.existsSync)(dir)) {
564
- (0, import_fs3.mkdirSync)(dir, { recursive: true });
564
+ if (!logger.isDryRun) {
565
+ (0, import_fs3.mkdirSync)(dir, { recursive: true });
566
+ logger.verbose(`Created directory: ${dir}`);
567
+ } else {
568
+ logger.dryRun(`Would create directory: ${dir}`);
569
+ }
570
+ }
571
+ if (logger.isDryRun) {
572
+ logger.dryRun(`Would write file: ${filePath}`);
573
+ logger.verbose(`File content length: ${fileContent.length} characters`);
574
+ } else {
575
+ (0, import_fs3.writeFileSync)(resolvedPath, fileContent, "utf-8");
576
+ logger.success(`Generated file: ${filePath}`);
565
577
  }
566
- (0, import_fs3.writeFileSync)(resolvedPath, fileContent, "utf-8");
567
- console.log(`Generated file: ${filePath}`);
568
578
  }
569
579
 
580
+ // src/utils/logger.ts
581
+ var import_chalk = __toESM(require("chalk"), 1);
582
+ var import_ora = __toESM(require("ora"), 1);
583
+ var Logger = class {
584
+ _verbose;
585
+ _dryRun;
586
+ constructor(options = {}) {
587
+ this._verbose = options.verbose ?? false;
588
+ this._dryRun = options.dryRun ?? false;
589
+ }
590
+ /**
591
+ * Check if verbose mode is enabled
592
+ */
593
+ get isVerbose() {
594
+ return this._verbose;
595
+ }
596
+ /**
597
+ * Check if dry-run mode is enabled
598
+ */
599
+ get isDryRun() {
600
+ return this._dryRun;
601
+ }
602
+ /**
603
+ * Log info message (always shown)
604
+ */
605
+ info(message) {
606
+ console.log(import_chalk.default.blue("\u2139"), message);
607
+ }
608
+ /**
609
+ * Log success message (always shown)
610
+ */
611
+ success(message) {
612
+ console.log(import_chalk.default.green("\u2713"), message);
613
+ }
614
+ /**
615
+ * Log warning message (always shown)
616
+ */
617
+ warn(message) {
618
+ console.log(import_chalk.default.yellow("\u26A0"), message);
619
+ }
620
+ /**
621
+ * Log error message (always shown)
622
+ */
623
+ error(message) {
624
+ console.error(import_chalk.default.red("\u2717"), message);
625
+ }
626
+ /**
627
+ * Log verbose message (only shown in verbose mode)
628
+ */
629
+ verbose(message) {
630
+ if (this._verbose) {
631
+ console.log(import_chalk.default.gray("\u2192"), message);
632
+ }
633
+ }
634
+ /**
635
+ * Log dry-run message (only shown in dry-run mode)
636
+ */
637
+ dryRun(message) {
638
+ if (this._dryRun) {
639
+ console.log(import_chalk.default.cyan("[DRY-RUN]"), message);
640
+ }
641
+ }
642
+ /**
643
+ * Create a spinner for long-running operations
644
+ */
645
+ spinner(text) {
646
+ return (0, import_ora.default)({
647
+ text,
648
+ color: "cyan",
649
+ spinner: "dots"
650
+ });
651
+ }
652
+ /**
653
+ * Log file operation (respects dry-run)
654
+ */
655
+ fileOperation(action, filePath) {
656
+ if (this._dryRun) {
657
+ this.dryRun(`Would ${action}: ${import_chalk.default.underline(filePath)}`);
658
+ } else {
659
+ this.verbose(`${action}: ${filePath}`);
660
+ }
661
+ }
662
+ /**
663
+ * Format error with context
664
+ */
665
+ formatError(error, context) {
666
+ let errorMessage = "";
667
+ if (error instanceof Error) {
668
+ errorMessage = error.message;
669
+ if (this._verbose && error.stack) {
670
+ errorMessage += `
671
+ ${import_chalk.default.gray(error.stack)}`;
672
+ }
673
+ } else if (error && typeof error === "object") {
674
+ const errorObj = error;
675
+ if (errorObj.message) {
676
+ errorMessage = String(errorObj.message);
677
+ } else if (errorObj.status) {
678
+ errorMessage = `HTTP ${errorObj.status}: ${errorObj.statusText || "Unknown error"}`;
679
+ } else {
680
+ try {
681
+ errorMessage = JSON.stringify(error, null, 2);
682
+ } catch {
683
+ errorMessage = String(error);
684
+ }
685
+ }
686
+ } else {
687
+ errorMessage = String(error);
688
+ }
689
+ if (context) {
690
+ return `${import_chalk.default.red(context)}
691
+ ${errorMessage}`;
692
+ }
693
+ return errorMessage;
694
+ }
695
+ };
696
+ var logger_default = Logger;
697
+
570
698
  // src/index.ts
571
- var main = async (configPath) => {
699
+ var main = async (options) => {
700
+ const opts = typeof options === "string" ? { configPath: options } : options ?? {};
701
+ const logger = new logger_default({
702
+ verbose: opts.verbose ?? false,
703
+ dryRun: opts.dryRun ?? false
704
+ });
572
705
  try {
573
- const config = await loadConfig(configPath);
574
- console.log("Config loaded successfully");
706
+ const configSpinner = logger.spinner("Loading configuration...");
707
+ configSpinner.start();
708
+ const config = await loadConfig(opts.configPath);
709
+ configSpinner.succeed("Configuration loaded successfully");
710
+ logger.verbose(`Config path: ${opts.configPath || "default"}`);
711
+ logger.verbose(`Overwrite mode: ${config.overwrite ? "enabled" : "disabled"}`);
575
712
  const generatesArray = Array.isArray(config.generates) ? config.generates : [config.generates];
713
+ logger.verbose(`Found ${generatesArray.length} generate configuration(s)`);
576
714
  for (const urlSchema of generatesArray) {
577
715
  for (const [filePath, generatorConfig] of Object.entries(urlSchema)) {
578
716
  try {
579
- await fetchAlgoliaData(filePath, generatorConfig, config.overwrite);
717
+ await fetchAlgoliaData(filePath, generatorConfig, config.overwrite, logger);
580
718
  } catch (error) {
581
- console.error(`
582
- Error processing file: ${filePath}`);
583
- if (error instanceof Error) {
584
- console.error(error.message);
585
- if (error.stack) {
586
- console.error(error.stack);
587
- }
588
- } else {
589
- try {
590
- console.error(JSON.stringify(error, null, 2));
591
- } catch {
592
- console.error(String(error));
593
- }
594
- }
719
+ logger.error(`Error processing file: ${filePath}`);
720
+ const errorMessage = logger.formatError(error, "Processing failed");
721
+ logger.error(errorMessage);
595
722
  }
596
723
  }
597
724
  }
598
- } catch (error) {
599
- console.error("Error loading config:");
600
- if (error instanceof Error) {
601
- console.error(error.message);
725
+ if (opts.dryRun) {
726
+ logger.info("Dry-run completed. No files were written.");
602
727
  } else {
603
- console.error(String(error));
728
+ logger.success("All files generated successfully!");
604
729
  }
730
+ } catch (error) {
731
+ logger.error("Failed to load configuration");
732
+ const errorMessage = logger.formatError(error, "Configuration error");
733
+ logger.error(errorMessage);
605
734
  process.exit(1);
606
735
  }
607
736
  };
@@ -612,6 +741,10 @@ if ((0, import_fs4.existsSync)(envPath)) {
612
741
  (0, import_dotenv.config)({ path: envPath });
613
742
  }
614
743
  var program = new import_commander.Command();
615
- program.name("algolia-codegen").description("Generate TypeScript types from Algolia index").option("-c, --config <path>", "Config file path").action(async (options) => {
616
- await main(options.config);
744
+ program.name("algolia-codegen").description("Generate TypeScript types from Algolia index").option("-c, --config <path>", "Config file path").option("-v, --verbose", "Enable verbose output").option("--dry-run", "Simulate execution without writing files").action(async (options) => {
745
+ await main({
746
+ configPath: options.config,
747
+ verbose: options.verbose ?? false,
748
+ dryRun: options.dryRun ?? false
749
+ });
617
750
  }).parse();
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  main
4
- } from "./chunk-R66ECGLW.js";
4
+ } from "./chunk-USMYY2DN.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { config as loadDotenv } from "dotenv";
@@ -13,6 +13,10 @@ if (existsSync(envPath)) {
13
13
  loadDotenv({ path: envPath });
14
14
  }
15
15
  var program = new Command();
16
- program.name("algolia-codegen").description("Generate TypeScript types from Algolia index").option("-c, --config <path>", "Config file path").action(async (options) => {
17
- await main(options.config);
16
+ program.name("algolia-codegen").description("Generate TypeScript types from Algolia index").option("-c, --config <path>", "Config file path").option("-v, --verbose", "Enable verbose output").option("--dry-run", "Simulate execution without writing files").action(async (options) => {
17
+ await main({
18
+ configPath: options.config,
19
+ verbose: options.verbose ?? false,
20
+ dryRun: options.dryRun ?? false
21
+ });
18
22
  }).parse();