@cldmv/slothlet 2.4.3 → 2.5.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/slothlet.mjs CHANGED
@@ -23,6 +23,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
23
23
 
24
24
  import { resolvePathFromCaller } from "@cldmv/slothlet/helpers/resolve-from-caller";
25
25
  import { sanitizePathName } from "@cldmv/slothlet/helpers/sanitize";
26
+ import { analyzeModule, processModuleFromAnalysis, getCategoryBuildingDecisions } from "@cldmv/slothlet/helpers/api_builder";
26
27
 
27
28
 
28
29
 
@@ -239,9 +240,9 @@ const slothletObject = {
239
240
 
240
241
  if (this.loaded) return this.api;
241
242
  if (this.config.lazy) {
242
- this.api = await this.modes.lazy.create.call(this, apiDir, true, this.config.apiDepth || Infinity, 0);
243
+ this.api = await this.modes.lazy.create.call(this, apiDir, this.config.apiDepth || Infinity, 0);
243
244
  } else {
244
- this.api = await this.modes.eager.create.call(this, apiDir, true, this.config.apiDepth || Infinity, 0);
245
+ this.api = await this.modes.eager.create.call(this, apiDir, this.config.apiDepth || Infinity, 0);
245
246
  }
246
247
  if (this.config.debug) console.log(this.api);
247
248
 
@@ -327,7 +328,7 @@ const slothletObject = {
327
328
  },
328
329
 
329
330
 
330
- _toApiKey(name) {
331
+ _toapiPathKey(name) {
331
332
  return sanitizePathName(name, this.config.sanitize || {});
332
333
 
333
334
  },
@@ -337,165 +338,74 @@ const slothletObject = {
337
338
  const { currentDepth = 0, maxDepth = Infinity, mode = "eager", subdirHandler } = options;
338
339
 
339
340
 
340
- if (this.config.debug) {
341
- console.log(`[DEBUG] _buildCategory called with path: ${categoryPath}, mode: ${mode}`);
342
- }
343
-
344
- const files = await fs.readdir(categoryPath, { withFileTypes: true });
345
- const moduleFiles = files.filter((f) => this._shouldIncludeFile(f));
346
- const categoryName = this._toApiKey(path.basename(categoryPath));
347
- const subDirs = files.filter((e) => e.isDirectory() && !e.name.startsWith("."));
341
+ const { buildCategoryDecisions } = await import("@cldmv/slothlet/helpers/api_builder");
342
+ const decisions = await buildCategoryDecisions(categoryPath, {
343
+ currentDepth,
344
+ maxDepth,
345
+ mode,
346
+ subdirHandler,
347
+ instance: this
348
+ });
348
349
 
349
350
 
350
- if (moduleFiles.length === 1 && subDirs.length === 0) {
351
- const moduleExt = path.extname(moduleFiles[0].name);
352
- const moduleName = this._toApiKey(path.basename(moduleFiles[0].name, moduleExt));
353
- const mod = await this._loadSingleModule(path.join(categoryPath, moduleFiles[0].name));
351
+ if (decisions.type === "single-file") {
352
+ const { singleFile } = decisions;
353
+ const { mod, moduleName } = singleFile;
354
354
 
355
355
 
356
- const functionNameMatchesFolder = typeof mod === "function" && mod.name && mod.name.toLowerCase() === categoryName.toLowerCase();
356
+ if (decisions.shouldFlatten) {
357
+ switch (decisions.flattenType) {
358
+ case "function-folder-match":
359
+ case "default-function":
360
+ try {
361
+ Object.defineProperty(mod, "name", { value: decisions.preferredName, configurable: true });
362
+ } catch {
363
+
364
+ }
365
+ return mod;
357
366
 
358
-
359
- const functionNameMatchesFilename =
360
- typeof mod === "function" &&
361
- mod.name &&
362
- this._toApiKey(mod.name).toLowerCase() === this._toApiKey(moduleName).toLowerCase() &&
363
- mod.name !== this._toApiKey(moduleName);
367
+ case "default-export-flatten":
368
+
369
+ return mod;
364
370
 
365
-
366
-
367
-
368
-
369
-
370
-
371
-
371
+ case "object-auto-flatten":
372
+
373
+ return mod[decisions.preferredName];
372
374
 
373
-
374
- if (moduleName === categoryName && typeof mod === "function") {
375
- try {
376
- Object.defineProperty(mod, "name", { value: categoryName, configurable: true });
377
- } catch {
378
-
379
- }
380
- return mod;
381
- }
375
+ case "parent-level-flatten": {
376
+
377
+ const exportValue = mod[Object.keys(mod).filter((k) => k !== "default")[0]];
378
+ return { [decisions.preferredName]: exportValue };
379
+ }
382
380
 
383
-
384
- if (functionNameMatchesFolder) {
385
- try {
386
-
387
- Object.defineProperty(mod, "name", { value: mod.name, configurable: true });
388
- } catch {
389
-
381
+ case "filename-folder-match-flatten":
382
+
383
+ return mod;
390
384
  }
391
- return mod;
392
385
  }
393
386
 
394
387
 
395
- if (functionNameMatchesFilename) {
396
-
397
-
398
-
399
- return { [mod.name]: mod };
388
+ if (decisions.preferredName && decisions.preferredName !== moduleName) {
389
+ return { [decisions.preferredName]: mod };
400
390
  }
401
391
 
402
392
 
403
-
404
- if (
405
- typeof mod === "function" &&
406
- (!mod.name || mod.name === "default" || mod.__slothletDefault === true)
407
- ) {
408
- try {
409
- Object.defineProperty(mod, "name", { value: categoryName, configurable: true });
410
- } catch {
411
-
412
- }
413
- return mod;
414
- }
415
- if (moduleName === categoryName && mod && typeof mod === "object" && !mod.default) {
416
- return { ...mod };
393
+ if (this.config.debug && moduleName === "nest") {
394
+ console.log(`[DEBUG] Single-file default case for nest: moduleName="${moduleName}" mod keys=[${Object.keys(mod)}]`);
417
395
  }
418
396
  return { [moduleName]: mod };
419
397
  }
420
398
 
421
399
 
422
400
  const categoryModules = {};
401
+ const { categoryName, processedModules, subdirectoryDecisions } = decisions;
423
402
 
424
403
 
425
- const defaultExportFiles = [];
426
- const selfReferentialFiles = new Set();
427
- const rawModuleCache = new Map();
428
-
429
-
430
- for (const file of moduleFiles) {
431
- const moduleExt = path.extname(file.name);
432
- const moduleName = this._toApiKey(path.basename(file.name, moduleExt));
433
- const moduleFilePath = path.resolve(categoryPath, file.name);
434
-
435
-
436
- const rawMod = await import(`file://${moduleFilePath.replace(/\\/g, "/")}`);
437
- rawModuleCache.set(file.name, rawMod);
438
-
404
+ for (const moduleDecision of processedModules) {
405
+ const { moduleName, mod, type, apiPathKey, shouldFlatten, flattenType, specialHandling, processedExports } = moduleDecision;
439
406
 
440
- if (rawMod && "default" in rawMod) {
407
+ if (specialHandling === "category-merge") {
441
408
 
442
- const isSelfReferential = Object.entries(rawMod).some(([key, value]) => key !== "default" && value === rawMod.default);
443
-
444
- if (this.config.debug) {
445
- console.log(`[DEBUG] _buildCategory: Checking ${file.name} in ${categoryPath}`);
446
- console.log(`[DEBUG] - moduleName: ${moduleName}`);
447
- console.log(`[DEBUG] - has default: ${rawMod && "default" in rawMod}`);
448
- console.log(`[DEBUG] - isSelfReferential: ${isSelfReferential}`);
449
- }
450
-
451
- if (!isSelfReferential) {
452
-
453
- const processedMod = await this._loadSingleModule(path.join(categoryPath, file.name));
454
- defaultExportFiles.push({ file, moduleName, mod: processedMod });
455
- if (this.config.debug) {
456
- console.log(`[DEBUG] Found default export in ${file.name} (non-self-referential)`);
457
- }
458
- } else {
459
- selfReferentialFiles.add(moduleName);
460
- if (this.config.debug) {
461
- console.log(`[DEBUG] Skipped ${file.name} - self-referential default export`);
462
- }
463
- }
464
- }
465
- }
466
-
467
- const hasMultipleDefaultExports = defaultExportFiles.length > 1;
468
-
469
- if (this.config.debug) {
470
- console.log(`[DEBUG] selfReferentialFiles Set:`, Array.from(selfReferentialFiles));
471
- console.log(`[DEBUG] hasMultipleDefaultExports:`, hasMultipleDefaultExports);
472
- }
473
-
474
- for (const file of moduleFiles) {
475
- const moduleExt = path.extname(file.name);
476
- const moduleName = this._toApiKey(path.basename(file.name, moduleExt));
477
-
478
-
479
- if (this.config.debug && moduleName === "config") {
480
- console.log("[DEBUG] Processing config file:", file.name, "moduleName:", moduleName);
481
- console.log("[DEBUG] selfReferentialFiles has config?", selfReferentialFiles.has(moduleName));
482
- }
483
-
484
-
485
- let mod = null;
486
- const existingDefault = defaultExportFiles.find(def => def.moduleName === moduleName);
487
- if (existingDefault) {
488
- mod = existingDefault.mod;
489
- } else {
490
-
491
- mod = await this._loadSingleModule(path.join(categoryPath, file.name));
492
- }
493
-
494
- if (this.config.debug && moduleName === "config") {
495
- console.log("[DEBUG] Config mod type:", typeof mod);
496
- console.log("[DEBUG] Config mod keys:", Object.keys(mod));
497
- }
498
- if (moduleName === categoryName && mod && typeof mod === "object") {
499
409
  if (
500
410
  Object.prototype.hasOwnProperty.call(mod, categoryName) &&
501
411
  typeof mod[categoryName] === "object" &&
@@ -503,139 +413,86 @@ const slothletObject = {
503
413
  ) {
504
414
  Object.assign(categoryModules, mod[categoryName]);
505
415
  for (const [key, value] of Object.entries(mod)) {
506
- if (key !== categoryName) categoryModules[this._toApiKey(key)] = value;
416
+ if (key !== categoryName) categoryModules[this._toapiPathKey(key)] = value;
507
417
  }
508
418
  } else {
509
419
  Object.assign(categoryModules, mod);
510
420
  }
511
- } else if (typeof mod === "function") {
421
+ } else if (type === "function") {
512
422
 
513
- const isSelfReferential = selfReferentialFiles.has(moduleName);
514
-
515
-
516
- let apiKey;
517
- if (hasMultipleDefaultExports && mod.__slothletDefault === true && !isSelfReferential) {
518
-
519
- apiKey = moduleName;
423
+ if (specialHandling === "multi-default-filename") {
520
424
  try {
521
425
  Object.defineProperty(mod, "name", { value: moduleName, configurable: true });
522
426
  } catch {
523
427
 
524
428
  }
525
- if (this.config.debug) {
526
- console.log(`[DEBUG] Multi-default detected: using filename '${moduleName}' for default export`);
527
- }
528
- } else if (selfReferentialFiles.has(moduleName)) {
529
-
530
- if (this.config.debug) {
531
- console.log(`[DEBUG] Self-referential default export: treating ${moduleName} as namespace`);
532
- }
533
-
534
- categoryModules[moduleName] = mod[moduleName] || mod;
535
- continue;
429
+ categoryModules[moduleName] = mod;
430
+ } else if (specialHandling === "prefer-function-name") {
431
+ categoryModules[apiPathKey] = mod;
536
432
  } else {
537
433
 
538
- const fnName = mod.name && mod.name !== "default" ? mod.name : moduleName;
539
- try {
540
- Object.defineProperty(mod, "name", { value: fnName, configurable: true });
541
- } catch {
542
-
543
- }
544
-
545
-
546
-
547
- if (fnName && fnName.toLowerCase() === moduleName.toLowerCase() && fnName !== moduleName) {
548
-
549
- apiKey = fnName;
550
- if (this.config.debug) {
551
- console.log(`[DEBUG] Using function name '${fnName}' instead of module name '${moduleName}'`);
552
- }
553
- } else {
554
-
555
- apiKey = this._toApiKey(fnName);
556
- if (this.config.debug) {
557
- console.log(`[DEBUG] Using sanitized key '${apiKey}' for function '${fnName}' (module: '${moduleName}')`);
558
- }
559
- }
434
+ categoryModules[apiPathKey] = mod;
560
435
  }
561
-
562
- categoryModules[apiKey] = mod;
563
- } else {
564
-
565
- let hasPreferredName = false;
566
- const modWithPreferredNames = {};
567
-
568
-
569
-
570
-
571
-
572
-
573
-
574
-
575
-
576
-
577
-
578
-
436
+ } else if (type === "self-referential") {
579
437
 
438
+ categoryModules[moduleName] = mod[moduleName] || mod;
439
+ } else if (type === "object") {
580
440
 
581
-
582
-
583
-
584
-
585
-
586
-
587
-
588
-
589
-
590
-
591
- for (const [exportName, exportValue] of Object.entries(mod)) {
592
- if (
593
- typeof exportValue === "function" &&
594
- exportValue.name &&
595
- this._toApiKey(exportValue.name).toLowerCase() === this._toApiKey(moduleName).toLowerCase() &&
596
- exportValue.name !== this._toApiKey(moduleName)
597
- ) {
598
-
599
- modWithPreferredNames[exportValue.name] = exportValue;
600
- hasPreferredName = true;
601
- if (this.config.debug) {
602
- console.log("[DEBUG] Using preferred name:", exportValue.name, "instead of:", this._toApiKey(moduleName));
441
+ if (specialHandling === "preferred-export-names") {
442
+ Object.assign(categoryModules, processedExports);
443
+ } else if (shouldFlatten) {
444
+ switch (flattenType) {
445
+ case "single-default-object": {
446
+
447
+ const flattened = { ...mod.default };
448
+
449
+ for (const [key, value] of Object.entries(mod)) {
450
+ if (key !== "default") {
451
+ flattened[key] = value;
452
+ }
453
+ }
454
+ categoryModules[apiPathKey] = flattened;
455
+ break;
456
+ }
457
+ case "multi-default-no-default": {
458
+
459
+ const moduleKeys = Object.keys(mod).filter((k) => k !== "default");
460
+ for (const key of moduleKeys) {
461
+ categoryModules[key] = mod[key];
462
+ }
463
+ break;
464
+ }
465
+ case "single-named-export-match":
466
+
467
+ categoryModules[apiPathKey] = mod[apiPathKey];
468
+ break;
469
+ case "category-name-match-flatten": {
470
+
471
+ const moduleKeys = Object.keys(mod).filter((k) => k !== "default");
472
+ for (const key of moduleKeys) {
473
+ categoryModules[key] = mod[key];
474
+ }
475
+ break;
603
476
  }
604
- } else {
605
- modWithPreferredNames[this._toApiKey(exportName)] = exportValue;
606
- }
607
- }
608
-
609
- if (hasPreferredName) {
610
- Object.assign(categoryModules, modWithPreferredNames);
611
-
612
- } else if (selfReferentialFiles.has(moduleName)) {
613
-
614
- if (this.config.debug) {
615
- console.log(`[DEBUG] Self-referential object: treating ${moduleName} as namespace`);
616
477
  }
617
- categoryModules[moduleName] = mod[moduleName] || mod;
618
478
  } else {
619
- categoryModules[this._toApiKey(moduleName)] = mod;
620
-
621
-
622
479
 
480
+ categoryModules[apiPathKey] = mod;
623
481
  }
624
482
  }
625
483
  }
626
484
 
627
485
 
628
- for (const subDirEntry of subDirs) {
629
- if (currentDepth < maxDepth) {
630
- const key = this._toApiKey(subDirEntry.name);
631
- const subDirPath = path.join(categoryPath, subDirEntry.name);
486
+ for (const subDirDecision of subdirectoryDecisions) {
487
+ if (subDirDecision.shouldRecurse) {
488
+ const { name, path: subDirPath, apiPathKey } = subDirDecision;
632
489
  let subModule;
633
490
 
634
491
  if (mode === "lazy" && typeof subdirHandler === "function") {
635
492
  subModule = subdirHandler({
636
- subDirEntry,
493
+ subDirEntry: { name },
637
494
  subDirPath,
638
- key,
495
+ key: apiPathKey,
639
496
  categoryModules,
640
497
  currentDepth,
641
498
  maxDepth
@@ -653,13 +510,13 @@ const slothletObject = {
653
510
  if (
654
511
  typeof subModule === "function" &&
655
512
  subModule.name &&
656
- subModule.name.toLowerCase() === key.toLowerCase() &&
657
- subModule.name !== key
513
+ subModule.name.toLowerCase() === apiPathKey.toLowerCase() &&
514
+ subModule.name !== apiPathKey
658
515
  ) {
659
516
 
660
517
  categoryModules[subModule.name] = subModule;
661
518
  } else {
662
- categoryModules[key] = subModule;
519
+ categoryModules[apiPathKey] = subModule;
663
520
  }
664
521
  }
665
522
  }
@@ -694,164 +551,125 @@ const slothletObject = {
694
551
  },
695
552
 
696
553
 
697
- async _loadSingleModule(modulePath, rootLevel = false) {
698
- const moduleUrl = pathToFileURL(modulePath).href;
699
-
554
+ async _loadSingleModule(modulePath, returnAnalysis = false) {
700
555
 
701
- const module = await import(moduleUrl);
556
+ const analysis = await analyzeModule(modulePath, {
557
+ debug: this.config.debug,
558
+ instance: this
559
+ });
560
+ const processedModule = processModuleFromAnalysis(analysis, {
561
+ debug: this.config.debug,
562
+ instance: this
563
+ });
702
564
 
703
565
 
566
+ if (returnAnalysis) {
567
+ return { mod: processedModule, analysis };
568
+ }
569
+
704
570
 
571
+ return processedModule;
572
+ },
573
+
574
+
575
+ async _buildCategoryEnhanced(categoryPath, options = {}) {
576
+ const { currentDepth = 0, maxDepth = Infinity, mode = "eager", subdirHandler } = options;
705
577
 
706
578
 
579
+ const decisions = await getCategoryBuildingDecisions(categoryPath, {
580
+ instance: this,
581
+ currentDepth,
582
+ maxDepth,
583
+ debug: this.config.debug
584
+ });
585
+
586
+ const { processingStrategy, categoryName, processedModules, subDirectories } = decisions;
707
587
 
708
- if (this.config.debug) console.log("module: ", module);
709
588
 
710
- if (typeof module.default === "function") {
711
- let fn;
712
- if (rootLevel) {
713
- fn = module;
714
- } else {
715
- fn = module.default;
716
-
717
- try {
718
- Object.defineProperty(fn, "__slothletDefault", { value: true, enumerable: false });
719
- } catch {
720
-
721
- }
589
+ if (processingStrategy === "single-file" && processedModules.length === 1) {
590
+ const { processedModule, flattening } = processedModules[0];
722
591
 
592
+ if (flattening.shouldFlatten) {
723
593
 
724
-
725
-
726
-
727
-
728
-
729
- for (const [exportName, exportValue] of Object.entries(module)) {
730
- if (exportName !== "default") {
731
-
732
-
733
-
734
-
735
-
736
- fn[this._toApiKey(exportName)] = exportValue;
594
+ if (typeof processedModule === "function") {
595
+ try {
596
+ Object.defineProperty(processedModule, "name", { value: flattening.apiPathKey, configurable: true });
597
+ } catch {
737
598
 
738
599
  }
739
600
  }
740
- if (this.config.debug) console.log("fn: ", fn);
601
+ return processedModule;
741
602
  }
742
- return fn;
603
+
604
+
605
+ return { [flattening.apiPathKey]: processedModule };
743
606
  }
744
607
 
745
- const moduleExports = Object.entries(module);
746
608
 
747
- if (!moduleExports.length) {
748
- throw new Error(
749
- `slothlet: No exports found in module '${modulePath}'. The file is empty or does not export any function/object/variable.`
750
- );
751
- }
752
- if (this.config.debug) console.log("moduleExports: ", moduleExports);
753
-
754
-
755
- const defaultExportObj =
756
- typeof module.default === "object" && module.default !== null
757
- ? module.default
758
- : typeof moduleExports[0][1] === "object" && typeof moduleExports[0][1].default === "function" && moduleExports[0][1] !== null
759
- ? moduleExports[0][1]
760
- : null;
761
- let objectName = null;
762
- if (typeof module.default === "function" && module.default.name) {
763
- objectName = module.default.name;
764
- } else if (moduleExports[0] && moduleExports[0][0] !== "default") {
765
- objectName = moduleExports[0][0];
609
+ const categoryModules = {};
610
+
611
+ for (const { processedModule, flattening } of processedModules) {
612
+ categoryModules[flattening.apiPathKey] = processedModule;
766
613
  }
767
-
768
-
769
614
 
770
- if (this.config.debug) console.log("defaultExportObj: ", defaultExportObj);
771
- if (this.config.debug) console.log("objectName: ", objectName);
615
+
616
+ for (const { dirEntry: subDirEntry, apiPathKey: key } of subDirectories) {
617
+ const subDirPath = path.join(categoryPath, subDirEntry.name);
618
+ let subModule;
772
619
 
773
- if (defaultExportObj && typeof defaultExportObj.default === "function") {
774
- if (this.config.debug) console.log("DEFAULT FUNCTION FOUND FOR: ", module);
775
-
776
- const callableApi = {
777
- [objectName]: function (...args) {
778
- return defaultExportObj.default.apply(defaultExportObj, args);
779
- }
780
- }[objectName];
781
- for (const [methodName, method] of Object.entries(defaultExportObj)) {
782
- if (methodName === "default") continue;
783
- callableApi[methodName] = method;
620
+ if (mode === "lazy" && typeof subdirHandler === "function") {
621
+ subModule = subdirHandler({
622
+ subDirEntry,
623
+ subDirPath,
624
+ key,
625
+ categoryModules,
626
+ currentDepth,
627
+ maxDepth
628
+ });
629
+ } else {
630
+
631
+ subModule = await this._buildCategoryEnhanced(subDirPath, {
632
+ currentDepth: currentDepth + 1,
633
+ maxDepth,
634
+ mode: "eager"
635
+ });
784
636
  }
785
-
786
-
787
-
788
-
789
-
790
- if (this.config.debug) console.log("callableApi", callableApi);
791
- return callableApi;
792
- } else if (defaultExportObj) {
793
- if (this.config.debug) console.log("DEFAULT FOUND FOR: ", module);
794
637
 
795
- const obj = { ...defaultExportObj };
796
-
797
-
798
-
799
-
800
-
801
-
802
638
 
803
-
804
-
805
-
806
-
807
-
808
- for (const [exportName, exportValue] of Object.entries(module)) {
809
- if (exportName !== "default" && exportValue !== obj) {
810
-
811
-
812
-
813
-
814
-
815
- obj[this._toApiKey(exportName)] = exportValue;
816
- }
639
+ if (
640
+ typeof subModule === "function" &&
641
+ subModule.name &&
642
+ subModule.name.toLowerCase() === key.toLowerCase() &&
643
+ subModule.name !== key
644
+ ) {
645
+ categoryModules[subModule.name] = subModule;
646
+ } else {
647
+ categoryModules[key] = subModule;
817
648
  }
818
-
819
- return obj;
820
649
  }
821
-
822
- const namedExports = Object.entries(module).filter(([k]) => k !== "default");
823
- if (this.config.debug) console.log("namedExports: ", namedExports);
824
- if (namedExports.length === 1 && !module.default) {
825
- if (typeof namedExports[0][1] === "object") {
826
-
827
- if (this.config.debug) console.log("namedExports[0][1] === object: ", namedExports[0][1]);
828
- const obj = { ...namedExports[0][1] };
829
-
830
-
831
-
832
-
833
-
834
-
835
-
836
-
837
-
838
650
 
839
- return obj;
840
- }
841
- if (typeof namedExports[0][1] === "function") {
842
- if (this.config.debug) console.log("namedExports[0][1] === function: ", namedExports[0][1]);
843
-
844
-
845
- return namedExports[0][1];
651
+
652
+ const keys = Object.keys(categoryModules);
653
+ if (keys.length === 1) {
654
+ const singleKey = keys[0];
655
+ if (singleKey === categoryName) {
656
+ const single = categoryModules[singleKey];
657
+ if (typeof single === "function") {
658
+ if (single.name !== categoryName) {
659
+ try {
660
+ Object.defineProperty(single, "name", { value: categoryName, configurable: true });
661
+ } catch {
662
+
663
+ }
664
+ }
665
+ return single;
666
+ } else if (single && typeof single === "object" && !Array.isArray(single)) {
667
+ return single;
668
+ }
846
669
  }
847
670
  }
848
- const apiExport = {};
849
- for (const [exportName, exportValue] of namedExports) {
850
-
851
-
852
- apiExport[this._toApiKey(exportName)] = exportValue;
853
- }
854
- return apiExport;
671
+
672
+ return categoryModules;
855
673
  },
856
674
 
857
675