silgi 0.34.4 → 0.34.6

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.
@@ -2,7 +2,7 @@ import { consola } from 'consola';
2
2
  import { createHooks, createDebugger } from 'hookable';
3
3
  import { resolve, join, relative, extname, basename, dirname, isAbsolute } from 'pathe';
4
4
  import { useSilgiCLI, replaceRuntimeValues, silgiCLICtx, autoImportTypes } from 'silgi';
5
- import { isPresents, addTemplate, addCoreFile, relativeWithDot, hash, resolveAlias, directoryToURL, removeExtension, addImports, baseHeaderBannerComment, writeFile, normalizeTemplate, useLogger, resolveSilgiPath, hasSilgiModule, genEnsureSafeVar, toArray, isDirectory } from 'silgi/kit';
5
+ import { isPresents, addTemplate, addCoreFile, relativeWithDot, hash, removeExtension, resolveAlias, directoryToURL, addImports, baseHeaderBannerComment, writeFile, normalizeTemplate, useLogger, resolveSilgiPath, hasSilgiModule, genEnsureSafeVar, toArray, isDirectory } from 'silgi/kit';
6
6
  import { runtimeDir } from 'silgi/runtime/meta';
7
7
  import { scanExports, createUnimport, toExports } from 'unimport';
8
8
  import * as p from '@clack/prompts';
@@ -14,7 +14,7 @@ import { h as hasInstalledModule } from './compatibility.mjs';
14
14
  import { fileURLToPath } from 'node:url';
15
15
  import { defu } from 'defu';
16
16
  import { resolveModuleURL } from 'exsolve';
17
- import { isRelative, withTrailingSlash } from 'ufo';
17
+ import { withTrailingSlash, isRelative } from 'ufo';
18
18
  import { readFile, readdir } from 'node:fs/promises';
19
19
  import { globby } from 'globby';
20
20
  import ignore from 'ignore';
@@ -473,221 +473,6 @@ async function installModule(moduleToInstall, silgi = useSilgiCLI(), inlineOptio
473
473
  }
474
474
  }
475
475
 
476
- const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
477
- async function _resolveSilgiModule(silgiModule, silgi) {
478
- let resolvedModulePath;
479
- let buildTimeModuleMeta = {};
480
- const jiti = createJiti(silgi.options.rootDir, {
481
- alias: silgi.options.alias,
482
- fsCache: true,
483
- moduleCache: true
484
- });
485
- if (typeof silgiModule === "string") {
486
- silgiModule = resolveAlias(silgiModule, silgi.options.alias);
487
- if (isRelative(silgiModule)) {
488
- silgiModule = resolve(silgi.options.rootDir, silgiModule);
489
- }
490
- try {
491
- const src = resolveModuleURL(silgiModule, {
492
- from: silgi.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
493
- suffixes: ["silgi", "silgi/index", "module", "module/index", "", "index"],
494
- extensions: [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]
495
- // Maybe add https://github.com/unjs/exsolve/blob/dfff3e9bbc4a3a173a2d56b9b9ff731ab15598be/src/resolve.ts#L7
496
- // conditions: silgi.options.conditions,
497
- });
498
- resolvedModulePath = fileURLToPath(src);
499
- const resolvedSilgiModule = await jiti.import(src, { default: true });
500
- if (typeof resolvedSilgiModule !== "function") {
501
- throw new TypeError(`Nuxt module should be a function: ${silgiModule}.`);
502
- }
503
- silgiModule = await jiti.import(src, {
504
- default: true,
505
- conditions: silgi.options.conditions
506
- });
507
- const moduleMetadataPath = new URL("module.json", src);
508
- if (existsSync(moduleMetadataPath)) {
509
- buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
510
- } else {
511
- if (typeof silgiModule === "function") {
512
- const meta = await silgiModule.getMeta?.();
513
- const _exports = await scanExports(resolvedModulePath, true);
514
- buildTimeModuleMeta = {
515
- ...meta,
516
- exports: _exports.map(({ from, ...rest }) => rest)
517
- };
518
- }
519
- }
520
- } catch (error) {
521
- const code = error.code;
522
- if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
523
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
524
- }
525
- if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
526
- const module = MissingModuleMatcher.exec(error.message)?.[1];
527
- if (module && !module.includes(silgiModule)) {
528
- throw new TypeError(`Error while importing module \`${silgiModule}\`: ${error}`);
529
- }
530
- }
531
- }
532
- }
533
- if (!buildTimeModuleMeta) {
534
- throw new Error(`Module ${silgiModule} is not a valid Silgi module`);
535
- }
536
- if (typeof silgiModule === "function") {
537
- if (!buildTimeModuleMeta.configKey) {
538
- const meta = await silgiModule.getMeta?.();
539
- buildTimeModuleMeta = {
540
- ...meta,
541
- exports: []
542
- };
543
- }
544
- if (silgi.scanModules.some((m) => m.meta?.configKey === buildTimeModuleMeta.configKey)) {
545
- throw new Error(`Module with key \`${buildTimeModuleMeta.configKey}\` already exists`);
546
- }
547
- const options = await silgiModule.getOptions?.() || {};
548
- if (options) {
549
- silgi.options._c12.config[buildTimeModuleMeta.configKey] = defu(
550
- silgi.options._c12.config[buildTimeModuleMeta.configKey] || {},
551
- options || {}
552
- );
553
- } else {
554
- throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
555
- }
556
- silgi.scanModules.push({
557
- meta: buildTimeModuleMeta,
558
- entryPath: resolvedModulePath || void 0,
559
- installed: false,
560
- options,
561
- module: silgiModule
562
- });
563
- }
564
- }
565
- async function scanModules$1(silgi) {
566
- const _modules = [
567
- ...silgi.options._modules,
568
- ...silgi.options.modules
569
- ];
570
- for await (const mod of _modules) {
571
- await _resolveSilgiModule(mod, silgi);
572
- }
573
- const moduleMap = new Map(
574
- silgi.scanModules.map((m) => [m.meta?.configKey, m])
575
- );
576
- const graphData = createDependencyGraph(silgi.scanModules);
577
- const sortedKeys = topologicalSort(graphData);
578
- const modules = sortedKeys.map((key) => moduleMap.get(key)).filter((module) => Boolean(module));
579
- silgi.scanModules = modules;
580
- }
581
- function createDependencyGraph(modules) {
582
- const graph = /* @__PURE__ */ new Map();
583
- const inDegree = /* @__PURE__ */ new Map();
584
- modules.forEach((module) => {
585
- const key = module.meta?.configKey;
586
- if (key) {
587
- graph.set(key, /* @__PURE__ */ new Set());
588
- inDegree.set(key, 0);
589
- }
590
- });
591
- modules.forEach((module) => {
592
- const key = module.meta?.configKey;
593
- if (!key) {
594
- return;
595
- }
596
- const requiredDeps = module.meta?.requiredDependencies || [];
597
- const beforeDeps = module.meta?.beforeDependencies || [];
598
- const afterDeps = module.meta?.afterDependencies || [];
599
- const processedDeps = /* @__PURE__ */ new Set();
600
- requiredDeps.forEach((dep) => {
601
- if (!graph.has(dep)) {
602
- throw new Error(`Required dependency "${dep}" for module "${key}" is missing`);
603
- }
604
- graph.get(dep)?.add(key);
605
- inDegree.set(key, (inDegree.get(key) || 0) + 1);
606
- processedDeps.add(dep);
607
- });
608
- beforeDeps.forEach((dep) => {
609
- if (!graph.has(dep)) {
610
- return;
611
- }
612
- graph.get(key)?.add(dep);
613
- inDegree.set(dep, (inDegree.get(dep) || 0) + 1);
614
- });
615
- afterDeps.forEach((dep) => {
616
- if (processedDeps.has(dep)) {
617
- return;
618
- }
619
- if (!graph.has(dep)) {
620
- return;
621
- }
622
- graph.get(dep)?.add(key);
623
- inDegree.set(key, (inDegree.get(key) || 0) + 1);
624
- });
625
- });
626
- return { graph, inDegree };
627
- }
628
- function findCyclicDependencies(graph) {
629
- const visited = /* @__PURE__ */ new Set();
630
- const recursionStack = /* @__PURE__ */ new Set();
631
- const cycles = [];
632
- function dfs(node, path = []) {
633
- visited.add(node);
634
- recursionStack.add(node);
635
- path.push(node);
636
- for (const neighbor of graph.get(node) || []) {
637
- if (recursionStack.has(neighbor)) {
638
- const cycleStart = path.indexOf(neighbor);
639
- if (cycleStart !== -1) {
640
- cycles.push([...path.slice(cycleStart), neighbor]);
641
- }
642
- } else if (!visited.has(neighbor)) {
643
- dfs(neighbor, [...path]);
644
- }
645
- }
646
- recursionStack.delete(node);
647
- path.pop();
648
- }
649
- for (const node of graph.keys()) {
650
- if (!visited.has(node)) {
651
- dfs(node, []);
652
- }
653
- }
654
- return cycles;
655
- }
656
- function topologicalSort(graphData) {
657
- const { graph, inDegree } = graphData;
658
- const order = [];
659
- const queue = [];
660
- for (const [node, degree] of inDegree.entries()) {
661
- if (degree === 0) {
662
- queue.push(node);
663
- }
664
- }
665
- while (queue.length > 0) {
666
- const node = queue.shift();
667
- order.push(node);
668
- const neighbors = Array.from(graph.get(node) || []);
669
- for (const neighbor of neighbors) {
670
- const newDegree = (inDegree.get(neighbor) || 0) - 1;
671
- inDegree.set(neighbor, newDegree);
672
- if (newDegree === 0) {
673
- queue.push(neighbor);
674
- }
675
- }
676
- }
677
- if (order.length !== graph.size) {
678
- const cycles = findCyclicDependencies(graph);
679
- if (cycles.length > 0) {
680
- const cycleStr = cycles.map((cycle) => ` ${cycle.join(" -> ")}`).join("\n");
681
- throw new Error(`Circular dependencies detected:
682
- ${cycleStr}`);
683
- } else {
684
- const unresolvedModules = Array.from(graph.keys()).filter((key) => !order.includes(key));
685
- throw new Error(`Unable to resolve dependencies for modules: ${unresolvedModules.join(", ")}`);
686
- }
687
- }
688
- return order;
689
- }
690
-
691
476
  function resolveIgnorePatterns(silgi, relativePath) {
692
477
  if (!silgi) {
693
478
  return [];
@@ -867,10 +652,10 @@ async function verifyDirectoryCaseSensitivity(directoryPath, rootDirectory) {
867
652
  } catch {
868
653
  }
869
654
  }
870
- async function scanExportFile(silgiInstance) {
655
+ async function scanSilgiExports(path, silgiInstance = useSilgiCLI()) {
871
656
  const processedFilePaths = /* @__PURE__ */ new Set();
872
657
  const alreadyScannedPaths = [];
873
- const serverDirectory = silgiInstance.options.serverDir;
658
+ const serverDirectory = path || silgiInstance.options.serverDir;
874
659
  if (!serverDirectory) {
875
660
  consola.warn("No server directory specified for scanning");
876
661
  return;
@@ -888,7 +673,7 @@ async function scanExportFile(silgiInstance) {
888
673
  }
889
674
  for (const relativeFilePath of matchedFiles.sort()) {
890
675
  const absoluteFilePath = resolve(silgiInstance.options.rootDir, relativeFilePath);
891
- if (alreadyScannedPaths.find((path) => absoluteFilePath.startsWith(withTrailingSlash(path))) || isIgnored(absoluteFilePath, silgiInstance) || processedFilePaths.has(absoluteFilePath)) {
676
+ if (alreadyScannedPaths.find((path2) => absoluteFilePath.startsWith(withTrailingSlash(path2))) || isIgnored(absoluteFilePath, silgiInstance) || processedFilePaths.has(absoluteFilePath)) {
892
677
  continue;
893
678
  }
894
679
  processedFilePaths.add(absoluteFilePath);
@@ -923,6 +708,222 @@ async function scanExportFile(silgiInstance) {
923
708
  }
924
709
  }
925
710
 
711
+ const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
712
+ async function _resolveSilgiModule(silgiModule, silgi) {
713
+ let resolvedModulePath;
714
+ let buildTimeModuleMeta = {};
715
+ const jiti = createJiti(silgi.options.rootDir, {
716
+ alias: silgi.options.alias,
717
+ fsCache: true,
718
+ moduleCache: true
719
+ });
720
+ if (typeof silgiModule === "string") {
721
+ silgiModule = resolveAlias(silgiModule, silgi.options.alias);
722
+ if (isRelative(silgiModule)) {
723
+ silgiModule = resolve(silgi.options.rootDir, silgiModule);
724
+ }
725
+ try {
726
+ const src = resolveModuleURL(silgiModule, {
727
+ from: silgi.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
728
+ suffixes: ["silgi", "silgi/index", "module", "module/index", "", "index"],
729
+ extensions: [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]
730
+ // Maybe add https://github.com/unjs/exsolve/blob/dfff3e9bbc4a3a173a2d56b9b9ff731ab15598be/src/resolve.ts#L7
731
+ // conditions: silgi.options.conditions,
732
+ });
733
+ resolvedModulePath = fileURLToPath(src);
734
+ const resolvedSilgiModule = await jiti.import(src, { default: true });
735
+ if (typeof resolvedSilgiModule !== "function") {
736
+ throw new TypeError(`Nuxt module should be a function: ${silgiModule}.`);
737
+ }
738
+ silgiModule = await jiti.import(src, {
739
+ default: true,
740
+ conditions: silgi.options.conditions
741
+ });
742
+ const moduleMetadataPath = new URL("module.json", src);
743
+ scanSilgiExports(join(src, "runtime"));
744
+ if (existsSync(moduleMetadataPath)) {
745
+ buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
746
+ } else {
747
+ if (typeof silgiModule === "function") {
748
+ const meta = await silgiModule.getMeta?.();
749
+ const _exports = await scanExports(resolvedModulePath, true);
750
+ buildTimeModuleMeta = {
751
+ ...meta,
752
+ exports: _exports.map(({ from, ...rest }) => rest)
753
+ };
754
+ }
755
+ }
756
+ } catch (error) {
757
+ const code = error.code;
758
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
759
+ throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
760
+ }
761
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
762
+ const module = MissingModuleMatcher.exec(error.message)?.[1];
763
+ if (module && !module.includes(silgiModule)) {
764
+ throw new TypeError(`Error while importing module \`${silgiModule}\`: ${error}`);
765
+ }
766
+ }
767
+ }
768
+ }
769
+ if (!buildTimeModuleMeta) {
770
+ throw new Error(`Module ${silgiModule} is not a valid Silgi module`);
771
+ }
772
+ if (typeof silgiModule === "function") {
773
+ if (!buildTimeModuleMeta.configKey) {
774
+ const meta = await silgiModule.getMeta?.();
775
+ buildTimeModuleMeta = {
776
+ ...meta,
777
+ exports: []
778
+ };
779
+ }
780
+ if (silgi.scanModules.some((m) => m.meta?.configKey === buildTimeModuleMeta.configKey)) {
781
+ throw new Error(`Module with key \`${buildTimeModuleMeta.configKey}\` already exists`);
782
+ }
783
+ const options = await silgiModule.getOptions?.() || {};
784
+ if (options) {
785
+ silgi.options._c12.config[buildTimeModuleMeta.configKey] = defu(
786
+ silgi.options._c12.config[buildTimeModuleMeta.configKey] || {},
787
+ options || {}
788
+ );
789
+ } else {
790
+ throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
791
+ }
792
+ silgi.scanModules.push({
793
+ meta: buildTimeModuleMeta,
794
+ entryPath: resolvedModulePath || void 0,
795
+ installed: false,
796
+ options,
797
+ module: silgiModule
798
+ });
799
+ }
800
+ }
801
+ async function scanModules$1(silgi) {
802
+ const _modules = [
803
+ ...silgi.options._modules,
804
+ ...silgi.options.modules
805
+ ];
806
+ for await (const mod of _modules) {
807
+ await _resolveSilgiModule(mod, silgi);
808
+ }
809
+ const moduleMap = new Map(
810
+ silgi.scanModules.map((m) => [m.meta?.configKey, m])
811
+ );
812
+ const graphData = createDependencyGraph(silgi.scanModules);
813
+ const sortedKeys = topologicalSort(graphData);
814
+ const modules = sortedKeys.map((key) => moduleMap.get(key)).filter((module) => Boolean(module));
815
+ silgi.scanModules = modules;
816
+ }
817
+ function createDependencyGraph(modules) {
818
+ const graph = /* @__PURE__ */ new Map();
819
+ const inDegree = /* @__PURE__ */ new Map();
820
+ modules.forEach((module) => {
821
+ const key = module.meta?.configKey;
822
+ if (key) {
823
+ graph.set(key, /* @__PURE__ */ new Set());
824
+ inDegree.set(key, 0);
825
+ }
826
+ });
827
+ modules.forEach((module) => {
828
+ const key = module.meta?.configKey;
829
+ if (!key) {
830
+ return;
831
+ }
832
+ const requiredDeps = module.meta?.requiredDependencies || [];
833
+ const beforeDeps = module.meta?.beforeDependencies || [];
834
+ const afterDeps = module.meta?.afterDependencies || [];
835
+ const processedDeps = /* @__PURE__ */ new Set();
836
+ requiredDeps.forEach((dep) => {
837
+ if (!graph.has(dep)) {
838
+ throw new Error(`Required dependency "${dep}" for module "${key}" is missing`);
839
+ }
840
+ graph.get(dep)?.add(key);
841
+ inDegree.set(key, (inDegree.get(key) || 0) + 1);
842
+ processedDeps.add(dep);
843
+ });
844
+ beforeDeps.forEach((dep) => {
845
+ if (!graph.has(dep)) {
846
+ return;
847
+ }
848
+ graph.get(key)?.add(dep);
849
+ inDegree.set(dep, (inDegree.get(dep) || 0) + 1);
850
+ });
851
+ afterDeps.forEach((dep) => {
852
+ if (processedDeps.has(dep)) {
853
+ return;
854
+ }
855
+ if (!graph.has(dep)) {
856
+ return;
857
+ }
858
+ graph.get(dep)?.add(key);
859
+ inDegree.set(key, (inDegree.get(key) || 0) + 1);
860
+ });
861
+ });
862
+ return { graph, inDegree };
863
+ }
864
+ function findCyclicDependencies(graph) {
865
+ const visited = /* @__PURE__ */ new Set();
866
+ const recursionStack = /* @__PURE__ */ new Set();
867
+ const cycles = [];
868
+ function dfs(node, path = []) {
869
+ visited.add(node);
870
+ recursionStack.add(node);
871
+ path.push(node);
872
+ for (const neighbor of graph.get(node) || []) {
873
+ if (recursionStack.has(neighbor)) {
874
+ const cycleStart = path.indexOf(neighbor);
875
+ if (cycleStart !== -1) {
876
+ cycles.push([...path.slice(cycleStart), neighbor]);
877
+ }
878
+ } else if (!visited.has(neighbor)) {
879
+ dfs(neighbor, [...path]);
880
+ }
881
+ }
882
+ recursionStack.delete(node);
883
+ path.pop();
884
+ }
885
+ for (const node of graph.keys()) {
886
+ if (!visited.has(node)) {
887
+ dfs(node, []);
888
+ }
889
+ }
890
+ return cycles;
891
+ }
892
+ function topologicalSort(graphData) {
893
+ const { graph, inDegree } = graphData;
894
+ const order = [];
895
+ const queue = [];
896
+ for (const [node, degree] of inDegree.entries()) {
897
+ if (degree === 0) {
898
+ queue.push(node);
899
+ }
900
+ }
901
+ while (queue.length > 0) {
902
+ const node = queue.shift();
903
+ order.push(node);
904
+ const neighbors = Array.from(graph.get(node) || []);
905
+ for (const neighbor of neighbors) {
906
+ const newDegree = (inDegree.get(neighbor) || 0) - 1;
907
+ inDegree.set(neighbor, newDegree);
908
+ if (newDegree === 0) {
909
+ queue.push(neighbor);
910
+ }
911
+ }
912
+ }
913
+ if (order.length !== graph.size) {
914
+ const cycles = findCyclicDependencies(graph);
915
+ if (cycles.length > 0) {
916
+ const cycleStr = cycles.map((cycle) => ` ${cycle.join(" -> ")}`).join("\n");
917
+ throw new Error(`Circular dependencies detected:
918
+ ${cycleStr}`);
919
+ } else {
920
+ const unresolvedModules = Array.from(graph.keys()).filter((key) => !order.includes(key));
921
+ throw new Error(`Unable to resolve dependencies for modules: ${unresolvedModules.join(", ")}`);
922
+ }
923
+ }
924
+ return order;
925
+ }
926
+
926
927
  async function readScanFile(silgi) {
927
928
  const path = resolve(silgi.options.silgi.serverDir, "scan.ts");
928
929
  const context = await promises.readFile(path, { encoding: "utf-8" });
@@ -1382,7 +1383,7 @@ async function createSilgiCLI(config = {}, opts = {}) {
1382
1383
  }
1383
1384
  await scanAndSyncOptions(silgi);
1384
1385
  await scanModules$1(silgi);
1385
- await scanExportFile(silgi);
1386
+ await scanSilgiExports();
1386
1387
  await installModules(silgi, true);
1387
1388
  useCLIRuntimeConfig(silgi);
1388
1389
  await writeScanFiles(silgi);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { defineCommand, runMain } from 'citty';
3
3
 
4
- const version = "0.34.4";
4
+ const version = "0.34.6";
5
5
  const packageJson = {
6
6
  version: version};
7
7
 
@@ -581,6 +581,7 @@ async function orchestrate(route, event) {
581
581
  cached = cacheData.cached;
582
582
  } else {
583
583
  silgiCtx.shared.$fetch = silgiFetch;
584
+ silgiCtx.shared.silgi = silgiCtx;
584
585
  result = await setup?.handler(
585
586
  {
586
587
  args: input,
@@ -898,6 +898,7 @@ interface SilgiRuntimeShareds extends SilgiRuntimeSharedsExtend {
898
898
  storage: <T extends StorageValue = StorageValue>(base: StorageConfig<T>['base']) => Storage<T>;
899
899
  runtimeConfig: SilgiRuntimeConfig;
900
900
  $fetch: typeof silgiFetch;
901
+ silgi: Silgi;
901
902
  }
902
903
  interface SilgiRuntimeSharedsExtend {
903
904
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "silgi",
3
3
  "type": "module",
4
- "version": "0.34.4",
4
+ "version": "0.34.6",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {