silgi 0.5.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,6 +87,8 @@ async function nitroFramework(silgi, skip = false) {
93
87
  packageImport: "silgi/runtime/internal/nitro",
94
88
  path: join(runtimeDir, "internal/nitro")
95
89
  });
90
+ silgi.hook("prepare:core.ts", (_data) => {
91
+ });
96
92
  await h3Framework(silgi, true);
97
93
  }
98
94
 
@@ -104,28 +100,121 @@ async function nuxtFramework(silgi, skip = false) {
104
100
 
105
101
  const frameworkSetup = [h3Framework, nitroFramework, nuxtFramework];
106
102
 
107
- async function prepare$1(silgi) {
108
- await prepareDir(silgi.options.output.dir);
103
+ async function prepare$1(_silgi) {
104
+ }
105
+
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);
111
+ }
112
+ }
113
+ });
109
114
  }
110
- async function prepareDir(dir) {
111
- await fsp.rm(dir, { recursive: true, force: true });
112
- await fsp.mkdir(dir, { recursive: true });
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
+ });
113
194
  }
114
195
 
115
196
  async function readCoreFile(silgi) {
116
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
+ }
117
203
  const jiti = createJiti(silgi.options.rootDir, {
118
204
  fsCache: false,
119
- interopDefault: true,
120
205
  moduleCache: false,
206
+ debug: silgi.options.debug,
121
207
  alias: silgi.options.alias
122
208
  });
123
- const resolvedPath = jiti.esmResolve(path);
124
- const context = await promises.readFile(path, { encoding: "utf-8" });
125
- const coreFile = await jiti.import(
126
- resolvedPath,
209
+ const coreFile = await jiti.evalModule(
210
+ injectedResult.code,
127
211
  {
212
+ filename: path,
213
+ async: true,
128
214
  conditions: silgi.options.conditions
215
+ },
216
+ async (data, name) => {
217
+ return (await silgi.unimport.injectImports(data, name)).code;
129
218
  }
130
219
  );
131
220
  silgi.uris = coreFile.uris;
@@ -156,7 +245,7 @@ function traverseObject(silgi, obj, currentPath = []) {
156
245
  let paramString = "";
157
246
  if (node.router) {
158
247
  let params = null;
159
- if (node.router?._def?.typeName !== undefined) {
248
+ if (node.router?._def?.typeName !== void 0) {
160
249
  try {
161
250
  const shape = node.router?.shape?.params?.shape;
162
251
  params = shape ? Object.keys(shape) : null;
@@ -188,16 +277,19 @@ function scanActionModulesUris(silgi, obj, currentPath = []) {
188
277
  if (path.length === 4) {
189
278
  const basePath = path.join("/");
190
279
  let moduleName = "";
191
- if (node.modules?.graphqlyoga) {
280
+ if (node.modules?.yoga) {
192
281
  let rootFieldName = null;
193
- if (node.modules?.graphqlyoga?.rootFieldName) {
194
- moduleName = "graphqlyoga";
195
- rootFieldName = node.modules?.graphqlyoga?.rootFieldName;
282
+ if (node.modules?.yoga?.rootFieldName) {
283
+ moduleName = "yoga";
284
+ rootFieldName = node.modules?.yoga?.rootFieldName;
196
285
  }
197
286
  if (!rootFieldName) {
198
287
  return;
199
288
  }
200
289
  uriMap[moduleName] ??= {};
290
+ if (uriMap[moduleName].rootFieldName) {
291
+ silgi.logger.withTag("scanActionModulesUris").error(`Hata ${moduleName} ${rootFieldName} ${basePath} bu zaten burada kullanilmis.`);
292
+ }
201
293
  uriMap[moduleName].rootFieldName ??= {};
202
294
  uriMap[moduleName].rootFieldName[rootFieldName] = basePath;
203
295
  }
@@ -235,99 +327,6 @@ ${uriContent}
235
327
  await promises.writeFile(path, newContext);
236
328
  }
237
329
 
238
- async function generateSilgiStorageBaseType(silgi) {
239
- silgi.hook("prepare:schema.ts", async (options) => {
240
- if (silgi.options.storage) {
241
- for (const [key, _value] of Object.entries(silgi.options.storage)) {
242
- options.storeBase.push(key);
243
- }
244
- }
245
- });
246
- }
247
-
248
- async function generateRouterDTS(silgi) {
249
- silgi.hook("read:core.ts", async (data) => {
250
- silgi.hook("close", async () => {
251
- const { object } = await data();
252
- const uris = object.uris;
253
- const subPath = "srn";
254
- const groupedPaths = /* @__PURE__ */ new Map();
255
- Object.entries(uris || {}).forEach(([key, params]) => {
256
- const [service, resource, method, action] = key.split("/");
257
- const basePath = params ? `${subPath}/${service}/${resource}/${action}/${params}` : `${subPath}/${service}/${resource}/${action}`;
258
- const fullPath = `${subPath}/${service}/${resource}/${action}`;
259
- if (!groupedPaths.has(basePath)) {
260
- groupedPaths.set(basePath, /* @__PURE__ */ new Map());
261
- }
262
- groupedPaths.get(basePath)?.set(method.toLowerCase(), fullPath);
263
- });
264
- const keys = [
265
- " keys: {",
266
- Array.from(groupedPaths.entries()).map(([basePath, methods]) => {
267
- return ` '/${basePath}': {${Array.from(methods.entries()).map(([method, path]) => `
268
- ${method}: '/${path}'`).join(",")}
269
- }`;
270
- }).join(",\n"),
271
- " }",
272
- ""
273
- ].join("\n");
274
- const groupedRoutes = Object.entries(uris || {}).reduce((acc, [key, _params]) => {
275
- const [service, resource, method, action] = key.split("/");
276
- const routePath = `${subPath}/${service}/${resource}/${action}`;
277
- if (!acc[routePath]) {
278
- acc[routePath] = {};
279
- }
280
- acc[routePath][method] = {
281
- input: `ExtractInputFromURI<'${key}'>`,
282
- output: `ExtractOutputFromURI<'${key}'>`,
283
- params: `ExtractRouterParamsFromURI<'${key}'>['params']`
284
- };
285
- return acc;
286
- }, {});
287
- const routerTypes = Object.entries(groupedRoutes).map(([path, methods]) => {
288
- const methodEntries = Object.entries(methods).map(([method, { input, output, params }]) => {
289
- return ` '${method}': {
290
- input: ${input},
291
- output: ${output}
292
- params: ${params}
293
- }`;
294
- }).join(",\n");
295
- return ` '/${path}': {
296
- ${methodEntries}
297
- }`;
298
- });
299
- const nitro = [
300
- "declare module 'nitropack/types' {",
301
- " interface InternalApi extends RouterTypes {}",
302
- "}"
303
- ];
304
- const content = [
305
- keys.slice(0, -1),
306
- // son satırdaki boş satırı kaldır
307
- ...routerTypes
308
- ].join(",\n");
309
- const context = [
310
- "import type { ExtractInputFromURI, ExtractOutputFromURI, ExtractRouterParamsFromURI } from 'silgi/types'",
311
- "",
312
- "export interface RouterTypes {",
313
- content,
314
- "}",
315
- "",
316
- "declare module 'silgi/types' {",
317
- " interface SilgiRouterTypes extends RouterTypes {",
318
- " }",
319
- "}",
320
- "",
321
- silgi.options.preset === "h3" || silgi.options.preset === "nitro" ? nitro.join("\n") : "",
322
- "",
323
- "export {}"
324
- ].join("\n");
325
- const outputPath = resolve(silgi.options.build.typesDir, "silgi-routes.d.ts");
326
- await promises.writeFile(outputPath, context);
327
- });
328
- });
329
- }
330
-
331
330
  async function createCoreFramework(silgi) {
332
331
  const relativeRootDir = relativeWithDot(silgi.options.rootDir, silgi.options.serverDir);
333
332
  if (silgi.options.preset !== "nitro" && silgi.options.preset !== "h3")
@@ -335,7 +334,7 @@ async function createCoreFramework(silgi) {
335
334
  const importItems = {
336
335
  "silgi/types": {
337
336
  import: [
338
- { name: "SilgiModuleContext", type: true }
337
+ { name: "ModuleRuntimeContext", type: true }
339
338
  ],
340
339
  from: "silgi/types"
341
340
  }
@@ -360,7 +359,7 @@ async function createCoreFramework(silgi) {
360
359
  functions
361
360
  });
362
361
  const content = [
363
- ...functions.map((f) => ` await ${f}(framework)`)
362
+ ...functions.map((f) => f.params?.length ? ` await ${f.name}(framework, ${f.params.join(",")})` : ` await ${f.name}(framework)`)
364
363
  ];
365
364
  return {
366
365
  content,
@@ -373,7 +372,7 @@ async function createDTSFramework(silgi) {
373
372
  const importItems = {
374
373
  "silgi/types": {
375
374
  import: [
376
- { name: "SilgiModuleContext", type: true }
375
+ { name: "ModuleRuntimeContext", type: true }
377
376
  ],
378
377
  from: "silgi/types"
379
378
  }
@@ -421,7 +420,7 @@ async function schemaTemplate(silgi) {
421
420
  import: [
422
421
  { name: "URIsTypes", type: true },
423
422
  { name: "Namespaces", type: true },
424
- { name: "SilgiModuleContext", type: true }
423
+ { name: "ModuleRuntimeContext", type: true }
425
424
  ],
426
425
  from: "silgi/types"
427
426
  }
@@ -438,23 +437,20 @@ async function schemaTemplate(silgi) {
438
437
  importItems[pkg.name].from = isAbsolute(id) ? relativeWithDot(relativeRootDir, id) : id;
439
438
  }
440
439
  }));
441
- const customImports = [];
442
- const configs = [];
443
- const contexts = [];
444
- const methods = [];
445
- const shareds = [];
446
- const events = [];
447
- const storeBase = [];
448
- await silgi.callHook("prepare:schema.ts", {
440
+ const data = {
449
441
  importItems,
450
- customImports,
451
- configs,
452
- contexts,
453
- methods,
454
- shareds,
455
- storeBase,
456
- events
457
- });
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);
458
454
  const silgiExport = relativeWithDot(silgi.options.build.typesDir, `${silgi.options.silgi.serverDir}/core.ts`);
459
455
  let addSilgiContext = false;
460
456
  const importsContent = [
@@ -463,7 +459,7 @@ async function schemaTemplate(silgi) {
463
459
  return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${path}'`;
464
460
  }),
465
461
  "",
466
- ...customImports,
462
+ ...data.customImports,
467
463
  ""
468
464
  ];
469
465
  const importData = [
@@ -475,31 +471,34 @@ async function schemaTemplate(silgi) {
475
471
  "",
476
472
  `type SilgiURIsMerge = URIsTypes<typeof import('${silgiExport}')['uris']>`,
477
473
  "",
478
- contexts.length ? `type SilgiModuleContextExtends = ${contexts.map(({ value }) => value).join(" & ")}` : "type SilgiModuleContextExtends = {}",
474
+ `type SilgiModuleContextExtends = ${data.contexts.length ? data.contexts.map(({ value }) => value).join(" & ") : "{}"}`,
479
475
  "",
480
- events.length ? `interface SilgiModuleEventsExtends extends ${events.map((item) => item.extends ? item.value : "").join(", ")} {
481
- ${events.map((item) => {
476
+ data.events.length ? `interface SilgiModuleEventsExtends extends ${data.events.map((item) => item.extends ? item.value : "").join(", ")} {
477
+ ${data.events.map((item) => {
482
478
  if (item.isSilgiContext) {
483
479
  addSilgiContext = true;
484
480
  }
485
- 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" : "";
486
482
  }).join(",\n")}
487
483
  }` : "interface SilgiModuleEventsExtends {}",
488
484
  "",
489
- 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 = {}",
490
486
  "",
491
487
  "interface SilgiModuleMethodsExtends {",
492
- ...(methods).map(({ key, value }) => ` ${key}: ${value},`),
488
+ ...(data.methods || []).map(({ key, value }) => ` ${key}: ${value},`),
493
489
  "}",
494
490
  "",
495
491
  "interface SilgiModuleOptionsExtends {",
496
- ...(configs).map(({ key, value }) => ` ${key}: ${value},`),
492
+ ...(data.configs || []).map(({ key, value }) => ` ${key}: ${value},`),
497
493
  "}",
498
494
  "",
499
495
  "interface SilgiStorageBaseExtends {",
500
- ...(storeBase).map((value) => ` ${value}: ''`),
496
+ ...(storeBase || []).map((value) => ` ${value}: ''`),
501
497
  "}",
502
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(" & ") : "{}"}`,
503
502
  "",
504
503
  "declare module 'silgi/types' {",
505
504
  " interface FrameworkContext extends FrameworkContextExtends {}",
@@ -508,11 +507,13 @@ async function schemaTemplate(silgi) {
508
507
  " interface SilgiStorageBase extends SilgiStorageBaseExtends {}",
509
508
  " interface SilgiModules extends SilgiModuleOptionsExtends {}",
510
509
  " interface SilgiURIs extends SilgiURIsMerge {}",
511
- " interface SilgiModuleContext extends SilgiModuleContextExtends {}",
510
+ " interface ModuleRuntimeContext extends SilgiModuleContextExtends {}",
512
511
  " interface SilgiEvent extends SilgiModuleEventsExtends {}",
513
512
  " interface SilgiDefaultShared extends SilgiModuleSharedExtends {}",
514
- " interface SilgiModuleMethods extends SilgiModuleMethodsExtends {}",
515
- " interface SilgiModuleOptions extends SilgiModuleOptionsExtends {}",
513
+ " interface ModuleRuntimeMethods extends SilgiModuleMethodsExtends {}",
514
+ " interface ModuleOptions extends SilgiModuleOptionsExtends {}",
515
+ " interface ModuleRuntimeHooks extends SilgiRuntimeHooksExtends {}",
516
+ " interface ModuleHooks extends ModuleHooksExtend {}",
516
517
  "}",
517
518
  "",
518
519
  "export {}"
@@ -533,11 +534,17 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
533
534
  },
534
535
  "silgi/types": {
535
536
  import: [
536
- { name: "SilgiModuleOptions", type: true },
537
+ { name: "ModuleOptions", type: true },
537
538
  { name: "SilgiOptions", type: true },
538
- { name: "FrameworkContext", type: true }
539
+ { name: "FrameworkContext", type: true },
540
+ { name: "DeepPartial", type: true },
541
+ { name: "BuildConfig", type: true }
539
542
  ],
540
543
  from: "silgi/types"
544
+ },
545
+ "#silgi/vfs": {
546
+ import: [],
547
+ from: "./vfs"
541
548
  }
542
549
  };
543
550
  importItems = { ...data._importItems, ...importItems };
@@ -559,6 +566,13 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
559
566
  const shareds = [];
560
567
  const schemas = [];
561
568
  const buildSilgiExtraContent = [];
569
+ const _silgiOptions = {};
570
+ const _silgiConfigs = [];
571
+ for (const module of silgi.scanModules) {
572
+ _silgiOptions[module.meta.configKey] = {
573
+ ...module.options
574
+ };
575
+ }
562
576
  await silgi.callHook("prepare:core.ts", {
563
577
  importItems,
564
578
  customImports,
@@ -566,8 +580,13 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
566
580
  services,
567
581
  shareds,
568
582
  schemas,
569
- buildSilgiExtraContent
583
+ buildSilgiExtraContent,
584
+ _silgiOptions,
585
+ _silgiConfigs
570
586
  });
587
+ if (importItems["#silgi/vfs"].import.length === 0) {
588
+ delete importItems["#silgi/vfs"];
589
+ }
571
590
  if (services.length > 0) {
572
591
  importItems["silgi/core"].import.push({ name: "mergeServices" });
573
592
  }
@@ -580,13 +599,14 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
580
599
  const plugins = [];
581
600
  for (const plugin of silgi.options.plugins) {
582
601
  const pluginImportName = `_${hash(plugin.packageImport)}`;
583
- customImports.push(`import ${pluginImportName} from '${plugin.packageImport}';`);
602
+ customImports.push(`import ${pluginImportName} from '${plugin.packageImport}'`);
584
603
  plugins.push(pluginImportName);
585
604
  }
586
605
  const importsContent = [
587
606
  ...Object.entries(importItems).map(([_name, { from, import: imports }]) => {
588
607
  return `import { ${imports.map(({ type, name }) => type ? `type ${name}` : name).join(", ")} } from '${from}'`;
589
608
  }),
609
+ "",
590
610
  ...customImports,
591
611
  ""
592
612
  ];
@@ -613,9 +633,9 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
613
633
  }),
614
634
  shareds.length > 0 ? "])" : "}",
615
635
  "",
636
+ `export const _silgiOptions: DeepPartial<ModuleOptions> = ${JSON.stringify(_silgiOptions, null, 2)}`,
616
637
  "",
617
- "export async function buildSilgi(framework: FrameworkContext, options?: Partial<SilgiModuleOptions>) {",
618
- " try {",
638
+ "export async function buildSilgi(framework: FrameworkContext, moduleOptions?: Partial<ModuleOptions>,buildOptions?: Partial<BuildConfig>, ) {",
619
639
  " const silgi = await createSilgi({",
620
640
  " framework,",
621
641
  " shared: shareds as any,",
@@ -624,10 +644,12 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
624
644
  " uris,",
625
645
  " modulesURIs,",
626
646
  ` plugins: [${plugins.join(", ")}],`,
627
- "",
647
+ _silgiConfigs.length > 0 ? ` ${_silgiConfigs.map((config) => Object.entries(config).map(([key, value]) => `${key}: ${value}`)).join(",\n ")},` : "",
648
+ " ...buildOptions,",
628
649
  " options: {",
629
650
  ` present: '${silgi.options.preset}',`,
630
- " ...options,",
651
+ " ..._silgiOptions,",
652
+ " ...moduleOptions,",
631
653
  " },",
632
654
  " })",
633
655
  "",
@@ -636,9 +658,6 @@ async function silgiCoreFile(data, frameworkContext, silgi) {
636
658
  ...buildSilgiExtraContent,
637
659
  "",
638
660
  " return silgi",
639
- " } catch (error) {",
640
- " throw new Error(error.message)",
641
- " }",
642
661
  "}",
643
662
  ""
644
663
  ];
@@ -745,14 +764,19 @@ async function writeTypesAndFiles(silgi) {
745
764
  path: join(typesDir, "framework.d.ts"),
746
765
  contents: frameworkDTS.content.join("\n")
747
766
  });
748
- await Promise.all(
749
- buildFiles.map(async (file) => {
750
- await writeFile(
751
- resolve(silgi.options.build.dir, file.path),
752
- file.contents
753
- );
754
- })
755
- );
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);
756
780
  }
757
781
 
758
782
  const commonArgs = {
@@ -767,133 +791,71 @@ const commonArgs = {
767
791
  }
768
792
  };
769
793
 
770
- async function graphQLLoadSchemaSync(schemaPointers, data = {}) {
771
- let result;
772
- try {
773
- result = loadSchemaSync(schemaPointers, {
774
- ...data,
775
- loaders: [
776
- new GraphQLFileLoader(),
777
- ...data.loaders || []
778
- ]
779
- });
780
- } catch (e) {
781
- if (
782
- // https://www.graphql-tools.com/docs/documents-loading#no-files-found
783
- (e.message || "").includes(
784
- "Unable to find any GraphQL type definitions for the following pointers:"
785
- )
786
- ) ; else {
787
- throw e;
788
- }
789
- }
790
- return result;
791
- }
792
-
793
- async function graphqlLoadSync(silgi) {
794
- const typeDefs = [];
795
- const resolvers = [];
796
- await silgi.callHook("before:graphql:schema", {
797
- typeDefs,
798
- resolvers
799
- });
800
- const schema = await graphQLLoadSchemaSync(silgi.options.serverDir, {
801
- cwd: silgi.options.rootDir
802
- });
803
- const makeSchema = makeExecutableSchema({
804
- typeDefs,
805
- resolvers
806
- });
807
- const merge = mergeSchemas({
808
- schemas: schema ? [makeSchema, schema] : [makeSchema]
809
- });
810
- if (merge) {
811
- const schemaString = printSchemaWithDirectives(merge);
812
- const context = [
813
- "// THIS FILE IS GENERATED, DO NOT EDIT!",
814
- "/* eslint-disable eslint-comments/no-unlimited-disable */",
815
- "/* tslint:disable */",
816
- "/* eslint-disable */",
817
- "/* prettier-ignore */",
818
- "/* silgi */",
819
- "export const schema = `",
820
- "",
821
- schemaString,
822
- "",
823
- "`"
824
- ].join("\n");
825
- const fsPath = join$1(silgi.options.silgi.serverDir, "generated/graphql.schema.ts");
826
- await promises.mkdir(dirname(fsPath), { recursive: true });
827
- await promises.writeFile(fsPath, context);
828
- }
829
- return {
830
- schema
831
- };
832
- }
833
-
834
- function moduleScanHooks(silgi) {
794
+ async function registerModuleExportScan(silgi) {
835
795
  silgi.hook("prepare:schema.ts", async (options) => {
836
796
  for (const module of silgi.scanModules) {
837
797
  const exports = module.meta.exports;
838
- if (exports?.interface) {
839
- let importName;
840
- options.importItems[module.meta.configKey] = {
841
- import: [],
842
- from: module.meta.name || module.meta._packageName
843
- };
844
- if (exports.interface.config) {
845
- importName = pascalCase(`${module.meta.configKey}Config`);
846
- options.importItems[module.meta.configKey].import.push({
847
- name: `SilgiModuleOptions as ${importName}`,
848
- type: true
849
- });
850
- options.configs.push({
851
- key: module.meta.configKey,
852
- value: importName
853
- });
854
- }
855
- if (exports.interface.context) {
856
- importName = pascalCase(`${module.meta.configKey}Context`);
857
- options.importItems[module.meta.configKey].import.push({
858
- name: `SilgiModuleContext as ${importName}`,
859
- type: true
860
- });
861
- options.contexts.push({
862
- key: module.meta.configKey,
863
- value: importName
864
- });
865
- }
866
- if (exports.interface.method) {
867
- importName = pascalCase(`${module.meta.configKey}Method`);
868
- options.importItems[module.meta.configKey].import.push({
869
- name: `SilgiModuleMethods as ${importName}`,
870
- type: true
871
- });
872
- options.methods.push({
873
- key: module.meta.configKey,
874
- value: importName
875
- });
876
- }
877
- if (exports.interface.shared) {
878
- importName = pascalCase(`${module.meta.configKey}Shared`);
879
- options.importItems[module.meta.configKey].import.push({
880
- name: `SilgiModuleShared as ${importName}`,
881
- type: true
882
- });
883
- options.shareds.push({
884
- key: module.meta.configKey,
885
- value: importName
886
- });
887
- }
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 });
888
854
  }
889
855
  }
890
856
  });
891
857
  }
892
858
 
893
- async function afterModuleScan(silgi) {
894
- await moduleScanHooks(silgi);
895
- }
896
-
897
859
  async function loadSilgiModuleInstance(silgiModule) {
898
860
  if (typeof silgiModule === "string") {
899
861
  throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
@@ -941,7 +903,7 @@ async function installModule(moduleToInstall, silgi = useSilgiCLI(), inlineOptio
941
903
  }
942
904
  }
943
905
 
944
- const logger = consola;
906
+ const logger$1 = consola;
945
907
  async function _resolveSilgiModule(mod, silgi) {
946
908
  let _url;
947
909
  let buildTimeModuleMeta = {};
@@ -954,7 +916,6 @@ async function _resolveSilgiModule(mod, silgi) {
954
916
  if (isRelative(mod)) {
955
917
  mod = resolve(silgi.options.rootDir, mod);
956
918
  }
957
- paths.add(join(mod, "silgi"));
958
919
  paths.add(join(mod, "module"));
959
920
  paths.add(mod);
960
921
  for (const path of paths) {
@@ -971,8 +932,10 @@ async function _resolveSilgiModule(mod, silgi) {
971
932
  } else {
972
933
  if (typeof mod === "function") {
973
934
  const meta = await mod.getMeta?.();
935
+ const _exports = await scanExports(_url, true);
974
936
  buildTimeModuleMeta = {
975
- ...meta
937
+ ...meta,
938
+ exports: _exports.map(({ from, ...rest }) => rest)
976
939
  };
977
940
  }
978
941
  }
@@ -982,7 +945,7 @@ async function _resolveSilgiModule(mod, silgi) {
982
945
  if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
983
946
  continue;
984
947
  }
985
- logger.error(`Error while importing module \`${mod}\`: ${error}`);
948
+ logger$1.error(`Error while importing module \`${mod}\`: ${error}`);
986
949
  throw error;
987
950
  }
988
951
  }
@@ -991,10 +954,14 @@ async function _resolveSilgiModule(mod, silgi) {
991
954
  throw new Error(`Module ${mod} is not a valid Silgi module`);
992
955
  }
993
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
+ }
994
960
  silgi.scanModules.push({
995
961
  meta: buildTimeModuleMeta,
996
962
  entryPath: _url,
997
- installed: false
963
+ installed: false,
964
+ options: await mod.getOptions?.() || {}
998
965
  });
999
966
  }
1000
967
  }
@@ -1042,9 +1009,8 @@ function topologicalSort(graph) {
1042
1009
  const temp = /* @__PURE__ */ new Set();
1043
1010
  const order = [];
1044
1011
  function visit(node) {
1045
- if (temp.has(node)) {
1046
- throw new Error(`D\xF6ng\xFCsel ba\u011F\u0131ml\u0131l\u0131k tespit edildi: ${node}`);
1047
- }
1012
+ if (temp.has(node))
1013
+ throw new Error(`Circular dependency detected: ${node}`);
1048
1014
  if (visited.has(node))
1049
1015
  return;
1050
1016
  temp.add(node);
@@ -1054,17 +1020,15 @@ function topologicalSort(graph) {
1054
1020
  }
1055
1021
  temp.delete(node);
1056
1022
  visited.add(node);
1057
- order.push(node);
1023
+ order.unshift(node);
1058
1024
  }
1059
1025
  for (const [node, deps] of graph.entries()) {
1060
- if (deps.size === 0 && !visited.has(node)) {
1026
+ if (deps.size === 0 && !visited.has(node))
1061
1027
  visit(node);
1062
- }
1063
1028
  }
1064
1029
  for (const node of graph.keys()) {
1065
- if (!visited.has(node)) {
1030
+ if (!visited.has(node))
1066
1031
  visit(node);
1067
- }
1068
1032
  }
1069
1033
  return order;
1070
1034
  }
@@ -1263,6 +1227,122 @@ async function createStorageCLI(silgi) {
1263
1227
  return storage;
1264
1228
  }
1265
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
+
1266
1346
  const GLOB_SCAN_PATTERN = "**/*.{js,mjs,cjs,ts,mts,cts,tsx,jsx}";
1267
1347
  async function scanAndSyncOptions(silgi) {
1268
1348
  const scannedModules = await scanModules(silgi);
@@ -1274,7 +1354,7 @@ async function scanAndSyncOptions(silgi) {
1274
1354
  }
1275
1355
  }
1276
1356
  async function scanModules(silgi) {
1277
- const files = await scanFiles(silgi, "modules");
1357
+ const files = await scanFiles(silgi, "silgi/modules");
1278
1358
  return files.map((f) => f.fullPath);
1279
1359
  }
1280
1360
  async function scanFiles(silgi, name) {
@@ -1308,15 +1388,16 @@ async function createSilgiCLI(config = {}, opts = {}) {
1308
1388
  uris: {},
1309
1389
  shareds: {},
1310
1390
  schemas: {},
1311
- unimport: undefined,
1391
+ unimport: void 0,
1312
1392
  options,
1313
1393
  hooks,
1314
1394
  // vfs: {}
1315
1395
  _requiredModules: {},
1316
1396
  logger: consola.withTag("silgi"),
1317
1397
  close: () => silgi.hooks.callHook("close", silgi),
1318
- storage: undefined,
1398
+ storage: void 0,
1319
1399
  scanModules: [],
1400
+ templates: [],
1320
1401
  callHook: hooks.callHook,
1321
1402
  addHooks: hooks.addHooks,
1322
1403
  hook: hooks.hook,
@@ -1340,20 +1421,22 @@ async function createSilgiCLI(config = {}, opts = {}) {
1340
1421
  await scanAndSyncOptions(silgi);
1341
1422
  await scanModules$1(silgi);
1342
1423
  await scanFiles$1(silgi);
1343
- await graphqlLoadSync(silgi);
1344
1424
  silgi.storage = await createStorageCLI(silgi);
1345
1425
  silgi.hooks.hook("close", async () => {
1346
1426
  await silgi.storage.dispose();
1347
1427
  });
1348
- if (silgi.options.logLevel !== undefined) {
1428
+ if (silgi.options.logLevel !== void 0) {
1349
1429
  silgi.logger.level = silgi.options.logLevel;
1350
1430
  }
1431
+ silgi.hooks.addHooks(silgi.options.hooks);
1351
1432
  await installModules(silgi);
1433
+ await silgi.hooks.callHook("scanFiles:done", silgi);
1434
+ await generateApp(silgi);
1352
1435
  if (silgi.options.imports) {
1353
1436
  silgi.unimport = createUnimport(silgi.options.imports);
1354
1437
  await silgi.unimport.init();
1355
1438
  }
1356
- await afterModuleScan(silgi);
1439
+ await registerModuleExportScan(silgi);
1357
1440
  return silgi;
1358
1441
  }
1359
1442
 
@@ -1368,17 +1451,25 @@ const prepare = defineCommand({
1368
1451
  preset: {
1369
1452
  type: "string",
1370
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"
1371
1458
  }
1372
1459
  },
1373
1460
  async run({ args }) {
1374
1461
  const rootDir = resolve(args.dir || args._dir || ".");
1375
- const silgi = await createSilgiCLI({ rootDir });
1376
- 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();
1377
1469
  for (const framework of frameworkSetup) {
1378
1470
  await framework(silgi);
1379
1471
  }
1380
1472
  await writeTypesAndFiles(silgi);
1381
- await scanUris(silgi);
1382
1473
  await silgi.callHook("read:core.ts", async () => {
1383
1474
  const data = await readCoreFile(silgi);
1384
1475
  return data;