silgi 0.21.8 → 0.22.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.
@@ -1,4 +1,4 @@
1
- const version = "0.21.8";
1
+ const version = "0.22.1";
2
2
  const peerDependencies = {
3
3
  "@fastify/deepmerge": "^3.0.0",
4
4
  "@nuxt/kit": "^3.15.3",
@@ -1,15 +1,7 @@
1
- import { tryUseSilgiCLI, useSilgiCLI } from 'silgi/core';
2
1
  import satisfies from 'semver/functions/satisfies.js';
2
+ import { useSilgiCLI } from 'silgi/core';
3
3
  import { version } from 'silgi/meta';
4
4
 
5
- function hasError(type, silgi) {
6
- silgi = silgi ?? tryUseSilgiCLI() ?? void 0;
7
- if (silgi && silgi.errors.some((error) => error.type === type)) {
8
- return true;
9
- }
10
- return false;
11
- }
12
-
13
5
  const SEMANTIC_VERSION_RE = /-\d+\.[0-9a-f]+/;
14
6
  function normalizeSemanticVersion(version) {
15
7
  return version.replace(SEMANTIC_VERSION_RE, "");
@@ -35,4 +27,4 @@ function hasInstalledModule(moduleKey, silgi = useSilgiCLI()) {
35
27
  return find?.installed ?? false;
36
28
  }
37
29
 
38
- export { hasInstalledModule as a, checkSilgiCompatibility as c, hasError as h };
30
+ export { checkSilgiCompatibility as c, hasInstalledModule as h };
@@ -1,10 +1,10 @@
1
1
  import { defineCommand, runCommand } from 'citty';
2
2
  import { join, resolve, relative, dirname, basename, extname, isAbsolute } from 'pathe';
3
3
  import { peerDependencies, version } from 'silgi/meta';
4
- import { writeFile, relativeWithDot, hash, resolveAlias, directoryToURL, addTemplate, parseServices, normalizeTemplate, useLogger, initRuntimeConfig, resolveSilgiPath, isDirectory } from 'silgi/kit';
4
+ import { writeFile, relativeWithDot, hash, resolveAlias, directoryToURL, addTemplate, hasError, parseServices, normalizeTemplate, useLogger, initRuntimeConfig, resolveSilgiPath, isDirectory } from 'silgi/kit';
5
5
  import { existsSync, promises, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
6
6
  import { readdir, readFile } from 'node:fs/promises';
7
- import consola$1, { consola } from 'consola';
7
+ import consola, { consola as consola$1 } from 'consola';
8
8
  import { createHooks, createDebugger } from 'hookable';
9
9
  import { useSilgiCLI, silgiCLICtx } from 'silgi/core';
10
10
  import { runtimeDir } from 'silgi/runtime/meta';
@@ -15,7 +15,7 @@ import * as p from '@clack/prompts';
15
15
  import * as dotenv from 'dotenv';
16
16
  import { resolveModuleExportNames, findTypeExports, findExports, resolvePath, parseNodeModulePath, lookupNodeModuleSubpath } from 'mlly';
17
17
  import { createJiti } from 'dev-jiti';
18
- import { a as hasInstalledModule, h as hasError } from './compatibility.mjs';
18
+ import { h as hasInstalledModule } from './compatibility.mjs';
19
19
  import { fileURLToPath } from 'node:url';
20
20
  import defu, { defu as defu$1 } from 'defu';
21
21
  import { resolveModuleURL } from 'exsolve';
@@ -435,6 +435,9 @@ async function registerModuleExportScan(silgi) {
435
435
  silgi.hook("prepare:schema.ts", async (options) => {
436
436
  for (const module of silgi.scanModules) {
437
437
  const moduleReExports = [];
438
+ if (!module.entryPath) {
439
+ continue;
440
+ }
438
441
  const moduleTypes = await promises.readFile(module.entryPath.replace(/\.mjs$/, "Types.d.ts"), "utf8").catch(() => "");
439
442
  const normalisedModuleTypes = moduleTypes.replace(/export\s*\{.*?\}/gs, (match) => match.replace(/\b(type|interface)\b/g, ""));
440
443
  for (const e of findTypeExports(normalisedModuleTypes)) {
@@ -574,10 +577,10 @@ async function installModules(silgi, prepare = false) {
574
577
  silgi.logger.info(`Module ${module.meta.configKey} installed`);
575
578
  }
576
579
  try {
577
- const silgiModule = await jiti.import(module.entryPath, {
580
+ const silgiModule = module.entryPath !== void 0 ? await jiti.import(module.entryPath, {
578
581
  default: true,
579
582
  conditions: silgi.options.conditions
580
- });
583
+ }) : module.module;
581
584
  if (silgiModule.name !== "silgiNormalizedModule") {
582
585
  silgi.scanModules = silgi.scanModules.filter((m) => m.entryPath !== module.entryPath);
583
586
  continue;
@@ -612,7 +615,9 @@ async function _resolveSilgiModule(silgiModule, silgi) {
612
615
  let resolvedModulePath;
613
616
  let buildTimeModuleMeta = {};
614
617
  const jiti = createJiti(silgi.options.rootDir, {
615
- alias: silgi.options.alias
618
+ alias: silgi.options.alias,
619
+ fsCache: true,
620
+ moduleCache: true
616
621
  });
617
622
  if (typeof silgiModule === "string") {
618
623
  silgiModule = resolveAlias(silgiModule, silgi.options.alias);
@@ -666,6 +671,13 @@ async function _resolveSilgiModule(silgiModule, silgi) {
666
671
  throw new Error(`Module ${silgiModule} is not a valid Silgi module`);
667
672
  }
668
673
  if (typeof silgiModule === "function") {
674
+ if (!buildTimeModuleMeta.configKey) {
675
+ const meta = await silgiModule.getMeta?.();
676
+ buildTimeModuleMeta = {
677
+ ...meta,
678
+ exports: []
679
+ };
680
+ }
669
681
  if (silgi.scanModules.some((m) => m.meta?.configKey === buildTimeModuleMeta.configKey)) {
670
682
  throw new Error(`Module with key \`${buildTimeModuleMeta.configKey}\` already exists`);
671
683
  }
@@ -680,9 +692,10 @@ async function _resolveSilgiModule(silgiModule, silgi) {
680
692
  }
681
693
  silgi.scanModules.push({
682
694
  meta: buildTimeModuleMeta,
683
- entryPath: resolvedModulePath || "",
695
+ entryPath: resolvedModulePath || void 0,
684
696
  installed: false,
685
- options
697
+ options,
698
+ module: silgiModule
686
699
  });
687
700
  }
688
701
  }
@@ -855,252 +868,6 @@ async function commands(silgi) {
855
868
  });
856
869
  }
857
870
 
858
- function buildUriMap(silgi, currentPath = []) {
859
- const uriMap = /* @__PURE__ */ new Map();
860
- function traverse(node, path = []) {
861
- if (!node || typeof node !== "object")
862
- return;
863
- if (path.length === 4) {
864
- const basePath = path.join("/");
865
- let pathString = "";
866
- if (node.pathParams) {
867
- let paths = null;
868
- if (node.pathParams?._def?.typeName !== void 0) {
869
- try {
870
- const shape = node.pathParams?.shape;
871
- paths = shape ? Object.keys(shape) : null;
872
- } catch {
873
- paths = null;
874
- }
875
- }
876
- if (paths?.length) {
877
- pathString = paths.map((p) => `:${p}`).join("/");
878
- }
879
- }
880
- uriMap.set(basePath, pathString);
881
- return;
882
- }
883
- for (const key in node) {
884
- if (!["_type", "fields"].includes(key)) {
885
- traverse(node[key], [...path, key]);
886
- }
887
- }
888
- }
889
- traverse(silgi.schemas, currentPath);
890
- silgi.uris = defu$1(silgi.uris, Object.fromEntries(uriMap));
891
- return uriMap;
892
- }
893
-
894
- async function readScanFile(silgi) {
895
- const path = resolve(silgi.options.silgi.serverDir, "scan.ts");
896
- const context = await promises.readFile(path, { encoding: "utf-8" });
897
- silgi.unimport = createUnimport(silgi.options.imports || {});
898
- await silgi.unimport.init();
899
- const injectedResult = await silgi.unimport.injectImports(context, path);
900
- if (!injectedResult) {
901
- throw new Error("Failed to inject imports");
902
- }
903
- const jiti = createJiti(silgi.options.rootDir, {
904
- fsCache: true,
905
- moduleCache: false,
906
- debug: silgi.options.debug,
907
- alias: silgi.options.alias
908
- });
909
- try {
910
- if (silgi.options.commandType === "prepare") {
911
- globalThis.$silgiSharedRuntimeConfig = silgi.options.runtimeConfig;
912
- injectedResult.code = `globalThis.$silgiSharedRuntimeConfig = ${JSON.stringify(silgi.options.runtimeConfig)};
913
- ${injectedResult.code}`;
914
- injectedResult.code = injectedResult.code.replace(/runtimeConfig: \{\}/, `runtimeConfig: ${JSON.stringify(silgi.options.runtimeConfig)}`);
915
- }
916
- const scanFile = await jiti.evalModule(
917
- injectedResult.code,
918
- {
919
- filename: path,
920
- async: true,
921
- conditions: silgi.options.conditions
922
- },
923
- async (data, name) => {
924
- return (await silgi.unimport.injectImports(data, name)).code;
925
- }
926
- );
927
- silgi.uris = defu$1(silgi.uris, scanFile.uris) || {};
928
- silgi.schemas = defu$1(scanFile.schemas, scanFile.uris) || {};
929
- silgi.services = defu$1(scanFile.services, scanFile.uris) || {};
930
- silgi.shareds = defu$1(scanFile.shareds, scanFile.shareds) || {};
931
- silgi.modulesURIs = defu$1(scanFile.modulesURIs, scanFile.modulesURIs) || {};
932
- return {
933
- context,
934
- object: {
935
- schemas: scanFile.schemas,
936
- uris: scanFile.uris,
937
- services: scanFile.services,
938
- shareds: scanFile.shareds,
939
- modulesURIs: scanFile.modulesURIs
940
- },
941
- path
942
- };
943
- } catch (error) {
944
- if (silgi.options.debug) {
945
- console.error("Failed to read scan.ts file:", error);
946
- } else {
947
- if (error instanceof Error) {
948
- consola.withTag("silgi").info(error.message);
949
- }
950
- }
951
- return {
952
- context,
953
- object: {
954
- schemas: {},
955
- uris: {},
956
- services: {},
957
- shareds: {},
958
- modulesURIs: {}
959
- },
960
- path
961
- };
962
- }
963
- }
964
-
965
- async function prepareServerFiles(silgi) {
966
- const importItems = {
967
- "silgi": {
968
- import: [
969
- { name: "createSilgi", key: "createSilgi" },
970
- { name: "createShared", key: "createShared" }
971
- ],
972
- from: "silgi"
973
- },
974
- "silgi/types": {
975
- import: [
976
- { name: "SilgiRuntimeOptions", type: true, key: "SilgiRuntimeOptions" },
977
- { name: "FrameworkContext", type: true, key: "FrameworkContext" }
978
- ],
979
- from: "silgi/types"
980
- },
981
- "#silgi/vfs": {
982
- import: [],
983
- from: "./vfs"
984
- },
985
- "configs.ts": {
986
- import: [
987
- {
988
- name: "cliConfigs",
989
- type: false,
990
- key: "cliConfigs"
991
- }
992
- ],
993
- from: "./configs.ts"
994
- }
995
- };
996
- const scanned = {
997
- uris: {},
998
- services: [],
999
- shareds: [
1000
- `createShared({
1001
- modulesURIs,
1002
- })`
1003
- ],
1004
- schemas: [],
1005
- modulesURIs: {},
1006
- customImports: [],
1007
- importItems
1008
- };
1009
- if (silgi.uris) {
1010
- defu$1(scanned.uris, silgi.uris);
1011
- }
1012
- if (silgi.modulesURIs) {
1013
- defu$1(scanned.modulesURIs, silgi.modulesURIs);
1014
- }
1015
- await silgi.callHook("prepare:scan.ts", scanned);
1016
- if (importItems["#silgi/vfs"].import.length === 0) {
1017
- delete importItems["#silgi/vfs"];
1018
- }
1019
- if (scanned.services.length > 0) {
1020
- importItems.silgi.import.push({ name: "mergeServices", key: "mergeServices" });
1021
- }
1022
- if (scanned.shareds.length > 0) {
1023
- importItems.silgi.import.push({ name: "mergeShared", key: "mergeShared" });
1024
- }
1025
- if (scanned.schemas.length > 0) {
1026
- importItems.silgi.import.push({ name: "mergeSchemas", key: "mergeSchemas" });
1027
- }
1028
- for (const key in importItems) {
1029
- importItems[key].import = deduplicateImportsByKey(importItems[key].import);
1030
- }
1031
- const importsContent = [
1032
- ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
1033
- if (silgi.options.typescript.removeFileExtension) {
1034
- from = from.replace(/\.(js|ts|mjs|cjs|jsx|tsx)$/, "");
1035
- }
1036
- return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${from}'`;
1037
- }),
1038
- "",
1039
- ...scanned.customImports,
1040
- ""
1041
- ];
1042
- const importData = [
1043
- `export const uris = ${JSON.stringify(scanned.uris, null, 2)}`,
1044
- "",
1045
- `export const modulesURIs = ${JSON.stringify(scanned.modulesURIs, null, 2)}`,
1046
- "",
1047
- scanned.schemas.length > 0 ? "export const schemas = mergeSchemas([" : "export const schemas = {",
1048
- ...scanned.schemas.map((name) => {
1049
- return ` ${name},`;
1050
- }),
1051
- scanned.schemas.length > 0 ? "])" : "}",
1052
- "",
1053
- scanned.services.length > 0 ? "export const services = mergeServices([" : "export const services = {",
1054
- ...scanned.services.map((name) => {
1055
- return ` ${name},`;
1056
- }),
1057
- scanned.services.length > 0 ? "])" : "}",
1058
- "",
1059
- scanned.shareds.length > 0 ? "export const shareds = mergeShared([" : "export const shareds = {",
1060
- ...scanned.shareds.map((name) => {
1061
- return ` ${name},`;
1062
- }),
1063
- scanned.shareds.length > 0 ? "])" : "}",
1064
- ""
1065
- ];
1066
- await silgi.callHook("after:prepare:scan.ts", importData);
1067
- importData.unshift(...importsContent);
1068
- return importData;
1069
- }
1070
- function deduplicateImportsByKey(imports) {
1071
- const seenKeys = /* @__PURE__ */ new Map();
1072
- return imports.filter((item) => {
1073
- if (seenKeys.has(item.key)) {
1074
- return false;
1075
- }
1076
- seenKeys.set(item.key, true);
1077
- return true;
1078
- });
1079
- }
1080
-
1081
- async function writeScanFiles(silgi) {
1082
- const data = await prepareServerFiles(silgi);
1083
- if (!silgi.errors.length) {
1084
- await writeFile(
1085
- resolve(silgi.options.silgi.serverDir, "scan.ts"),
1086
- data.join("\n")
1087
- );
1088
- }
1089
- await readScanFile(silgi);
1090
- buildUriMap(silgi);
1091
- parseServices(silgi);
1092
- silgi.hook("prepare:scan.ts", (file) => {
1093
- file.uris = {
1094
- ...file.uris,
1095
- ...silgi.uris
1096
- };
1097
- file.modulesURIs = {
1098
- ...file.modulesURIs,
1099
- ...silgi.modulesURIs
1100
- };
1101
- });
1102
- }
1103
-
1104
871
  function resolveIgnorePatterns(silgi, relativePath) {
1105
872
  if (!silgi) {
1106
873
  return [];
@@ -1172,7 +939,7 @@ class SchemaParser {
1172
939
  type: "Parser",
1173
940
  path
1174
941
  });
1175
- consola$1.warn("This file has a problem:", path);
942
+ consola.warn("This file has a problem:", path);
1176
943
  }
1177
944
  const variableDeclarations = ast.program.body.filter((i) => i.type === "ExportNamedDeclaration").filter((i) => i.declaration?.type === "VariableDeclaration");
1178
945
  return variableDeclarations;
@@ -1184,7 +951,7 @@ class SchemaParser {
1184
951
  type: "Parser",
1185
952
  path
1186
953
  });
1187
- consola$1.warn("This file has a problem:", path);
954
+ consola.warn("This file has a problem:", path);
1188
955
  }
1189
956
  const interfaceDeclarations = ast.program.body.filter((i) => i.type === "ExportNamedDeclaration").filter((i) => i.declaration?.type === "TSInterfaceDeclaration");
1190
957
  return interfaceDeclarations;
@@ -1293,7 +1060,7 @@ class SchemaParser {
1293
1060
  // }
1294
1061
  }
1295
1062
 
1296
- async function scanFiles$1(silgi, watchFiles) {
1063
+ async function scanExportFile(silgi) {
1297
1064
  const filePaths = /* @__PURE__ */ new Set();
1298
1065
  const scannedPaths = [];
1299
1066
  const dir = silgi.options.serverDir;
@@ -1307,7 +1074,7 @@ async function scanFiles$1(silgi, watchFiles) {
1307
1074
  if (caseCorrected) {
1308
1075
  const original = relative(silgi.options.serverDir, dir);
1309
1076
  const corrected = relative(silgi.options.serverDir, join(dirname(dir), caseCorrected));
1310
- consola.warn(`Components not scanned from \`~/${corrected}\`. Did you mean to name the directory \`~/${original}\` instead?`);
1077
+ consola$1.warn(`Components not scanned from \`~/${corrected}\`. Did you mean to name the directory \`~/${original}\` instead?`);
1311
1078
  }
1312
1079
  }
1313
1080
  }
@@ -1334,7 +1101,6 @@ async function scanFiles$1(silgi, watchFiles) {
1334
1101
  const schemaTS = [];
1335
1102
  if (createServices.length > 0) {
1336
1103
  scanTS.push(...createServices.map(({ exportName, path }) => {
1337
- silgi.options.devServer.watch.push(path);
1338
1104
  const randomString = hash(basename(path) + exportName);
1339
1105
  const _name = `_v${randomString}`;
1340
1106
  return { exportName, path, _name, type: "service" };
@@ -1346,7 +1112,6 @@ async function scanFiles$1(silgi, watchFiles) {
1346
1112
  }
1347
1113
  if (createSchemas.length > 0) {
1348
1114
  scanTS.push(...createSchemas.map(({ exportName, path }) => {
1349
- silgi.options.devServer.watch.push(path);
1350
1115
  const randomString = hash(basename(path) + exportName);
1351
1116
  const _name = `_v${randomString}`;
1352
1117
  return { exportName, path, _name, type: "schema" };
@@ -1358,7 +1123,6 @@ async function scanFiles$1(silgi, watchFiles) {
1358
1123
  }
1359
1124
  if (createShareds.length > 0) {
1360
1125
  scanTS.push(...createShareds.map(({ exportName, path }) => {
1361
- silgi.options.devServer.watch.push(path);
1362
1126
  const randomString = hash(basename(path) + exportName);
1363
1127
  const _name = `_v${randomString}`;
1364
1128
  return { exportName, path, _name, type: "shared" };
@@ -1370,7 +1134,6 @@ async function scanFiles$1(silgi, watchFiles) {
1370
1134
  }
1371
1135
  if (sharedsTypes.length > 0) {
1372
1136
  schemaTS.push(...sharedsTypes.map(({ exportName, path }) => {
1373
- silgi.options.devServer.watch.push(path);
1374
1137
  const randomString = hash(basename(path) + exportName);
1375
1138
  const _name = `_v${randomString}`;
1376
1139
  return { exportName, path, _name, type: "shared" };
@@ -1382,7 +1145,6 @@ async function scanFiles$1(silgi, watchFiles) {
1382
1145
  }
1383
1146
  if (contextTypes.length > 0) {
1384
1147
  schemaTS.push(...contextTypes.map(({ exportName, path }) => {
1385
- silgi.options.devServer.watch.push(path);
1386
1148
  const randomString = hash(basename(path) + exportName);
1387
1149
  const _name = `_v${randomString}`;
1388
1150
  return { exportName, path, _name, type: "context" };
@@ -1390,6 +1152,9 @@ async function scanFiles$1(silgi, watchFiles) {
1390
1152
  }
1391
1153
  silgi.hook("prepare:scan.ts", (options) => {
1392
1154
  for (const { exportName, path, _name, type } of scanTS) {
1155
+ if (!path.includes("vfs")) {
1156
+ silgi.options.devServer.watch.push(path);
1157
+ }
1393
1158
  if (type === "service") {
1394
1159
  options.services.push(_name);
1395
1160
  }
@@ -1411,6 +1176,9 @@ async function scanFiles$1(silgi, watchFiles) {
1411
1176
  });
1412
1177
  silgi.hook("prepare:schema.ts", (options) => {
1413
1178
  for (const { exportName, path, _name, type } of schemaTS) {
1179
+ if (!path.includes("vfs")) {
1180
+ silgi.options.devServer.watch.push(path);
1181
+ }
1414
1182
  if (type === "shared") {
1415
1183
  options.shareds.push({
1416
1184
  key: _name,
@@ -1437,6 +1205,252 @@ async function scanFiles$1(silgi, watchFiles) {
1437
1205
  }
1438
1206
  }
1439
1207
 
1208
+ function buildUriMap(silgi, currentPath = []) {
1209
+ const uriMap = /* @__PURE__ */ new Map();
1210
+ function traverse(node, path = []) {
1211
+ if (!node || typeof node !== "object")
1212
+ return;
1213
+ if (path.length === 4) {
1214
+ const basePath = path.join("/");
1215
+ let pathString = "";
1216
+ if (node.pathParams) {
1217
+ let paths = null;
1218
+ if (node.pathParams?._def?.typeName !== void 0) {
1219
+ try {
1220
+ const shape = node.pathParams?.shape;
1221
+ paths = shape ? Object.keys(shape) : null;
1222
+ } catch {
1223
+ paths = null;
1224
+ }
1225
+ }
1226
+ if (paths?.length) {
1227
+ pathString = paths.map((p) => `:${p}`).join("/");
1228
+ }
1229
+ }
1230
+ uriMap.set(basePath, pathString);
1231
+ return;
1232
+ }
1233
+ for (const key in node) {
1234
+ if (!["_type", "fields"].includes(key)) {
1235
+ traverse(node[key], [...path, key]);
1236
+ }
1237
+ }
1238
+ }
1239
+ traverse(silgi.schemas, currentPath);
1240
+ silgi.uris = defu$1(silgi.uris, Object.fromEntries(uriMap));
1241
+ return uriMap;
1242
+ }
1243
+
1244
+ async function readScanFile(silgi) {
1245
+ const path = resolve(silgi.options.silgi.serverDir, "scan.ts");
1246
+ const context = await promises.readFile(path, { encoding: "utf-8" });
1247
+ silgi.unimport = createUnimport(silgi.options.imports || {});
1248
+ await silgi.unimport.init();
1249
+ const injectedResult = await silgi.unimport.injectImports(context, path);
1250
+ if (!injectedResult) {
1251
+ throw new Error("Failed to inject imports");
1252
+ }
1253
+ const jiti = createJiti(silgi.options.rootDir, {
1254
+ fsCache: true,
1255
+ moduleCache: false,
1256
+ debug: silgi.options.debug,
1257
+ alias: silgi.options.alias
1258
+ });
1259
+ try {
1260
+ if (silgi.options.commandType === "prepare") {
1261
+ globalThis.$silgiSharedRuntimeConfig = silgi.options.runtimeConfig;
1262
+ injectedResult.code = `globalThis.$silgiSharedRuntimeConfig = ${JSON.stringify(silgi.options.runtimeConfig)};
1263
+ ${injectedResult.code}`;
1264
+ injectedResult.code = injectedResult.code.replace(/runtimeConfig: \{\}/, `runtimeConfig: ${JSON.stringify(silgi.options.runtimeConfig)}`);
1265
+ }
1266
+ const scanFile = await jiti.evalModule(
1267
+ injectedResult.code,
1268
+ {
1269
+ filename: path,
1270
+ async: true,
1271
+ conditions: silgi.options.conditions
1272
+ },
1273
+ async (data, name) => {
1274
+ return (await silgi.unimport.injectImports(data, name)).code;
1275
+ }
1276
+ );
1277
+ silgi.uris = defu$1(silgi.uris, scanFile.uris) || {};
1278
+ silgi.schemas = defu$1(scanFile.schemas, scanFile.uris) || {};
1279
+ silgi.services = defu$1(scanFile.services, scanFile.uris) || {};
1280
+ silgi.shareds = defu$1(scanFile.shareds, scanFile.shareds) || {};
1281
+ silgi.modulesURIs = defu$1(scanFile.modulesURIs, scanFile.modulesURIs) || {};
1282
+ return {
1283
+ context,
1284
+ object: {
1285
+ schemas: scanFile.schemas,
1286
+ uris: scanFile.uris,
1287
+ services: scanFile.services,
1288
+ shareds: scanFile.shareds,
1289
+ modulesURIs: scanFile.modulesURIs
1290
+ },
1291
+ path
1292
+ };
1293
+ } catch (error) {
1294
+ if (silgi.options.debug) {
1295
+ console.error("Failed to read scan.ts file:", error);
1296
+ } else {
1297
+ if (error instanceof Error) {
1298
+ consola$1.withTag("silgi").info(error.message);
1299
+ }
1300
+ }
1301
+ return {
1302
+ context,
1303
+ object: {
1304
+ schemas: {},
1305
+ uris: {},
1306
+ services: {},
1307
+ shareds: {},
1308
+ modulesURIs: {}
1309
+ },
1310
+ path
1311
+ };
1312
+ }
1313
+ }
1314
+
1315
+ async function prepareServerFiles(silgi) {
1316
+ const importItems = {
1317
+ "silgi": {
1318
+ import: [
1319
+ { name: "createSilgi", key: "createSilgi" },
1320
+ { name: "createShared", key: "createShared" }
1321
+ ],
1322
+ from: "silgi"
1323
+ },
1324
+ "silgi/types": {
1325
+ import: [
1326
+ { name: "SilgiRuntimeOptions", type: true, key: "SilgiRuntimeOptions" },
1327
+ { name: "FrameworkContext", type: true, key: "FrameworkContext" }
1328
+ ],
1329
+ from: "silgi/types"
1330
+ },
1331
+ "#silgi/vfs": {
1332
+ import: [],
1333
+ from: "./vfs"
1334
+ },
1335
+ "configs.ts": {
1336
+ import: [
1337
+ {
1338
+ name: "cliConfigs",
1339
+ type: false,
1340
+ key: "cliConfigs"
1341
+ }
1342
+ ],
1343
+ from: "./configs.ts"
1344
+ }
1345
+ };
1346
+ const scanned = {
1347
+ uris: {},
1348
+ services: [],
1349
+ shareds: [
1350
+ `createShared({
1351
+ modulesURIs,
1352
+ })`
1353
+ ],
1354
+ schemas: [],
1355
+ modulesURIs: {},
1356
+ customImports: [],
1357
+ importItems
1358
+ };
1359
+ if (silgi.uris) {
1360
+ defu$1(scanned.uris, silgi.uris);
1361
+ }
1362
+ if (silgi.modulesURIs) {
1363
+ defu$1(scanned.modulesURIs, silgi.modulesURIs);
1364
+ }
1365
+ await silgi.callHook("prepare:scan.ts", scanned);
1366
+ if (importItems["#silgi/vfs"].import.length === 0) {
1367
+ delete importItems["#silgi/vfs"];
1368
+ }
1369
+ if (scanned.services.length > 0) {
1370
+ importItems.silgi.import.push({ name: "mergeServices", key: "mergeServices" });
1371
+ }
1372
+ if (scanned.shareds.length > 0) {
1373
+ importItems.silgi.import.push({ name: "mergeShared", key: "mergeShared" });
1374
+ }
1375
+ if (scanned.schemas.length > 0) {
1376
+ importItems.silgi.import.push({ name: "mergeSchemas", key: "mergeSchemas" });
1377
+ }
1378
+ for (const key in importItems) {
1379
+ importItems[key].import = deduplicateImportsByKey(importItems[key].import);
1380
+ }
1381
+ const importsContent = [
1382
+ ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
1383
+ if (silgi.options.typescript.removeFileExtension) {
1384
+ from = from.replace(/\.(js|ts|mjs|cjs|jsx|tsx)$/, "");
1385
+ }
1386
+ return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${from}'`;
1387
+ }),
1388
+ "",
1389
+ ...scanned.customImports,
1390
+ ""
1391
+ ];
1392
+ const importData = [
1393
+ `export const uris = ${JSON.stringify(scanned.uris, null, 2)}`,
1394
+ "",
1395
+ `export const modulesURIs = ${JSON.stringify(scanned.modulesURIs, null, 2)}`,
1396
+ "",
1397
+ scanned.schemas.length > 0 ? "export const schemas = mergeSchemas([" : "export const schemas = {",
1398
+ ...scanned.schemas.map((name) => {
1399
+ return ` ${name},`;
1400
+ }),
1401
+ scanned.schemas.length > 0 ? "])" : "}",
1402
+ "",
1403
+ scanned.services.length > 0 ? "export const services = mergeServices([" : "export const services = {",
1404
+ ...scanned.services.map((name) => {
1405
+ return ` ${name},`;
1406
+ }),
1407
+ scanned.services.length > 0 ? "])" : "}",
1408
+ "",
1409
+ scanned.shareds.length > 0 ? "export const shareds = mergeShared([" : "export const shareds = {",
1410
+ ...scanned.shareds.map((name) => {
1411
+ return ` ${name},`;
1412
+ }),
1413
+ scanned.shareds.length > 0 ? "])" : "}",
1414
+ ""
1415
+ ];
1416
+ await silgi.callHook("after:prepare:scan.ts", importData);
1417
+ importData.unshift(...importsContent);
1418
+ return importData;
1419
+ }
1420
+ function deduplicateImportsByKey(imports) {
1421
+ const seenKeys = /* @__PURE__ */ new Map();
1422
+ return imports.filter((item) => {
1423
+ if (seenKeys.has(item.key)) {
1424
+ return false;
1425
+ }
1426
+ seenKeys.set(item.key, true);
1427
+ return true;
1428
+ });
1429
+ }
1430
+
1431
+ async function writeScanFiles(silgi) {
1432
+ const data = await prepareServerFiles(silgi);
1433
+ if (!silgi.errors.length) {
1434
+ await writeFile(
1435
+ resolve(silgi.options.silgi.serverDir, "scan.ts"),
1436
+ data.join("\n")
1437
+ );
1438
+ }
1439
+ await readScanFile(silgi);
1440
+ buildUriMap(silgi);
1441
+ parseServices(silgi);
1442
+ silgi.hook("prepare:scan.ts", (file) => {
1443
+ file.uris = {
1444
+ ...file.uris,
1445
+ ...silgi.uris
1446
+ };
1447
+ file.modulesURIs = {
1448
+ ...file.modulesURIs,
1449
+ ...silgi.modulesURIs
1450
+ };
1451
+ });
1452
+ }
1453
+
1440
1454
  async function createStorageCLI(silgi) {
1441
1455
  const storage = createStorage();
1442
1456
  const mounts = klona({
@@ -1661,7 +1675,7 @@ async function createSilgiCLI(config = {}, opts = {}) {
1661
1675
  errors: [],
1662
1676
  commands: {},
1663
1677
  _requiredModules: {},
1664
- logger: consola.withTag("silgi"),
1678
+ logger: consola$1.withTag("silgi"),
1665
1679
  close: () => silgi.hooks.callHook("close", silgi),
1666
1680
  storage: void 0,
1667
1681
  scanModules: [],
@@ -1696,7 +1710,7 @@ async function createSilgiCLI(config = {}, opts = {}) {
1696
1710
  }
1697
1711
  await scanAndSyncOptions(silgi);
1698
1712
  await scanModules$1(silgi);
1699
- await scanFiles$1(silgi);
1713
+ await scanExportFile(silgi);
1700
1714
  await installModules(silgi, true);
1701
1715
  await writeScanFiles(silgi);
1702
1716
  silgi.storage = await createStorageCLI(silgi);
@@ -2477,7 +2491,7 @@ const run = defineCommand({
2477
2491
  rawArgs: ["--commands", "run"]
2478
2492
  }) : void 0;
2479
2493
  if (!data?.result?.silgi && args.active) {
2480
- consola.error("Silgi not found");
2494
+ consola$1.error("Silgi not found");
2481
2495
  return;
2482
2496
  }
2483
2497
  const silgi = useSilgiCLI();
@@ -2508,11 +2522,11 @@ const run = defineCommand({
2508
2522
  }
2509
2523
  } else {
2510
2524
  if (!silgi) {
2511
- consola.error("Silgi not found");
2525
+ consola$1.error("Silgi not found");
2512
2526
  return;
2513
2527
  }
2514
2528
  if (Object.keys(cliJson).length === 0) {
2515
- consola.warn("No commands found in cli.json");
2529
+ consola$1.warn("No commands found in cli.json");
2516
2530
  return;
2517
2531
  }
2518
2532
  const allTags = Object.values(silgi.commands).reduce((acc, commandGroup) => {
@@ -557,7 +557,6 @@ async function _loadUserConfig(configOverrides = {}, opts = {}) {
557
557
  defaults: SilgiCLIDefaults,
558
558
  jitiOptions: {
559
559
  alias: {
560
- "silgi": "silgi/config",
561
560
  "silgi/config": "silgi/config"
562
561
  }
563
562
  },
@@ -1,16 +1,15 @@
1
- import { c as checkSilgiCompatibility } from '../cli/compatibility.mjs';
2
- export { h as hasError } from '../cli/compatibility.mjs';
1
+ import { tryUseSilgiCLI, useSilgiCLI, useSilgi, tryUseSilgi } from 'silgi/core';
3
2
  import { pathToFileURL, fileURLToPath } from 'node:url';
4
3
  import { resolvePath as resolvePath$1 } from 'mlly';
5
4
  import fsp from 'node:fs/promises';
6
5
  import consola, { consola as consola$1 } from 'consola';
7
6
  import { relative, resolve, dirname, normalize, isAbsolute, join, parse, basename } from 'pathe';
8
- import { useSilgiCLI, useSilgi, tryUseSilgiCLI, tryUseSilgi } from 'silgi/core';
9
7
  import { colors } from 'consola/utils';
10
8
  import { getProperty } from 'dot-prop';
11
9
  import { hash as hash$1 } from 'ohash';
12
10
  import { camelCase, snakeCase } from 'scule';
13
11
  import { defu } from 'defu';
12
+ import { c as checkSilgiCompatibility } from '../cli/compatibility.mjs';
14
13
  import { withLeadingSlash } from 'ufo';
15
14
  import { existsSync, promises } from 'node:fs';
16
15
  import { resolveAlias as resolveAlias$1 } from 'pathe/utils';
@@ -20,6 +19,14 @@ import { hash as hash$2 } from 'silgi/kit';
20
19
  import 'semver/functions/satisfies.js';
21
20
  import 'silgi/meta';
22
21
 
22
+ function hasError(type, silgi) {
23
+ silgi = silgi ?? tryUseSilgiCLI() ?? void 0;
24
+ if (silgi && silgi.errors.some((error) => error.type === type)) {
25
+ return true;
26
+ }
27
+ return false;
28
+ }
29
+
23
30
  function directoryToURL(dir) {
24
31
  return pathToFileURL(`${dir}/`);
25
32
  }
@@ -563,4 +570,4 @@ function isValidIp(ip) {
563
570
  return false;
564
571
  }
565
572
 
566
- export { MODE_RE, addTemplate, applyEnv, createResolver, defineSilgiModule, defineSilgiPreset, directoryToURL, filterInPlace, getIpAddress, hasInstalledModule, hasSilgiModule, hash, initRuntimeConfig, ipAddress, isDirectory$1 as isDirectory, isH3, isNitro, isNuxt, normalizeTemplate, parseServices, prettyPath, relativeWithDot, resolveAlias, resolvePath, resolveSilgiModule, resolveSilgiPath, serviceParseModule, toArray, tryResolveModule, useLogger, useRequest, useResponse, useSilgiRuntimeConfig, writeFile };
573
+ export { MODE_RE, addTemplate, applyEnv, createResolver, defineSilgiModule, defineSilgiPreset, directoryToURL, filterInPlace, getIpAddress, hasError, hasInstalledModule, hasSilgiModule, hash, initRuntimeConfig, ipAddress, isDirectory$1 as isDirectory, isH3, isNitro, isNuxt, normalizeTemplate, parseServices, prettyPath, relativeWithDot, resolveAlias, resolvePath, resolveSilgiModule, resolveSilgiPath, serviceParseModule, toArray, tryResolveModule, useLogger, useRequest, useResponse, useSilgiRuntimeConfig, writeFile };
@@ -1,4 +1,4 @@
1
- const version = "0.21.8";
1
+ const version = "0.22.1";
2
2
  const peerDependencies = {
3
3
  "@fastify/deepmerge": "^3.0.0",
4
4
  "@nuxt/kit": "^3.15.3",
@@ -1,4 +1,4 @@
1
- const version = "0.21.8";
1
+ const version = "0.22.1";
2
2
  const peerDependencies = {
3
3
  "@fastify/deepmerge": "^3.0.0",
4
4
  "@nuxt/kit": "^3.15.3",
@@ -6,7 +6,7 @@ import { Hookable, NestedHooks } from 'hookable';
6
6
  import { Ignore, Options } from 'ignore';
7
7
  import { TSConfig } from 'pkg-types';
8
8
  import { PresetName, PresetOptions, PresetNameInput } from 'silgi/presets';
9
- import { ResolvedServiceType as ResolvedServiceType$1, SilgiRuntimeShareds as SilgiRuntimeShareds$1, SilgiRuntimeOptions as SilgiRuntimeOptions$1, RouteRules as RouteRules$1, ModuleMeta as ModuleMeta$1, SilgiRouteRules as SilgiRouteRules$1, DotenvOptions as DotenvOptions$1, EnvOptions as EnvOptions$1, SilgiRuntimeConfig as SilgiRuntimeConfig$1, ServiceParseModule as ServiceParseModule$1, SilgiCLIHooks as SilgiCLIHooks$1, StorageMounts as StorageMounts$1, SilgiTemplate as SilgiTemplate$1, SilgiFrameworkInfo as SilgiFrameworkInfo$1 } from 'silgi/types';
9
+ import { ResolvedServiceType as ResolvedServiceType$1, SilgiRuntimeShareds as SilgiRuntimeShareds$1, SilgiRuntimeOptions as SilgiRuntimeOptions$1, RouteRules as RouteRules$1, ModuleMeta as ModuleMeta$1, SilgiModule as SilgiModule$1, SilgiRouteRules as SilgiRouteRules$1, DotenvOptions as DotenvOptions$1, EnvOptions as EnvOptions$1, SilgiRuntimeConfig as SilgiRuntimeConfig$1, ServiceParseModule as ServiceParseModule$1, SilgiCLIHooks as SilgiCLIHooks$1, StorageMounts as StorageMounts$1, SilgiTemplate as SilgiTemplate$1, SilgiFrameworkInfo as SilgiFrameworkInfo$1 } from 'silgi/types';
10
10
  import { UnimportPluginOptions } from 'unimport/unplugin';
11
11
  import { Defu } from 'defu';
12
12
  import { Stats } from 'node:fs';
@@ -70,8 +70,9 @@ interface SilgiCLI {
70
70
  updateConfig: (config: SilgiCLIDynamicConfig) => void | Promise<void>;
71
71
  scanModules: Array<{
72
72
  meta: ModuleMeta$1;
73
+ module: SilgiModule$1;
73
74
  timings?: Record<string, number | undefined>;
74
- entryPath: string;
75
+ entryPath?: string;
75
76
  installed?: boolean;
76
77
  options: Record<string, any>;
77
78
  }>;
@@ -6,7 +6,7 @@ import { Hookable, NestedHooks } from 'hookable';
6
6
  import { Ignore, Options } from 'ignore';
7
7
  import { TSConfig } from 'pkg-types';
8
8
  import { PresetName, PresetOptions, PresetNameInput } from 'silgi/presets';
9
- import { ResolvedServiceType as ResolvedServiceType$1, SilgiRuntimeShareds as SilgiRuntimeShareds$1, SilgiRuntimeOptions as SilgiRuntimeOptions$1, RouteRules as RouteRules$1, ModuleMeta as ModuleMeta$1, SilgiRouteRules as SilgiRouteRules$1, DotenvOptions as DotenvOptions$1, EnvOptions as EnvOptions$1, SilgiRuntimeConfig as SilgiRuntimeConfig$1, ServiceParseModule as ServiceParseModule$1, SilgiCLIHooks as SilgiCLIHooks$1, StorageMounts as StorageMounts$1, SilgiTemplate as SilgiTemplate$1, SilgiFrameworkInfo as SilgiFrameworkInfo$1 } from 'silgi/types';
9
+ import { ResolvedServiceType as ResolvedServiceType$1, SilgiRuntimeShareds as SilgiRuntimeShareds$1, SilgiRuntimeOptions as SilgiRuntimeOptions$1, RouteRules as RouteRules$1, ModuleMeta as ModuleMeta$1, SilgiModule as SilgiModule$1, SilgiRouteRules as SilgiRouteRules$1, DotenvOptions as DotenvOptions$1, EnvOptions as EnvOptions$1, SilgiRuntimeConfig as SilgiRuntimeConfig$1, ServiceParseModule as ServiceParseModule$1, SilgiCLIHooks as SilgiCLIHooks$1, StorageMounts as StorageMounts$1, SilgiTemplate as SilgiTemplate$1, SilgiFrameworkInfo as SilgiFrameworkInfo$1 } from 'silgi/types';
10
10
  import { UnimportPluginOptions } from 'unimport/unplugin';
11
11
  import { Defu } from 'defu';
12
12
  import { Stats } from 'node:fs';
@@ -70,8 +70,9 @@ interface SilgiCLI {
70
70
  updateConfig: (config: SilgiCLIDynamicConfig) => void | Promise<void>;
71
71
  scanModules: Array<{
72
72
  meta: ModuleMeta$1;
73
+ module: SilgiModule$1;
73
74
  timings?: Record<string, number | undefined>;
74
- entryPath: string;
75
+ entryPath?: string;
75
76
  installed?: boolean;
76
77
  options: Record<string, any>;
77
78
  }>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "silgi",
3
3
  "type": "module",
4
- "version": "0.21.8",
4
+ "version": "0.22.1",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {