@cldmv/slothlet 2.4.2 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -6
- package/dist/lib/helpers/api_builder.mjs +1446 -0
- package/dist/lib/helpers/multidefault.mjs +197 -0
- package/dist/lib/modes/slothlet_eager.mjs +53 -109
- package/dist/lib/modes/slothlet_lazy.mjs +89 -67
- package/dist/slothlet.mjs +192 -315
- package/package.json +4 -3
- package/types/dist/lib/helpers/api_builder.d.mts +446 -0
- package/types/dist/lib/helpers/api_builder.d.mts.map +1 -0
- package/types/dist/lib/helpers/multidefault.d.mts +85 -0
- package/types/dist/lib/helpers/multidefault.d.mts.map +1 -0
- package/types/dist/lib/modes/slothlet_eager.d.mts +3 -4
- package/types/dist/lib/modes/slothlet_eager.d.mts.map +1 -1
- package/types/dist/lib/modes/slothlet_lazy.d.mts +3 -4
- package/types/dist/lib/modes/slothlet_lazy.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts.map +1 -1
package/dist/slothlet.mjs
CHANGED
|
@@ -23,6 +23,12 @@ 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 {
|
|
27
|
+
processModuleForAPI,
|
|
28
|
+
analyzeModule,
|
|
29
|
+
processModuleFromAnalysis,
|
|
30
|
+
getCategoryBuildingDecisions
|
|
31
|
+
} from "@cldmv/slothlet/helpers/api_builder";
|
|
26
32
|
|
|
27
33
|
|
|
28
34
|
|
|
@@ -239,9 +245,9 @@ const slothletObject = {
|
|
|
239
245
|
|
|
240
246
|
if (this.loaded) return this.api;
|
|
241
247
|
if (this.config.lazy) {
|
|
242
|
-
this.api = await this.modes.lazy.create.call(this, apiDir,
|
|
248
|
+
this.api = await this.modes.lazy.create.call(this, apiDir, this.config.apiDepth || Infinity, 0);
|
|
243
249
|
} else {
|
|
244
|
-
this.api = await this.modes.eager.create.call(this, apiDir,
|
|
250
|
+
this.api = await this.modes.eager.create.call(this, apiDir, this.config.apiDepth || Infinity, 0);
|
|
245
251
|
}
|
|
246
252
|
if (this.config.debug) console.log(this.api);
|
|
247
253
|
|
|
@@ -327,7 +333,7 @@ const slothletObject = {
|
|
|
327
333
|
},
|
|
328
334
|
|
|
329
335
|
|
|
330
|
-
|
|
336
|
+
_toapiPathKey(name) {
|
|
331
337
|
return sanitizePathName(name, this.config.sanitize || {});
|
|
332
338
|
|
|
333
339
|
},
|
|
@@ -337,120 +343,74 @@ const slothletObject = {
|
|
|
337
343
|
const { currentDepth = 0, maxDepth = Infinity, mode = "eager", subdirHandler } = options;
|
|
338
344
|
|
|
339
345
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
346
|
+
const { buildCategoryDecisions } = await import("@cldmv/slothlet/helpers/api_builder");
|
|
347
|
+
const decisions = await buildCategoryDecisions(categoryPath, {
|
|
348
|
+
currentDepth,
|
|
349
|
+
maxDepth,
|
|
350
|
+
mode,
|
|
351
|
+
subdirHandler,
|
|
352
|
+
instance: this
|
|
353
|
+
});
|
|
348
354
|
|
|
349
355
|
|
|
350
|
-
if (
|
|
351
|
-
const
|
|
352
|
-
const moduleName =
|
|
353
|
-
const mod = await this._loadSingleModule(path.join(categoryPath, moduleFiles[0].name));
|
|
356
|
+
if (decisions.type === "single-file") {
|
|
357
|
+
const { singleFile } = decisions;
|
|
358
|
+
const { mod, moduleName } = singleFile;
|
|
354
359
|
|
|
355
360
|
|
|
356
|
-
|
|
361
|
+
if (decisions.shouldFlatten) {
|
|
362
|
+
switch (decisions.flattenType) {
|
|
363
|
+
case "function-folder-match":
|
|
364
|
+
case "default-function":
|
|
365
|
+
try {
|
|
366
|
+
Object.defineProperty(mod, "name", { value: decisions.preferredName, configurable: true });
|
|
367
|
+
} catch {
|
|
368
|
+
|
|
369
|
+
}
|
|
370
|
+
return mod;
|
|
357
371
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
mod.name &&
|
|
362
|
-
this._toApiKey(mod.name).toLowerCase() === this._toApiKey(moduleName).toLowerCase() &&
|
|
363
|
-
mod.name !== this._toApiKey(moduleName);
|
|
372
|
+
case "default-export-flatten":
|
|
373
|
+
|
|
374
|
+
return mod;
|
|
364
375
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
376
|
+
case "object-auto-flatten":
|
|
377
|
+
|
|
378
|
+
return mod[decisions.preferredName];
|
|
372
379
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
return mod;
|
|
381
|
-
}
|
|
380
|
+
case "parent-level-flatten": {
|
|
381
|
+
|
|
382
|
+
const exportValue = mod[Object.keys(mod).filter((k) => k !== "default")[0]];
|
|
383
|
+
return { [decisions.preferredName]: exportValue };
|
|
384
|
+
}
|
|
382
385
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
Object.defineProperty(mod, "name", { value: mod.name, configurable: true });
|
|
388
|
-
} catch {
|
|
389
|
-
|
|
386
|
+
case "filename-folder-match-flatten":
|
|
387
|
+
|
|
388
|
+
return mod;
|
|
390
389
|
}
|
|
391
|
-
return mod;
|
|
392
390
|
}
|
|
393
391
|
|
|
394
392
|
|
|
395
|
-
if (
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
return { [mod.name]: mod };
|
|
393
|
+
if (decisions.preferredName && decisions.preferredName !== moduleName) {
|
|
394
|
+
return { [decisions.preferredName]: mod };
|
|
400
395
|
}
|
|
401
396
|
|
|
402
397
|
|
|
403
|
-
|
|
404
|
-
|
|
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 };
|
|
398
|
+
if (this.config.debug && moduleName === "nest") {
|
|
399
|
+
console.log(`[DEBUG] Single-file default case for nest: moduleName="${moduleName}" mod keys=[${Object.keys(mod)}]`);
|
|
417
400
|
}
|
|
418
401
|
return { [moduleName]: mod };
|
|
419
402
|
}
|
|
420
403
|
|
|
421
404
|
|
|
422
405
|
const categoryModules = {};
|
|
406
|
+
const { categoryName, processedModules, subdirectoryDecisions } = decisions;
|
|
423
407
|
|
|
424
408
|
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
const moduleExt = path.extname(file.name);
|
|
428
|
-
const moduleName = this._toApiKey(path.basename(file.name, moduleExt));
|
|
429
|
-
const tempMod = await this._loadSingleModule(path.join(categoryPath, file.name));
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
if (tempMod && tempMod.__slothletDefault === true) {
|
|
434
|
-
defaultExportFiles.push({ file, moduleName, mod: tempMod });
|
|
435
|
-
if (this.config.debug) {
|
|
436
|
-
console.log(`[DEBUG] Found default export in ${file.name}`);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
const hasMultipleDefaultExports = defaultExportFiles.length > 1;
|
|
442
|
-
|
|
443
|
-
for (const file of moduleFiles) {
|
|
444
|
-
const moduleExt = path.extname(file.name);
|
|
445
|
-
const moduleName = this._toApiKey(path.basename(file.name, moduleExt));
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
409
|
+
for (const moduleDecision of processedModules) {
|
|
410
|
+
const { moduleName, mod, type, apiPathKey, shouldFlatten, flattenType, specialHandling, processedExports } = moduleDecision;
|
|
450
411
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
if (moduleName === categoryName && mod && typeof mod === "object") {
|
|
412
|
+
if (specialHandling === "category-merge") {
|
|
413
|
+
|
|
454
414
|
if (
|
|
455
415
|
Object.prototype.hasOwnProperty.call(mod, categoryName) &&
|
|
456
416
|
typeof mod[categoryName] === "object" &&
|
|
@@ -458,122 +418,86 @@ const slothletObject = {
|
|
|
458
418
|
) {
|
|
459
419
|
Object.assign(categoryModules, mod[categoryName]);
|
|
460
420
|
for (const [key, value] of Object.entries(mod)) {
|
|
461
|
-
if (key !== categoryName) categoryModules[this.
|
|
421
|
+
if (key !== categoryName) categoryModules[this._toapiPathKey(key)] = value;
|
|
462
422
|
}
|
|
463
423
|
} else {
|
|
464
424
|
Object.assign(categoryModules, mod);
|
|
465
425
|
}
|
|
466
|
-
} else if (
|
|
426
|
+
} else if (type === "function") {
|
|
467
427
|
|
|
468
|
-
|
|
469
|
-
if (hasMultipleDefaultExports && mod.__slothletDefault === true) {
|
|
470
|
-
|
|
471
|
-
apiKey = moduleName;
|
|
428
|
+
if (specialHandling === "multi-default-filename") {
|
|
472
429
|
try {
|
|
473
430
|
Object.defineProperty(mod, "name", { value: moduleName, configurable: true });
|
|
474
431
|
} catch {
|
|
475
432
|
|
|
476
433
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
434
|
+
categoryModules[moduleName] = mod;
|
|
435
|
+
} else if (specialHandling === "prefer-function-name") {
|
|
436
|
+
categoryModules[apiPathKey] = mod;
|
|
480
437
|
} else {
|
|
481
438
|
|
|
482
|
-
|
|
483
|
-
try {
|
|
484
|
-
Object.defineProperty(mod, "name", { value: fnName, configurable: true });
|
|
485
|
-
} catch {
|
|
486
|
-
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
if (fnName && fnName.toLowerCase() === moduleName.toLowerCase() && fnName !== moduleName) {
|
|
492
|
-
|
|
493
|
-
apiKey = fnName;
|
|
494
|
-
if (this.config.debug) {
|
|
495
|
-
console.log(`[DEBUG] Using function name '${fnName}' instead of module name '${moduleName}'`);
|
|
496
|
-
}
|
|
497
|
-
} else {
|
|
498
|
-
|
|
499
|
-
apiKey = this._toApiKey(fnName);
|
|
500
|
-
if (this.config.debug) {
|
|
501
|
-
console.log(`[DEBUG] Using sanitized key '${apiKey}' for function '${fnName}' (module: '${moduleName}')`);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
439
|
+
categoryModules[apiPathKey] = mod;
|
|
504
440
|
}
|
|
505
|
-
|
|
506
|
-
categoryModules[apiKey] = mod;
|
|
507
|
-
} else {
|
|
508
|
-
|
|
509
|
-
let hasPreferredName = false;
|
|
510
|
-
const modWithPreferredNames = {};
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
441
|
+
} else if (type === "self-referential") {
|
|
519
442
|
|
|
443
|
+
categoryModules[moduleName] = mod[moduleName] || mod;
|
|
444
|
+
} else if (type === "object") {
|
|
520
445
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
446
|
+
if (specialHandling === "preferred-export-names") {
|
|
447
|
+
Object.assign(categoryModules, processedExports);
|
|
448
|
+
} else if (shouldFlatten) {
|
|
449
|
+
switch (flattenType) {
|
|
450
|
+
case "single-default-object": {
|
|
451
|
+
|
|
452
|
+
const flattened = { ...mod.default };
|
|
453
|
+
|
|
454
|
+
for (const [key, value] of Object.entries(mod)) {
|
|
455
|
+
if (key !== "default") {
|
|
456
|
+
flattened[key] = value;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
categoryModules[apiPathKey] = flattened;
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
case "multi-default-no-default": {
|
|
463
|
+
|
|
464
|
+
const moduleKeys = Object.keys(mod).filter((k) => k !== "default");
|
|
465
|
+
for (const key of moduleKeys) {
|
|
466
|
+
categoryModules[key] = mod[key];
|
|
467
|
+
}
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
case "single-named-export-match":
|
|
471
|
+
|
|
472
|
+
categoryModules[apiPathKey] = mod[apiPathKey];
|
|
473
|
+
break;
|
|
474
|
+
case "category-name-match-flatten": {
|
|
475
|
+
|
|
476
|
+
const moduleKeys = Object.keys(mod).filter((k) => k !== "default");
|
|
477
|
+
for (const key of moduleKeys) {
|
|
478
|
+
categoryModules[key] = mod[key];
|
|
479
|
+
}
|
|
480
|
+
break;
|
|
547
481
|
}
|
|
548
|
-
} else {
|
|
549
|
-
modWithPreferredNames[this._toApiKey(exportName)] = exportValue;
|
|
550
482
|
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
if (hasPreferredName) {
|
|
554
|
-
Object.assign(categoryModules, modWithPreferredNames);
|
|
555
|
-
|
|
556
483
|
} else {
|
|
557
|
-
categoryModules[this._toApiKey(moduleName)] = mod;
|
|
558
|
-
|
|
559
|
-
|
|
560
484
|
|
|
485
|
+
categoryModules[apiPathKey] = mod;
|
|
561
486
|
}
|
|
562
487
|
}
|
|
563
488
|
}
|
|
564
489
|
|
|
565
490
|
|
|
566
|
-
for (const
|
|
567
|
-
if (
|
|
568
|
-
const
|
|
569
|
-
const subDirPath = path.join(categoryPath, subDirEntry.name);
|
|
491
|
+
for (const subDirDecision of subdirectoryDecisions) {
|
|
492
|
+
if (subDirDecision.shouldRecurse) {
|
|
493
|
+
const { name, path: subDirPath, apiPathKey } = subDirDecision;
|
|
570
494
|
let subModule;
|
|
571
495
|
|
|
572
496
|
if (mode === "lazy" && typeof subdirHandler === "function") {
|
|
573
497
|
subModule = subdirHandler({
|
|
574
|
-
subDirEntry,
|
|
498
|
+
subDirEntry: { name },
|
|
575
499
|
subDirPath,
|
|
576
|
-
key,
|
|
500
|
+
key: apiPathKey,
|
|
577
501
|
categoryModules,
|
|
578
502
|
currentDepth,
|
|
579
503
|
maxDepth
|
|
@@ -591,13 +515,13 @@ const slothletObject = {
|
|
|
591
515
|
if (
|
|
592
516
|
typeof subModule === "function" &&
|
|
593
517
|
subModule.name &&
|
|
594
|
-
subModule.name.toLowerCase() ===
|
|
595
|
-
subModule.name !==
|
|
518
|
+
subModule.name.toLowerCase() === apiPathKey.toLowerCase() &&
|
|
519
|
+
subModule.name !== apiPathKey
|
|
596
520
|
) {
|
|
597
521
|
|
|
598
522
|
categoryModules[subModule.name] = subModule;
|
|
599
523
|
} else {
|
|
600
|
-
categoryModules[
|
|
524
|
+
categoryModules[apiPathKey] = subModule;
|
|
601
525
|
}
|
|
602
526
|
}
|
|
603
527
|
}
|
|
@@ -632,164 +556,117 @@ const slothletObject = {
|
|
|
632
556
|
},
|
|
633
557
|
|
|
634
558
|
|
|
635
|
-
async _loadSingleModule(modulePath
|
|
636
|
-
const moduleUrl = pathToFileURL(modulePath).href;
|
|
637
|
-
|
|
559
|
+
async _loadSingleModule(modulePath) {
|
|
638
560
|
|
|
639
|
-
const
|
|
561
|
+
const analysis = await analyzeModule(modulePath, {
|
|
562
|
+
debug: this.config.debug,
|
|
563
|
+
instance: this
|
|
564
|
+
});
|
|
565
|
+
return processModuleFromAnalysis(analysis, {
|
|
566
|
+
debug: this.config.debug,
|
|
567
|
+
instance: this
|
|
568
|
+
});
|
|
569
|
+
},
|
|
640
570
|
|
|
641
|
-
|
|
642
|
-
|
|
571
|
+
|
|
572
|
+
async _buildCategoryEnhanced(categoryPath, options = {}) {
|
|
573
|
+
const { currentDepth = 0, maxDepth = Infinity, mode = "eager", subdirHandler } = options;
|
|
643
574
|
|
|
644
575
|
|
|
576
|
+
const decisions = await getCategoryBuildingDecisions(categoryPath, {
|
|
577
|
+
instance: this,
|
|
578
|
+
currentDepth,
|
|
579
|
+
maxDepth,
|
|
580
|
+
debug: this.config.debug
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
const { processingStrategy, categoryName, processedModules, subDirectories } = decisions;
|
|
645
584
|
|
|
646
|
-
if (this.config.debug) console.log("module: ", module);
|
|
647
585
|
|
|
648
|
-
if (
|
|
649
|
-
|
|
650
|
-
if (rootLevel) {
|
|
651
|
-
fn = module;
|
|
652
|
-
} else {
|
|
653
|
-
fn = module.default;
|
|
654
|
-
|
|
655
|
-
try {
|
|
656
|
-
Object.defineProperty(fn, "__slothletDefault", { value: true, enumerable: false });
|
|
657
|
-
} catch {
|
|
658
|
-
|
|
659
|
-
}
|
|
586
|
+
if (processingStrategy === "single-file" && processedModules.length === 1) {
|
|
587
|
+
const { processedModule, flattening } = processedModules[0];
|
|
660
588
|
|
|
589
|
+
if (flattening.shouldFlatten) {
|
|
661
590
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
for (const [exportName, exportValue] of Object.entries(module)) {
|
|
668
|
-
if (exportName !== "default") {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
fn[this._toApiKey(exportName)] = exportValue;
|
|
591
|
+
if (typeof processedModule === "function") {
|
|
592
|
+
try {
|
|
593
|
+
Object.defineProperty(processedModule, "name", { value: flattening.apiPathKey, configurable: true });
|
|
594
|
+
} catch {
|
|
675
595
|
|
|
676
596
|
}
|
|
677
597
|
}
|
|
678
|
-
|
|
598
|
+
return processedModule;
|
|
679
599
|
}
|
|
680
|
-
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
return { [flattening.apiPathKey]: processedModule };
|
|
681
603
|
}
|
|
682
604
|
|
|
683
|
-
const moduleExports = Object.entries(module);
|
|
684
605
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
}
|
|
690
|
-
if (this.config.debug) console.log("moduleExports: ", moduleExports);
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
const defaultExportObj =
|
|
694
|
-
typeof module.default === "object" && module.default !== null
|
|
695
|
-
? module.default
|
|
696
|
-
: typeof moduleExports[0][1] === "object" && typeof moduleExports[0][1].default === "function" && moduleExports[0][1] !== null
|
|
697
|
-
? moduleExports[0][1]
|
|
698
|
-
: null;
|
|
699
|
-
let objectName = null;
|
|
700
|
-
if (typeof module.default === "function" && module.default.name) {
|
|
701
|
-
objectName = module.default.name;
|
|
702
|
-
} else if (moduleExports[0] && moduleExports[0][0] !== "default") {
|
|
703
|
-
objectName = moduleExports[0][0];
|
|
606
|
+
const categoryModules = {};
|
|
607
|
+
|
|
608
|
+
for (const { processedModule, flattening } of processedModules) {
|
|
609
|
+
categoryModules[flattening.apiPathKey] = processedModule;
|
|
704
610
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
611
|
|
|
708
|
-
|
|
709
|
-
|
|
612
|
+
|
|
613
|
+
for (const { dirEntry: subDirEntry, apiPathKey: key } of subDirectories) {
|
|
614
|
+
const subDirPath = path.join(categoryPath, subDirEntry.name);
|
|
615
|
+
let subModule;
|
|
710
616
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
617
|
+
if (mode === "lazy" && typeof subdirHandler === "function") {
|
|
618
|
+
subModule = subdirHandler({
|
|
619
|
+
subDirEntry,
|
|
620
|
+
subDirPath,
|
|
621
|
+
key,
|
|
622
|
+
categoryModules,
|
|
623
|
+
currentDepth,
|
|
624
|
+
maxDepth
|
|
625
|
+
});
|
|
626
|
+
} else {
|
|
627
|
+
|
|
628
|
+
subModule = await this._buildCategoryEnhanced(subDirPath, {
|
|
629
|
+
currentDepth: currentDepth + 1,
|
|
630
|
+
maxDepth,
|
|
631
|
+
mode: "eager"
|
|
632
|
+
});
|
|
722
633
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (this.config.debug) console.log("callableApi", callableApi);
|
|
729
|
-
return callableApi;
|
|
730
|
-
} else if (defaultExportObj) {
|
|
731
|
-
if (this.config.debug) console.log("DEFAULT FOUND FOR: ", module);
|
|
732
|
-
|
|
733
|
-
const obj = { ...defaultExportObj };
|
|
734
634
|
|
|
735
635
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
for (const [exportName, exportValue] of Object.entries(module)) {
|
|
747
|
-
if (exportName !== "default" && exportValue !== obj) {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
obj[this._toApiKey(exportName)] = exportValue;
|
|
754
|
-
}
|
|
636
|
+
if (
|
|
637
|
+
typeof subModule === "function" &&
|
|
638
|
+
subModule.name &&
|
|
639
|
+
subModule.name.toLowerCase() === key.toLowerCase() &&
|
|
640
|
+
subModule.name !== key
|
|
641
|
+
) {
|
|
642
|
+
categoryModules[subModule.name] = subModule;
|
|
643
|
+
} else {
|
|
644
|
+
categoryModules[key] = subModule;
|
|
755
645
|
}
|
|
756
|
-
|
|
757
|
-
return obj;
|
|
758
646
|
}
|
|
759
|
-
|
|
760
|
-
const namedExports = Object.entries(module).filter(([k]) => k !== "default");
|
|
761
|
-
if (this.config.debug) console.log("namedExports: ", namedExports);
|
|
762
|
-
if (namedExports.length === 1 && !module.default) {
|
|
763
|
-
if (typeof namedExports[0][1] === "object") {
|
|
764
|
-
|
|
765
|
-
if (this.config.debug) console.log("namedExports[0][1] === object: ", namedExports[0][1]);
|
|
766
|
-
const obj = { ...namedExports[0][1] };
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
647
|
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
648
|
+
|
|
649
|
+
const keys = Object.keys(categoryModules);
|
|
650
|
+
if (keys.length === 1) {
|
|
651
|
+
const singleKey = keys[0];
|
|
652
|
+
if (singleKey === categoryName) {
|
|
653
|
+
const single = categoryModules[singleKey];
|
|
654
|
+
if (typeof single === "function") {
|
|
655
|
+
if (single.name !== categoryName) {
|
|
656
|
+
try {
|
|
657
|
+
Object.defineProperty(single, "name", { value: categoryName, configurable: true });
|
|
658
|
+
} catch {
|
|
659
|
+
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return single;
|
|
663
|
+
} else if (single && typeof single === "object" && !Array.isArray(single)) {
|
|
664
|
+
return single;
|
|
665
|
+
}
|
|
784
666
|
}
|
|
785
667
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
apiExport[this._toApiKey(exportName)] = exportValue;
|
|
791
|
-
}
|
|
792
|
-
return apiExport;
|
|
668
|
+
|
|
669
|
+
return categoryModules;
|
|
793
670
|
},
|
|
794
671
|
|
|
795
672
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cldmv/slothlet",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"moduleVersions": {
|
|
5
|
-
"lazy": "1.
|
|
6
|
-
"eager": "1.
|
|
5
|
+
"lazy": "1.3.0",
|
|
6
|
+
"eager": "1.3.0"
|
|
7
7
|
},
|
|
8
8
|
"description": "Slothlet: Modular API Loader for Node.js. Lazy mode dynamically loads API modules and submodules only when accessed, supporting both lazy and eager loading.",
|
|
9
9
|
"main": "./index.cjs",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"types": "./types/index.d.mts",
|
|
55
55
|
"scripts": {
|
|
56
|
+
"precommit": "node tools/precommit-validation.mjs",
|
|
56
57
|
"publish:manual": "npm publish --access public",
|
|
57
58
|
"test": "node tests/test-conditional.mjs",
|
|
58
59
|
"test:pre-build": "node tests/test-conditional.mjs",
|