silgi 0.6.0 → 0.7.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.
@@ -2,25 +2,20 @@ import { defineCommand } from 'citty';
2
2
  import { join, resolve, isAbsolute, relative, dirname, basename, extname } from 'pathe';
3
3
  import { version } from 'silgi/meta';
4
4
  import { runtimeDir } from 'silgi/runtime/meta';
5
- import fsp, { readdir } from 'node:fs/promises';
6
- import { promises, existsSync, readFileSync } from 'node:fs';
7
- import { createJiti } from 'jiti';
5
+ import { promises, existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
6
+ import { readdir } from 'node:fs/promises';
8
7
  import { resolvePath, parseNodeModulePath, lookupNodeModuleSubpath, resolve as resolve$1 } from 'mlly';
9
8
  import { resolveAlias } from 'pathe/utils';
10
- import { silgiGenerateType, SchemaParser, loadOptions } from 'silgi/core';
11
- import { relativeWithDot, isDirectory, writeFile, resolveAlias as resolveAlias$1, resolvePath as resolvePath$1 } from 'silgi/kit';
12
- import { toExports, createUnimport } from 'unimport';
9
+ import { silgiGenerateType, useSilgiCLI, SchemaParser, loadOptions, silgiCLICtx } from 'silgi/core';
10
+ import { relativeWithDot, isDirectory, writeFile, resolveAlias as resolveAlias$1, resolvePath as resolvePath$1, normalizeTemplate, useLogger } from 'silgi/kit';
11
+ import { toExports, scanExports, createUnimport } from 'unimport';
12
+ import { createJiti } from 'dev-jiti';
13
13
  import { readPackageJSON } from 'pkg-types';
14
14
  import { hash } from 'ohash';
15
15
  import { consola } from 'consola';
16
16
  import { createHooks, createDebugger } from 'hookable';
17
- import { join as join$1 } from 'node:path';
18
- import { makeExecutableSchema, mergeSchemas } from '@graphql-tools/schema';
19
- import { printSchemaWithDirectives } from '@graphql-tools/utils';
20
- import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
21
- import { loadSchemaSync } from '@graphql-tools/load';
22
17
  import { pascalCase } from 'scule';
23
- import { h as hasInstalledModule, u as useSilgiCLI, s as silgiCLICtx } from './compatibility.mjs';
18
+ import { h as hasInstalledModule } from './compatibility.mjs';
24
19
  import { pathToFileURL, fileURLToPath } from 'node:url';
25
20
  import { isRelative, withTrailingSlash } from 'ufo';
26
21
  import { globby } from 'globby';
@@ -28,7 +23,6 @@ import ignore from 'ignore';
28
23
  import { klona } from 'klona';
29
24
  import { createStorage, builtinDrivers } from 'unstorage';
30
25
  import 'semver/functions/satisfies.js';
31
- import 'unctx';
32
26
 
33
27
  async function h3Framework(silgi, skip = false) {
34
28
  if (silgi.options.preset !== "h3" && skip === false)
@@ -61,14 +55,14 @@ async function h3Framework(silgi, skip = false) {
61
55
  silgi.hook("prepare:createDTSFramework", (data) => {
62
56
  data.importItems["silgi/types"] = {
63
57
  import: [
64
- { name: "SilgiModuleContext", type: true }
58
+ { name: "ModuleRuntimeContext", type: true }
65
59
  ],
66
60
  from: "silgi/types"
67
61
  };
68
62
  data.customContent?.push(
69
63
  "",
70
64
  'declare module "h3" {',
71
- " interface H3EventContext extends SilgiModuleContext {}",
65
+ " interface H3EventContext extends ModuleRuntimeContext {}",
72
66
  "}",
73
67
  ""
74
68
  );
@@ -93,17 +87,7 @@ async function nitroFramework(silgi, skip = false) {
93
87
  packageImport: "silgi/runtime/internal/nitro",
94
88
  path: join(runtimeDir, "internal/nitro")
95
89
  });
96
- silgi.hook("prepare:core.ts", (data) => {
97
- data.importItems["nitropack/runtime"] ??= {
98
- import: [],
99
- from: "nitropack/runtime"
100
- };
101
- data.importItems["nitropack/runtime"].import.push(
102
- { name: "useStorage" }
103
- );
104
- data._silgiConfigs.push({
105
- storage: `useStorage()`
106
- });
90
+ silgi.hook("prepare:core.ts", (_data) => {
107
91
  });
108
92
  await h3Framework(silgi, true);
109
93
  }
@@ -116,55 +100,121 @@ async function nuxtFramework(silgi, skip = false) {
116
100
 
117
101
  const frameworkSetup = [h3Framework, nitroFramework, nuxtFramework];
118
102
 
119
- async function prepare$1(silgi) {
120
- await prepareDir(silgi.options.output.dir);
121
- }
122
- async function prepareDir(dir) {
123
- await fsp.rm(dir, { recursive: true, force: true });
124
- await fsp.mkdir(dir, { recursive: true });
103
+ async function prepare$1(_silgi) {
125
104
  }
126
105
 
127
- function myBabelPlugin() {
128
- return {
129
- visitor: {
130
- CallExpression(path) {
131
- const callee = path.get("callee");
132
- if (callee.isMemberExpression() && callee.get("object").isIdentifier({ name: "console" }) && callee.get("property").isIdentifier({ name: "log" })) {
133
- callee.get("property").replaceWithSourceString("warn");
134
- }
135
- },
136
- StringLiteral(path) {
137
- if (path.node.value === "nitropack/runtime") {
138
- path.replaceWithSourceString("'silgi/runtime'");
139
- }
106
+ async function generateSilgiStorageBaseType(silgi) {
107
+ silgi.hook("prepare:schema.ts", async (options) => {
108
+ if (silgi.options.storage) {
109
+ for (const [key, _value] of Object.entries(silgi.options.storage)) {
110
+ options.storeBase.push(key);
140
111
  }
141
112
  }
142
- };
113
+ });
143
114
  }
115
+
116
+ async function generateRouterDTS(silgi) {
117
+ silgi.hook("finish:types", async (data) => {
118
+ const uris = data.object.uris;
119
+ const subPath = "srn";
120
+ const groupedPaths = /* @__PURE__ */ new Map();
121
+ Object.entries(uris || {}).forEach(([key, params]) => {
122
+ const [service, resource, method, action] = key.split("/");
123
+ const basePath = params ? `${subPath}/${service}/${resource}/${action}/${params}` : `${subPath}/${service}/${resource}/${action}`;
124
+ const fullPath = `${subPath}/${service}/${resource}/${action}`;
125
+ if (!groupedPaths.has(basePath)) {
126
+ groupedPaths.set(basePath, /* @__PURE__ */ new Map());
127
+ }
128
+ groupedPaths.get(basePath)?.set(method.toLowerCase(), fullPath);
129
+ });
130
+ const keys = [
131
+ " keys: {",
132
+ Array.from(groupedPaths.entries()).map(([basePath, methods]) => {
133
+ return ` '/${basePath}': {${Array.from(methods.entries()).map(([method, path]) => `
134
+ ${method}: '/${path}'`).join(",")}
135
+ }`;
136
+ }).join(",\n"),
137
+ " }",
138
+ ""
139
+ ].join("\n");
140
+ const groupedRoutes = Object.entries(uris || {}).reduce((acc, [key, _params]) => {
141
+ const [service, resource, method, action] = key.split("/");
142
+ const routePath = `${subPath}/${service}/${resource}/${action}`;
143
+ if (!acc[routePath]) {
144
+ acc[routePath] = {};
145
+ }
146
+ acc[routePath][method] = {
147
+ input: `ExtractInputFromURI<'${key}'>`,
148
+ output: `ExtractOutputFromURI<'${key}'>`,
149
+ params: `ExtractRouterParamsFromURI<'${key}'>['params']`
150
+ };
151
+ return acc;
152
+ }, {});
153
+ const routerTypes = Object.entries(groupedRoutes).map(([path, methods]) => {
154
+ const methodEntries = Object.entries(methods).map(([method, { input, output, params }]) => {
155
+ return ` '${method}': {
156
+ input: ${input},
157
+ output: ${output}
158
+ params: ${params}
159
+ }`;
160
+ }).join(",\n");
161
+ return ` '/${path}': {
162
+ ${methodEntries}
163
+ }`;
164
+ });
165
+ const nitro = [
166
+ "declare module 'nitropack/types' {",
167
+ " interface InternalApi extends RouterTypes {}",
168
+ "}"
169
+ ];
170
+ const content = [
171
+ keys.slice(0, -1),
172
+ // son satırdaki boş satırı kaldır
173
+ ...routerTypes
174
+ ].join(",\n");
175
+ const context = [
176
+ "import type { ExtractInputFromURI, ExtractOutputFromURI, ExtractRouterParamsFromURI } from 'silgi/types'",
177
+ "",
178
+ "export interface RouterTypes {",
179
+ content,
180
+ "}",
181
+ "",
182
+ "declare module 'silgi/types' {",
183
+ " interface SilgiRouterTypes extends RouterTypes {",
184
+ " }",
185
+ "}",
186
+ "",
187
+ silgi.options.preset === "h3" || silgi.options.preset === "nitro" ? nitro.join("\n") : "",
188
+ "",
189
+ "export {}"
190
+ ].join("\n");
191
+ const outputPath = resolve(silgi.options.build.typesDir, "silgi-routes.d.ts");
192
+ await promises.writeFile(outputPath, context);
193
+ });
194
+ }
195
+
144
196
  async function readCoreFile(silgi) {
145
197
  const path = resolve(silgi.options.silgi.serverDir, "core.ts");
198
+ const context = await promises.readFile(path, { encoding: "utf-8" });
199
+ const injectedResult = await silgi.unimport.injectImports(context, path);
200
+ if (!injectedResult) {
201
+ throw new Error("Failed to inject imports");
202
+ }
146
203
  const jiti = createJiti(silgi.options.rootDir, {
147
204
  fsCache: false,
148
- interopDefault: true,
149
205
  moduleCache: false,
150
- transformOptions: {
151
- babel: {
152
- plugins: [myBabelPlugin()]
153
- }
154
- },
155
- // debug: true,
156
- // transform(opts) {
157
- // console.log(opts)
158
- // return babelTransform(opts)
159
- // },
206
+ debug: silgi.options.debug,
160
207
  alias: silgi.options.alias
161
208
  });
162
- const resolvedPath = jiti.esmResolve(path);
163
- const context = await promises.readFile(path, { encoding: "utf-8" });
164
- const coreFile = await jiti.import(
165
- resolvedPath,
209
+ const coreFile = await jiti.evalModule(
210
+ injectedResult.code,
166
211
  {
212
+ filename: path,
213
+ async: true,
167
214
  conditions: silgi.options.conditions
215
+ },
216
+ async (data, name) => {
217
+ return (await silgi.unimport.injectImports(data, name)).code;
168
218
  }
169
219
  );
170
220
  silgi.uris = coreFile.uris;
@@ -195,7 +245,7 @@ function traverseObject(silgi, obj, currentPath = []) {
195
245
  let paramString = "";
196
246
  if (node.router) {
197
247
  let params = null;
198
- if (node.router?._def?.typeName !== undefined) {
248
+ if (node.router?._def?.typeName !== void 0) {
199
249
  try {
200
250
  const shape = node.router?.shape?.params?.shape;
201
251
  params = shape ? Object.keys(shape) : null;
@@ -277,99 +327,6 @@ ${uriContent}
277
327
  await promises.writeFile(path, newContext);
278
328
  }
279
329
 
280
- async function generateSilgiStorageBaseType(silgi) {
281
- silgi.hook("prepare:schema.ts", async (options) => {
282
- if (silgi.options.storage) {
283
- for (const [key, _value] of Object.entries(silgi.options.storage)) {
284
- options.storeBase.push(key);
285
- }
286
- }
287
- });
288
- }
289
-
290
- async function generateRouterDTS(silgi) {
291
- silgi.hook("read:core.ts", async (data) => {
292
- silgi.hook("close", async () => {
293
- const { object } = await data();
294
- const uris = object.uris;
295
- const subPath = "srn";
296
- const groupedPaths = /* @__PURE__ */ new Map();
297
- Object.entries(uris || {}).forEach(([key, params]) => {
298
- const [service, resource, method, action] = key.split("/");
299
- const basePath = params ? `${subPath}/${service}/${resource}/${action}/${params}` : `${subPath}/${service}/${resource}/${action}`;
300
- const fullPath = `${subPath}/${service}/${resource}/${action}`;
301
- if (!groupedPaths.has(basePath)) {
302
- groupedPaths.set(basePath, /* @__PURE__ */ new Map());
303
- }
304
- groupedPaths.get(basePath)?.set(method.toLowerCase(), fullPath);
305
- });
306
- const keys = [
307
- " keys: {",
308
- Array.from(groupedPaths.entries()).map(([basePath, methods]) => {
309
- return ` '/${basePath}': {${Array.from(methods.entries()).map(([method, path]) => `
310
- ${method}: '/${path}'`).join(",")}
311
- }`;
312
- }).join(",\n"),
313
- " }",
314
- ""
315
- ].join("\n");
316
- const groupedRoutes = Object.entries(uris || {}).reduce((acc, [key, _params]) => {
317
- const [service, resource, method, action] = key.split("/");
318
- const routePath = `${subPath}/${service}/${resource}/${action}`;
319
- if (!acc[routePath]) {
320
- acc[routePath] = {};
321
- }
322
- acc[routePath][method] = {
323
- input: `ExtractInputFromURI<'${key}'>`,
324
- output: `ExtractOutputFromURI<'${key}'>`,
325
- params: `ExtractRouterParamsFromURI<'${key}'>['params']`
326
- };
327
- return acc;
328
- }, {});
329
- const routerTypes = Object.entries(groupedRoutes).map(([path, methods]) => {
330
- const methodEntries = Object.entries(methods).map(([method, { input, output, params }]) => {
331
- return ` '${method}': {
332
- input: ${input},
333
- output: ${output}
334
- params: ${params}
335
- }`;
336
- }).join(",\n");
337
- return ` '/${path}': {
338
- ${methodEntries}
339
- }`;
340
- });
341
- const nitro = [
342
- "declare module 'nitropack/types' {",
343
- " interface InternalApi extends RouterTypes {}",
344
- "}"
345
- ];
346
- const content = [
347
- keys.slice(0, -1),
348
- // son satırdaki boş satırı kaldır
349
- ...routerTypes
350
- ].join(",\n");
351
- const context = [
352
- "import type { ExtractInputFromURI, ExtractOutputFromURI, ExtractRouterParamsFromURI } from 'silgi/types'",
353
- "",
354
- "export interface RouterTypes {",
355
- content,
356
- "}",
357
- "",
358
- "declare module 'silgi/types' {",
359
- " interface SilgiRouterTypes extends RouterTypes {",
360
- " }",
361
- "}",
362
- "",
363
- silgi.options.preset === "h3" || silgi.options.preset === "nitro" ? nitro.join("\n") : "",
364
- "",
365
- "export {}"
366
- ].join("\n");
367
- const outputPath = resolve(silgi.options.build.typesDir, "silgi-routes.d.ts");
368
- await promises.writeFile(outputPath, context);
369
- });
370
- });
371
- }
372
-
373
330
  async function createCoreFramework(silgi) {
374
331
  const relativeRootDir = relativeWithDot(silgi.options.rootDir, silgi.options.serverDir);
375
332
  if (silgi.options.preset !== "nitro" && silgi.options.preset !== "h3")
@@ -377,7 +334,7 @@ async function createCoreFramework(silgi) {
377
334
  const importItems = {
378
335
  "silgi/types": {
379
336
  import: [
380
- { name: "SilgiModuleContext", type: true }
337
+ { name: "ModuleRuntimeContext", type: true }
381
338
  ],
382
339
  from: "silgi/types"
383
340
  }
@@ -415,7 +372,7 @@ async function createDTSFramework(silgi) {
415
372
  const importItems = {
416
373
  "silgi/types": {
417
374
  import: [
418
- { name: "SilgiModuleContext", type: true }
375
+ { name: "ModuleRuntimeContext", type: true }
419
376
  ],
420
377
  from: "silgi/types"
421
378
  }
@@ -463,7 +420,7 @@ async function schemaTemplate(silgi) {
463
420
  import: [
464
421
  { name: "URIsTypes", type: true },
465
422
  { name: "Namespaces", type: true },
466
- { name: "SilgiModuleContext", type: true }
423
+ { name: "ModuleRuntimeContext", type: true }
467
424
  ],
468
425
  from: "silgi/types"
469
426
  }
@@ -480,23 +437,20 @@ async function schemaTemplate(silgi) {
480
437
  importItems[pkg.name].from = isAbsolute(id) ? relativeWithDot(relativeRootDir, id) : id;
481
438
  }
482
439
  }));
483
- const customImports = [];
484
- const configs = [];
485
- const contexts = [];
486
- const methods = [];
487
- const shareds = [];
488
- const events = [];
489
- const storeBase = [];
490
- await silgi.callHook("prepare:schema.ts", {
440
+ const data = {
491
441
  importItems,
492
- customImports,
493
- configs,
494
- contexts,
495
- methods,
496
- shareds,
497
- storeBase,
498
- events
499
- });
442
+ customImports: [],
443
+ configs: [],
444
+ contexts: [],
445
+ methods: [],
446
+ shareds: [],
447
+ events: [],
448
+ storeBase: [],
449
+ hooks: [],
450
+ runtimeHooks: []
451
+ };
452
+ const storeBase = [];
453
+ await silgi.callHook("prepare:schema.ts", data);
500
454
  const silgiExport = relativeWithDot(silgi.options.build.typesDir, `${silgi.options.silgi.serverDir}/core.ts`);
501
455
  let addSilgiContext = false;
502
456
  const importsContent = [
@@ -505,7 +459,7 @@ async function schemaTemplate(silgi) {
505
459
  return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${path}'`;
506
460
  }),
507
461
  "",
508
- ...customImports,
462
+ ...data.customImports,
509
463
  ""
510
464
  ];
511
465
  const importData = [
@@ -517,31 +471,34 @@ async function schemaTemplate(silgi) {
517
471
  "",
518
472
  `type SilgiURIsMerge = URIsTypes<typeof import('${silgiExport}')['uris']>`,
519
473
  "",
520
- contexts.length ? `type SilgiModuleContextExtends = ${contexts.map(({ value }) => value).join(" & ")}` : "type SilgiModuleContextExtends = {}",
474
+ `type SilgiModuleContextExtends = ${data.contexts.length ? data.contexts.map(({ value }) => value).join(" & ") : "{}"}`,
521
475
  "",
522
- events.length ? `interface SilgiModuleEventsExtends extends ${events.map((item) => item.extends ? item.value : "").join(", ")} {
523
- ${events.map((item) => {
476
+ data.events.length ? `interface SilgiModuleEventsExtends extends ${data.events.map((item) => item.extends ? item.value : "").join(", ")} {
477
+ ${data.events.map((item) => {
524
478
  if (item.isSilgiContext) {
525
479
  addSilgiContext = true;
526
480
  }
527
- return !item.extends && !addSilgiContext ? ` ${item.key}: ${item.value}` : item.isSilgiContext ? " context: SilgiModuleContext" : "";
481
+ return !item.extends && !addSilgiContext ? ` ${item.key}: ${item.value}` : item.isSilgiContext ? " context: ModuleRuntimeContext" : "";
528
482
  }).join(",\n")}
529
483
  }` : "interface SilgiModuleEventsExtends {}",
530
484
  "",
531
- shareds.length ? `type SilgiModuleSharedExtends = ${shareds.map(({ value }) => value).join(" & ")}` : "type SilgiModuleSharedExtends = {}",
485
+ data.shareds.length ? `type SilgiModuleSharedExtends = ${data.shareds.map(({ value }) => value).join(" & ")}` : "type SilgiModuleSharedExtends = {}",
532
486
  "",
533
487
  "interface SilgiModuleMethodsExtends {",
534
- ...(methods).map(({ key, value }) => ` ${key}: ${value},`),
488
+ ...(data.methods || []).map(({ key, value }) => ` ${key}: ${value},`),
535
489
  "}",
536
490
  "",
537
491
  "interface SilgiModuleOptionsExtends {",
538
- ...(configs).map(({ key, value }) => ` ${key}: ${value},`),
492
+ ...(data.configs || []).map(({ key, value }) => ` ${key}: ${value},`),
539
493
  "}",
540
494
  "",
541
495
  "interface SilgiStorageBaseExtends {",
542
- ...(storeBase).map((value) => ` ${value}: ''`),
496
+ ...(storeBase || []).map((value) => ` ${value}: ''`),
543
497
  "}",
544
498
  "",
499
+ `type ModuleHooksExtend = ${data.hooks?.length ? data.hooks.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
500
+ "",
501
+ `type SilgiRuntimeHooksExtends = ${data.runtimeHooks?.length ? data.runtimeHooks.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
545
502
  "",
546
503
  "declare module 'silgi/types' {",
547
504
  " interface FrameworkContext extends FrameworkContextExtends {}",
@@ -550,11 +507,13 @@ async function schemaTemplate(silgi) {
550
507
  " interface SilgiStorageBase extends SilgiStorageBaseExtends {}",
551
508
  " interface SilgiModules extends SilgiModuleOptionsExtends {}",
552
509
  " interface SilgiURIs extends SilgiURIsMerge {}",
553
- " interface SilgiModuleContext extends SilgiModuleContextExtends {}",
510
+ " interface ModuleRuntimeContext extends SilgiModuleContextExtends {}",
554
511
  " interface SilgiEvent extends SilgiModuleEventsExtends {}",
555
512
  " interface SilgiDefaultShared extends SilgiModuleSharedExtends {}",
556
- " interface SilgiModuleMethods extends SilgiModuleMethodsExtends {}",
557
- " interface SilgiModuleOptions extends SilgiModuleOptionsExtends {}",
513
+ " interface ModuleRuntimeMethods extends SilgiModuleMethodsExtends {}",
514
+ " interface ModuleOptions extends SilgiModuleOptionsExtends {}",
515
+ " interface ModuleRuntimeHooks extends SilgiRuntimeHooksExtends {}",
516
+ " interface ModuleHooks extends ModuleHooksExtend {}",
558
517
  "}",
559
518
  "",
560
519
  "export {}"
@@ -575,12 +534,17 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
575
534
  },
576
535
  "silgi/types": {
577
536
  import: [
578
- { name: "SilgiModuleOptions", type: true },
537
+ { name: "ModuleOptions", type: true },
579
538
  { name: "SilgiOptions", type: true },
580
539
  { name: "FrameworkContext", type: true },
581
- { name: "DeepPartial", type: true }
540
+ { name: "DeepPartial", type: true },
541
+ { name: "BuildConfig", type: true }
582
542
  ],
583
543
  from: "silgi/types"
544
+ },
545
+ "#silgi/vfs": {
546
+ import: [],
547
+ from: "./vfs"
584
548
  }
585
549
  };
586
550
  importItems = { ...data._importItems, ...importItems };
@@ -620,6 +584,9 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
620
584
  _silgiOptions,
621
585
  _silgiConfigs
622
586
  });
587
+ if (importItems["#silgi/vfs"].import.length === 0) {
588
+ delete importItems["#silgi/vfs"];
589
+ }
623
590
  if (services.length > 0) {
624
591
  importItems["silgi/core"].import.push({ name: "mergeServices" });
625
592
  }
@@ -632,13 +599,14 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
632
599
  const plugins = [];
633
600
  for (const plugin of silgi.options.plugins) {
634
601
  const pluginImportName = `_${hash(plugin.packageImport)}`;
635
- customImports.push(`import ${pluginImportName} from '${plugin.packageImport}';`);
602
+ customImports.push(`import ${pluginImportName} from '${plugin.packageImport}'`);
636
603
  plugins.push(pluginImportName);
637
604
  }
638
605
  const importsContent = [
639
606
  ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
640
607
  return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${from}'`;
641
608
  }),
609
+ "",
642
610
  ...customImports,
643
611
  ""
644
612
  ];
@@ -665,9 +633,9 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
665
633
  }),
666
634
  shareds.length > 0 ? "])" : "}",
667
635
  "",
668
- `export const _silgiOptions: DeepPartial<SilgiModuleOptions> = ${JSON.stringify(_silgiOptions, null, 2)}`,
636
+ `export const _silgiOptions: DeepPartial<ModuleOptions> = ${JSON.stringify(_silgiOptions, null, 2)}`,
669
637
  "",
670
- "export async function buildSilgi(framework: FrameworkContext, options?: Partial<SilgiModuleOptions>) {",
638
+ "export async function buildSilgi(framework: FrameworkContext, moduleOptions?: Partial<ModuleOptions>,buildOptions?: Partial<BuildConfig>, ) {",
671
639
  " const silgi = await createSilgi({",
672
640
  " framework,",
673
641
  " shared: shareds as any,",
@@ -677,10 +645,11 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
677
645
  " modulesURIs,",
678
646
  ` plugins: [${plugins.join(", ")}],`,
679
647
  _silgiConfigs.length > 0 ? ` ${_silgiConfigs.map((config) => Object.entries(config).map(([key, value]) => `${key}: ${value}`)).join(",\n ")},` : "",
648
+ " ...buildOptions,",
680
649
  " options: {",
681
650
  ` present: '${silgi.options.preset}',`,
682
651
  " ..._silgiOptions,",
683
- " ...options,",
652
+ " ...moduleOptions,",
684
653
  " },",
685
654
  " })",
686
655
  "",
@@ -795,14 +764,19 @@ async function writeTypesAndFiles(silgi) {
795
764
  path: join(typesDir, "framework.d.ts"),
796
765
  contents: frameworkDTS.content.join("\n")
797
766
  });
798
- await Promise.all(
799
- buildFiles.map(async (file) => {
800
- await writeFile(
801
- resolve(silgi.options.build.dir, file.path),
802
- file.contents
803
- );
804
- })
805
- );
767
+ for await (const file of buildFiles) {
768
+ await writeFile(
769
+ resolve(silgi.options.build.dir, file.path),
770
+ file.contents
771
+ );
772
+ }
773
+ await scanUris(silgi);
774
+ const readCore = await readCoreFile(silgi);
775
+ silgi.uris = readCore.object.uris;
776
+ silgi.modulesURIs = readCore.object.modulesURIs;
777
+ silgi.schemas = readCore.object.schemas;
778
+ silgi.shareds = readCore.object.shareds;
779
+ await silgi.hooks.callHook("finish:types", readCore);
806
780
  }
807
781
 
808
782
  const commonArgs = {
@@ -817,133 +791,71 @@ const commonArgs = {
817
791
  }
818
792
  };
819
793
 
820
- async function graphQLLoadSchemaSync(schemaPointers, data = {}) {
821
- let result;
822
- try {
823
- result = loadSchemaSync(schemaPointers, {
824
- ...data,
825
- loaders: [
826
- new GraphQLFileLoader(),
827
- ...data.loaders || []
828
- ]
829
- });
830
- } catch (e) {
831
- if (
832
- // https://www.graphql-tools.com/docs/documents-loading#no-files-found
833
- (e.message || "").includes(
834
- "Unable to find any GraphQL type definitions for the following pointers:"
835
- )
836
- ) ; else {
837
- throw e;
838
- }
839
- }
840
- return result;
841
- }
842
-
843
- async function graphqlLoadSync(silgi) {
844
- const typeDefs = [];
845
- const resolvers = [];
846
- await silgi.callHook("before:graphql:schema", {
847
- typeDefs,
848
- resolvers
849
- });
850
- const schema = await graphQLLoadSchemaSync(silgi.options.serverDir, {
851
- cwd: silgi.options.rootDir
852
- });
853
- const makeSchema = makeExecutableSchema({
854
- typeDefs,
855
- resolvers
856
- });
857
- const merge = mergeSchemas({
858
- schemas: schema ? [makeSchema, schema] : [makeSchema]
859
- });
860
- if (merge) {
861
- const schemaString = printSchemaWithDirectives(merge);
862
- const context = [
863
- "// THIS FILE IS GENERATED, DO NOT EDIT!",
864
- "/* eslint-disable eslint-comments/no-unlimited-disable */",
865
- "/* tslint:disable */",
866
- "/* eslint-disable */",
867
- "/* prettier-ignore */",
868
- "/* silgi */",
869
- "export const schema = `",
870
- "",
871
- schemaString,
872
- "",
873
- "`"
874
- ].join("\n");
875
- const fsPath = join$1(silgi.options.silgi.serverDir, "generated/graphql.schema.ts");
876
- await promises.mkdir(dirname(fsPath), { recursive: true });
877
- await promises.writeFile(fsPath, context);
878
- }
879
- return {
880
- schema
881
- };
882
- }
883
-
884
- function moduleScanHooks(silgi) {
794
+ async function registerModuleExportScan(silgi) {
885
795
  silgi.hook("prepare:schema.ts", async (options) => {
886
796
  for (const module of silgi.scanModules) {
887
797
  const exports = module.meta.exports;
888
- if (exports?.interface) {
889
- let importName;
890
- options.importItems[module.meta.configKey] = {
891
- import: [],
892
- from: module.meta.name || module.meta._packageName
893
- };
894
- if (exports.interface.config) {
895
- importName = pascalCase(`${module.meta.configKey}Config`);
896
- options.importItems[module.meta.configKey].import.push({
897
- name: `SilgiModuleOptions as ${importName}`,
898
- type: true
899
- });
900
- options.configs.push({
901
- key: module.meta.configKey,
902
- value: importName
903
- });
904
- }
905
- if (exports.interface.context) {
906
- importName = pascalCase(`${module.meta.configKey}Context`);
907
- options.importItems[module.meta.configKey].import.push({
908
- name: `SilgiModuleContext as ${importName}`,
909
- type: true
910
- });
911
- options.contexts.push({
912
- key: module.meta.configKey,
913
- value: importName
914
- });
915
- }
916
- if (exports.interface.method) {
917
- importName = pascalCase(`${module.meta.configKey}Method`);
918
- options.importItems[module.meta.configKey].import.push({
919
- name: `SilgiModuleMethods as ${importName}`,
920
- type: true
921
- });
922
- options.methods.push({
923
- key: module.meta.configKey,
924
- value: importName
925
- });
926
- }
927
- if (exports.interface.shared) {
928
- importName = pascalCase(`${module.meta.configKey}Shared`);
929
- options.importItems[module.meta.configKey].import.push({
930
- name: `SilgiModuleShared as ${importName}`,
931
- type: true
932
- });
933
- options.shareds.push({
934
- key: module.meta.configKey,
935
- value: importName
936
- });
937
- }
798
+ if (!exports?.length)
799
+ continue;
800
+ const configKey = module.meta.configKey;
801
+ const moduleName = module.meta.name || module.meta._packageName;
802
+ options.importItems[configKey] = {
803
+ import: [],
804
+ from: module.meta._packageName ? moduleName : relativeWithDot(silgi.options.build.typesDir, module.entryPath)
805
+ };
806
+ const exportedTypes = exports.filter((exp) => exp.type).map((exp) => exp.name);
807
+ if (exportedTypes.includes("ModuleOptions")) {
808
+ const importName = pascalCase(`${configKey}Config`);
809
+ options.importItems[configKey].import.push({
810
+ name: `ModuleOptions as ${importName}`,
811
+ type: true
812
+ });
813
+ options.configs.push({ key: configKey, value: importName });
814
+ }
815
+ if (exportedTypes.includes("ModuleRuntimeContext")) {
816
+ const importName = pascalCase(`${configKey}Context`);
817
+ options.importItems[configKey].import.push({
818
+ name: `ModuleRuntimeContext as ${importName}`,
819
+ type: true
820
+ });
821
+ options.contexts.push({ key: configKey, value: importName });
822
+ }
823
+ if (exportedTypes.includes("ModuleRuntimeMethods")) {
824
+ const importName = pascalCase(`${configKey}Method`);
825
+ options.importItems[configKey].import.push({
826
+ name: `ModuleRuntimeMethods as ${importName}`,
827
+ type: true
828
+ });
829
+ options.methods.push({ key: configKey, value: importName });
830
+ }
831
+ if (exportedTypes.includes("ModuleRuntimeShared")) {
832
+ const importName = pascalCase(`${configKey}Shared`);
833
+ options.importItems[configKey].import.push({
834
+ name: `ModuleRuntimeShared as ${importName}`,
835
+ type: true
836
+ });
837
+ options.shareds.push({ key: configKey, value: importName });
838
+ }
839
+ if (exportedTypes.includes("ModuleHooks")) {
840
+ const importName = pascalCase(`${configKey}Hooks`);
841
+ options.importItems[configKey].import.push({
842
+ name: `ModuleHooks as ${importName}`,
843
+ type: true
844
+ });
845
+ options.hooks.push({ key: configKey, value: importName });
846
+ }
847
+ if (exportedTypes.includes("ModuleRuntimeHooks")) {
848
+ const importName = pascalCase(`${configKey}RuntimeHooks`);
849
+ options.importItems[configKey].import.push({
850
+ name: `ModuleRuntimeHooks as ${importName}`,
851
+ type: true
852
+ });
853
+ options.runtimeHooks.push({ key: configKey, value: importName });
938
854
  }
939
855
  }
940
856
  });
941
857
  }
942
858
 
943
- async function afterModuleScan(silgi) {
944
- await moduleScanHooks(silgi);
945
- }
946
-
947
859
  async function loadSilgiModuleInstance(silgiModule) {
948
860
  if (typeof silgiModule === "string") {
949
861
  throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
@@ -991,7 +903,7 @@ async function installModule(moduleToInstall, silgi = useSilgiCLI(), inlineOptio
991
903
  }
992
904
  }
993
905
 
994
- const logger = consola;
906
+ const logger$1 = consola;
995
907
  async function _resolveSilgiModule(mod, silgi) {
996
908
  let _url;
997
909
  let buildTimeModuleMeta = {};
@@ -1004,7 +916,6 @@ async function _resolveSilgiModule(mod, silgi) {
1004
916
  if (isRelative(mod)) {
1005
917
  mod = resolve(silgi.options.rootDir, mod);
1006
918
  }
1007
- paths.add(join(mod, "silgi"));
1008
919
  paths.add(join(mod, "module"));
1009
920
  paths.add(mod);
1010
921
  for (const path of paths) {
@@ -1021,8 +932,10 @@ async function _resolveSilgiModule(mod, silgi) {
1021
932
  } else {
1022
933
  if (typeof mod === "function") {
1023
934
  const meta = await mod.getMeta?.();
935
+ const _exports = await scanExports(_url, true);
1024
936
  buildTimeModuleMeta = {
1025
- ...meta
937
+ ...meta,
938
+ exports: _exports.map(({ from, ...rest }) => rest)
1026
939
  };
1027
940
  }
1028
941
  }
@@ -1032,7 +945,7 @@ async function _resolveSilgiModule(mod, silgi) {
1032
945
  if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
1033
946
  continue;
1034
947
  }
1035
- logger.error(`Error while importing module \`${mod}\`: ${error}`);
948
+ logger$1.error(`Error while importing module \`${mod}\`: ${error}`);
1036
949
  throw error;
1037
950
  }
1038
951
  }
@@ -1041,6 +954,9 @@ async function _resolveSilgiModule(mod, silgi) {
1041
954
  throw new Error(`Module ${mod} is not a valid Silgi module`);
1042
955
  }
1043
956
  if (typeof mod === "function") {
957
+ if (silgi.scanModules.some((m) => m.meta?.configKey === buildTimeModuleMeta.configKey)) {
958
+ throw new Error(`Module with key \`${buildTimeModuleMeta.configKey}\` already exists`);
959
+ }
1044
960
  silgi.scanModules.push({
1045
961
  meta: buildTimeModuleMeta,
1046
962
  entryPath: _url,
@@ -1093,9 +1009,8 @@ function topologicalSort(graph) {
1093
1009
  const temp = /* @__PURE__ */ new Set();
1094
1010
  const order = [];
1095
1011
  function visit(node) {
1096
- if (temp.has(node)) {
1097
- throw new Error(`D\xF6ng\xFCsel ba\u011F\u0131ml\u0131l\u0131k tespit edildi: ${node}`);
1098
- }
1012
+ if (temp.has(node))
1013
+ throw new Error(`Circular dependency detected: ${node}`);
1099
1014
  if (visited.has(node))
1100
1015
  return;
1101
1016
  temp.add(node);
@@ -1105,17 +1020,15 @@ function topologicalSort(graph) {
1105
1020
  }
1106
1021
  temp.delete(node);
1107
1022
  visited.add(node);
1108
- order.push(node);
1023
+ order.unshift(node);
1109
1024
  }
1110
1025
  for (const [node, deps] of graph.entries()) {
1111
- if (deps.size === 0 && !visited.has(node)) {
1026
+ if (deps.size === 0 && !visited.has(node))
1112
1027
  visit(node);
1113
- }
1114
1028
  }
1115
1029
  for (const node of graph.keys()) {
1116
- if (!visited.has(node)) {
1030
+ if (!visited.has(node))
1117
1031
  visit(node);
1118
- }
1119
1032
  }
1120
1033
  return order;
1121
1034
  }
@@ -1314,6 +1227,122 @@ async function createStorageCLI(silgi) {
1314
1227
  return storage;
1315
1228
  }
1316
1229
 
1230
+ const vueShim = {
1231
+ filename: "types/vue-shim.d.ts",
1232
+ getContents: ({ app }) => {
1233
+ if (!app.options.typescript.shim) {
1234
+ return "";
1235
+ }
1236
+ return [
1237
+ "declare module '*.vue' {",
1238
+ " import { DefineComponent } from 'vue'",
1239
+ " const component: DefineComponent<{}, {}, any>",
1240
+ " export default component",
1241
+ "}"
1242
+ ].join("\n");
1243
+ }
1244
+ };
1245
+ const pluginsDeclaration = {
1246
+ filename: "types/plugins.d.ts",
1247
+ getContents: async () => {
1248
+ return `
1249
+ declare module 'nuxt' {
1250
+ interface NuxtApp {
1251
+ $myPlugin: any;
1252
+ }
1253
+ }
1254
+ `;
1255
+ }
1256
+ };
1257
+
1258
+ const defaultTemplates = {
1259
+ __proto__: null,
1260
+ pluginsDeclaration: pluginsDeclaration,
1261
+ vueShim: vueShim
1262
+ };
1263
+
1264
+ const postTemplates = [
1265
+ pluginsDeclaration.filename
1266
+ ];
1267
+ const logger = useLogger("silgi");
1268
+ async function generateApp(app, options = {}) {
1269
+ app.templates = Object.values(defaultTemplates).concat(app.options.build.templates);
1270
+ await app.callHook("app:templates", app);
1271
+ app.templates = app.templates.map((tmpl) => normalizeTemplate(tmpl, app.options.silgi.vfsDir));
1272
+ const filteredTemplates = {
1273
+ pre: [],
1274
+ post: []
1275
+ };
1276
+ for (const template of app.templates) {
1277
+ if (options.filter && !options.filter(template)) {
1278
+ continue;
1279
+ }
1280
+ const key = template.filename && postTemplates.includes(template.filename) ? "post" : "pre";
1281
+ filteredTemplates[key].push(template);
1282
+ }
1283
+ const templateContext = { app };
1284
+ const writes = [];
1285
+ const indexImports = [];
1286
+ const dirs = /* @__PURE__ */ new Set();
1287
+ const changedTemplates = [];
1288
+ async function processTemplate(template) {
1289
+ const fullPath = template.dst || resolve(app.options.silgi.vfsDir, template.filename);
1290
+ const start = performance.now();
1291
+ const contents = await compileTemplate(template, templateContext).catch((e) => {
1292
+ logger.error(`Could not compile template \`${template.filename}\`.`);
1293
+ logger.error(e);
1294
+ throw e;
1295
+ });
1296
+ template.modified = true;
1297
+ if (template.modified) {
1298
+ changedTemplates.push(template);
1299
+ }
1300
+ const perf = performance.now() - start;
1301
+ const setupTime = Math.round(perf * 100) / 100;
1302
+ if (app.options.debug || setupTime > 500) {
1303
+ logger.info(`Compiled \`${template.filename}\` in ${setupTime}ms`);
1304
+ }
1305
+ if (template.modified && template.write) {
1306
+ dirs.add(dirname(fullPath));
1307
+ if (!fullPath.endsWith(".d.ts")) {
1308
+ indexImports.push(relativeWithDot(app.options.silgi.serverDir, fullPath));
1309
+ }
1310
+ writes.push(() => writeFileSync(fullPath, contents, "utf8"));
1311
+ }
1312
+ }
1313
+ await Promise.allSettled(filteredTemplates.pre.map(processTemplate));
1314
+ await Promise.allSettled(filteredTemplates.post.map(processTemplate));
1315
+ for (const dir of dirs) {
1316
+ mkdirSync(dir, { recursive: true });
1317
+ }
1318
+ for (const write of writes) {
1319
+ write();
1320
+ }
1321
+ writeFileSync(resolve(app.options.silgi.serverDir, "index.ts"), `${indexImports.map((i) => `export * from '${i}'`).join("\n")}
1322
+ `, "utf8");
1323
+ if (changedTemplates.length) {
1324
+ await app.callHook("app:templatesGenerated", app, changedTemplates, options);
1325
+ }
1326
+ }
1327
+ async function compileTemplate(template, ctx) {
1328
+ delete ctx.utils;
1329
+ if (template.src) {
1330
+ try {
1331
+ return await promises.readFile(template.src, "utf-8");
1332
+ } catch (err) {
1333
+ logger.error(`[nuxt] Error reading template from \`${template.src}\``);
1334
+ throw err;
1335
+ }
1336
+ }
1337
+ if (template.getContents) {
1338
+ return template.getContents({
1339
+ ...ctx,
1340
+ options: template.options
1341
+ });
1342
+ }
1343
+ throw new Error(`[nuxt] Invalid template. Templates must have either \`src\` or \`getContents\`: ${JSON.stringify(template)}`);
1344
+ }
1345
+
1317
1346
  const GLOB_SCAN_PATTERN = "**/*.{js,mjs,cjs,ts,mts,cts,tsx,jsx}";
1318
1347
  async function scanAndSyncOptions(silgi) {
1319
1348
  const scannedModules = await scanModules(silgi);
@@ -1325,7 +1354,7 @@ async function scanAndSyncOptions(silgi) {
1325
1354
  }
1326
1355
  }
1327
1356
  async function scanModules(silgi) {
1328
- const files = await scanFiles(silgi, "modules");
1357
+ const files = await scanFiles(silgi, "silgi/modules");
1329
1358
  return files.map((f) => f.fullPath);
1330
1359
  }
1331
1360
  async function scanFiles(silgi, name) {
@@ -1359,15 +1388,16 @@ async function createSilgiCLI(config = {}, opts = {}) {
1359
1388
  uris: {},
1360
1389
  shareds: {},
1361
1390
  schemas: {},
1362
- unimport: undefined,
1391
+ unimport: void 0,
1363
1392
  options,
1364
1393
  hooks,
1365
1394
  // vfs: {}
1366
1395
  _requiredModules: {},
1367
1396
  logger: consola.withTag("silgi"),
1368
1397
  close: () => silgi.hooks.callHook("close", silgi),
1369
- storage: undefined,
1398
+ storage: void 0,
1370
1399
  scanModules: [],
1400
+ templates: [],
1371
1401
  callHook: hooks.callHook,
1372
1402
  addHooks: hooks.addHooks,
1373
1403
  hook: hooks.hook,
@@ -1390,24 +1420,23 @@ async function createSilgiCLI(config = {}, opts = {}) {
1390
1420
  }
1391
1421
  await scanAndSyncOptions(silgi);
1392
1422
  await scanModules$1(silgi);
1393
- try {
1394
- await scanFiles$1(silgi);
1395
- await graphqlLoadSync(silgi);
1396
- } catch {
1397
- }
1423
+ await scanFiles$1(silgi);
1398
1424
  silgi.storage = await createStorageCLI(silgi);
1399
1425
  silgi.hooks.hook("close", async () => {
1400
1426
  await silgi.storage.dispose();
1401
1427
  });
1402
- if (silgi.options.logLevel !== undefined) {
1428
+ if (silgi.options.logLevel !== void 0) {
1403
1429
  silgi.logger.level = silgi.options.logLevel;
1404
1430
  }
1431
+ silgi.hooks.addHooks(silgi.options.hooks);
1405
1432
  await installModules(silgi);
1433
+ await silgi.hooks.callHook("scanFiles:done", silgi);
1434
+ await generateApp(silgi);
1406
1435
  if (silgi.options.imports) {
1407
1436
  silgi.unimport = createUnimport(silgi.options.imports);
1408
1437
  await silgi.unimport.init();
1409
1438
  }
1410
- await afterModuleScan(silgi);
1439
+ await registerModuleExportScan(silgi);
1411
1440
  return silgi;
1412
1441
  }
1413
1442
 
@@ -1422,17 +1451,25 @@ const prepare = defineCommand({
1422
1451
  preset: {
1423
1452
  type: "string",
1424
1453
  description: "The build preset to use (you can also use `SILGI_PRESET` environment variable)."
1454
+ },
1455
+ stub: {
1456
+ type: "boolean",
1457
+ description: "Run in silgi development mode"
1425
1458
  }
1426
1459
  },
1427
1460
  async run({ args }) {
1428
1461
  const rootDir = resolve(args.dir || args._dir || ".");
1429
- const silgi = await createSilgiCLI({ rootDir });
1430
- await prepare$1(silgi);
1462
+ const silgi = await createSilgiCLI({
1463
+ rootDir,
1464
+ dev: args.stub,
1465
+ stub: args.stub,
1466
+ typescript: { internalPaths: args.stub }
1467
+ });
1468
+ await prepare$1();
1431
1469
  for (const framework of frameworkSetup) {
1432
1470
  await framework(silgi);
1433
1471
  }
1434
1472
  await writeTypesAndFiles(silgi);
1435
- await scanUris(silgi);
1436
1473
  await silgi.callHook("read:core.ts", async () => {
1437
1474
  const data = await readCoreFile(silgi);
1438
1475
  return data;